3
* RIL library with GLib integration
5
* Copyright (C) 2008-2011 Intel Corporation. All rights reserved.
6
* Copyright (C) 2012-2013 Canonical Ltd.
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License version 2 as
10
* published by the Free Software Foundation.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34
#include <ofono/log.h>
35
#include <ofono/modem.h>
36
#include <ofono/gprs-context.h>
40
#include "grilunsol.h"
42
/* Minimum size is two int32s version/number of calls */
43
#define MIN_DATA_CALL_LIST_SIZE 8
46
* Minimum NITZ is: 'yy/mm/dd,hh:mm:ss'
47
* TZ '(+/-)tz,dt' are optional
49
#define MIN_NITZ_SIZE 17
51
static gint data_call_compare(gconstpointer a, gconstpointer b)
53
const struct ril_data_call *ca = a;
54
const struct ril_data_call *cb = b;
56
if (ca->cid < cb->cid)
59
if (ca->cid > cb->cid)
65
static void free_data_call(gpointer data, gpointer user_data)
67
struct ril_data_call *call = data;
71
g_free(call->ip_addr);
72
g_free(call->dns_addrs);
73
g_free(call->gateways);
78
void g_ril_unsol_free_data_call_list(struct ril_data_call_list *call_list)
81
g_slist_foreach(call_list->calls, (GFunc) free_data_call, NULL);
82
g_slist_free(call_list->calls);
87
static gboolean handle_settings(struct ril_data_call *call, char *type,
88
char *ifname, char *raw_ip_addrs,
89
char *raw_dns, char *raw_gws)
91
gboolean result = FALSE;
93
char **dns_addrs = NULL, **gateways = NULL;
94
char **ip_addrs = NULL, **split_ip_addr = NULL;
96
protocol = ril_protocol_string_to_ofono_protocol(type);
98
ofono_error("%s: invalid type(protocol) specified: %s",
103
if (ifname == NULL || strlen(ifname) == 0) {
104
ofono_error("%s: no interface specified: %s",
109
/* Split DNS addresses */
111
dns_addrs = g_strsplit(raw_dns, " ", 3);
113
if (dns_addrs == NULL || g_strv_length(dns_addrs) == 0) {
114
ofono_error("%s: no DNS: %s", __func__, raw_dns);
119
* RILD can return multiple addresses; oFono only supports
120
* setting a single IPv4 gateway.
123
gateways = g_strsplit(raw_gws, " ", 3);
125
if (gateways == NULL || g_strv_length(gateways) == 0) {
126
ofono_error("%s: no gateways: %s", __func__, raw_gws);
131
* RILD can return multiple addresses; oFono only supports
132
* setting a single IPv4 address. At this time, we only
133
* use the first address. It's possible that a RIL may
134
* just specify the end-points of the point-to-point
135
* connection, in which case this code will need to
136
* changed to handle such a device.
138
* For now split into a maximum of three, and only use
139
* the first address for the remaining operations.
142
ip_addrs = g_strsplit(raw_ip_addrs, " ", 3);
144
if (ip_addrs == NULL || g_strv_length(ip_addrs) == 0) {
145
ofono_error("%s: no IP address: %s", __func__, raw_ip_addrs);
149
DBG("num ip addrs is: %d", g_strv_length(ip_addrs));
151
if (g_strv_length(ip_addrs) > 1)
152
ofono_warn("%s: more than one IP addr returned: %s", __func__,
155
* Note - the address may optionally include a prefix size
156
* ( Eg. "/30" ). As this confuses NetworkManager, we
157
* explicitly strip any prefix after calculating the netmask.
159
split_ip_addr = g_strsplit(ip_addrs[0], "/", 2);
161
if (split_ip_addr == NULL || g_strv_length(split_ip_addr) == 0) {
162
ofono_error("%s: invalid IP address field returned: %s",
163
__func__, ip_addrs[0]);
167
call->protocol = protocol;
168
call->ifname = g_strdup(ifname);
169
call->ip_addr = g_strdup(split_ip_addr[0]);
170
call->dns_addrs = g_strdupv(dns_addrs);
171
call->gateways = g_strdupv(gateways);
177
g_strfreev(dns_addrs);
180
g_strfreev(gateways);
183
g_strfreev(ip_addrs);
186
g_strfreev(split_ip_addr);
193
* This function handles RIL_UNSOL_DATA_CALL_LIST_CHANGED messages,
194
* as well as RIL_REQUEST_DATA_CALL_LIST/SETUP_DATA_CALL replies, as
195
* all have the same payload.
197
struct ril_data_call_list *g_ril_unsol_parse_data_call_list(GRil *gril,
198
const struct ril_msg *message)
200
struct ril_data_call *call;
202
struct ril_data_call_list *reply = NULL;
203
unsigned int active, cid, i, num_calls, retry, status;
204
char *type = NULL, *ifname = NULL, *raw_addrs = NULL;
205
char *raw_dns = NULL, *raw_gws = NULL;
209
/* Can happen for RIL_REQUEST_DATA_CALL_LIST replies */
210
if (message->buf_len < MIN_DATA_CALL_LIST_SIZE) {
211
if (message->req == RIL_REQUEST_SETUP_DATA_CALL) {
212
ofono_error("%s: message too small: %d",
214
(int) message->buf_len);
217
g_ril_append_print_buf(gril, "{");
222
reply = g_try_new0(struct ril_data_call_list, 1);
224
ofono_error("%s: out of memory", __func__);
228
g_ril_init_parcel(message, &rilp);
231
* ril.h documents the reply to a RIL_REQUEST_DATA_CALL_LIST
232
* as being an array of RIL_Data_Call_Response_v6 structs,
233
* however in reality, the response also includes a version
236
reply->version = parcel_r_int32(&rilp);
237
num_calls = parcel_r_int32(&rilp);
239
g_ril_append_print_buf(gril,
240
"{version=%d,num=%d",
244
for (i = 0; i < num_calls; i++) {
245
status = parcel_r_int32(&rilp);
246
retry = parcel_r_int32(&rilp); /* ignore */
247
cid = parcel_r_int32(&rilp);
248
active = parcel_r_int32(&rilp);
249
type = parcel_r_string(&rilp);
250
ifname = parcel_r_string(&rilp);
251
raw_addrs = parcel_r_string(&rilp);
252
raw_dns = parcel_r_string(&rilp);
253
raw_gws = parcel_r_string(&rilp);
255
/* malformed check */
256
if (rilp.malformed) {
257
ofono_error("%s: malformed parcel received", __func__);
261
g_ril_append_print_buf(gril,
262
"%s [status=%d,retry=%d,cid=%d,"
263
"active=%d,type=%s,ifname=%s,"
264
"address=%s,dns=%s,gateways=%s]",
276
call = g_try_new0(struct ril_data_call, 1);
278
ofono_error("%s: out of memory", __func__);
282
call->status = status;
284
call->active = active;
286
if (message->req == RIL_REQUEST_SETUP_DATA_CALL &&
287
status == PDP_FAIL_NONE &&
288
handle_settings(call, type, ifname, raw_addrs,
289
raw_dns, raw_gws) == FALSE)
299
g_slist_insert_sorted(reply->calls, call,
304
g_ril_append_print_buf(gril, "%s}", print_buf);
306
if (message->unsolicited)
307
g_ril_print_unsol(gril, message);
309
g_ril_print_response(gril, message);
319
g_ril_unsol_free_data_call_list(reply);
324
char *g_ril_unsol_parse_nitz(GRil *gril, const struct ril_msg *message)
331
if (message->buf_len < MIN_NITZ_SIZE) {
332
ofono_error("%s: NITZ too small: %d",
334
(int) message->buf_len);
338
g_ril_init_parcel(message, &rilp);
340
nitz = parcel_r_string(&rilp);
342
g_ril_append_print_buf(gril, "(%s)", nitz);
343
g_ril_print_unsol(gril, message);
349
void g_ril_unsol_free_sms_data(struct unsol_sms_data *unsol)
357
struct unsol_sms_data *g_ril_unsol_parse_new_sms(GRil *gril,
358
const struct ril_msg *message)
363
struct unsol_sms_data *sms_data;
365
sms_data = g_new0(struct unsol_sms_data, 1);
366
if (sms_data == NULL) {
367
ofono_error("%s out of memory", __func__);
371
g_ril_init_parcel(message, &rilp);
373
ril_pdu = parcel_r_string(&rilp);
374
if (ril_pdu == NULL) {
375
ofono_error("%s Unable to parse notification", __func__);
379
ril_pdu_len = strlen(ril_pdu);
381
sms_data->data = decode_hex(ril_pdu, ril_pdu_len,
382
&sms_data->length, -1);
383
if (sms_data->data == NULL) {
384
ofono_error("%s Unable to decode notification", __func__);
388
g_ril_append_print_buf(gril, "{%s}", ril_pdu);
389
g_ril_print_unsol(gril, message);
398
g_ril_unsol_free_sms_data(sms_data);
402
int g_ril_unsol_parse_radio_state_changed(GRil *gril, const struct ril_msg *message)
407
g_ril_init_parcel(message, &rilp);
409
radio_state = parcel_r_int32(&rilp);
411
if (rilp.malformed) {
412
ofono_error("%s: malformed parcel received", __func__);
416
g_ril_append_print_buf(gril, "(state: %s)",
417
ril_radio_state_to_string(radio_state));
419
g_ril_print_unsol(gril, message);
424
int g_ril_unsol_parse_signal_strength(GRil *gril, const struct ril_msg *message)
427
int gw_signal, cdma_dbm, evdo_dbm, lte_signal;
429
g_ril_init_parcel(message, &rilp);
431
/* RIL_SignalStrength_v5 */
432
/* GW_SignalStrength */
433
gw_signal = parcel_r_int32(&rilp);
434
parcel_r_int32(&rilp); /* bitErrorRate */
436
/* CDMA_SignalStrength */
437
cdma_dbm = parcel_r_int32(&rilp);
438
parcel_r_int32(&rilp); /* ecio */
440
/* EVDO_SignalStrength */
441
evdo_dbm = parcel_r_int32(&rilp);
442
parcel_r_int32(&rilp); /* ecio */
443
parcel_r_int32(&rilp); /* signalNoiseRatio */
445
/* Present only for RIL_SignalStrength_v6 or newer */
446
if (parcel_data_avail(&rilp) > 0) {
447
/* LTE_SignalStrength */
448
lte_signal = parcel_r_int32(&rilp);
449
parcel_r_int32(&rilp); /* rsrp */
450
parcel_r_int32(&rilp); /* rsrq */
451
parcel_r_int32(&rilp); /* rssnr */
452
parcel_r_int32(&rilp); /* cqi */
457
g_ril_append_print_buf(gril, "(gw: %d, cdma: %d, evdo: %d, lte: %d)",
458
gw_signal, cdma_dbm, evdo_dbm, lte_signal);
460
if (message->unsolicited)
461
g_ril_print_unsol(gril, message);
463
g_ril_print_response(gril, message);
465
/* Return the first valid one */
466
if ((gw_signal != 99) && (gw_signal != -1))
467
return (gw_signal * 100) / 31;
468
if ((lte_signal != 99) && (lte_signal != -1))
469
return (lte_signal * 100) / 31;
471
/* In case of dbm, return the value directly */
472
if (cdma_dbm != -1) {
477
if (evdo_dbm != -1) {
486
void g_ril_unsol_free_supp_svc_notif(struct unsol_supp_svc_notif *unsol)
491
struct unsol_supp_svc_notif *g_ril_unsol_parse_supp_svc_notif(GRil *gril,
492
struct ril_msg *message)
497
struct unsol_supp_svc_notif *unsol =
498
g_new0(struct unsol_supp_svc_notif, 1);
500
g_ril_init_parcel(message, &rilp);
502
unsol->notif_type = parcel_r_int32(&rilp);
503
unsol->code = parcel_r_int32(&rilp);
504
unsol->index = parcel_r_int32(&rilp);
505
type = parcel_r_int32(&rilp);
506
tmp_number = parcel_r_string(&rilp);
508
if (tmp_number != NULL) {
509
strncpy(unsol->number.number, tmp_number,
510
OFONO_MAX_PHONE_NUMBER_LENGTH);
511
unsol->number.type = type;
515
g_ril_append_print_buf(gril, "{%d,%d,%d,%d,%s}",
516
unsol->notif_type, unsol->code, unsol->index,
518
g_ril_print_unsol(gril, message);
523
void g_ril_unsol_free_ussd(struct unsol_ussd *unsol)
526
g_free(unsol->message);
531
struct unsol_ussd *g_ril_unsol_parse_ussd(GRil *gril, struct ril_msg *message)
534
struct unsol_ussd *ussd;
535
char *typestr = NULL;
538
ussd = g_try_malloc0(sizeof(*ussd));
540
ofono_error("%s out of memory", __func__);
544
g_ril_init_parcel(message, &rilp);
546
numstr = parcel_r_int32(&rilp);
548
ofono_error("%s malformed parcel", __func__);
552
typestr = parcel_r_string(&rilp);
553
if (typestr == NULL || *typestr == '\0') {
554
ofono_error("%s wrong type", __func__);
558
ussd->type = *typestr - '0';
563
ussd->message = parcel_r_string(&rilp);
565
g_ril_append_print_buf(gril, "{%d,%s}", ussd->type, ussd->message);
567
g_ril_print_unsol(gril, message);