Compare commits

...

29 Commits

Author SHA1 Message Date
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
Slava Monich
93eb292b75 Merge pull request #271 from monich/OperatorsChanged
Add NetworkRegistration.OperatorsChanged signal
2014-12-31 12:47:57 +03:00
Slava Monich
3cc42fb087 [network] Added NetworkRegistration.OperatorsChanged signal
This signal gets emitted when operator list has changed.
It contains the current list of operators.
2014-12-22 09:12:18 +01:00
Jarko Poutiainen
782f2327fd Merge pull request #270 from jpoutiai/ipv6
[RILMODEM] fix same gateway for ipv4 and ipv6 issue
2014-12-12 12:38:26 +02:00
Tommi Kenakkala
8bda4032ca Merge pull request #269 from tkenakka/master
[rilmodem] Log ril version
2014-12-12 10:40:53 +02:00
Tommi Kenakkala
b2f4bd7603 [rilmodem] Log ril version 2014-12-12 10:22:11 +02:00
Jarko Poutiainen
33bb6d829c [RILMODEM] fix same gateway for ipv4 and ipv6 issue
Signed-off-by: Jarko Poutiainen <Jarko.Poutiainen@oss.tieto.com>
2014-12-12 08:32:38 +02:00
14 changed files with 450 additions and 29 deletions

View File

@@ -155,6 +155,15 @@ Methods dict GetProperties()
[service].Error.AttachInProgress [service].Error.AttachInProgress
[service].Error.NotImplemented [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) Signals PropertyChanged(string property, variant value)
This signal indicates a changed value of the given This signal indicates a changed value of the given

View File

@@ -57,6 +57,11 @@ Signals PropertyChanged(string property, variant value)
This signal indicates a changed value of the given This signal indicates a changed value of the given
property. property.
OperatorsChanged(array{object,dict})
Signal that gets emitted when operator list has
changed. It contains the current list of operators.
Properties string Mode [readonly] Properties string Mode [readonly]
The current registration mode. The default of this The current registration mode. The default of this

View File

@@ -66,6 +66,8 @@ struct gprs_context_data {
gint active_rild_cid; gint active_rild_cid;
enum state state; enum state state;
guint regid; guint regid;
struct unsol_data_call_list *old_list;
guint prev_active_status;
}; };
static void set_context_disconnected(struct gprs_context_data *gcd) static void set_context_disconnected(struct gprs_context_data *gcd)
@@ -112,11 +114,11 @@ static void ril_gprs_split_gw_by_protocol(char **gw_array, char **ip_gw,
for (i=0; i< g_strv_length(gw_array); i++) { for (i=0; i< g_strv_length(gw_array); i++) {
if (strchr(gw_array[i],ipv6_delimiter)) { if (strchr(gw_array[i],ipv6_delimiter)) {
if (*ipv6_gw == NULL) { if (*ipv6_gw == NULL) {
*ipv6_gw = g_strdup(gw_array[0]); *ipv6_gw = g_strdup(gw_array[i]);
} }
} else if (strchr(gw_array[i],ip_delimiter)) { } else if (strchr(gw_array[i],ip_delimiter)) {
if (*ip_gw == NULL) if (*ip_gw == NULL)
*ip_gw = g_strdup(gw_array[0]); *ip_gw = g_strdup(gw_array[i]);
} }
} }
} }
@@ -126,7 +128,6 @@ static void ril_gprs_split_dns_by_protocol(char **dns_array, char ***dns_addr,
{ {
const char ipv6_delimiter = ':'; const char ipv6_delimiter = ':';
const char ip_delimiter = '.'; const char ip_delimiter = '.';
const char dns_delimiter = ',';
char *temp = NULL; char *temp = NULL;
char *temp1 = NULL; char *temp1 = NULL;
char *dnsip = NULL; char *dnsip = NULL;
@@ -162,15 +163,11 @@ static void ril_gprs_split_dns_by_protocol(char **dns_array, char ***dns_addr,
} }
} }
if (dnsip){ if (dnsip)
if (strchr(dnsip,dns_delimiter)) *dns_addr = g_strsplit(dnsip, ",", dnsip_len);
*dns_addr = g_strsplit(dnsip, ",", dnsip_len);
}
if (dnsipv6) { if (dnsipv6)
if (strchr(dnsipv6,dns_delimiter)) *dns_ipv6_addr = g_strsplit(dnsipv6, ",", dnsipv6_len);
*dns_ipv6_addr = g_strsplit(dnsipv6, ",", dnsipv6_len);
}
g_free(dnsip); g_free(dnsip);
g_free(dnsipv6); g_free(dnsipv6);
@@ -184,6 +181,7 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
struct data_call *call = NULL; struct data_call *call = NULL;
struct unsol_data_call_list *unsol; struct unsol_data_call_list *unsol;
gboolean disconnect = FALSE; gboolean disconnect = FALSE;
gboolean signal = FALSE;
GSList *iterator = NULL; GSList *iterator = NULL;
struct ofono_error error; struct ofono_error error;
@@ -192,6 +190,12 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
if (error.type != OFONO_ERROR_TYPE_NO_ERROR) if (error.type != OFONO_ERROR_TYPE_NO_ERROR)
goto 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); DBG("number of call in call_list_changed is: %d", unsol->num);
for (iterator = unsol->call_list; iterator; iterator = iterator->next) { for (iterator = unsol->call_list; iterator; iterator = iterator->next) {
@@ -204,11 +208,15 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
if (call->cid != gcd->active_rild_cid) if (call->cid != gcd->active_rild_cid)
continue; continue;
if (call->active == DATA_CALL_LINK_DOWN)
gcd->prev_active_status = call->active;
if (call->status != 0) if (call->status != 0)
ofono_info("data call status:%d", call->status); ofono_info("data call status:%d", call->status);
if (call->active == DATA_CALL_INACTIVE) { if (call->active == DATA_CALL_INACTIVE) {
disconnect = TRUE; disconnect = TRUE;
gcd->prev_active_status = call->active;
ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid); ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
break; break;
} }
@@ -216,6 +224,11 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
if (call->active == DATA_CALL_ACTIVE) { if (call->active == DATA_CALL_ACTIVE) {
int protocol = -1; int protocol = -1;
if (gcd->prev_active_status != DATA_CALL_LINK_DOWN)
signal = TRUE;
gcd->prev_active_status = call->active;
if (call->type) if (call->type)
protocol = ril_protocol_string_to_ofono_protocol(call->type); protocol = ril_protocol_string_to_ofono_protocol(call->type);
@@ -326,8 +339,15 @@ static void ril_gprs_context_call_list_changed(struct ril_msg *message,
if (disconnect) { if (disconnect) {
ofono_error("Clearing active context"); ofono_error("Clearing active context");
set_context_disconnected(gcd); set_context_disconnected(gcd);
gcd->old_list = NULL;
goto error;
} }
if (signal)
ofono_gprs_context_signal_change(gc, gcd->active_ctx_cid);
return;
error: error:
g_ril_unsol_free_data_call_list(unsol); g_ril_unsol_free_data_call_list(unsol);
} }
@@ -656,6 +676,8 @@ static void ril_gprs_context_remove(struct ofono_gprs_context *gc)
DBG(""); DBG("");
g_ril_unsol_free_data_call_list(gcd->old_list);
if (gcd->state != STATE_IDLE) if (gcd->state != STATE_IDLE)
ril_gprs_context_detach_shutdown(gc, 0); ril_gprs_context_detach_shutdown(gc, 0);

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 unsol_data_call_list *g_ril_unsol_parse_data_call_list(GRil *gril,
struct ril_msg *message, struct ril_msg *message,
struct ofono_error *error) 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); 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 unsol_data_call_list *g_ril_unsol_parse_data_call_list(GRil *gril,
struct ril_msg *message, struct ril_msg *message,
struct ofono_error *error); 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); const char *gateway);
void ofono_gprs_context_set_ipv6_dns_servers(struct ofono_gprs_context *gc, void ofono_gprs_context_set_ipv6_dns_servers(struct ofono_gprs_context *gc,
const char **dns); const char **dns);
void ofono_gprs_context_signal_change(struct ofono_gprs_context *gc,
unsigned int cid);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -49,6 +49,7 @@
#include <ofono/handsfree.h> #include <ofono/handsfree.h>
#include <ofono/handsfree-audio.h> #include <ofono/handsfree-audio.h>
#include <ofono/siri.h> #include <ofono/siri.h>
#include <ofono.h>
#include <drivers/atmodem/atutil.h> #include <drivers/atmodem/atutil.h>
#include <drivers/hfpmodem/slc.h> #include <drivers/hfpmodem/slc.h>
@@ -762,6 +763,8 @@ static int hfp_init(void)
if (DBUS_TYPE_UNIX_FD < 0) if (DBUS_TYPE_UNIX_FD < 0)
return -EBADF; return -EBADF;
__ofono_handsfree_audio_manager_init();
/* Registers External Profile handler */ /* Registers External Profile handler */
if (!g_dbus_register_interface(conn, HFP_EXT_PROFILE_PATH, if (!g_dbus_register_interface(conn, HFP_EXT_PROFILE_PATH,
BLUEZ_PROFILE_INTERFACE, BLUEZ_PROFILE_INTERFACE,
@@ -817,6 +820,8 @@ static void hfp_exit(void)
g_dbus_client_unref(bluez); g_dbus_client_unref(bluez);
ofono_handsfree_audio_unref(); ofono_handsfree_audio_unref();
__ofono_handsfree_audio_manager_cleanup();
} }
OFONO_PLUGIN_DEFINE(hfp_bluez5, "External Hands-Free Profile Plugin", VERSION, OFONO_PLUGIN_DEFINE(hfp_bluez5, "External Hands-Free Profile Plugin", VERSION,

View File

@@ -402,12 +402,14 @@ static void ril_connected(struct ril_msg *message, gpointer user_data)
struct ofono_modem *modem = (struct ofono_modem *) user_data; struct ofono_modem *modem = (struct ofono_modem *) user_data;
struct ril_data *ril = ofono_modem_get_data(modem); struct ril_data *ril = ofono_modem_get_data(modem);
int ril_version = 0;
struct parcel rilp;
/* TODO: make conditional */ ril_util_init_parcel(message, &rilp);
ofono_debug("[UNSOL]< %s", ril_unsol_request_to_string(message->req)); ril_version = parcel_r_int32(&rilp);
/* TODO: make conditional */ ofono_debug("[UNSOL]< %s, RIL_VERSION %d",
ril_unsol_request_to_string(message->req), ril_version);
/* TODO: need a disconnect function to restart things! */
ril->connected = TRUE; ril->connected = TRUE;
send_get_sim_status(modem); send_get_sim_status(modem);
@@ -430,8 +432,7 @@ static gboolean ril_re_init(gpointer user_data)
static void gril_disconnected(gpointer user_data) static void gril_disconnected(gpointer user_data)
{ {
/* Signal clients modem going down ofono_info("gril disconnected");
*/
struct ofono_modem *modem = user_data; struct ofono_modem *modem = user_data;
DBusConnection *conn = ofono_dbus_get_connection(); DBusConnection *conn = ofono_dbus_get_connection();

View File

@@ -151,6 +151,8 @@ struct pri_context {
static void gprs_netreg_update(struct ofono_gprs *gprs); static void gprs_netreg_update(struct ofono_gprs *gprs);
static void gprs_deactivate_next(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_drivers = NULL;
static GSList *g_context_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); 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; char *scheme, *host, *port, *path;
if (proxy[0] == 0)
return FALSE;
scheme = g_strdup(proxy); scheme = g_strdup(proxy);
if (scheme == NULL) if (scheme == NULL)
return; return FALSE;
host = strstr(scheme, "://"); host = strstr(scheme, "://");
if (host != NULL) { if (host != NULL) {
@@ -580,7 +585,7 @@ static void pri_parse_proxy(struct pri_context *ctx, const char *proxy)
ctx->proxy_port = 80; ctx->proxy_port = 80;
else { else {
g_free(scheme); g_free(scheme);
return; return FALSE;
} }
} else { } else {
host = scheme; 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); g_free(ctx->proxy_host);
ctx->proxy_host = g_strdup(host); ctx->proxy_host = g_strdup(host);
g_free(scheme); g_free(scheme);
return TRUE;
} }
static void pri_ifupdown(const char *interface, ofono_bool_t active) 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 rtentry rt;
struct sockaddr_in addr; struct sockaddr_in addr;
in_addr_t proxy_addr;
int sk; int sk;
if (interface == NULL) if (interface == NULL)
return; return;
proxy_addr = inet_addr(proxy);
if (proxy_addr == INADDR_NONE)
return;
sk = socket(PF_INET, SOCK_DGRAM, 0); sk = socket(PF_INET, SOCK_DGRAM, 0);
if (sk < 0) if (sk < 0)
return; return;
@@ -706,7 +722,7 @@ static void pri_setproxy(const char *interface, const char *proxy)
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET; 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)); memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
@@ -793,7 +809,8 @@ static void pri_update_mms_context_settings(struct pri_context *ctx)
if (ctx->message_proxy) if (ctx->message_proxy)
settings->ipv4->proxy = g_strdup(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); DBG("proxy %s port %u", ctx->proxy_host, ctx->proxy_port);
@@ -805,6 +822,185 @@ static void pri_update_mms_context_settings(struct pri_context *ctx)
pri_limit_mtu(settings->interface, MAX_MMS_MTU); 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)
{
if (newval) {
if (strcmp(val, newval)) {
strcpy(val, newval);
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", ap->apn);
}
if (ap->name && strncmp(ctx->name, ap->name, MAX_CONTEXT_NAME_LENGTH)) {
changed = TRUE;
strncpy(ctx->name, ap->name, MAX_CONTEXT_NAME_LENGTH);
pri_str_signal_change(ctx, "Name", ap->name);
}
if (pri_str_update(ctx->context.username, ap->username)) {
changed = TRUE;
pri_str_signal_change(ctx, "Username", ap->username);
}
if (pri_str_update(ctx->context.password, ap->password)) {
changed = TRUE;
pri_str_signal_change(ctx, "Password", ap->password);
}
if (ctx->context.proto != ap->proto) {
ctx->context.proto = ap->proto;
changed = TRUE;
pri_str_signal_change(ctx, "Protocol",
gprs_proto_to_string(ap->proto));
}
if (ap->type == OFONO_GPRS_CONTEXT_TYPE_MMS) {
if (pri_str_update(ctx->message_proxy, ap->message_proxy)) {
changed = TRUE;
pri_str_signal_change(ctx, "MessageProxy",
ap->message_proxy);
}
if (pri_str_update(ctx->message_center, ap->message_center)) {
changed = TRUE;
pri_str_signal_change(ctx, "MessageCenter",
ap->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)
{
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 {
/* Othwise context must be deactivated first */
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, static void append_context_properties(struct pri_context *ctx,
DBusMessageIter *dict) DBusMessageIter *dict)
{ {
@@ -1322,6 +1518,8 @@ static const GDBusMethodTable context_methods[] = {
{ GDBUS_ASYNC_METHOD("SetProperty", { GDBUS_ASYNC_METHOD("SetProperty",
GDBUS_ARGS({ "property", "s" }, { "value", "v" }), GDBUS_ARGS({ "property", "s" }, { "value", "v" }),
NULL, pri_set_property) }, NULL, pri_set_property) },
{ GDBUS_METHOD("ProvisionContext", NULL, NULL,
pri_provision_context) },
{ } { }
}; };
@@ -2550,6 +2748,29 @@ void ofono_gprs_context_set_ipv6_dns_servers(struct ofono_gprs_context *gc,
settings->ipv6->dns = g_strdupv((char **) dns); 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) int ofono_gprs_driver_register(const struct ofono_gprs_driver *d)
{ {
DBG("driver: %p, name: %s", d, d->name); DBG("driver: %p, name: %s", d, d->name);

View File

@@ -244,7 +244,11 @@ int main(int argc, char **argv)
__ofono_manager_init(); __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); __ofono_plugin_init(option_plugin, option_noplugin);
@@ -255,7 +259,7 @@ int main(int argc, char **argv)
__ofono_plugin_cleanup(); __ofono_plugin_cleanup();
__ofono_handsfree_audio_manager_cleanup(); //__ofono_handsfree_audio_manager_cleanup(); See comment above
__ofono_manager_cleanup(); __ofono_manager_cleanup();

View File

@@ -934,6 +934,40 @@ static void append_operator_struct_list(struct ofono_netreg *netreg,
dbus_free_string_array(children); dbus_free_string_array(children);
} }
static void network_signal_operators_changed(struct ofono_netreg *netreg)
{
const char *path = __ofono_atom_get_path(netreg->atom);
DBusConnection *conn = ofono_dbus_get_connection();
DBusMessage *signal;
DBusMessageIter iter;
DBusMessageIter array;
signal = dbus_message_new_signal(path,
OFONO_NETWORK_REGISTRATION_INTERFACE, "OperatorsChanged");
if (signal == NULL) {
ofono_error("Unable to allocate new "
OFONO_NETWORK_REGISTRATION_INTERFACE
".OperatorsChanged signal");
return;
}
dbus_message_iter_init_append(signal, &iter);
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
DBUS_STRUCT_BEGIN_CHAR_AS_STRING
DBUS_TYPE_OBJECT_PATH_AS_STRING
DBUS_TYPE_ARRAY_AS_STRING
DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING
DBUS_STRUCT_END_CHAR_AS_STRING,
&array);
append_operator_struct_list(netreg, &array);
dbus_message_iter_close_container(&iter, &array);
g_dbus_send_message(conn, signal);
}
static void operator_list_callback(const struct ofono_error *error, int total, static void operator_list_callback(const struct ofono_error *error, int total,
const struct ofono_network_operator *list, const struct ofono_network_operator *list,
void *data) void *data)
@@ -942,6 +976,7 @@ static void operator_list_callback(const struct ofono_error *error, int total,
DBusMessage *reply; DBusMessage *reply;
DBusMessageIter iter; DBusMessageIter iter;
DBusMessageIter array; DBusMessageIter array;
gboolean changed;
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
DBG("Error occurred during operator list"); DBG("Error occurred during operator list");
@@ -950,7 +985,7 @@ static void operator_list_callback(const struct ofono_error *error, int total,
return; return;
} }
update_operator_list(netreg, total, list); changed = update_operator_list(netreg, total, list);
reply = dbus_message_new_method_return(netreg->pending); reply = dbus_message_new_method_return(netreg->pending);
@@ -970,6 +1005,11 @@ static void operator_list_callback(const struct ofono_error *error, int total,
dbus_message_iter_close_container(&iter, &array); dbus_message_iter_close_container(&iter, &array);
__ofono_dbus_pending_reply(&netreg->pending, reply); __ofono_dbus_pending_reply(&netreg->pending, reply);
DBG("operator list %schanged", changed ? "" : "not ");
if (changed)
network_signal_operators_changed(netreg);
} }
static DBusMessage *network_scan(DBusConnection *conn, static DBusMessage *network_scan(DBusConnection *conn,
@@ -1041,6 +1081,8 @@ static const GDBusMethodTable network_registration_methods[] = {
static const GDBusSignalTable network_registration_signals[] = { static const GDBusSignalTable network_registration_signals[] = {
{ GDBUS_SIGNAL("PropertyChanged", { GDBUS_SIGNAL("PropertyChanged",
GDBUS_ARGS({ "name", "s" }, { "value", "v" })) }, GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
{ GDBUS_SIGNAL("OperatorsChanged",
GDBUS_ARGS({ "operators", "a(oa{sv})"})) },
{ } { }
}; };

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, gboolean sms_encode_address_field(const struct sms_address *in, gboolean sc,
unsigned char *pdu, int *offset) 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 addr_len = 0;
unsigned char p[10]; 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 *gsm;
unsigned char *r; 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; return FALSE;
gsm = convert_utf8_to_gsm(in->address, len, NULL, &written, 0); gsm = convert_utf8_to_gsm(in->address, len, NULL, &written, 0);
if (gsm == NULL) if (gsm == NULL)
return FALSE; return FALSE;
if (written > 11) {
g_free(gsm);
return FALSE;
}
r = pack_7bit_own_buf(gsm, written, 0, FALSE, &packed, 0, p); r = pack_7bit_own_buf(gsm, written, 0, FALSE, &packed, 0, p);
g_free(gsm); g_free(gsm);
@@ -675,7 +682,11 @@ gboolean sms_decode_address_field(const unsigned char *pdu, int len,
if (utf8 == NULL) if (utf8 == NULL)
return FALSE; 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); g_free(utf8);
return FALSE; return FALSE;
} }

View File

@@ -220,7 +220,11 @@ enum cbs_geo_scope {
struct sms_address { struct sms_address {
enum sms_number_type number_type; enum sms_number_type number_type;
enum sms_numbering_plan numbering_plan; 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 { struct sms_scts {

View File

@@ -38,6 +38,12 @@ static const char *simple_deliver = "07911326040000F0"
"040B911346610089F60000208062917314480CC8F71D14969741F977FD07"; "040B911346610089F60000208062917314480CC8F71D14969741F977FD07";
static const char *alnum_sender = "0791447758100650" static const char *alnum_sender = "0791447758100650"
"040DD0F334FC1CA6970100008080312170224008D4F29CDE0EA7D9"; "040DD0F334FC1CA6970100008080312170224008D4F29CDE0EA7D9";
static const char *unicode_deliver = "04819999990414D0FBFD7EBFDFEFF77BFE1E001"
"9512090801361807E00DC00FC00C400E400D600F600C500E500D800F800C"
"600E600C700E700C900E900CA00EA00DF003100320033003400350036003"
"7003800390030002000540068006900730020006D0065007300730061006"
"7006500200069007300200036003300200075006E00690063006F0064006"
"5002000630068006100720073002E";
static const char *simple_submit = "0011000B916407281553F80000AA" static const char *simple_submit = "0011000B916407281553F80000AA"
"0AE8329BFD4697D9EC37"; "0AE8329BFD4697D9EC37";
@@ -362,6 +368,38 @@ static void test_deliver_encode(void)
g_assert(strcmp(alnum_sender, encoded_pdu) == 0); g_assert(strcmp(alnum_sender, encoded_pdu) == 0);
g_free(encoded_pdu); 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) static void test_simple_submit(void)