mirror of
https://github.com/sailfishos/ofono
synced 2025-11-29 14:11:05 +08:00
Compare commits
38 Commits
jolla-1.1.
...
mer/1.14+g
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
011bc0741a | ||
|
|
773834c5a3 | ||
|
|
14acafc581 | ||
|
|
b4df40608b | ||
|
|
26f750fe4f | ||
|
|
51f6837545 | ||
|
|
6919c43ff6 | ||
|
|
621614e518 | ||
|
|
8e820dfdd3 | ||
|
|
04cc2e9fd2 | ||
|
|
ae5c8e6e3a | ||
|
|
1509cb811a | ||
|
|
5682df6d82 | ||
|
|
3e38512e2f | ||
|
|
dc5157c5d0 | ||
|
|
59449f74a1 | ||
|
|
ff63e9b057 | ||
|
|
7b73f569eb | ||
|
|
5672f7248d | ||
|
|
2ed0073bd1 | ||
|
|
f6ade48648 | ||
|
|
73ba48c9fb | ||
|
|
f3611cef21 | ||
|
|
15d682e62a | ||
|
|
0c23ed90b7 | ||
|
|
54854c44a2 | ||
|
|
da297d5722 | ||
|
|
aba76cec73 | ||
|
|
3cdc8f775d | ||
|
|
bee03f8b56 | ||
|
|
7f4da6d59f | ||
|
|
5754fff800 | ||
|
|
fff6952703 | ||
|
|
96ff96ab1a | ||
|
|
986ac50b9e | ||
|
|
8600d8d293 | ||
|
|
369af1b401 | ||
|
|
500b5234b2 |
@@ -120,6 +120,9 @@ endif
|
||||
if RILMODEM
|
||||
builtin_sources += $(gril_sources)
|
||||
|
||||
builtin_modules += rildev
|
||||
builtin_sources += plugins/rildev.c
|
||||
|
||||
builtin_modules += ril
|
||||
builtin_sources += plugins/ril.c
|
||||
|
||||
|
||||
@@ -155,6 +155,15 @@ Methods dict GetProperties()
|
||||
[service].Error.AttachInProgress
|
||||
[service].Error.NotImplemented
|
||||
|
||||
Methods void ProvisionContext()
|
||||
Resets all properties back to default. Fails to make
|
||||
any changes to the context if it is active or in the
|
||||
process of being activated or deactivated.
|
||||
|
||||
Possible Errors: [service].Error.Failed
|
||||
[service].Error.InProgress
|
||||
[service].Error.NotAvailable
|
||||
|
||||
Signals PropertyChanged(string property, variant value)
|
||||
|
||||
This signal indicates a changed value of the given
|
||||
|
||||
@@ -66,6 +66,8 @@ struct gprs_context_data {
|
||||
gint active_rild_cid;
|
||||
enum state state;
|
||||
guint regid;
|
||||
struct unsol_data_call_list *old_list;
|
||||
guint prev_active_status;
|
||||
};
|
||||
|
||||
static void set_context_disconnected(struct gprs_context_data *gcd)
|
||||
@@ -179,6 +181,7 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
||||
struct data_call *call = NULL;
|
||||
struct unsol_data_call_list *unsol;
|
||||
gboolean disconnect = FALSE;
|
||||
gboolean signal = FALSE;
|
||||
GSList *iterator = NULL;
|
||||
struct ofono_error error;
|
||||
|
||||
@@ -187,6 +190,12 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
||||
if (error.type != OFONO_ERROR_TYPE_NO_ERROR)
|
||||
goto error;
|
||||
|
||||
if (g_ril_unsol_cmp_dcl(unsol,gcd->old_list,gcd->active_rild_cid))
|
||||
goto error;
|
||||
|
||||
g_ril_unsol_free_data_call_list(gcd->old_list);
|
||||
gcd->old_list = unsol;
|
||||
|
||||
DBG("number of call in call_list_changed is: %d", unsol->num);
|
||||
|
||||
for (iterator = unsol->call_list; iterator; iterator = iterator->next) {
|
||||
@@ -199,11 +208,15 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
||||
if (call->cid != gcd->active_rild_cid)
|
||||
continue;
|
||||
|
||||
if (call->active == DATA_CALL_LINK_DOWN)
|
||||
gcd->prev_active_status = call->active;
|
||||
|
||||
if (call->status != 0)
|
||||
ofono_info("data call status:%d", call->status);
|
||||
|
||||
if (call->active == DATA_CALL_INACTIVE) {
|
||||
disconnect = TRUE;
|
||||
gcd->prev_active_status = call->active;
|
||||
ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
|
||||
break;
|
||||
}
|
||||
@@ -211,6 +224,11 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
||||
if (call->active == DATA_CALL_ACTIVE) {
|
||||
int protocol = -1;
|
||||
|
||||
if (gcd->prev_active_status != DATA_CALL_LINK_DOWN)
|
||||
signal = TRUE;
|
||||
|
||||
gcd->prev_active_status = call->active;
|
||||
|
||||
if (call->type)
|
||||
protocol = ril_protocol_string_to_ofono_protocol(call->type);
|
||||
|
||||
@@ -321,8 +339,15 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
||||
if (disconnect) {
|
||||
ofono_error("Clearing active context");
|
||||
set_context_disconnected(gcd);
|
||||
gcd->old_list = NULL;
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (signal)
|
||||
ofono_gprs_context_signal_change(gc, gcd->active_ctx_cid);
|
||||
|
||||
return;
|
||||
|
||||
error:
|
||||
g_ril_unsol_free_data_call_list(unsol);
|
||||
}
|
||||
@@ -651,6 +676,8 @@ static void ril_gprs_context_remove(struct ofono_gprs_context *gc)
|
||||
|
||||
DBG("");
|
||||
|
||||
g_ril_unsol_free_data_call_list(gcd->old_list);
|
||||
|
||||
if (gcd->state != STATE_IDLE)
|
||||
ril_gprs_context_detach_shutdown(gc, 0);
|
||||
|
||||
|
||||
@@ -679,31 +679,7 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
||||
}
|
||||
}
|
||||
|
||||
if (current_passwd) {
|
||||
if (!strcmp(current_passwd, defaultpasswd)) {
|
||||
__ofono_sim_recheck_pin(sim);
|
||||
} else if (sd->passwd_state !=
|
||||
OFONO_SIM_PASSWORD_SIM_PIN) {
|
||||
__ofono_sim_recheck_pin(sim);
|
||||
} else if (sd->passwd_state ==
|
||||
OFONO_SIM_PASSWORD_SIM_PIN) {
|
||||
parcel_init(&rilp);
|
||||
|
||||
parcel_w_int32(&rilp,
|
||||
ENTER_SIM_PIN_PARAMS);
|
||||
parcel_w_string(&rilp, current_passwd);
|
||||
parcel_w_string(&rilp, sd->aid_str);
|
||||
|
||||
g_ril_send(sd->ril,
|
||||
RIL_REQUEST_ENTER_SIM_PIN,
|
||||
rilp.data, rilp.size, NULL,
|
||||
NULL, g_free);
|
||||
|
||||
parcel_free(&rilp);
|
||||
}
|
||||
} else {
|
||||
__ofono_sim_recheck_pin(sim);
|
||||
}
|
||||
__ofono_sim_recheck_pin(sim);
|
||||
|
||||
if (current_online_state == RIL_ONLINE_PREF) {
|
||||
|
||||
@@ -737,9 +713,6 @@ static void sim_status_cb(struct ril_msg *message, gpointer user_data)
|
||||
sd->removed = TRUE;
|
||||
sd->card_state = RIL_CARDSTATE_ABSENT;
|
||||
|
||||
if (current_passwd)
|
||||
g_stpcpy(current_passwd, defaultpasswd);
|
||||
|
||||
sd->initialized = FALSE;
|
||||
}
|
||||
}
|
||||
@@ -886,8 +859,6 @@ static void ril_pin_change_state_cb(struct ril_msg *message, gpointer user_data)
|
||||
g_ril_print_response_no_args(sd->ril, message);
|
||||
|
||||
} else {
|
||||
if (current_passwd)
|
||||
g_stpcpy(current_passwd, defaultpasswd);
|
||||
CALLBACK_WITH_FAILURE(cb, cbd->data);
|
||||
}
|
||||
|
||||
@@ -905,9 +876,6 @@ static void ril_pin_send(struct ofono_sim *sim, const char *passwd,
|
||||
sd->passwd_type = OFONO_SIM_PASSWORD_SIM_PIN;
|
||||
cbd->user = sd;
|
||||
|
||||
if (current_passwd)
|
||||
g_stpcpy(current_passwd, passwd);
|
||||
|
||||
parcel_init(&rilp);
|
||||
|
||||
parcel_w_int32(&rilp, ENTER_SIM_PIN_PARAMS);
|
||||
@@ -995,8 +963,6 @@ static void ril_pin_change_state(struct ofono_sim *sim,
|
||||
*/
|
||||
switch (passwd_type) {
|
||||
case OFONO_SIM_PASSWORD_SIM_PIN:
|
||||
if (current_passwd)
|
||||
g_stpcpy(current_passwd, passwd);
|
||||
g_ril_append_print_buf(sd->ril, "(SC,");
|
||||
parcel_w_string(&rilp, "SC");
|
||||
break;
|
||||
@@ -1078,9 +1044,6 @@ static void ril_pin_send_puk(struct ofono_sim *sim,
|
||||
sd->passwd_type = OFONO_SIM_PASSWORD_SIM_PUK;
|
||||
cbd->user = sd;
|
||||
|
||||
if (current_passwd)
|
||||
g_stpcpy(current_passwd, passwd);
|
||||
|
||||
parcel_init(&rilp);
|
||||
|
||||
parcel_w_int32(&rilp, ENTER_SIM_PUK_PARAMS);
|
||||
@@ -1129,8 +1092,6 @@ static void ril_change_passwd(struct ofono_sim *sim,
|
||||
|
||||
if (passwd_type == OFONO_SIM_PASSWORD_SIM_PIN2)
|
||||
request = RIL_REQUEST_CHANGE_SIM_PIN2;
|
||||
else if (current_passwd)
|
||||
g_stpcpy(current_passwd, new_passwd);
|
||||
|
||||
ret = g_ril_send(sd->ril, request, rilp.data, rilp.size,
|
||||
ril_pin_change_state_cb, cbd, g_free);
|
||||
|
||||
@@ -834,8 +834,8 @@ static struct ril_s *create_ril()
|
||||
|
||||
ril->sk = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
if (ril->sk < 0) {
|
||||
ofono_error("create_ril: can't create unix socket: %s (%d)\n",
|
||||
strerror(errno), errno);
|
||||
ofono_error("%s: can't create unix socket: %s (%d)\n",
|
||||
__func__, strerror(errno), errno);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -844,15 +844,15 @@ static struct ril_s *create_ril()
|
||||
strncpy(addr.sun_path, RILD_CMD_SOCKET, sizeof(addr.sun_path) - 1);
|
||||
|
||||
if (connect(ril->sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
ofono_error("create_ril: can't connect to RILD: %s (%d)\n",
|
||||
strerror(errno), errno);
|
||||
ofono_error("%s: can't connect to RILD: %s (%d)\n",
|
||||
__func__, strerror(errno), errno);
|
||||
goto error;
|
||||
}
|
||||
|
||||
io = g_io_channel_unix_new(ril->sk);
|
||||
if (io == NULL) {
|
||||
ofono_error("create_ril: can't connect to RILD: %s (%d)\n",
|
||||
strerror(errno), errno);
|
||||
ofono_error("%s: can't connect to RILD: %s (%d)\n",
|
||||
__func__, strerror(errno), errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -861,7 +861,7 @@ static struct ril_s *create_ril()
|
||||
|
||||
ril->io = g_ril_io_new(io);
|
||||
if (ril->io == NULL) {
|
||||
ofono_error("create_ril: can't create ril->io");
|
||||
ofono_error("%s: can't create ril->io", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -869,13 +869,13 @@ static struct ril_s *create_ril()
|
||||
|
||||
ril->command_queue = g_queue_new();
|
||||
if (ril->command_queue == NULL) {
|
||||
ofono_error("create_ril: Couldn't create command_queue.");
|
||||
ofono_error("%s: Couldn't create command_queue.", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ril->out_queue = g_queue_new();
|
||||
if (ril->out_queue == NULL) {
|
||||
ofono_error("create_ril: Couldn't create out_queue.");
|
||||
ofono_error("%s: Couldn't create out_queue.", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -905,9 +905,6 @@ static struct ril_s *create_ril()
|
||||
g_strfreev(subscriptions);
|
||||
}
|
||||
|
||||
current_passwd = g_try_malloc(16);
|
||||
if (current_passwd)
|
||||
g_stpcpy(current_passwd, defaultpasswd);
|
||||
current_online_state = RIL_OFFLINE;
|
||||
|
||||
return ril;
|
||||
|
||||
@@ -138,7 +138,6 @@ guint g_ril_register(GRil *ril, const int req,
|
||||
gboolean g_ril_unregister(GRil *ril, guint id);
|
||||
gboolean g_ril_unregister_all(GRil *ril);
|
||||
|
||||
gchar *current_passwd;
|
||||
guint current_online_state;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -77,6 +77,58 @@ void g_ril_unsol_free_data_call_list(struct unsol_data_call_list *unsol)
|
||||
}
|
||||
}
|
||||
|
||||
gboolean g_ril_unsol_cmp_dcl(struct unsol_data_call_list *current,
|
||||
struct unsol_data_call_list *old,
|
||||
gint cid)
|
||||
{
|
||||
GSList *nl,*ol;
|
||||
struct data_call *new_call, *old_call;
|
||||
|
||||
new_call = old_call = NULL;
|
||||
gboolean no_cid = TRUE;
|
||||
|
||||
|
||||
if (!current || !old)
|
||||
return FALSE;
|
||||
|
||||
if (current->num != old->num)
|
||||
return FALSE;
|
||||
|
||||
for (nl = current->call_list; nl; nl = nl->next) {
|
||||
new_call = (struct data_call *) nl->data;
|
||||
|
||||
if (new_call->cid != cid)
|
||||
continue;
|
||||
|
||||
for (ol = old->call_list; ol; ol = ol->next) {
|
||||
old_call = (struct data_call *) ol->data;
|
||||
if(new_call->cid == old_call->cid) {
|
||||
no_cid = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (no_cid)
|
||||
return FALSE;
|
||||
|
||||
if (new_call->active != old_call->active)
|
||||
return FALSE;
|
||||
if (g_strcmp0(new_call->type,old_call->type))
|
||||
return FALSE;
|
||||
if (g_strcmp0(new_call->ifname,old_call->ifname))
|
||||
return FALSE;
|
||||
if (g_strcmp0(new_call->addresses,old_call->addresses))
|
||||
return FALSE;
|
||||
if (g_strcmp0(new_call->dnses,old_call->dnses))
|
||||
return FALSE;
|
||||
if (g_strcmp0(new_call->gateways,old_call->gateways))
|
||||
return FALSE;
|
||||
}
|
||||
if (no_cid)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct unsol_data_call_list *g_ril_unsol_parse_data_call_list(GRil *gril,
|
||||
struct ril_msg *message,
|
||||
struct ofono_error *error)
|
||||
|
||||
@@ -51,6 +51,9 @@ struct data_call {
|
||||
|
||||
void g_ril_unsol_free_data_call_list(struct unsol_data_call_list *unsol);
|
||||
|
||||
gboolean g_ril_unsol_cmp_dcl(struct unsol_data_call_list *current,
|
||||
struct unsol_data_call_list *old, gint cid);
|
||||
|
||||
struct unsol_data_call_list *g_ril_unsol_parse_data_call_list(GRil *gril,
|
||||
struct ril_msg *message,
|
||||
struct ofono_error *error);
|
||||
|
||||
@@ -117,6 +117,10 @@ void ofono_gprs_context_set_ipv6_gateway(struct ofono_gprs_context *gc,
|
||||
const char *gateway);
|
||||
void ofono_gprs_context_set_ipv6_dns_servers(struct ofono_gprs_context *gc,
|
||||
const char **dns);
|
||||
|
||||
void ofono_gprs_context_signal_change(struct ofono_gprs_context *gc,
|
||||
unsigned int cid);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <ofono/handsfree.h>
|
||||
#include <ofono/handsfree-audio.h>
|
||||
#include <ofono/siri.h>
|
||||
#include <ofono.h>
|
||||
|
||||
#include <drivers/atmodem/atutil.h>
|
||||
#include <drivers/hfpmodem/slc.h>
|
||||
@@ -762,6 +763,8 @@ static int hfp_init(void)
|
||||
if (DBUS_TYPE_UNIX_FD < 0)
|
||||
return -EBADF;
|
||||
|
||||
__ofono_handsfree_audio_manager_init();
|
||||
|
||||
/* Registers External Profile handler */
|
||||
if (!g_dbus_register_interface(conn, HFP_EXT_PROFILE_PATH,
|
||||
BLUEZ_PROFILE_INTERFACE,
|
||||
@@ -817,6 +820,8 @@ static void hfp_exit(void)
|
||||
g_dbus_client_unref(bluez);
|
||||
|
||||
ofono_handsfree_audio_unref();
|
||||
|
||||
__ofono_handsfree_audio_manager_cleanup();
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(hfp_bluez5, "External Hands-Free Profile Plugin", VERSION,
|
||||
|
||||
@@ -65,12 +65,26 @@
|
||||
#include <ofono/oemraw.h>
|
||||
#include <ofono/stk.h>
|
||||
|
||||
#include "rildev.h"
|
||||
#include "drivers/rilmodem/rilmodem.h"
|
||||
|
||||
#define MAX_POWER_ON_RETRIES 5
|
||||
#define MAX_SIM_STATUS_RETRIES 15
|
||||
#define RADIO_ID 1001
|
||||
#define MAX_PDP_CONTEXTS 2
|
||||
#define MAX_POWER_ON_RETRIES 5
|
||||
#define MAX_SIM_STATUS_RETRIES 15
|
||||
#define RADIO_ID 1001
|
||||
#define MAX_PDP_CONTEXTS 2
|
||||
|
||||
/* MCE definitions */
|
||||
#define MCE_SERVICE "com.nokia.mce"
|
||||
#define MCE_SIGNAL_IF "com.nokia.mce.signal"
|
||||
|
||||
/* MCE signal definitions */
|
||||
#define MCE_DISPLAY_SIG "display_status_ind"
|
||||
|
||||
#define MCE_DISPLAY_ON_STRING "on"
|
||||
|
||||
/* transitional state between ON and OFF (3 seconds) */
|
||||
#define MCE_DISPLAY_DIM_STRING "dimmed"
|
||||
#define MCE_DISPLAY_OFF_STRING "off"
|
||||
|
||||
struct ril_data {
|
||||
GRil *modem;
|
||||
@@ -83,22 +97,9 @@ struct ril_data {
|
||||
guint timer_id;
|
||||
};
|
||||
|
||||
/* MCE definitions */
|
||||
#define MCE_SERVICE "com.nokia.mce"
|
||||
#define MCE_SIGNAL_IF "com.nokia.mce.signal"
|
||||
|
||||
/* MCE signal definitions */
|
||||
#define MCE_DISPLAY_SIG "display_status_ind"
|
||||
|
||||
#define MCE_DISPLAY_ON_STRING "on"
|
||||
/* transitional state between ON and OFF (3 seconds) */
|
||||
#define MCE_DISPLAY_DIM_STRING "dimmed"
|
||||
#define MCE_DISPLAY_OFF_STRING "off"
|
||||
|
||||
static guint mce_daemon_watch;
|
||||
static guint signal_watch;
|
||||
static DBusConnection *connection;
|
||||
gboolean reconnecting = FALSE;
|
||||
|
||||
static int ril_init(void);
|
||||
static void ril_exit(void);
|
||||
@@ -188,7 +189,7 @@ static int send_get_sim_status(struct ofono_modem *modem)
|
||||
|
||||
static int ril_probe(struct ofono_modem *modem)
|
||||
{
|
||||
DBG("");
|
||||
DBG("modem: %p", modem);
|
||||
struct ril_data *ril = NULL;
|
||||
|
||||
ril = g_try_new0(struct ril_data, 1);
|
||||
@@ -211,8 +212,8 @@ error:
|
||||
|
||||
static void ril_remove(struct ofono_modem *modem)
|
||||
{
|
||||
DBG("");
|
||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||
DBG("modem: %p ril: %p", modem, ril);
|
||||
|
||||
ofono_modem_set_data(modem, NULL);
|
||||
|
||||
@@ -225,6 +226,11 @@ static void ril_remove(struct ofono_modem *modem)
|
||||
g_ril_unref(ril->modem);
|
||||
|
||||
g_free(ril);
|
||||
|
||||
g_dbus_remove_watch(connection, mce_daemon_watch);
|
||||
|
||||
if (signal_watch > 0)
|
||||
g_dbus_remove_watch(connection, signal_watch);
|
||||
}
|
||||
|
||||
static void ril_pre_sim(struct ofono_modem *modem)
|
||||
@@ -314,7 +320,7 @@ static void ril_set_online(struct ofono_modem *modem, ofono_bool_t online,
|
||||
parcel_w_int32(&rilp, 1); /* Number of params */
|
||||
parcel_w_int32(&rilp, online); /* Radio ON = 1, Radio OFF = 0 */
|
||||
|
||||
ofono_info("RIL_REQUEST_RADIO_POWER %d", online);
|
||||
ofono_info("%s: RIL_REQUEST_RADIO_POWER %d", __func__, online);
|
||||
ret = g_ril_send(ril->modem, RIL_REQUEST_RADIO_POWER, rilp.data,
|
||||
rilp.size, ril_set_online_cb, cbd, g_free);
|
||||
|
||||
@@ -407,8 +413,9 @@ static void ril_connected(struct ril_msg *message, gpointer user_data)
|
||||
|
||||
ril_util_init_parcel(message, &rilp);
|
||||
ril_version = parcel_r_int32(&rilp);
|
||||
ofono_debug("[UNSOL]< %s, RIL_VERSION %d",
|
||||
ril_unsol_request_to_string(message->req), ril_version);
|
||||
ofono_debug("%s: [UNSOL]< %s, RIL_VERSION %d",
|
||||
__func__, ril_unsol_request_to_string(message->req),
|
||||
ril_version);
|
||||
|
||||
ril->connected = TRUE;
|
||||
|
||||
@@ -419,47 +426,51 @@ static void ril_connected(struct ril_msg *message, gpointer user_data)
|
||||
mce_connect, mce_disconnect, modem, NULL);
|
||||
}
|
||||
|
||||
static gboolean ril_re_init(gpointer user_data)
|
||||
static int create_gril(struct ofono_modem *modem);
|
||||
|
||||
static gboolean connect_rild(gpointer user_data)
|
||||
|
||||
{
|
||||
DBG("");
|
||||
if (reconnecting) {
|
||||
ril_init();
|
||||
struct ofono_modem *modem = (struct ofono_modem *) user_data;
|
||||
|
||||
ofono_info("%s: Connecting %p to rild...", __func__, modem);
|
||||
|
||||
if (create_gril(modem) < 0) {
|
||||
DBG("Connecting %p to rild failed, retry timer continues...",
|
||||
modem);
|
||||
return TRUE;
|
||||
} else {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* RIL socket callback from g_io channel */
|
||||
static void gril_disconnected(gpointer user_data)
|
||||
{
|
||||
/* Signal clients modem going down
|
||||
*/
|
||||
struct ofono_modem *modem = user_data;
|
||||
ofono_error("%s: modem: %p", __func__, modem);
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
if (ofono_modem_is_registered(modem)) {
|
||||
ofono_modem_remove(modem);
|
||||
mce_disconnect(conn, user_data);
|
||||
ril_modem_remove(modem);
|
||||
}
|
||||
|
||||
if (!reconnecting) {
|
||||
reconnecting = TRUE;
|
||||
g_timeout_add_seconds(2, ril_re_init, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void ril_switchUser()
|
||||
{
|
||||
if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0)
|
||||
ofono_error("prctl(PR_SET_KEEPCAPS) failed:%s,%d",
|
||||
strerror(errno), errno);
|
||||
ofono_error("%s: prctl(PR_SET_KEEPCAPS) failed:%s,%d",
|
||||
__func__, strerror(errno), errno);
|
||||
|
||||
if (setgid(RADIO_ID) < 0)
|
||||
ofono_error("setgid(%d) failed:%s,%d",
|
||||
RADIO_ID, strerror(errno), errno);
|
||||
ofono_error("%s: setgid(%d) failed:%s,%d",
|
||||
__func__, RADIO_ID, strerror(errno), errno);
|
||||
if (setuid(RADIO_ID) < 0)
|
||||
ofono_error("setuid(%d) failed:%s,%d",
|
||||
RADIO_ID, strerror(errno), errno);
|
||||
ofono_error("%s: setuid(%d) failed:%s,%d",
|
||||
__func__, RADIO_ID, strerror(errno), errno);
|
||||
|
||||
struct __user_cap_header_struct header;
|
||||
struct __user_cap_data_struct cap;
|
||||
@@ -470,14 +481,14 @@ void ril_switchUser()
|
||||
cap.inheritable = 0;
|
||||
|
||||
if (syscall(SYS_capset, &header, &cap) < 0)
|
||||
ofono_error("syscall(SYS_capset) failed:%s,%d",
|
||||
strerror(errno), errno);
|
||||
ofono_error("%s: syscall(SYS_capset) failed:%s,%d",
|
||||
__func__, strerror(errno), errno);
|
||||
|
||||
}
|
||||
|
||||
static int ril_enable(struct ofono_modem *modem)
|
||||
static int create_gril(struct ofono_modem *modem)
|
||||
{
|
||||
DBG("%p", modem);
|
||||
DBG(" modem: %p", modem);
|
||||
struct ril_data *ril = ofono_modem_get_data(modem);
|
||||
|
||||
ril->have_sim = FALSE;
|
||||
@@ -486,6 +497,7 @@ static int ril_enable(struct ofono_modem *modem)
|
||||
ril_switchUser();
|
||||
|
||||
ril->modem = g_ril_new();
|
||||
|
||||
g_ril_set_disconnect_function(ril->modem, gril_disconnected, modem);
|
||||
|
||||
/* NOTE: Since AT modems open a tty, and then call
|
||||
@@ -498,12 +510,9 @@ static int ril_enable(struct ofono_modem *modem)
|
||||
|
||||
if (ril->modem == NULL) {
|
||||
DBG("g_ril_new() failed to create modem!");
|
||||
gril_disconnected(modem);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
reconnecting = FALSE;
|
||||
|
||||
if (getenv("OFONO_RIL_TRACE"))
|
||||
g_ril_set_trace(ril->modem, TRUE);
|
||||
|
||||
@@ -515,6 +524,22 @@ static int ril_enable(struct ofono_modem *modem)
|
||||
|
||||
ofono_devinfo_create(modem, 0, "rilmodem", ril->modem);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ril_enable(struct ofono_modem *modem)
|
||||
{
|
||||
int ret;
|
||||
DBG("");
|
||||
|
||||
ret = create_gril(modem);
|
||||
if (ret < 0) {
|
||||
DBG("create gril: %d, queue reconnect", ret);
|
||||
g_timeout_add_seconds(2,
|
||||
connect_rild, modem);
|
||||
}
|
||||
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
@@ -531,7 +556,7 @@ static int ril_disable(struct ofono_modem *modem)
|
||||
parcel_w_int32(&rilp, 1); /* size of array */
|
||||
parcel_w_int32(&rilp, 0); /* POWER=OFF */
|
||||
|
||||
ofono_info("RIL_REQUEST_RADIO_POWER OFF");
|
||||
ofono_info("%s: RIL_REQUEST_RADIO_POWER OFF", __func__);
|
||||
/* fire and forget i.e. not waiting for the callback*/
|
||||
ret = g_ril_send(ril->modem, request, rilp.data,
|
||||
rilp.size, NULL, NULL, NULL);
|
||||
@@ -560,67 +585,19 @@ static struct ofono_modem_driver ril_driver = {
|
||||
.set_online = ril_set_online,
|
||||
};
|
||||
|
||||
/*
|
||||
* Note - as an aal+ container doesn't include a running udev,
|
||||
* the udevng plugin will never detect a modem, and thus modem
|
||||
* creation for a RIL-based modem needs to be hard-coded.
|
||||
*
|
||||
* Typically, udevng would create the modem, which in turn would
|
||||
* lead to this plugin's probe function being called.
|
||||
*
|
||||
* This is a first attempt at registering like this.
|
||||
*
|
||||
* IMPORTANT - this code relies on the fact that the 'rilmodem' is
|
||||
* added to top-level Makefile's builtin_modules *after* 'ril'.
|
||||
* This has means 'rilmodem' will already be registered before we try
|
||||
* to create and register the modem. In standard ofono, 'udev'/'udevng'
|
||||
* is initialized last due to the fact that it's the first module
|
||||
* added in the top-level Makefile.
|
||||
*/
|
||||
static int ril_init(void)
|
||||
{
|
||||
DBG("");
|
||||
int retval = 0;
|
||||
struct ofono_modem *modem;
|
||||
|
||||
if ((retval = ofono_modem_driver_register(&ril_driver))) {
|
||||
int retval = ofono_modem_driver_register(&ril_driver);
|
||||
if (retval)
|
||||
DBG("ofono_modem_driver_register returned: %d", retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
/* everything after _modem_driver_register, is
|
||||
* non-standard ( see udev comment above ).
|
||||
* usually called by undevng::create_modem
|
||||
*
|
||||
* args are name (optional) & type
|
||||
*/
|
||||
modem = ofono_modem_create("ril_0", "ril");
|
||||
if (modem == NULL) {
|
||||
DBG("ofono_modem_create failed for ril");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* This causes driver->probe() to be called... */
|
||||
retval = ofono_modem_register(modem);
|
||||
DBG("ofono_modem_register returned: %d", retval);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void ril_exit(void)
|
||||
{
|
||||
DBG("");
|
||||
if (current_passwd)
|
||||
g_free(current_passwd);
|
||||
|
||||
g_dbus_remove_watch(connection, mce_daemon_watch);
|
||||
|
||||
if (signal_watch > 0)
|
||||
g_dbus_remove_watch(connection, signal_watch);
|
||||
|
||||
ofono_modem_driver_unregister(&ril_driver);
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(ril, "RIL modem driver", VERSION,
|
||||
OFONO_PLUGIN_DEFINE(ril, "RIL modem plugin", VERSION,
|
||||
OFONO_PLUGIN_PRIORITY_DEFAULT, ril_init, ril_exit)
|
||||
|
||||
|
||||
299
ofono/plugins/rildev.c
Normal file
299
ofono/plugins/rildev.c
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony
|
||||
*
|
||||
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
|
||||
* Copyright (C) 2014 Canonical Ltd.
|
||||
* Copyright (C) 2015 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/inotify.h>
|
||||
|
||||
#define OFONO_API_SUBJECT_TO_CHANGE
|
||||
#include <ofono/plugin.h>
|
||||
#include <ofono/modem.h>
|
||||
#include <ofono/log.h>
|
||||
|
||||
#include "rildev.h"
|
||||
|
||||
#define EVENT_SIZE (sizeof(struct inotify_event))
|
||||
/*
|
||||
* As a best guess use a buffer size of 100 inotify events.
|
||||
* NAME_MAX+1 from inotify documentation.
|
||||
*/
|
||||
#define IBUF_LEN (100*(EVENT_SIZE + NAME_MAX + 1))
|
||||
|
||||
static int inotify_fd = -1;
|
||||
static int inotify_watch_id = -1;
|
||||
static guint inotify_watch_source_id;
|
||||
static GIOChannel *inotify_watch_channel;
|
||||
|
||||
static GSList *modem_list;
|
||||
static int watch_for_rild_socket(void);
|
||||
static void detect_rild(void);
|
||||
|
||||
static struct ofono_modem *find_ril_modem(int slot)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
for (list = modem_list; list; list = list->next) {
|
||||
struct ofono_modem *modem = list->data;
|
||||
int ril_slot = ofono_modem_get_integer(modem, "Slot");
|
||||
|
||||
if (ril_slot == slot)
|
||||
return modem;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void remove_watchers(void)
|
||||
{
|
||||
DBG("");
|
||||
if (inotify_watch_channel == NULL)
|
||||
return;
|
||||
|
||||
g_source_remove(inotify_watch_source_id);
|
||||
inotify_watch_source_id = 0;
|
||||
g_io_channel_unref(inotify_watch_channel);
|
||||
inotify_watch_channel = NULL;
|
||||
inotify_rm_watch(inotify_fd, inotify_watch_id);
|
||||
inotify_watch_id = -1;
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
}
|
||||
|
||||
/* Removes a RIL modem and initiates a sequence to create a new one */
|
||||
void ril_modem_remove(struct ofono_modem *modem)
|
||||
{
|
||||
DBG("modem: %p", modem);
|
||||
struct ofono_modem *list_modem;
|
||||
int slot = -1;
|
||||
list_modem = NULL;
|
||||
|
||||
if (modem)
|
||||
slot = ofono_modem_get_integer(modem, "Slot");
|
||||
|
||||
if (slot >= 0)
|
||||
list_modem = find_ril_modem(slot);
|
||||
|
||||
if (list_modem) {
|
||||
ofono_modem_remove(modem);
|
||||
modem_list = g_slist_remove(modem_list, list_modem);
|
||||
}
|
||||
|
||||
detect_rild();
|
||||
}
|
||||
|
||||
/* return: 0 if successful or modem already exists, otherwise and error */
|
||||
static int create_rilmodem(const char *ril_type, int slot)
|
||||
{
|
||||
struct ofono_modem *modem;
|
||||
char dev_name[64];
|
||||
int retval;
|
||||
DBG("");
|
||||
snprintf(dev_name, sizeof(dev_name), "ril_%d", slot);
|
||||
|
||||
/* Check that not created already */
|
||||
if (find_ril_modem(slot))
|
||||
return 0;
|
||||
|
||||
/* Currently there is only one ril implementation, create always */
|
||||
modem = ofono_modem_create(dev_name, ril_type);
|
||||
if (modem == NULL) {
|
||||
DBG("ofono_modem_create failed for type: %s", ril_type);
|
||||
return -ENODEV;
|
||||
}
|
||||
DBG("created modem: %p", modem);
|
||||
|
||||
modem_list = g_slist_prepend(modem_list, modem);
|
||||
|
||||
ofono_modem_set_integer(modem, "Slot", slot);
|
||||
|
||||
/* This causes driver->probe() to be called */
|
||||
retval = ofono_modem_register(modem);
|
||||
if (retval != 0) {
|
||||
ofono_error("%s: ofono_modem_register error: %d",
|
||||
__func__, retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try creating a ril modem
|
||||
* return: false if failed, true successful or modem already exists.
|
||||
*/
|
||||
static gboolean try_create_modem()
|
||||
{
|
||||
gboolean result = FALSE;
|
||||
int ares = access(RILD_CMD_SOCKET, F_OK);
|
||||
if (ares != -1)
|
||||
result = !create_rilmodem("ril", 0);
|
||||
else
|
||||
DBG("problems accessing rild socket: %d", ares);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean rild_inotify(GIOChannel *gio, GIOCondition c,
|
||||
gpointer data)
|
||||
{
|
||||
DBG("");
|
||||
struct inotify_event *event = 0;
|
||||
int i = 0;
|
||||
int length = 0;
|
||||
char *ievents = 0; /* inotify event buffer */
|
||||
gboolean result = TRUE;
|
||||
|
||||
ievents = g_try_malloc(IBUF_LEN);
|
||||
if (!ievents) {
|
||||
/* Continue observing so don't set "result" false here */
|
||||
goto end;
|
||||
}
|
||||
|
||||
length = read(inotify_fd, ievents, IBUF_LEN);
|
||||
/*
|
||||
* If iNotify fd read returns an error, just keep on watching for
|
||||
* read events.
|
||||
*/
|
||||
while (i < length) {
|
||||
event = (struct inotify_event *) &ievents[i];
|
||||
|
||||
if (event->len && (event->mask & IN_CREATE)
|
||||
&& (!(event->mask & IN_ISDIR))) {
|
||||
|
||||
DBG("File created: %s", event->name);
|
||||
if (!strcmp(event->name, RILD_SOCKET_FILE)) {
|
||||
result = !try_create_modem();
|
||||
/*
|
||||
* On modem create fail continue observing
|
||||
* events so don't set result false here.
|
||||
*/
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
i += EVENT_SIZE + event->len;
|
||||
}
|
||||
|
||||
end:
|
||||
/* "if" works around potential glib runtime warning */
|
||||
if (ievents)
|
||||
g_free(ievents);
|
||||
|
||||
if (!result)
|
||||
remove_watchers();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* return 0 if successful, otherwise an error */
|
||||
static int watch_for_rild_socket(void)
|
||||
{
|
||||
DBG("");
|
||||
inotify_fd = inotify_init();
|
||||
if (inotify_fd < 0)
|
||||
return -EIO;
|
||||
|
||||
inotify_watch_channel = g_io_channel_unix_new(inotify_fd);
|
||||
if (inotify_watch_channel == NULL) {
|
||||
ofono_error("%s: rildev gio chan creation fail!", __func__);
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
inotify_watch_id = inotify_add_watch(inotify_fd, RILD_SOCKET_DIR,
|
||||
IN_CREATE);
|
||||
if (inotify_watch_id < 0) {
|
||||
ofono_error("%s: inotify says: %d, errno: %d",
|
||||
__func__, inotify_watch_id, errno);
|
||||
g_io_channel_unref(inotify_watch_channel);
|
||||
inotify_watch_channel = NULL;
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
inotify_watch_source_id = g_io_add_watch(inotify_watch_channel,
|
||||
G_IO_IN,
|
||||
rild_inotify, NULL);
|
||||
if (inotify_watch_source_id <= 0) {
|
||||
ofono_error("%s: rildev add gio watch fail!", __func__);
|
||||
g_io_channel_unref(inotify_watch_channel);
|
||||
inotify_watch_channel = NULL;
|
||||
inotify_rm_watch(inotify_fd, inotify_watch_id);
|
||||
inotify_watch_id = -1;
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void detect_rild(void)
|
||||
{
|
||||
DBG("");
|
||||
gboolean created = try_create_modem();
|
||||
if (!created)
|
||||
watch_for_rild_socket();
|
||||
|
||||
/* Let's re-check if we just missed the notification */
|
||||
if (!created && try_create_modem())
|
||||
remove_watchers();
|
||||
}
|
||||
|
||||
static int detect_init(void)
|
||||
{
|
||||
DBG("");
|
||||
detect_rild();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void detect_exit(void)
|
||||
{
|
||||
GSList *list;
|
||||
|
||||
DBG("");
|
||||
|
||||
for (list = modem_list; list; list = list->next) {
|
||||
struct ofono_modem *modem = list->data;
|
||||
|
||||
ofono_modem_remove(modem);
|
||||
}
|
||||
|
||||
g_slist_free(modem_list);
|
||||
modem_list = NULL;
|
||||
remove_watchers();
|
||||
}
|
||||
|
||||
OFONO_PLUGIN_DEFINE(rildev, "RIL type detection", VERSION,
|
||||
OFONO_PLUGIN_PRIORITY_DEFAULT, detect_init, detect_exit)
|
||||
32
ofono/plugins/rildev.h
Normal file
32
ofono/plugins/rildev.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
*
|
||||
* oFono - Open Source Telephony - RIL-based devices
|
||||
*
|
||||
* Copyright (C) 2015 Jolla Ltd.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __RILDEV_H
|
||||
#define __RILDEV_H
|
||||
|
||||
#define RILD_CMD_SOCKET "/dev/socket/rild"
|
||||
#define RILD_SOCKET_DIR "/dev/socket"
|
||||
#define RILD_SOCKET_FILE "rild"
|
||||
|
||||
|
||||
void ril_modem_remove(struct ofono_modem *modem);
|
||||
|
||||
#endif /* __RILDEV_H */
|
||||
239
ofono/src/gprs.c
239
ofono/src/gprs.c
@@ -151,6 +151,8 @@ struct pri_context {
|
||||
|
||||
static void gprs_netreg_update(struct ofono_gprs *gprs);
|
||||
static void gprs_deactivate_next(struct ofono_gprs *gprs);
|
||||
static void write_context_settings(struct ofono_gprs *gprs,
|
||||
struct pri_context *context);
|
||||
|
||||
static GSList *g_drivers = NULL;
|
||||
static GSList *g_context_drivers = NULL;
|
||||
@@ -561,13 +563,16 @@ static void pri_context_signal_settings(struct pri_context *ctx,
|
||||
context_settings_append_ipv6);
|
||||
}
|
||||
|
||||
static void pri_parse_proxy(struct pri_context *ctx, const char *proxy)
|
||||
static gboolean pri_parse_proxy(struct pri_context *ctx, const char *proxy)
|
||||
{
|
||||
char *scheme, *host, *port, *path;
|
||||
|
||||
if (proxy[0] == 0)
|
||||
return FALSE;
|
||||
|
||||
scheme = g_strdup(proxy);
|
||||
if (scheme == NULL)
|
||||
return;
|
||||
return FALSE;
|
||||
|
||||
host = strstr(scheme, "://");
|
||||
if (host != NULL) {
|
||||
@@ -580,7 +585,7 @@ static void pri_parse_proxy(struct pri_context *ctx, const char *proxy)
|
||||
ctx->proxy_port = 80;
|
||||
else {
|
||||
g_free(scheme);
|
||||
return;
|
||||
return FALSE;
|
||||
}
|
||||
} else {
|
||||
host = scheme;
|
||||
@@ -602,10 +607,16 @@ static void pri_parse_proxy(struct pri_context *ctx, const char *proxy)
|
||||
}
|
||||
}
|
||||
|
||||
if (host[0] == 0) {
|
||||
g_free(scheme);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free(ctx->proxy_host);
|
||||
ctx->proxy_host = g_strdup(host);
|
||||
|
||||
g_free(scheme);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void pri_ifupdown(const char *interface, ofono_bool_t active)
|
||||
@@ -691,11 +702,16 @@ static void pri_setproxy(const char *interface, const char *proxy)
|
||||
{
|
||||
struct rtentry rt;
|
||||
struct sockaddr_in addr;
|
||||
in_addr_t proxy_addr;
|
||||
int sk;
|
||||
|
||||
if (interface == NULL)
|
||||
return;
|
||||
|
||||
proxy_addr = inet_addr(proxy);
|
||||
if (proxy_addr == INADDR_NONE)
|
||||
return;
|
||||
|
||||
sk = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (sk < 0)
|
||||
return;
|
||||
@@ -706,7 +722,7 @@ static void pri_setproxy(const char *interface, const char *proxy)
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = inet_addr(proxy);
|
||||
addr.sin_addr.s_addr = proxy_addr;
|
||||
memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
@@ -793,7 +809,8 @@ static void pri_update_mms_context_settings(struct pri_context *ctx)
|
||||
if (ctx->message_proxy)
|
||||
settings->ipv4->proxy = g_strdup(ctx->message_proxy);
|
||||
|
||||
pri_parse_proxy(ctx, ctx->message_proxy);
|
||||
if (!pri_parse_proxy(ctx, ctx->message_proxy))
|
||||
pri_parse_proxy(ctx, ctx->message_center);
|
||||
|
||||
DBG("proxy %s port %u", ctx->proxy_host, ctx->proxy_port);
|
||||
|
||||
@@ -805,6 +822,193 @@ static void pri_update_mms_context_settings(struct pri_context *ctx)
|
||||
pri_limit_mtu(settings->interface, MAX_MMS_MTU);
|
||||
}
|
||||
|
||||
static gboolean pri_str_changed(const char *val, const char *newval)
|
||||
{
|
||||
return newval ? (strcmp(val, newval) != 0) : (val[0] != 0);
|
||||
}
|
||||
|
||||
static gboolean pri_str_update(char *val, const char *newval,
|
||||
const int maxlen)
|
||||
{
|
||||
DBG("oldval: %s, newval: %s, mmaxlen: %d", val, newval, maxlen);
|
||||
|
||||
if (newval) {
|
||||
if (strcmp(val, newval)) {
|
||||
strncpy(val, newval, maxlen);
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
if (val[0]) {
|
||||
val[0] = 0;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void pri_str_signal_change(struct pri_context *ctx,
|
||||
const char *name, const char *value)
|
||||
{
|
||||
ofono_dbus_signal_property_changed(ofono_dbus_get_connection(),
|
||||
ctx->path, OFONO_CONNECTION_CONTEXT_INTERFACE,
|
||||
name, DBUS_TYPE_STRING, &value);
|
||||
}
|
||||
|
||||
static void pri_reset_context_properties(struct pri_context *ctx,
|
||||
const struct ofono_gprs_provision_data *ap)
|
||||
{
|
||||
struct ofono_gprs *gprs = ctx->gprs;
|
||||
gboolean changed = FALSE;
|
||||
|
||||
DBG("%s", ctx->path);
|
||||
|
||||
if (strcmp(ctx->context.apn, ap->apn)) {
|
||||
changed = TRUE;
|
||||
strcpy(ctx->context.apn, ap->apn);
|
||||
pri_str_signal_change(ctx, "AccessPointName",
|
||||
ctx->context.apn);
|
||||
}
|
||||
if (ap->name && pri_str_update(ctx->name, ap->name,
|
||||
sizeof(ctx->name))) {
|
||||
changed = TRUE;
|
||||
pri_str_signal_change(ctx, "Name", ctx->name);
|
||||
}
|
||||
|
||||
if (pri_str_update(ctx->context.username, ap->username,
|
||||
sizeof(ctx->context.username))) {
|
||||
changed = TRUE;
|
||||
pri_str_signal_change(ctx, "Username", ctx->context.username);
|
||||
}
|
||||
|
||||
if (pri_str_update(ctx->context.password, ap->password,
|
||||
sizeof(ctx->context.password))) {
|
||||
changed = TRUE;
|
||||
pri_str_signal_change(ctx, "Password", ctx->context.password);
|
||||
}
|
||||
|
||||
if (ctx->context.proto != ap->proto) {
|
||||
ctx->context.proto = ap->proto;
|
||||
changed = TRUE;
|
||||
pri_str_signal_change(ctx, "Protocol",
|
||||
gprs_proto_to_string(ctx->context.proto));
|
||||
}
|
||||
|
||||
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
|
||||
if (pri_str_update(ctx->message_proxy, ap->message_proxy,
|
||||
sizeof(ctx->message_proxy))) {
|
||||
changed = TRUE;
|
||||
pri_str_signal_change(ctx, "MessageProxy",
|
||||
ctx->message_proxy);
|
||||
}
|
||||
|
||||
if (pri_str_update(ctx->message_center, ap->message_center,
|
||||
sizeof(ctx->message_center))) {
|
||||
changed = TRUE;
|
||||
pri_str_signal_change(ctx, "MessageCenter",
|
||||
ctx->message_center);
|
||||
}
|
||||
}
|
||||
|
||||
if (gprs->settings && changed) {
|
||||
write_context_settings(gprs, ctx);
|
||||
storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean ap_valid(const struct ofono_gprs_provision_data *ap)
|
||||
{
|
||||
if (!ap->apn || strlen(ap->apn) > OFONO_GPRS_MAX_APN_LENGTH ||
|
||||
!is_valid_apn(ap->apn))
|
||||
return FALSE;
|
||||
|
||||
if (ap->username &&
|
||||
strlen(ap->username) > OFONO_GPRS_MAX_USERNAME_LENGTH)
|
||||
return FALSE;
|
||||
|
||||
if (ap->password &&
|
||||
strlen(ap->password) > OFONO_GPRS_MAX_PASSWORD_LENGTH)
|
||||
return FALSE;
|
||||
|
||||
if (ap->message_proxy &&
|
||||
strlen(ap->message_proxy) > MAX_MESSAGE_PROXY_LENGTH)
|
||||
return FALSE;
|
||||
|
||||
if (ap->message_center &&
|
||||
strlen(ap->message_center) > MAX_MESSAGE_CENTER_LENGTH)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean pri_deactivation_required(struct pri_context *ctx,
|
||||
const struct ofono_gprs_provision_data *ap)
|
||||
{
|
||||
if (ctx->context.proto != ap->proto)
|
||||
return TRUE;
|
||||
|
||||
if (strcmp(ctx->context.apn, ap->apn))
|
||||
return TRUE;
|
||||
|
||||
if (pri_str_changed(ctx->context.username, ap->username))
|
||||
return TRUE;
|
||||
|
||||
if (pri_str_changed(ctx->context.password, ap->password))
|
||||
return TRUE;
|
||||
|
||||
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
|
||||
if (pri_str_changed(ctx->message_proxy, ap->message_proxy))
|
||||
return TRUE;
|
||||
|
||||
if (pri_str_changed(ctx->message_center, ap->message_center))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static DBusMessage *pri_provision_context(DBusConnection *conn,
|
||||
DBusMessage *msg, void *data)
|
||||
{
|
||||
DBG("");
|
||||
struct pri_context *ctx = data;
|
||||
struct ofono_gprs *gprs = ctx->gprs;
|
||||
struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
|
||||
struct ofono_sim *sim = __ofono_atom_find(OFONO_ATOM_TYPE_SIM, modem);
|
||||
struct ofono_gprs_provision_data *settings;
|
||||
DBusMessage *reply = NULL;
|
||||
int i, count = 0;
|
||||
|
||||
if (sim == NULL)
|
||||
return __ofono_error_failed(msg);
|
||||
|
||||
if (__ofono_gprs_provision_get_settings(ofono_sim_get_mcc(sim),
|
||||
ofono_sim_get_mnc(sim), ofono_sim_get_spn(sim),
|
||||
&settings, &count) == FALSE)
|
||||
return __ofono_error_failed(msg);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
const struct ofono_gprs_provision_data *ap = settings + i;
|
||||
if (ap->type == ctx->type && ap_valid(ap)) {
|
||||
if ((!ctx->active &&
|
||||
!ctx->pending && !ctx->gprs->pending) ||
|
||||
!pri_deactivation_required(ctx, ap)) {
|
||||
/* Re-provision the context */
|
||||
pri_reset_context_properties(ctx, ap);
|
||||
reply = dbus_message_new_method_return(msg);
|
||||
} else {
|
||||
/* Context should be inactive */
|
||||
if (ctx->gprs->pending || ctx->pending)
|
||||
reply = __ofono_error_busy(msg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__ofono_gprs_provision_free_settings(settings, count);
|
||||
|
||||
return reply ? reply : __ofono_error_not_available(msg);
|
||||
}
|
||||
|
||||
static void append_context_properties(struct pri_context *ctx,
|
||||
DBusMessageIter *dict)
|
||||
{
|
||||
@@ -1322,6 +1526,8 @@ static const GDBusMethodTable context_methods[] = {
|
||||
{ GDBUS_ASYNC_METHOD("SetProperty",
|
||||
GDBUS_ARGS({ "property", "s" }, { "value", "v" }),
|
||||
NULL, pri_set_property) },
|
||||
{ GDBUS_METHOD("ProvisionContext", NULL, NULL,
|
||||
pri_provision_context) },
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -2550,6 +2756,29 @@ void ofono_gprs_context_set_ipv6_dns_servers(struct ofono_gprs_context *gc,
|
||||
settings->ipv6->dns = g_strdupv((char **) dns);
|
||||
}
|
||||
|
||||
void ofono_gprs_context_signal_change(struct ofono_gprs_context *gc,
|
||||
unsigned int cid)
|
||||
{
|
||||
GSList *l;
|
||||
struct pri_context *ctx;
|
||||
|
||||
if (gc->gprs == NULL)
|
||||
return;
|
||||
|
||||
for (l = gc->gprs->contexts; l; l = l->next) {
|
||||
ctx = l->data;
|
||||
|
||||
if (ctx->context.cid != cid)
|
||||
continue;
|
||||
|
||||
if (ctx->active == FALSE)
|
||||
break;
|
||||
|
||||
pri_context_signal_settings(ctx, gc->settings->ipv4 != NULL,
|
||||
gc->settings->ipv6 != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
int ofono_gprs_driver_register(const struct ofono_gprs_driver *d)
|
||||
{
|
||||
DBG("driver: %p, name: %s", d, d->name);
|
||||
|
||||
@@ -244,7 +244,11 @@ int main(int argc, char **argv)
|
||||
|
||||
__ofono_manager_init();
|
||||
|
||||
__ofono_handsfree_audio_manager_init();
|
||||
/*
|
||||
* BT HFP SCO socket creation moved to Bluez5 plugin.
|
||||
* Bluez4 handles the SCO socket, it will conflict with oFono.
|
||||
*/
|
||||
//__ofono_handsfree_audio_manager_init();
|
||||
|
||||
__ofono_plugin_init(option_plugin, option_noplugin);
|
||||
|
||||
@@ -255,7 +259,7 @@ int main(int argc, char **argv)
|
||||
|
||||
__ofono_plugin_cleanup();
|
||||
|
||||
__ofono_handsfree_audio_manager_cleanup();
|
||||
//__ofono_handsfree_audio_manager_cleanup(); See comment above
|
||||
|
||||
__ofono_manager_cleanup();
|
||||
|
||||
|
||||
@@ -524,7 +524,8 @@ static gboolean encode_validity_period(const struct sms_validity_period *vp,
|
||||
gboolean sms_encode_address_field(const struct sms_address *in, gboolean sc,
|
||||
unsigned char *pdu, int *offset)
|
||||
{
|
||||
size_t len = strlen(in->address);
|
||||
const char *addr = (const char *)&in->address;
|
||||
size_t len = strlen(addr);
|
||||
unsigned char addr_len = 0;
|
||||
unsigned char p[10];
|
||||
|
||||
@@ -546,13 +547,19 @@ gboolean sms_encode_address_field(const struct sms_address *in, gboolean sc,
|
||||
unsigned char *gsm;
|
||||
unsigned char *r;
|
||||
|
||||
if (len > 11)
|
||||
/* TP-OA's 10 octets transport 11 8-bit chars */
|
||||
if (g_utf8_strlen(addr, strlen(addr)) > 11)
|
||||
return FALSE;
|
||||
|
||||
gsm = convert_utf8_to_gsm(in->address, len, NULL, &written, 0);
|
||||
if (gsm == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (written > 11) {
|
||||
g_free(gsm);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
r = pack_7bit_own_buf(gsm, written, 0, FALSE, &packed, 0, p);
|
||||
|
||||
g_free(gsm);
|
||||
@@ -675,7 +682,11 @@ gboolean sms_decode_address_field(const unsigned char *pdu, int len,
|
||||
if (utf8 == NULL)
|
||||
return FALSE;
|
||||
|
||||
if (strlen(utf8) > 20) {
|
||||
/*
|
||||
* TP-OA's 10 octets transport 11 8-bit chars,
|
||||
* 22 bytes+terminator in UTF-8.
|
||||
*/
|
||||
if (strlen(utf8) > 22) {
|
||||
g_free(utf8);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -220,7 +220,11 @@ enum cbs_geo_scope {
|
||||
struct sms_address {
|
||||
enum sms_number_type number_type;
|
||||
enum sms_numbering_plan numbering_plan;
|
||||
char address[21]; /* Max 20 in semi-octet, 11 in alnum */
|
||||
/*
|
||||
* An alphanum TP-OA is 10 7-bit coded octets, which can carry
|
||||
* 11 8-bit characters. 22 bytes + terminator in UTF-8.
|
||||
*/
|
||||
char address[23];
|
||||
};
|
||||
|
||||
struct sms_scts {
|
||||
|
||||
@@ -38,6 +38,12 @@ static const char *simple_deliver = "07911326040000F0"
|
||||
"040B911346610089F60000208062917314480CC8F71D14969741F977FD07";
|
||||
static const char *alnum_sender = "0791447758100650"
|
||||
"040DD0F334FC1CA6970100008080312170224008D4F29CDE0EA7D9";
|
||||
static const char *unicode_deliver = "04819999990414D0FBFD7EBFDFEFF77BFE1E001"
|
||||
"9512090801361807E00DC00FC00C400E400D600F600C500E500D800F800C"
|
||||
"600E600C700E700C900E900CA00EA00DF003100320033003400350036003"
|
||||
"7003800390030002000540068006900730020006D0065007300730061006"
|
||||
"7006500200069007300200036003300200075006E00690063006F0064006"
|
||||
"5002000630068006100720073002E";
|
||||
static const char *simple_submit = "0011000B916407281553F80000AA"
|
||||
"0AE8329BFD4697D9EC37";
|
||||
|
||||
@@ -362,6 +368,38 @@ static void test_deliver_encode(void)
|
||||
g_assert(strcmp(alnum_sender, encoded_pdu) == 0);
|
||||
|
||||
g_free(encoded_pdu);
|
||||
|
||||
/* test unicode_deliver*/
|
||||
decoded_pdu = decode_hex(unicode_deliver, -1, &pdu_len, 0);
|
||||
g_assert(decoded_pdu);
|
||||
g_assert(pdu_len == (long)strlen(unicode_deliver) / 2);
|
||||
|
||||
ret = sms_decode(decoded_pdu, pdu_len, FALSE, 149, &sms);
|
||||
|
||||
g_free(decoded_pdu);
|
||||
|
||||
g_assert(ret);
|
||||
g_assert(sms.type == SMS_TYPE_DELIVER);
|
||||
|
||||
ret = sms_encode(&sms, &encoded_pdu_len, &encoded_tpdu_len, pdu);
|
||||
|
||||
if (g_test_verbose()) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < encoded_pdu_len; i++)
|
||||
g_print("%02X", pdu[i]);
|
||||
g_print("\n");
|
||||
}
|
||||
|
||||
g_assert(ret);
|
||||
g_assert(encoded_tpdu_len == 149);
|
||||
g_assert(encoded_pdu_len == pdu_len);
|
||||
|
||||
encoded_pdu = encode_hex(pdu, encoded_pdu_len, 0);
|
||||
|
||||
g_assert(strcmp(unicode_deliver, encoded_pdu) == 0);
|
||||
|
||||
g_free(encoded_pdu);
|
||||
}
|
||||
|
||||
static void test_simple_submit(void)
|
||||
|
||||
Reference in New Issue
Block a user