Compare commits

..

38 Commits

Author SHA1 Message Date
Tommi Kenakkala
011bc0741a Merge pull request #284 from tkenakka/master
[gprs] Fix pri_reset_context_properties crashes
2015-02-27 11:36:09 +02:00
Tommi Kenakkala
773834c5a3 [gprs] Fix pri_reset_context_properties crashes
Fixes issues of ff63e9b0
2015-02-27 11:08:03 +02:00
Tommi Kenakkala
14acafc581 Merge pull request #283 from tkenakka/norild
Rild comms socket detection and monitoring for oFono rilmodem plugin
2015-02-26 13:29:32 +02:00
Tommi Kenakkala
b4df40608b [gril] Minor updates to ofono gril logging 2015-02-26 11:52:24 +02:00
Tommi Kenakkala
26f750fe4f [plugins] Improved ofono rilmodem socket handling
- Fix rildev.c's rild socket inotify handling
- Fix gril creation fail handling
- Improve logic logging and add __func__ arg for some ofono_XXX log prints
- Same style for rildev plugin name descriptor as what rilmodem plugin has
2015-02-26 11:52:23 +02:00
Jarko Poutiainen
51f6837545 [plugins] rildev.c remove unnecessary modem reset
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-02-25 15:18:52 +02:00
Jarko Poutiainen
6919c43ff6 [plugins] rildev.c add error handling
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-02-25 15:18:52 +02:00
Jarko Poutiainen
621614e518 [Makefile] add rildev as builtin
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-02-25 15:18:52 +02:00
Jarko Poutiainen
8e820dfdd3 [gril] gril.h remove current_passwd
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-02-25 15:18:51 +02:00
Jarko Poutiainen
04cc2e9fd2 [gril] gril.c remove current_passwd
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-02-25 15:18:51 +02:00
Jarko Poutiainen
ae5c8e6e3a [rilmodem] remove current_passwd support from sim driver
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-02-25 15:18:51 +02:00
Jarko Poutiainen
1509cb811a [plugins] ril to support rild socket detection
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-02-25 15:18:51 +02:00
Jarko Poutiainen
5682df6d82 [plugins] rildev to detect rild socket
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-02-25 15:18:51 +02:00
Jarko Poutiainen
3e38512e2f [plugins] add rildev.h
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-02-25 15:18:51 +02:00
Alfonso Sanchez-Beato
dc5157c5d0 plugins: Add rildev for creation of ril modems
This new plugin will create ril modems, providing the same
functionality as udev/udevng does for USB-based modems.
2015-02-25 15:18:51 +02:00
Tommi Kenakkala
59449f74a1 Merge pull request #282 from monich/provision
Add ProvisionContext method to ConnectionContext interface
2015-02-25 15:16:31 +02:00
Slava Monich
ff63e9b057 [ofono] Added ProvisionContext method to ConnectionContext interface
Allows to reset connection context properties back to default.
2015-02-25 12:36:04 +02:00
Pasi Sjöholm
7b73f569eb Merge pull request #280 from tigeli/master
[rilmodem] fix issue with only one nameserver being provided
2015-02-23 10:03:55 +01:00
Pasi Sjöholm
5672f7248d [rilmodem] fix issue with only one nameserver being provided
No need to check if we have multiple nameserver provided
by the context, single one is enough.
2015-02-20 22:21:26 +02:00
Tommi Kenakkala
2ed0073bd1 Merge pull request #279 from tkenakka/log
[ofono] Add ril disconnect logging
2015-02-17 12:29:19 +02:00
Tommi Kenakkala
f6ade48648 Merge pull request #278 from tkenakka/sms-tp-oa
Fix received SMS alphanumeric TP-OA handling
2015-02-17 12:28:55 +02:00
Tommi Kenakkala
73ba48c9fb [ofono] Add ril disconnect logging 2015-02-17 11:12:18 +02:00
Tommi Kenakkala
f3611cef21 [ofono] unit: Add test to encode / decode 11 char SMS TP-OA 2015-02-16 10:31:16 +02:00
Tommi Kenakkala
15d682e62a [ofono] sms: Fix alphanumeric TP-OA handling
This fixes the issue of ofono ignoring received SMS if originator address
is a 11-character long alphanumeric string (with ext. ASCII).

TP-OA max length comparisons were incorrect because TP-OA's 7-bit coded
octets transport eleven 8-bit chars. The current code assumed only 10 chars
were possible.
- increases the array size to 23, (max 22 bytes for UTF8 + null terminator)
- Updates the sanity check to account for the correct maximum
- For encoding, checks the maximum length in UTF8 characters instead of bytes
- Make sure after the UTF8 -> GSM conversion that the number of GSM bytes is
not > 11, which is the maximum payload.
2015-02-16 10:30:18 +02:00
Tommi Kenakkala
0c23ed90b7 Merge pull request #276 from tkenakka/sco-sock
[ofono] hfp_hf_bluez5 typo fix
2015-01-27 10:44:12 +02:00
Tommi Kenakkala
54854c44a2 [ofono] hfp_hf_bluez5 typo fix 2015-01-27 10:41:00 +02:00
Tommi Kenakkala
da297d5722 Merge pull request #275 from tkenakka/sco-sock
[ofono] Move handsfree audio manager cleanup to hfp_hf_bluez5 plugin
2015-01-27 10:34:12 +02:00
Tommi Kenakkala
aba76cec73 [ofono] Move handsfree audio manager cleanup to hfp_hf_bluez5 plugin 2015-01-27 10:02:40 +02:00
Tommi Kenakkala
3cdc8f775d Merge pull request #274 from tkenakka/sco-sock
[ofono] Move SCO socket allocation to hfp_hf_bluez5 plugin
2015-01-27 09:02:20 +02:00
Tommi Kenakkala
bee03f8b56 [ofono] Move SCO socket allocation to hfp_hf_bluez5 plugin
SCO socket is handled by Bluez4 and conflicts with ofono's socket
allocation.
2015-01-27 08:58:48 +02:00
Tommi Kenakkala
7f4da6d59f Merge pull request #273 from jpoutiai/signal-context
Emit signal when context changed
2015-01-13 09:17:30 +02:00
Tommi Kenakkala
5754fff800 Merge pull request #272 from monich/noproxy
Setup route for mmsc if there's no mms proxy
2015-01-07 16:05:02 +02:00
Jarko Poutiainen
fff6952703 [rilmodem] if data call changed emit signal
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-01-07 09:44:06 +02:00
Jarko Poutiainen
96ff96ab1a [gril] compare data call lists based on cid
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-01-07 09:43:43 +02:00
Jarko Poutiainen
986ac50b9e [gril] publish g_ril_unsol_cmp_dcl
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-01-07 09:43:10 +02:00
Jarko Poutiainen
8600d8d293 [gprs] implement ofono_gprs_context_signal_change
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-01-07 09:42:52 +02:00
Jarko Poutiainen
369af1b401 [gprs] define ofono_gprs_context_signal_change
Signed-off-by: Jarko Poutiainen <jarko.poutiainen@oss.tieto.com>
2015-01-06 13:08:28 +02:00
Slava Monich
500b5234b2 [gprs] Setup route for mmsc if there's no mms proxy 2015-01-05 15:56:12 +03:00
18 changed files with 818 additions and 164 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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

View File

@@ -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)

View File

@@ -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);

View File

@@ -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

View File

@@ -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,

View File

@@ -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
View 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
View 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 */

View File

@@ -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);

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -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)