mirror of
https://github.com/sailfishos/ofono
synced 2025-11-28 13:41:04 +08:00
Compare commits
48 Commits
mer/1.14+g
...
mer/1.14+g
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59449f74a1 | ||
|
|
ff63e9b057 | ||
|
|
7b73f569eb | ||
|
|
5672f7248d | ||
|
|
2ed0073bd1 | ||
|
|
f6ade48648 | ||
|
|
73ba48c9fb | ||
|
|
f3611cef21 | ||
|
|
15d682e62a | ||
|
|
0c23ed90b7 | ||
|
|
54854c44a2 | ||
|
|
da297d5722 | ||
|
|
aba76cec73 | ||
|
|
3cdc8f775d | ||
|
|
bee03f8b56 | ||
|
|
7f4da6d59f | ||
|
|
5754fff800 | ||
|
|
fff6952703 | ||
|
|
96ff96ab1a | ||
|
|
986ac50b9e | ||
|
|
8600d8d293 | ||
|
|
369af1b401 | ||
|
|
500b5234b2 | ||
|
|
93eb292b75 | ||
|
|
3cc42fb087 | ||
|
|
782f2327fd | ||
|
|
8bda4032ca | ||
|
|
b2f4bd7603 | ||
|
|
33bb6d829c | ||
|
|
1bea99ac56 | ||
|
|
aab24b3f24 | ||
|
|
65eea56efe | ||
|
|
8ac7e502b7 | ||
|
|
9e8bdf0d64 | ||
|
|
70e99152a3 | ||
|
|
a90fc92665 | ||
|
|
1d23793eb0 | ||
|
|
804bef98ad | ||
|
|
1fdde8fecb | ||
|
|
1c484a6d04 | ||
|
|
64e888ef04 | ||
|
|
b33e0061d0 | ||
|
|
2babf82823 | ||
|
|
87a35d5d83 | ||
|
|
3d264276de | ||
|
|
d6bd24add3 | ||
|
|
9624eb9ace | ||
|
|
14672319d2 |
@@ -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
|
||||
|
||||
@@ -57,6 +57,11 @@ Signals PropertyChanged(string property, variant value)
|
||||
This signal indicates a changed value of the given
|
||||
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]
|
||||
|
||||
The current registration mode. The default of this
|
||||
|
||||
@@ -134,7 +134,9 @@ static void routing_resp_cb(const GIsiMessage *msg, void *data)
|
||||
struct cbs_data *cd = ofono_cbs_get_data(cbs);
|
||||
|
||||
if (!check_resp(msg, SMS_GSM_CB_ROUTING_RESP)) {
|
||||
ofono_cbs_remove(cbs);
|
||||
/* on shutdown, cbs is already being removed */
|
||||
if (g_isi_msg_error(msg) != -ESHUTDOWN)
|
||||
ofono_cbs_remove(cbs);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -75,6 +77,102 @@ static void set_context_disconnected(struct gprs_context_data *gcd)
|
||||
gcd->state = STATE_IDLE;
|
||||
}
|
||||
|
||||
static void ril_gprs_split_ip_by_protocol(char **ip_array,
|
||||
char ***split_ip_addr,
|
||||
char ***split_ipv6_addr,
|
||||
char **ip_addr)
|
||||
{
|
||||
const char ipv6_delimiter = ':';
|
||||
const char ip_delimiter = '.';
|
||||
int i;
|
||||
|
||||
*split_ipv6_addr = *split_ip_addr = NULL;
|
||||
for (i=0; i< g_strv_length(ip_array); i++) {
|
||||
if (strchr(ip_array[i], ipv6_delimiter)) {
|
||||
if (*split_ipv6_addr == NULL) {
|
||||
*split_ipv6_addr = g_strsplit(
|
||||
ip_array[i], "/",2);
|
||||
}
|
||||
} else if (strchr(ip_array[i], ip_delimiter)) {
|
||||
if (*split_ip_addr == NULL) {
|
||||
*ip_addr = g_strdup(ip_array[i]);
|
||||
*split_ip_addr = g_strsplit(
|
||||
ip_array[i], "/", 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_gprs_split_gw_by_protocol(char **gw_array, char **ip_gw,
|
||||
char **ipv6_gw)
|
||||
{
|
||||
const char ipv6_delimiter = ':';
|
||||
const char ip_delimiter = '.';
|
||||
int i;
|
||||
|
||||
*ip_gw = *ipv6_gw = NULL;
|
||||
for (i=0; i< g_strv_length(gw_array); i++) {
|
||||
if (strchr(gw_array[i],ipv6_delimiter)) {
|
||||
if (*ipv6_gw == NULL) {
|
||||
*ipv6_gw = g_strdup(gw_array[i]);
|
||||
}
|
||||
} else if (strchr(gw_array[i],ip_delimiter)) {
|
||||
if (*ip_gw == NULL)
|
||||
*ip_gw = g_strdup(gw_array[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ril_gprs_split_dns_by_protocol(char **dns_array, char ***dns_addr,
|
||||
char ***dns_ipv6_addr)
|
||||
{
|
||||
const char ipv6_delimiter = ':';
|
||||
const char ip_delimiter = '.';
|
||||
char *temp = NULL;
|
||||
char *temp1 = NULL;
|
||||
char *dnsip = NULL;
|
||||
char *dnsipv6 = NULL;
|
||||
int i, dnsip_len, dnsipv6_len;
|
||||
|
||||
dnsip_len = dnsipv6_len = 0;
|
||||
|
||||
for (i=0; i< g_strv_length(dns_array); i++) {
|
||||
if (strchr(dns_array[i],ipv6_delimiter)) {
|
||||
if (dnsipv6 == NULL) {
|
||||
dnsipv6 = g_strdup(dns_array[i]);
|
||||
} else {
|
||||
temp = g_strconcat(dnsipv6, ",", NULL);
|
||||
g_free(dnsipv6);
|
||||
temp1 = g_strconcat(temp, dns_array[i], NULL);
|
||||
g_free(temp);
|
||||
dnsipv6 = temp1;
|
||||
}
|
||||
dnsipv6_len++;
|
||||
} else if (strchr(dns_array[i],ip_delimiter)) {
|
||||
if (dnsip == NULL) {
|
||||
dnsip = g_strdup(dns_array[i]);
|
||||
} else {
|
||||
temp = g_strconcat(dnsip, ",", NULL);
|
||||
g_free(dnsip);
|
||||
temp1 = g_strconcat(temp, dns_array[i], NULL);
|
||||
g_free(temp);
|
||||
dnsip = temp1;
|
||||
|
||||
}
|
||||
dnsip_len++;
|
||||
}
|
||||
}
|
||||
|
||||
if (dnsip)
|
||||
*dns_addr = g_strsplit(dnsip, ",", dnsip_len);
|
||||
|
||||
if (dnsipv6)
|
||||
*dns_ipv6_addr = g_strsplit(dnsipv6, ",", dnsipv6_len);
|
||||
|
||||
g_free(dnsip);
|
||||
g_free(dnsipv6);
|
||||
}
|
||||
|
||||
static void ril_gprs_context_call_list_changed(struct ril_msg *message,
|
||||
gpointer user_data)
|
||||
{
|
||||
@@ -83,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;
|
||||
|
||||
@@ -91,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) {
|
||||
@@ -103,50 +208,130 @@ 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;
|
||||
}
|
||||
|
||||
if (call->active == DATA_CALL_ACTIVE) {
|
||||
char **dns_addresses;
|
||||
int protocol = -1;
|
||||
|
||||
if (call->ifname) {
|
||||
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);
|
||||
|
||||
if (call->ifname)
|
||||
ofono_gprs_context_set_interface(gc,
|
||||
call->ifname);
|
||||
}
|
||||
|
||||
if (call->addresses) {
|
||||
char **split_ip_addr;
|
||||
ofono_gprs_context_set_ipv4_netmask(gc,
|
||||
ril_util_get_netmask(call->addresses));
|
||||
char **split_ip_addr = NULL;
|
||||
char **ip_array = NULL;
|
||||
char **split_ipv6_addr = NULL;
|
||||
char *ip_addr = NULL;
|
||||
|
||||
split_ip_addr = g_strsplit(call->addresses,
|
||||
"/", 2);
|
||||
ofono_gprs_context_set_ipv4_address(gc,
|
||||
/*addresses to an array*/
|
||||
ip_array = g_strsplit(call->addresses, " ",-1);
|
||||
|
||||
/*pick 1 address of each protocol*/
|
||||
ril_gprs_split_ip_by_protocol(ip_array,
|
||||
&split_ip_addr,
|
||||
&split_ipv6_addr,
|
||||
&ip_addr);
|
||||
|
||||
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
|
||||
protocol == OFONO_GPRS_PROTO_IPV6)
|
||||
&& split_ipv6_addr != NULL){
|
||||
|
||||
ofono_gprs_context_set_ipv6_address(gc,
|
||||
split_ipv6_addr[0]);
|
||||
}
|
||||
|
||||
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
|
||||
protocol == OFONO_GPRS_PROTO_IP)
|
||||
&& split_ip_addr != NULL) {
|
||||
|
||||
ofono_gprs_context_set_ipv4_netmask(gc,
|
||||
ril_util_get_netmask(ip_addr));
|
||||
ofono_gprs_context_set_ipv4_address(gc,
|
||||
split_ip_addr[0], TRUE);
|
||||
}
|
||||
|
||||
g_strfreev(split_ip_addr);
|
||||
g_strfreev(split_ipv6_addr);
|
||||
g_strfreev(ip_array);
|
||||
g_free(ip_addr);
|
||||
}
|
||||
|
||||
if (call->gateways) {
|
||||
ofono_gprs_context_set_ipv4_gateway(gc,
|
||||
call->gateways);
|
||||
char **gw_array = NULL;
|
||||
char *ip_gw = NULL;
|
||||
char *ipv6_gw = NULL;
|
||||
/*addresses to an array*/
|
||||
gw_array = g_strsplit(call->gateways, " ", -1);
|
||||
|
||||
/*pick 1 gw for each protocol*/
|
||||
ril_gprs_split_gw_by_protocol(gw_array, &ip_gw,
|
||||
&ipv6_gw);
|
||||
|
||||
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
|
||||
protocol == OFONO_GPRS_PROTO_IPV6)
|
||||
&& ipv6_gw != NULL)
|
||||
ofono_gprs_context_set_ipv6_gateway(gc,
|
||||
ipv6_gw);
|
||||
|
||||
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
|
||||
protocol == OFONO_GPRS_PROTO_IP)
|
||||
&& ip_gw != NULL)
|
||||
ofono_gprs_context_set_ipv4_gateway(gc,
|
||||
ip_gw);
|
||||
|
||||
g_strfreev(gw_array);
|
||||
g_free(ip_gw);
|
||||
g_free(ipv6_gw);
|
||||
}
|
||||
|
||||
if (call->dnses) {
|
||||
char **dns_array = NULL;
|
||||
char **dns_ip = NULL;
|
||||
char **dns_ipv6 = NULL;
|
||||
|
||||
if (call->dnses)
|
||||
DBG("dnses:%s", call->dnses);
|
||||
/*addresses to an array*/
|
||||
dns_array = g_strsplit(call->dnses, " ", -1);
|
||||
|
||||
dns_addresses = (call->dnses ?
|
||||
g_strsplit(call->dnses, " ", 3) : NULL);
|
||||
/*split based on protocol*/
|
||||
ril_gprs_split_dns_by_protocol(dns_array,
|
||||
&dns_ip,
|
||||
&dns_ipv6);
|
||||
|
||||
ofono_gprs_context_set_ipv4_dns_servers(gc,
|
||||
(const char**)dns_addresses);
|
||||
g_strfreev(dns_addresses);
|
||||
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
|
||||
protocol == OFONO_GPRS_PROTO_IPV6)
|
||||
&& dns_ipv6 != NULL)
|
||||
ofono_gprs_context_set_ipv6_dns_servers(
|
||||
gc, (const char **) dns_ipv6);
|
||||
|
||||
if ((protocol == OFONO_GPRS_PROTO_IPV4V6 ||
|
||||
protocol == OFONO_GPRS_PROTO_IP)
|
||||
&& dns_ip != NULL)
|
||||
ofono_gprs_context_set_ipv4_dns_servers(
|
||||
gc, (const char**)dns_ip);
|
||||
|
||||
g_strfreev(dns_ip);
|
||||
g_strfreev(dns_ipv6);
|
||||
g_strfreev(dns_array);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -154,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);
|
||||
}
|
||||
@@ -169,6 +361,12 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
|
||||
struct ofono_error error;
|
||||
struct reply_setup_data_call *reply = NULL;
|
||||
char **split_ip_addr = NULL;
|
||||
char **split_ipv6_addr = NULL;
|
||||
char* ip_addr = NULL;
|
||||
char* ip_gw = NULL;
|
||||
char* ipv6_gw = NULL;
|
||||
char** dns_addr = NULL;
|
||||
char** dns_ipv6_addr = NULL;
|
||||
|
||||
ofono_info("setting up data call");
|
||||
|
||||
@@ -203,20 +401,13 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: consier moving this into parse_data_reply
|
||||
*
|
||||
* Note - the address may optionally include a prefix size
|
||||
* ( Eg. "/30" ). As this may confuse client, we
|
||||
* explicitly strip any prefix after calculating the netmask.
|
||||
*/
|
||||
split_ip_addr = g_strsplit(reply->ip_addrs[0], "/", 2);
|
||||
/*check the ip address protocol*/
|
||||
ril_gprs_split_ip_by_protocol(reply->ip_addrs, &split_ip_addr,
|
||||
&split_ipv6_addr, &ip_addr);
|
||||
|
||||
/* TODO: see note above re: invalid messages... */
|
||||
if (split_ip_addr[0] == NULL) {
|
||||
ofono_error("%s: invalid IP address field returned: %s",
|
||||
__func__,
|
||||
reply->ip_addrs[0]);
|
||||
if (split_ip_addr == NULL && split_ipv6_addr == NULL) {
|
||||
ofono_error("%s: No IP address returned",
|
||||
__func__);
|
||||
|
||||
error.type = OFONO_ERROR_TYPE_FAILURE;
|
||||
error.error = EINVAL;
|
||||
@@ -229,26 +420,48 @@ static void ril_setup_data_call_cb(struct ril_msg *message, gpointer user_data)
|
||||
|
||||
ofono_gprs_context_set_interface(gc, reply->ifname);
|
||||
|
||||
ril_gprs_split_gw_by_protocol(reply->gateways, &ip_gw, &ipv6_gw);
|
||||
|
||||
ril_gprs_split_dns_by_protocol(reply->dns_addresses, &dns_addr,
|
||||
&dns_ipv6_addr);
|
||||
|
||||
/* TODO:
|
||||
* RILD can return multiple addresses; oFono only supports
|
||||
* setting a single IPv4 address. At this time, we only
|
||||
* use the first address. It's possible that a RIL may
|
||||
* just specify the end-points of the point-to-point
|
||||
* connection, in which case this code will need to
|
||||
* changed to handle such a device.
|
||||
* RILD can return multiple addresses; oFono only supports setting
|
||||
* a single IPv4 and single IPV6 address. At this time, we only use
|
||||
* the first address. It's possible that a RIL may just specify
|
||||
* the end-points of the point-to-point connection, in which case this
|
||||
* code will need to changed to handle such a device.
|
||||
*/
|
||||
ofono_gprs_context_set_ipv4_netmask(gc,
|
||||
ril_util_get_netmask(reply->ip_addrs[0]));
|
||||
|
||||
ofono_gprs_context_set_ipv4_address(gc, split_ip_addr[0], TRUE);
|
||||
ofono_gprs_context_set_ipv4_gateway(gc, reply->gateways[0]);
|
||||
if (split_ipv6_addr != NULL &&
|
||||
(reply->protocol == OFONO_GPRS_PROTO_IPV6 ||
|
||||
reply->protocol == OFONO_GPRS_PROTO_IPV4V6)) {
|
||||
|
||||
ofono_gprs_context_set_ipv4_dns_servers(gc,
|
||||
(const char **) reply->dns_addresses);
|
||||
ofono_gprs_context_set_ipv6_address(gc, split_ipv6_addr[0]);
|
||||
ofono_gprs_context_set_ipv6_gateway(gc, ipv6_gw);
|
||||
ofono_gprs_context_set_ipv6_dns_servers(gc,
|
||||
(const char **) dns_ipv6_addr);
|
||||
}
|
||||
|
||||
if (split_ip_addr != NULL &&
|
||||
(reply->protocol == OFONO_GPRS_PROTO_IP ||
|
||||
reply->protocol == OFONO_GPRS_PROTO_IPV4V6)) {
|
||||
ofono_gprs_context_set_ipv4_netmask(gc,
|
||||
ril_util_get_netmask(ip_addr));
|
||||
ofono_gprs_context_set_ipv4_address(gc, split_ip_addr[0], TRUE);
|
||||
ofono_gprs_context_set_ipv4_gateway(gc, ip_gw);
|
||||
ofono_gprs_context_set_ipv4_dns_servers(gc,
|
||||
(const char **) dns_addr);
|
||||
}
|
||||
error:
|
||||
g_ril_reply_free_setup_data_call(reply);
|
||||
g_strfreev(split_ip_addr);
|
||||
g_strfreev(split_ipv6_addr);
|
||||
g_strfreev(dns_addr);
|
||||
g_strfreev(dns_ipv6_addr);
|
||||
g_free(ip_addr);
|
||||
g_free(ip_gw);
|
||||
g_free(ipv6_gw);
|
||||
|
||||
cb(&error, cbd->data);
|
||||
}
|
||||
@@ -290,6 +503,7 @@ static void ril_gprs_context_activate_primary(struct ofono_gprs_context *gc,
|
||||
request.username = g_strdup(ctx->username);
|
||||
request.password = g_strdup(ctx->password);
|
||||
request.auth_type = RIL_AUTH_BOTH;
|
||||
|
||||
request.protocol = ctx->proto;
|
||||
|
||||
if (g_ril_request_setup_data_call(gcd->ril,
|
||||
@@ -462,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);
|
||||
|
||||
|
||||
@@ -65,23 +65,21 @@
|
||||
* +CREG ( see 27.003 7.2 ).
|
||||
*/
|
||||
|
||||
#define FAKE_STATE_TIMER 5
|
||||
|
||||
struct gprs_data {
|
||||
GRil *ril;
|
||||
gboolean ofono_attached;
|
||||
int max_cids;
|
||||
int true_status; /* Status by driver before state faking */
|
||||
int rild_status; /* Status for temporary state faking logic */
|
||||
gboolean notified;
|
||||
int rild_status; /* Driver Status */
|
||||
guint registerid;
|
||||
guint timer_id;
|
||||
guint fake_timer_id;
|
||||
struct cb_data *fake_cbd;
|
||||
};
|
||||
|
||||
/* Following constants are purely to improve readability */
|
||||
static const int roaming = NETWORK_REGISTRATION_STATUS_ROAMING;
|
||||
static const int registered = NETWORK_REGISTRATION_STATUS_REGISTERED;
|
||||
|
||||
/*if we have called ofono_gprs_register or not*/
|
||||
static gboolean registered;
|
||||
static gboolean ofono_registered;
|
||||
|
||||
static void ril_gprs_registration_status(struct ofono_gprs *gprs,
|
||||
ofono_gprs_status_cb_t cb,
|
||||
@@ -143,8 +141,6 @@ static void ril_gprs_set_attached(struct ofono_gprs *gprs, int attached,
|
||||
* are met.
|
||||
*/
|
||||
|
||||
gd->notified = (gd->ofono_attached == attached) ? TRUE : FALSE;
|
||||
|
||||
gd->ofono_attached = attached;
|
||||
|
||||
cbd->user = gprs;
|
||||
@@ -159,38 +155,6 @@ static void ril_gprs_set_attached(struct ofono_gprs *gprs, int attached,
|
||||
cbd);
|
||||
}
|
||||
|
||||
static void remove_fake_timer(struct gprs_data *gd)
|
||||
{
|
||||
DBG("");
|
||||
|
||||
if (!gd)
|
||||
return;
|
||||
|
||||
if (gd->fake_timer_id > 0) {
|
||||
g_source_remove(gd->fake_timer_id);
|
||||
gd->fake_timer_id = 0;
|
||||
}
|
||||
|
||||
g_free(gd->fake_cbd);
|
||||
gd->fake_cbd = NULL;
|
||||
}
|
||||
|
||||
static gboolean ril_fake_response(gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
struct ofono_gprs *gprs = cbd->user;
|
||||
struct gprs_data *gd = ofono_gprs_get_data(gprs);
|
||||
|
||||
ofono_info("data reg timeout, status changed to %d", gd->true_status);
|
||||
|
||||
gd->fake_timer_id = 0;
|
||||
gd->fake_cbd = NULL;
|
||||
|
||||
ofono_gprs_status_notify(gprs, gd->true_status);
|
||||
g_free(cbd); /* == gd->fake_cbd */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gboolean ril_roaming_allowed()
|
||||
{
|
||||
GError *error;
|
||||
@@ -222,12 +186,9 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
||||
struct ofono_gprs *gprs = cbd->user;
|
||||
struct gprs_data *gd = ofono_gprs_get_data(gprs);
|
||||
struct ofono_error error;
|
||||
int status, lac, ci, tech;
|
||||
int lac, ci, tech;
|
||||
int max_cids = 1;
|
||||
|
||||
DBG("");
|
||||
|
||||
status = -1;
|
||||
int status = -1;
|
||||
|
||||
if (gd && message->error == RIL_E_SUCCESS) {
|
||||
decode_ril_error(&error, "OK");
|
||||
@@ -236,29 +197,22 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
||||
ril_error_to_string(message->error));
|
||||
decode_ril_error(&error, "FAIL");
|
||||
error.error = message->error;
|
||||
goto error;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ril_util_parse_reg(gd->ril, message, &status,
|
||||
&lac, &ci, &tech, &max_cids) == FALSE) {
|
||||
ofono_error("Failure parsing data registration response.");
|
||||
decode_ril_error(&error, "FAIL");
|
||||
goto error;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (status > 10)
|
||||
status = status - 10;
|
||||
|
||||
if ((gd->fake_timer_id > 0)
|
||||
&& ((status == NETWORK_REGISTRATION_STATUS_REGISTERED
|
||||
|| status == NETWORK_REGISTRATION_STATUS_ROAMING)
|
||||
|| !gd->ofono_attached)) {
|
||||
remove_fake_timer(gd);
|
||||
}
|
||||
|
||||
if (!registered) {
|
||||
if (!ofono_registered) {
|
||||
ofono_gprs_register(gprs);
|
||||
registered = TRUE;
|
||||
ofono_registered = TRUE;
|
||||
}
|
||||
|
||||
if (max_cids > gd->max_cids) {
|
||||
@@ -267,19 +221,32 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
||||
ofono_gprs_set_cid_range(gprs, 1, max_cids);
|
||||
}
|
||||
|
||||
if (status == NETWORK_REGISTRATION_STATUS_ROAMING)
|
||||
if (status == roaming)
|
||||
status = check_if_really_roaming(status);
|
||||
|
||||
if (gd->true_status != status) {
|
||||
ofono_info("data reg changes %d (%d), rilds %d, attached %d",
|
||||
status, gd->true_status, gd->rild_status,
|
||||
gd->ofono_attached);
|
||||
gd->true_status = status;
|
||||
/* Let's minimize logging */
|
||||
if (status != gd->rild_status)
|
||||
ofono_info("data reg changes %d (%d), attached %d",
|
||||
status, gd->rild_status, gd->ofono_attached);
|
||||
|
||||
/* Must be attached if registered or roaming */
|
||||
if ((gd->rild_status != registered) && (gd->rild_status != roaming)) {
|
||||
if (status == registered)
|
||||
gd->ofono_attached = TRUE;
|
||||
else if ((status == roaming) && (ril_roaming_allowed() == TRUE))
|
||||
gd->ofono_attached = TRUE;
|
||||
}
|
||||
|
||||
if (!ofono_modem_get_online(ofono_gprs_get_modem(gprs)))
|
||||
gd->ofono_attached = FALSE;
|
||||
|
||||
/* if unsolicitated and no state change let's not notify core */
|
||||
if ((status == gd->rild_status) && gd->ofono_attached)
|
||||
goto cb_out;
|
||||
|
||||
if (!gd->ofono_attached) {
|
||||
if (status == NETWORK_REGISTRATION_STATUS_ROAMING) {
|
||||
if (!gd->notified && cb) {
|
||||
if (!cb) {
|
||||
if (status == roaming) {
|
||||
if (ril_roaming_allowed() == FALSE)
|
||||
ofono_gprs_detached_notify(gprs);
|
||||
|
||||
@@ -288,59 +255,31 @@ static void ril_data_reg_cb(struct ril_msg *message, gpointer user_data)
|
||||
* into eternal loop with driver
|
||||
*/
|
||||
decode_ril_error(&error, "FAIL");
|
||||
|
||||
ofono_gprs_status_notify(gprs, status);
|
||||
}
|
||||
|
||||
ofono_gprs_status_notify(gprs, status);
|
||||
|
||||
} else {
|
||||
if (status == NETWORK_REGISTRATION_STATUS_SEARCHING
|
||||
&& !gd->notified
|
||||
&& cb)
|
||||
/*
|
||||
* This is a hack that prevents core ending
|
||||
* into eternal loop with driver
|
||||
*/
|
||||
decode_ril_error(&error, "FAIL");
|
||||
|
||||
ofono_gprs_status_notify(gprs, status);
|
||||
/*
|
||||
* This prevents core ending
|
||||
* into eternal loop with driver
|
||||
*/
|
||||
decode_ril_error(&error, "FAIL");
|
||||
}
|
||||
|
||||
if (cb)
|
||||
gd->notified = TRUE;
|
||||
|
||||
gd->rild_status = status;
|
||||
goto error;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (status == NETWORK_REGISTRATION_STATUS_ROAMING ||
|
||||
status == NETWORK_REGISTRATION_STATUS_REGISTERED) {
|
||||
ofono_gprs_status_notify(gprs, status);
|
||||
gd->rild_status = status;
|
||||
} else {
|
||||
if (gd->fake_timer_id <= 0) {
|
||||
gd->fake_cbd = cb_data_new(NULL, NULL);
|
||||
gd->fake_cbd->user = gprs;
|
||||
ofono_info("data reg rilmodem status timer starts");
|
||||
gd->fake_timer_id = g_timeout_add_seconds(
|
||||
FAKE_STATE_TIMER,
|
||||
ril_fake_response,
|
||||
gd->fake_cbd);
|
||||
}
|
||||
if (!cb)
|
||||
ofono_gprs_status_notify(gprs, status);
|
||||
|
||||
if (gd->rild_status == NETWORK_REGISTRATION_STATUS_ROAMING)
|
||||
status = NETWORK_REGISTRATION_STATUS_ROAMING;
|
||||
else
|
||||
status = NETWORK_REGISTRATION_STATUS_REGISTERED;
|
||||
|
||||
gd->rild_status = status;
|
||||
ofono_info("data reg status mod to %d", status);
|
||||
}
|
||||
|
||||
error:
|
||||
|
||||
DBG("data reg status %d, true_status %d, rilds %d, attached %d",
|
||||
status, gd->true_status, gd->rild_status,
|
||||
gd->ofono_attached);
|
||||
gd->rild_status = status;
|
||||
|
||||
exit:
|
||||
DBG("data reg status %d, rild_status %d, attached %d",
|
||||
status, gd->rild_status, gd->ofono_attached);
|
||||
cb_out:
|
||||
if (cb)
|
||||
cb(&error, status, cbd->data);
|
||||
}
|
||||
@@ -385,7 +324,7 @@ static void ril_data_probe_reg_cb(struct ril_msg *message, gpointer user_data)
|
||||
|
||||
ofono_gprs_register(gprs);
|
||||
|
||||
registered = TRUE;
|
||||
ofono_registered = TRUE;
|
||||
|
||||
if (max_cids > gd->max_cids) {
|
||||
DBG("Setting max cids to %d", max_cids);
|
||||
@@ -393,11 +332,9 @@ static void ril_data_probe_reg_cb(struct ril_msg *message, gpointer user_data)
|
||||
ofono_gprs_set_cid_range(gprs, 1, max_cids);
|
||||
}
|
||||
|
||||
if (status == NETWORK_REGISTRATION_STATUS_ROAMING)
|
||||
if (status == roaming)
|
||||
status = check_if_really_roaming(status);
|
||||
|
||||
gd->true_status = status;
|
||||
|
||||
out:
|
||||
ofono_info("data reg status probed %d", status);
|
||||
|
||||
@@ -454,14 +391,10 @@ static int ril_gprs_probe(struct ofono_gprs *gprs,
|
||||
gd->ofono_attached = FALSE;
|
||||
gd->max_cids = 0;
|
||||
gd->rild_status = -1;
|
||||
gd->true_status = -1;
|
||||
gd->notified = FALSE;
|
||||
gd->registerid = -1;
|
||||
gd->timer_id = 0;
|
||||
gd->fake_timer_id = 0;
|
||||
gd->fake_cbd = NULL;
|
||||
|
||||
registered = FALSE;
|
||||
ofono_registered = FALSE;
|
||||
|
||||
ofono_gprs_set_data(gprs, gd);
|
||||
|
||||
@@ -476,8 +409,6 @@ static void ril_gprs_remove(struct ofono_gprs *gprs)
|
||||
|
||||
DBG("");
|
||||
|
||||
remove_fake_timer(gd);
|
||||
|
||||
ofono_gprs_set_data(gprs, NULL);
|
||||
|
||||
if (gd->registerid != -1)
|
||||
|
||||
@@ -818,6 +818,9 @@ static void ril_query_passwd_state_cb(struct ril_msg *message, gpointer user_dat
|
||||
}
|
||||
DBG("passwd_state %u", sd->passwd_state);
|
||||
|
||||
/* if pin code required cannot be initialized yet*/
|
||||
if (sd->passwd_state == OFONO_SIM_PASSWORD_SIM_PIN)
|
||||
sd->initialized = FALSE;
|
||||
/*
|
||||
* To prevent double call to sim_initialize_after_pin from
|
||||
* sim_pin_query_cb we must prevent calling sim_pin_query_cb
|
||||
|
||||
@@ -159,19 +159,8 @@ struct reply_setup_data_call *g_ril_reply_parse_data_call(GRil *gril,
|
||||
|
||||
}
|
||||
|
||||
/* TODO:
|
||||
* RILD can return multiple addresses; oFono only supports
|
||||
* setting a single IPv4 address. At this time, we only
|
||||
* use the first address. It's possible that a RIL may
|
||||
* just specify the end-points of the point-to-point
|
||||
* connection, in which case this code will need to
|
||||
* changed to handle such a device.
|
||||
*
|
||||
* For now split into a maximum of three, and only use
|
||||
* the first address for the remaining operations.
|
||||
*/
|
||||
if (raw_ip_addrs)
|
||||
reply->ip_addrs = g_strsplit(raw_ip_addrs, " ", 3);
|
||||
reply->ip_addrs = g_strsplit(raw_ip_addrs, " ", -1);
|
||||
else
|
||||
reply->ip_addrs = NULL;
|
||||
|
||||
@@ -191,7 +180,7 @@ struct reply_setup_data_call *g_ril_reply_parse_data_call(GRil *gril,
|
||||
* setting a single IPv4 gateway.
|
||||
*/
|
||||
if (raw_gws)
|
||||
reply->gateways = g_strsplit(raw_gws, " ", 3);
|
||||
reply->gateways = g_strsplit(raw_gws, " ", -1);
|
||||
else
|
||||
reply->gateways = NULL;
|
||||
|
||||
@@ -203,7 +192,7 @@ struct reply_setup_data_call *g_ril_reply_parse_data_call(GRil *gril,
|
||||
|
||||
/* Split DNS addresses */
|
||||
if (dnses)
|
||||
reply->dns_addresses = g_strsplit(dnses, " ", 3);
|
||||
reply->dns_addresses = g_strsplit(dnses, " ", -1);
|
||||
else
|
||||
reply->dns_addresses = NULL;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -78,6 +78,8 @@ void ofono_gprs_set_cid_range(struct ofono_gprs *gprs,
|
||||
void ofono_gprs_add_context(struct ofono_gprs *gprs,
|
||||
struct ofono_gprs_context *gc);
|
||||
|
||||
struct ofono_modem *ofono_gprs_get_modem(struct ofono_gprs *gprs);
|
||||
|
||||
#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,
|
||||
|
||||
@@ -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 ril_data *ril = ofono_modem_get_data(modem);
|
||||
int ril_version = 0;
|
||||
struct parcel rilp;
|
||||
|
||||
/* TODO: make conditional */
|
||||
ofono_debug("[UNSOL]< %s", ril_unsol_request_to_string(message->req));
|
||||
/* TODO: make conditional */
|
||||
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);
|
||||
|
||||
/* TODO: need a disconnect function to restart things! */
|
||||
ril->connected = TRUE;
|
||||
|
||||
send_get_sim_status(modem);
|
||||
@@ -430,8 +432,7 @@ static gboolean ril_re_init(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;
|
||||
DBusConnection *conn = ofono_dbus_get_connection();
|
||||
|
||||
|
||||
236
ofono/src/gprs.c
236
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,185 @@ 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)
|
||||
{
|
||||
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,
|
||||
DBusMessageIter *dict)
|
||||
{
|
||||
@@ -1322,6 +1518,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 +2748,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);
|
||||
@@ -3138,3 +3359,8 @@ void *ofono_gprs_get_data(struct ofono_gprs *gprs)
|
||||
{
|
||||
return gprs->driver_data;
|
||||
}
|
||||
|
||||
struct ofono_modem *ofono_gprs_get_modem(struct ofono_gprs *gprs)
|
||||
{
|
||||
return __ofono_atom_get_modem(gprs->atom);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -934,6 +934,40 @@ static void append_operator_struct_list(struct ofono_netreg *netreg,
|
||||
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,
|
||||
const struct ofono_network_operator *list,
|
||||
void *data)
|
||||
@@ -942,6 +976,7 @@ static void operator_list_callback(const struct ofono_error *error, int total,
|
||||
DBusMessage *reply;
|
||||
DBusMessageIter iter;
|
||||
DBusMessageIter array;
|
||||
gboolean changed;
|
||||
|
||||
if (error->type != OFONO_ERROR_TYPE_NO_ERROR) {
|
||||
DBG("Error occurred during operator list");
|
||||
@@ -950,7 +985,7 @@ static void operator_list_callback(const struct ofono_error *error, int total,
|
||||
return;
|
||||
}
|
||||
|
||||
update_operator_list(netreg, total, list);
|
||||
changed = update_operator_list(netreg, total, list);
|
||||
|
||||
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);
|
||||
|
||||
__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,
|
||||
@@ -1041,6 +1081,8 @@ static const GDBusMethodTable network_registration_methods[] = {
|
||||
static const GDBusSignalTable network_registration_signals[] = {
|
||||
{ GDBUS_SIGNAL("PropertyChanged",
|
||||
GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
|
||||
{ GDBUS_SIGNAL("OperatorsChanged",
|
||||
GDBUS_ARGS({ "operators", "a(oa{sv})"})) },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -239,7 +239,7 @@
|
||||
- upgrade to 0.15
|
||||
- add patch 0001-add-netmask-to-hso-gprs-context-driver.patch
|
||||
|
||||
* Monday Dec 14 2009 Martin Xu <martin.xu@intel.com> - 0.14
|
||||
* Mon Dec 14 2009 Martin Xu <martin.xu@intel.com> - 0.14
|
||||
- upgrade to 0.14
|
||||
|
||||
* Thu Dec 7 2009 Martin Xu <martin.xu@intel.com> - 0.13
|
||||
|
||||
Reference in New Issue
Block a user