diff -Nru ofono-1.16.bzr6902+15.10.20150911/AUTHORS ofono-1.17.bzr6904+15.10.20150928.1/AUTHORS --- ofono-1.16.bzr6902+15.10.20150911/AUTHORS 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/AUTHORS 2015-09-28 09:27:15.000000000 +0000 @@ -99,3 +99,8 @@ Sergio Checa Blanco Philip Paeps Kuba Pawlak +Tommi Kenakkala +Alex J Lennon +Sergey Alirzaev +Marko Sulejic +Johannes 'josch' Schauer diff -Nru ofono-1.16.bzr6902+15.10.20150911/ChangeLog ofono-1.17.bzr6904+15.10.20150928.1/ChangeLog --- ofono-1.16.bzr6902+15.10.20150911/ChangeLog 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/ChangeLog 2015-09-28 09:27:15.000000000 +0000 @@ -1,3 +1,13 @@ +ver 1.17: + Fix issue with alphanumeric TP-OA handling. + Fix issue with push notification origin port. + Fix issue with reading of EF_MWIS records. + Fix issue with handling AT+CPINR results. + Fix issue with SIM state polling for Sierra modems. + Fix issue with HFP handling and AT command prefixes. + Fix issue with HFP and extra CCWA event handling. + Fix issue with HFP call state and +CHUP errors. + ver 1.16: Fix issue with PIN retry handling. Fix issue with HFP and multiple calls. diff -Nru ofono-1.16.bzr6902+15.10.20150911/configure.ac ofono-1.17.bzr6904+15.10.20150928.1/configure.ac --- ofono-1.16.bzr6902+15.10.20150911/configure.ac 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/configure.ac 2015-09-28 09:27:15.000000000 +0000 @@ -1,5 +1,5 @@ AC_PREREQ(2.60) -AC_INIT(ofono, 1.16) +AC_INIT(ofono, 1.17) AM_INIT_AUTOMAKE([foreign subdir-objects color-tests]) AC_CONFIG_HEADERS(config.h) @@ -209,7 +209,7 @@ [location of provision database]), [path_provisiondb=${withval}]) AC_ARG_ENABLE(provision, AC_HELP_STRING([--disable-provision], - [disable provisioning suport]), + [disable provisioning support]), [enable_provision=${enableval}]) if (test "${enable_provision}" != "no"); then if (test -n "${path_provisiondb}"); then diff -Nru ofono-1.16.bzr6902+15.10.20150911/debian/changelog ofono-1.17.bzr6904+15.10.20150928.1/debian/changelog --- ofono-1.16.bzr6902+15.10.20150911/debian/changelog 2015-09-28 09:44:14.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/debian/changelog 2015-09-28 09:44:15.000000000 +0000 @@ -1,3 +1,17 @@ +ofono (1.17.bzr6904+15.10.20150928.1-0ubuntu1) wily; urgency=medium + + [ Alfonso Sanchez-Beato (email Canonical) ] + * Update to upstream release 1.17 + * Do not assert when the radio is unavailable (LP: #1490991) + * Fix crash when importing phonebook (LP: #1486004) + * Check only destination port when receiving push (LP: #1490673) + * Fix crash when retrying to close context (LP: #1492483) + + [ CI Train Bot ] + * No-change rebuild. + + -- Alfonso Sanchez-Beato Mon, 28 Sep 2015 09:27:18 +0000 + ofono (1.16.bzr6902+15.10.20150911-0ubuntu1) wily; urgency=medium [ Alfonso Sanchez-Beato ] diff -Nru ofono-1.16.bzr6902+15.10.20150911/doc/connman-api.txt ofono-1.17.bzr6904+15.10.20150928.1/doc/connman-api.txt --- ofono-1.16.bzr6902+15.10.20150911/doc/connman-api.txt 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/doc/connman-api.txt 2015-09-28 09:27:15.000000000 +0000 @@ -64,7 +64,7 @@ Removes all contexts and re-provisions from the APN database. Contexts must all be deactivated for this - method to work. + method to work, and the atom must not be powered. Possible Errors: [service].Error.InProgress [service].Error.InvalidArguments diff -Nru ofono-1.16.bzr6902+15.10.20150911/drivers/atmodem/network-registration.c ofono-1.17.bzr6904+15.10.20150928.1/drivers/atmodem/network-registration.c --- ofono-1.16.bzr6902+15.10.20150911/drivers/atmodem/network-registration.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/drivers/atmodem/network-registration.c 2015-09-28 09:27:15.000000000 +0000 @@ -838,6 +838,39 @@ ofono_netreg_strength_notify(netreg, strength); } +static void cinterion_ciev_notify(GAtResult *result, gpointer user_data) +{ + struct ofono_netreg *netreg = user_data; + struct netreg_data *nd = ofono_netreg_get_data(netreg); + const char *signal_identifier = "rssi"; + const char *ind_str; + int strength; + GAtResultIter iter; + + g_at_result_iter_init(&iter, result); + + if (!g_at_result_iter_next(&iter, "+CIEV:")) + return; + + if (!g_at_result_iter_next_unquoted_string(&iter, &ind_str)) + return; + + if (!g_str_equal(signal_identifier, ind_str)) + return; + + if (!g_at_result_iter_next_number(&iter, &strength)) + return; + + DBG("rssi %d", strength); + + if (strength == nd->signal_invalid) + strength = -1; + else + strength = (strength * 100) / (nd->signal_max - nd->signal_min); + + ofono_netreg_strength_notify(netreg, strength); +} + static void ctzv_notify(GAtResult *result, gpointer user_data) { struct ofono_netreg *netreg = user_data; @@ -1915,6 +1948,27 @@ g_at_chat_send(nd->chat, "AT*TLTS=1", none_prefix, NULL, NULL, NULL); break; + case OFONO_VENDOR_CINTERION: + /* + * We can't set rssi bounds from Cinterion responses + * so set them up to specified values here + * + * Cinterion rssi signal strength specified as: + * 0 <= -112dBm + * 1 - 4 signal strengh in 15 dB steps + * 5 >= -51 dBm + * 99 not known or undetectable + */ + nd->signal_min = 0; + nd->signal_max = 5; + nd->signal_invalid = 99; + + /* Register for specific signal strength reports */ + g_at_chat_send(nd->chat, "AT^SIND=\"rssi\",1", none_prefix, + NULL, NULL, NULL); + g_at_chat_register(nd->chat, "+CIEV:", + cinterion_ciev_notify, FALSE, netreg, NULL); + break; case OFONO_VENDOR_NOKIA: case OFONO_VENDOR_SAMSUNG: /* Signal strength reporting via CIND is not supported */ diff -Nru ofono-1.16.bzr6902+15.10.20150911/drivers/atmodem/sim.c ofono-1.17.bzr6904+15.10.20150928.1/drivers/atmodem/sim.c --- ofono-1.16.bzr6902+15.10.20150911/drivers/atmodem/sim.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/drivers/atmodem/sim.c 2015-09-28 09:27:15.000000000 +0000 @@ -827,7 +827,7 @@ for (i = 1; i < len; i++) { if (!strcmp(name, at_sim_name[i].name)) { - retries[i] = val; + retries[at_sim_name[i].type] = val; break; } } @@ -1350,6 +1350,7 @@ case OFONO_VENDOR_ALCATEL: case OFONO_VENDOR_HUAWEI: case OFONO_VENDOR_SIMCOM: + case OFONO_VENDOR_SIERRA: /* * On ZTE modems, after pin is entered, SIM state is checked * by polling CPIN as their modem doesn't provide unsolicited diff -Nru ofono-1.16.bzr6902+15.10.20150911/drivers/atmodem/vendor.h ofono-1.17.bzr6904+15.10.20150928.1/drivers/atmodem/vendor.h --- ofono-1.16.bzr6902+15.10.20150911/drivers/atmodem/vendor.h 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/drivers/atmodem/vendor.h 2015-09-28 09:27:15.000000000 +0000 @@ -45,4 +45,5 @@ OFONO_VENDOR_ALCATEL, OFONO_VENDOR_QUECTEL, OFONO_VENDOR_UBLOX, + OFONO_VENDOR_CINTERION, }; diff -Nru ofono-1.16.bzr6902+15.10.20150911/drivers/hfpmodem/handsfree.c ofono-1.17.bzr6904+15.10.20150928.1/drivers/hfpmodem/handsfree.c --- ofono-1.16.bzr6902+15.10.20150911/drivers/hfpmodem/handsfree.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/drivers/hfpmodem/handsfree.c 2015-09-28 09:27:15.000000000 +0000 @@ -45,6 +45,7 @@ static const char *binp_prefix[] = { "+BINP:", NULL }; static const char *bvra_prefix[] = { "+BVRA:", NULL }; +static const char *none_prefix[] = { NULL }; struct hf_data { GAtChat *chat; @@ -197,7 +198,7 @@ struct hf_data *hd = ofono_handsfree_get_data(hf); struct cb_data *cbd = cb_data_new(cb, data); - if (g_at_chat_send(hd->chat, "AT+CNUM", NULL, + if (g_at_chat_send(hd->chat, "AT+CNUM", none_prefix, cnum_query_cb, cbd, g_free) > 0) return; @@ -382,8 +383,8 @@ struct cb_data *cbd = cb_data_new(cb, data); const char *buf = "AT+NREC=0"; - if (g_at_chat_send(hd->chat, buf, NULL, hf_generic_set_cb, - cbd, g_free) > 0) + if (g_at_chat_send(hd->chat, buf, none_prefix, + hf_generic_set_cb, cbd, g_free) > 0) return; g_free(cbd); @@ -401,8 +402,8 @@ snprintf(buf, sizeof(buf), "AT+BIEV=%u,%u", indicator, value); - if (g_at_chat_send(hd->chat, buf, NULL, hf_generic_set_cb, - cbd, g_free) > 0) + if (g_at_chat_send(hd->chat, buf, none_prefix, + hf_generic_set_cb, cbd, g_free) > 0) return; g_free(cbd); diff -Nru ofono-1.16.bzr6902+15.10.20150911/drivers/hfpmodem/network-registration.c ofono-1.17.bzr6904+15.10.20150928.1/drivers/hfpmodem/network-registration.c --- ofono-1.16.bzr6902+15.10.20150911/drivers/hfpmodem/network-registration.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/drivers/hfpmodem/network-registration.c 2015-09-28 09:27:15.000000000 +0000 @@ -46,6 +46,7 @@ static const char *cops_prefix[] = { "+COPS:", NULL }; static const char *cind_prefix[] = { "+CIND:", NULL }; +static const char *none_prefix[] = { NULL }; struct netreg_data { GAtChat *chat; @@ -263,7 +264,7 @@ cbd->user = netreg; - ok = g_at_chat_send(nd->chat, "AT+COPS=3,0", NULL, + ok = g_at_chat_send(nd->chat, "AT+COPS=3,0", none_prefix, NULL, cbd, NULL); if (ok) diff -Nru ofono-1.16.bzr6902+15.10.20150911/drivers/hfpmodem/slc.c ofono-1.17.bzr6904+15.10.20150928.1/drivers/hfpmodem/slc.c --- ofono-1.16.bzr6902+15.10.20150911/drivers/hfpmodem/slc.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/drivers/hfpmodem/slc.c 2015-09-28 09:27:15.000000000 +0000 @@ -113,7 +113,8 @@ { struct hfp_slc_info *info = sed->info; - g_at_chat_send(info->chat, "AT+CMEE=1", NULL, NULL, NULL, NULL); + g_at_chat_send(info->chat, "AT+CMEE=1", none_prefix, + NULL, NULL, NULL); sed->connect_cb(sed->userdata); } @@ -434,8 +435,8 @@ sprintf(str, "AT+BAC=%d", HFP_CODEC_CVSD); slc_establish_data_ref(sed); - g_at_chat_send(info->chat, str, NULL, bac_cb, sed, - slc_establish_data_unref); + g_at_chat_send(info->chat, str, none_prefix, bac_cb, + sed, slc_establish_data_unref); return; } diff -Nru ofono-1.16.bzr6902+15.10.20150911/drivers/hfpmodem/voicecall.c ofono-1.17.bzr6904+15.10.20150928.1/drivers/hfpmodem/voicecall.c --- ofono-1.16.bzr6902+15.10.20150911/drivers/hfpmodem/voicecall.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/drivers/hfpmodem/voicecall.c 2015-09-28 09:27:15.000000000 +0000 @@ -333,6 +333,10 @@ } } + if (!ok && vd->calls) + g_at_chat_send(vd->chat, "AT+CLCC", clcc_prefix, + clcc_poll_cb, req->vc, NULL); + req->cb(&error, req->data); } @@ -711,6 +715,16 @@ at_util_call_compare_by_status)) return; + /* some phones may send extra CCWA after active call is ended + * this would trigger creation of second call in state 'WAITING' + * as our previous WAITING call has been promoted to INCOMING + */ + if (g_slist_find_custom(vd->calls, + GINT_TO_POINTER(CALL_STATUS_INCOMING), + at_util_call_compare_by_status)) + return; + + g_at_result_iter_init(&iter, result); if (!g_at_result_iter_next(&iter, "+CCWA:")) @@ -1134,6 +1148,10 @@ struct ofono_voicecall *vc = user_data; struct voicecall_data *vd = ofono_voicecall_get_data(vc); unsigned int mpty_ids; + GSList *n; + struct ofono_call *nc; + unsigned int num_active = 0; + unsigned int num_held = 0; if (!ok) return; @@ -1142,6 +1160,22 @@ g_slist_foreach(vd->calls, voicecall_notify, vc); ofono_voicecall_mpty_hint(vc, mpty_ids); + + n = vd->calls; + + while (n) { + nc = n->data; + + if (nc->status == CALL_STATUS_ACTIVE) + num_active++; + else if (nc->status == CALL_STATUS_HELD) + num_held++; + + n = n->next; + } + + if ((num_active > 1 || num_held > 1) && !vd->clcc_source) + vd->clcc_source = g_timeout_add(POLL_CLCC_INTERVAL, poll_clcc, vc); } static void hfp_voicecall_initialized(gboolean ok, GAtResult *result, @@ -1183,8 +1217,8 @@ ofono_voicecall_set_data(vc, vd); - g_at_chat_send(vd->chat, "AT+CLIP=1", NULL, NULL, NULL, NULL); - g_at_chat_send(vd->chat, "AT+CCWA=1", NULL, + g_at_chat_send(vd->chat, "AT+CLIP=1", none_prefix, NULL, NULL, NULL); + g_at_chat_send(vd->chat, "AT+CCWA=1", none_prefix, hfp_voicecall_initialized, vc, NULL); return 0; } diff -Nru ofono-1.16.bzr6902+15.10.20150911/drivers/rilmodem/gprs-context.c ofono-1.17.bzr6904+15.10.20150928.1/drivers/rilmodem/gprs-context.c --- ofono-1.16.bzr6902+15.10.20150911/drivers/rilmodem/gprs-context.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/drivers/rilmodem/gprs-context.c 2015-09-28 09:27:15.000000000 +0000 @@ -69,6 +69,9 @@ char *apn; enum ofono_gprs_context_type type; int deact_retries; + guint retry_ev_id; + struct cb_data *retry_cbd; + guint reset_ev_id; }; static void ril_gprs_context_deactivate_primary(struct ofono_gprs_context *gc, @@ -329,7 +332,12 @@ static gboolean reset_modem(gpointer data) { - mtk_reset_modem(data); + struct gprs_context_data *gcd = data; + struct ofono_modem *modem = gcd->modem; + + gcd->reset_ev_id = 0; + + mtk_reset_modem(modem); return FALSE; } @@ -344,6 +352,8 @@ struct parcel rilp; struct ofono_error error; + gcd->retry_ev_id = 0; + /* We might have received a call list update while waiting */ if (gcd->state == STATE_IDLE) { if (cb) @@ -392,8 +402,9 @@ set_context_disconnected(gcd); /* - * If the deactivate was a result of a shutdown, there won't be - * call back, so _deactivated() needs to be called directly. + * If the deactivate was a result of a data network detach or of + * an error in data call establishment, there won't be call + * back, so _deactivated() needs to be called directly. */ if (cb) CALLBACK_WITH_SUCCESS(cb, cbd->data); @@ -410,11 +421,11 @@ * temporarily. We do retries to handle that case. */ if (--(gcd->deact_retries) > 0) { - struct cb_data *cbd2; - - cbd2 = cb_data_new(cb, cbd->data, gc); - g_timeout_add_seconds(TIME_BETWEEN_DEACT_RETRIES_S, - retry_deactivate, cbd2); + gcd->retry_cbd = cb_data_new(cb, cbd->data, gc); + gcd->retry_ev_id = + g_timeout_add_seconds( + TIME_BETWEEN_DEACT_RETRIES_S, + retry_deactivate, gcd->retry_cbd); } else { ofono_error("%s: retry limit hit", __func__); @@ -428,7 +439,7 @@ * internal reset nonetheless. */ if (gcd->vendor == OFONO_RIL_VENDOR_MTK) - g_idle_add(reset_modem, gcd->modem); + gcd->reset_ev_id = g_idle_add(reset_modem, gcd); } } } @@ -533,10 +544,28 @@ DBG("*gc: %p", gc); - if (gcd->state != STATE_IDLE) { - ril_gprs_context_detach_shutdown(gc, 0); + if (gcd->state != STATE_IDLE && gcd->state != STATE_DISABLING) { + struct req_deactivate_data_call request; + struct parcel rilp; + struct ofono_error error; + + request.cid = gcd->active_rild_cid; + request.reason = RIL_DEACTIVATE_DATA_CALL_NO_REASON; + g_ril_request_deactivate_data_call(gcd->ril, &request, + &rilp, &error); + + g_ril_send(gcd->ril, RIL_REQUEST_DEACTIVATE_DATA_CALL, + &rilp, NULL, NULL, NULL); + } + + if (gcd->retry_ev_id > 0) { + g_source_remove(gcd->retry_ev_id); + g_free(gcd->retry_cbd); } + if (gcd->reset_ev_id > 0) + g_source_remove(gcd->reset_ev_id); + ofono_gprs_context_set_data(gc, NULL); g_ril_unref(gcd->ril); diff -Nru ofono-1.16.bzr6902+15.10.20150911/drivers/rilmodem/phonebook.c ofono-1.17.bzr6904+15.10.20150928.1/drivers/rilmodem/phonebook.c --- ofono-1.16.bzr6902+15.10.20150911/drivers/rilmodem/phonebook.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/drivers/rilmodem/phonebook.c 2015-09-28 09:27:15.000000000 +0000 @@ -669,18 +669,19 @@ export_and_return(TRUE, cbd); } else { struct pb_ref_rec *ref; - struct pb_file_info *file_info; DBG("Next EFpbr record"); ref = pbd->pb_ref_next->data; - ref->pb_next = ref->pb_files; - file_info = ref->pb_files->data; - - if (!file_info) { + if (!ref->pb_files) { export_and_return(TRUE, cbd); } else { + struct pb_file_info *file_info; + + ref->pb_next = ref->pb_files; + file_info = ref->pb_files->data; + ofono_sim_read_info(pbd->sim_context, file_info->file_id, OFONO_SIM_FILE_STRUCTURE_FIXED, @@ -921,7 +922,6 @@ ptr[i]); DBG("File ID=%04X", file_id); - file_info->pbr_type = pbr_type; file_info->file_type = ptr[i]; file_info->file_id = file_id; @@ -944,7 +944,7 @@ pbd->pb_refs = g_slist_append(pbd->pb_refs, ref_rec); if (record*record_length >= total_length) { - struct pb_ref_rec *ref; + struct pb_ref_rec *ref; struct pb_file_info *file_info; DBG("All EFpbr records read"); @@ -952,14 +952,15 @@ pbd->pb_ref_next = pbd->pb_refs; ref = pbd->pb_ref_next->data; - ref->pb_next = ref->pb_files; - file_info = ref->pb_files->data; - if (file_info == NULL) { + if (ref->pb_files == NULL) { ofono_error("%s: no files to read", __func__); export_and_return(FALSE, cbd); return; } + ref->pb_next = ref->pb_files; + file_info = ref->pb_files->data; + /* Start reading process for first EF_PBR entry */ ofono_sim_read_info(pbd->sim_context, file_info->file_id, diff -Nru ofono-1.16.bzr6902+15.10.20150911/dundee/bluez4.c ofono-1.17.bzr6904+15.10.20150928.1/dundee/bluez4.c --- ofono-1.16.bzr6902+15.10.20150911/dundee/bluez4.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/dundee/bluez4.c 2015-09-28 09:27:15.000000000 +0000 @@ -128,9 +128,8 @@ if (status == 0) return; - g_free(cbd); - CALLBACK_WITH_FAILURE(cb, -1, cbd->data); + g_free(cbd); } struct dundee_device_driver bluetooth_driver = { diff -Nru ofono-1.16.bzr6902+15.10.20150911/gatchat/gatchat.c ofono-1.17.bzr6904+15.10.20150928.1/gatchat/gatchat.c --- ofono-1.16.bzr6902+15.10.20150911/gatchat/gatchat.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/gatchat/gatchat.c 2015-09-28 09:27:15.000000000 +0000 @@ -583,7 +583,7 @@ return; /* Check for echo, this should not happen, but lets be paranoid */ - if (!strncmp(str, "AT", 2) == TRUE) + if (!strncmp(str, "AT", 2)) goto done; cmd = g_queue_peek_head(p->command_queue); @@ -1135,6 +1135,29 @@ return TRUE; } +static gpointer at_chat_get_userdata(struct at_chat *chat, + guint group, guint id) +{ + GList *l; + struct at_command *c; + + if (chat->command_queue == NULL) + return NULL; + + l = g_queue_find_custom(chat->command_queue, GUINT_TO_POINTER(id), + at_command_compare_by_id); + + if (l == NULL) + return NULL; + + c = l->data; + + if (c->gid != group) + return NULL; + + return c->user_data; +} + static guint at_chat_register(struct at_chat *chat, guint group, const char *prefix, GAtNotifyFunc func, gboolean expect_pdu, gpointer user_data, @@ -1540,6 +1563,14 @@ return at_chat_cancel_group(chat->parent, chat->group); } +gpointer g_at_chat_get_userdata(GAtChat *chat, guint id) +{ + if (chat == NULL) + return NULL; + + return at_chat_get_userdata(chat->parent, chat->group, id); +} + guint g_at_chat_register(GAtChat *chat, const char *prefix, GAtNotifyFunc func, gboolean expect_pdu, gpointer user_data, diff -Nru ofono-1.16.bzr6902+15.10.20150911/gatchat/gatchat.h ofono-1.17.bzr6904+15.10.20150928.1/gatchat/gatchat.h --- ofono-1.16.bzr6902+15.10.20150911/gatchat/gatchat.h 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/gatchat/gatchat.h 2015-09-28 09:27:15.000000000 +0000 @@ -150,6 +150,8 @@ gboolean g_at_chat_cancel(GAtChat *chat, guint id); gboolean g_at_chat_cancel_all(GAtChat *chat); +gpointer g_at_chat_get_userdata(GAtChat *chat, guint id); + guint g_at_chat_register(GAtChat *chat, const char *prefix, GAtNotifyFunc func, gboolean expect_pdu, gpointer user_data, GDestroyNotify notify); diff -Nru ofono-1.16.bzr6902+15.10.20150911/gatchat/ppp_net.c ofono-1.17.bzr6904+15.10.20150928.1/gatchat/ppp_net.c --- ofono-1.16.bzr6902+15.10.20150911/gatchat/ppp_net.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/gatchat/ppp_net.c 2015-09-28 09:27:15.000000000 +0000 @@ -64,10 +64,10 @@ return FALSE; memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, net->if_name, sizeof(ifr.ifr_name)); + strncpy(ifr.ifr_name, net->if_name, IFNAMSIZ - 1); ifr.ifr_mtu = mtu; - err = ioctl(sk, SIOCSIFMTU, (caddr_t) &ifr); + err = ioctl(sk, SIOCSIFMTU, (void *) &ifr); close(sk); diff -Nru ofono-1.16.bzr6902+15.10.20150911/gdbus/client.c ofono-1.17.bzr6904+15.10.20150928.1/gdbus/client.c --- ofono-1.16.bzr6902+15.10.20150911/gdbus/client.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/gdbus/client.c 2015-09-28 09:27:15.000000000 +0000 @@ -42,6 +42,7 @@ DBusConnection *dbus_conn; char *service_name; char *base_path; + char *root_path; guint watch; guint added_watch; guint removed_watch; @@ -1107,7 +1108,11 @@ { DBusMessage *msg; - if (!client->proxy_added && !client->proxy_removed) { + if (!client->connected) + return; + + if ((!client->proxy_added && !client->proxy_removed) || + !client->root_path) { refresh_properties(client); return; } @@ -1115,9 +1120,10 @@ if (client->get_objects_call != NULL) return; - msg = dbus_message_new_method_call(client->service_name, "/", - DBUS_INTERFACE_DBUS ".ObjectManager", - "GetManagedObjects"); + msg = dbus_message_new_method_call(client->service_name, + client->root_path, + DBUS_INTERFACE_OBJECT_MANAGER, + "GetManagedObjects"); if (msg == NULL) return; @@ -1142,13 +1148,13 @@ g_dbus_client_ref(client); + client->connected = TRUE; + if (client->connect_func) client->connect_func(conn, client->connect_data); get_managed_objects(client); - client->connected = TRUE; - g_dbus_client_unref(client); } @@ -1156,13 +1162,13 @@ { GDBusClient *client = user_data; + client->connected = FALSE; + g_list_free_full(client->proxy_list, proxy_free); client->proxy_list = NULL; - if (client->disconn_func) { + if (client->disconn_func) client->disconn_func(conn, client->disconn_data); - client->connected = FALSE; - } } static DBusHandlerResult message_filter(DBusConnection *connection, @@ -1196,10 +1202,18 @@ GDBusClient *g_dbus_client_new(DBusConnection *connection, const char *service, const char *path) { + return g_dbus_client_new_full(connection, service, path, "/"); +} + +GDBusClient *g_dbus_client_new_full(DBusConnection *connection, + const char *service, + const char *path, + const char *root_path) +{ GDBusClient *client; unsigned int i; - if (connection == NULL) + if (!connection || !service) return NULL; client = g_try_new0(GDBusClient, 1); @@ -1215,6 +1229,7 @@ client->dbus_conn = dbus_connection_ref(connection); client->service_name = g_strdup(service); client->base_path = g_strdup(path); + client->root_path = g_strdup(root_path); client->connected = FALSE; client->match_rules = g_ptr_array_sized_new(1); @@ -1224,14 +1239,18 @@ service_connect, service_disconnect, client, NULL); + + if (!root_path) + return g_dbus_client_ref(client); + client->added_watch = g_dbus_add_signal_watch(connection, service, - "/", + client->root_path, DBUS_INTERFACE_OBJECT_MANAGER, "InterfacesAdded", interfaces_added, client, NULL); client->removed_watch = g_dbus_add_signal_watch(connection, service, - "/", + client->root_path, DBUS_INTERFACE_OBJECT_MANAGER, "InterfacesRemoved", interfaces_removed, @@ -1305,6 +1324,7 @@ g_free(client->service_name); g_free(client->base_path); + g_free(client->root_path); g_free(client); } @@ -1371,7 +1391,8 @@ client->property_changed = property_changed; client->user_data = user_data; - get_managed_objects(client); + if (proxy_added || proxy_removed || property_changed) + get_managed_objects(client); return TRUE; } diff -Nru ofono-1.16.bzr6902+15.10.20150911/gdbus/gdbus.h ofono-1.17.bzr6904+15.10.20150928.1/gdbus/gdbus.h --- ofono-1.16.bzr6902+15.10.20150911/gdbus/gdbus.h 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/gdbus/gdbus.h 2015-09-28 09:27:15.000000000 +0000 @@ -216,6 +216,7 @@ .flags = G_DBUS_SIGNAL_FLAG_EXPERIMENTAL void g_dbus_set_flags(int flags); +int g_dbus_get_flags(void); gboolean g_dbus_register_interface(DBusConnection *connection, const char *path, const char *name, @@ -355,6 +356,10 @@ GDBusClient *g_dbus_client_new(DBusConnection *connection, const char *service, const char *path); +GDBusClient *g_dbus_client_new_full(DBusConnection *connection, + const char *service, + const char *path, + const char *root_path); GDBusClient *g_dbus_client_ref(GDBusClient *client); void g_dbus_client_unref(GDBusClient *client); diff -Nru ofono-1.16.bzr6902+15.10.20150911/gdbus/mainloop.c ofono-1.17.bzr6904+15.10.20150928.1/gdbus/mainloop.c --- ofono-1.16.bzr6902+15.10.20150911/gdbus/mainloop.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/gdbus/mainloop.c 2015-09-28 09:27:15.000000000 +0000 @@ -322,6 +322,7 @@ return NULL; if (setup_bus(conn, name, error) == FALSE) { + dbus_connection_close(conn); dbus_connection_unref(conn); return NULL; } diff -Nru ofono-1.16.bzr6902+15.10.20150911/gdbus/object.c ofono-1.17.bzr6904+15.10.20150928.1/gdbus/object.c --- ofono-1.16.bzr6902+15.10.20150911/gdbus/object.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/gdbus/object.c 2015-09-28 09:27:15.000000000 +0000 @@ -1412,7 +1412,10 @@ { char str[1024]; - vsnprintf(str, sizeof(str), format, args); + if (format) + vsnprintf(str, sizeof(str), format, args); + else + str[0] = '\0'; return dbus_message_new_error(message, name, str); } @@ -1530,11 +1533,8 @@ const char *format, va_list args) { DBusMessage *error; - char str[1024]; - - vsnprintf(str, sizeof(str), format, args); - error = dbus_message_new_error(message, name, str); + error = g_dbus_create_error_valist(message, name, format, args); if (error == NULL) return FALSE; @@ -1816,3 +1816,8 @@ { global_flags = flags; } + +int g_dbus_get_flags(void) +{ + return global_flags; +} diff -Nru ofono-1.16.bzr6902+15.10.20150911/gdbus/watch.c ofono-1.17.bzr6904+15.10.20150928.1/gdbus/watch.c --- ofono-1.16.bzr6902+15.10.20150911/gdbus/watch.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/gdbus/watch.c 2015-09-28 09:27:15.000000000 +0000 @@ -523,9 +523,7 @@ member = dbus_message_get_member(message); dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &arg, DBUS_TYPE_INVALID); - /* Sender is always the owner */ - if (sender == NULL) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + /* If sender != NULL it is always the owner */ for (current = listeners; current != NULL; current = current->next) { data = current->data; @@ -533,6 +531,9 @@ if (connection != data->connection) continue; + if (!sender && data->owner) + continue; + if (data->owner && g_str_equal(sender, data->owner) == FALSE) continue; diff -Nru ofono-1.16.bzr6902+15.10.20150911/include/handsfree-audio.h ofono-1.17.bzr6904+15.10.20150928.1/include/handsfree-audio.h --- ofono-1.16.bzr6902+15.10.20150911/include/handsfree-audio.h 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/include/handsfree-audio.h 2015-09-28 09:27:15.000000000 +0000 @@ -41,6 +41,7 @@ void (*connect)(struct ofono_handsfree_card *card, ofono_handsfree_card_connect_cb_t cb, void *data); + void (*sco_connected_hint)(struct ofono_handsfree_card *card); }; struct ofono_handsfree_card *ofono_handsfree_card_create(unsigned int vendor, diff -Nru ofono-1.16.bzr6902+15.10.20150911/Makefile.am ofono-1.17.bzr6904+15.10.20150928.1/Makefile.am --- ofono-1.16.bzr6902+15.10.20150911/Makefile.am 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/Makefile.am 2015-09-28 09:27:15.000000000 +0000 @@ -468,8 +468,8 @@ builtin_modules += caif builtin_sources += plugins/caif.c -builtin_modules += tc65 -builtin_sources += plugins/tc65.c +builtin_modules += cinterion +builtin_sources += plugins/cinterion.c builtin_modules += nokia builtin_sources += plugins/nokia.c diff -Nru ofono-1.16.bzr6902+15.10.20150911/plugins/cinterion.c ofono-1.17.bzr6904+15.10.20150928.1/plugins/cinterion.c --- ofono-1.16.bzr6902+15.10.20150911/plugins/cinterion.c 1970-01-01 00:00:00.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/plugins/cinterion.c 2015-09-28 09:27:15.000000000 +0000 @@ -0,0 +1,250 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2008-2011 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include +#include +#include + +#define OFONO_API_SUBJECT_TO_CHANGE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +static int cinterion_probe(struct ofono_modem *modem) +{ + return 0; +} + +static void cinterion_remove(struct ofono_modem *modem) +{ +} + +static void cinterion_debug(const char *str, void *user_data) +{ + const char *prefix = user_data; + + ofono_info("%s%s", prefix, str); +} + +static int cinterion_enable(struct ofono_modem *modem) +{ + GAtChat *chat; + GIOChannel *channel; + GAtSyntax *syntax; + GHashTable *options; + const char *device; + + DBG("%p", modem); + + options = g_hash_table_new(g_str_hash, g_str_equal); + if (options == NULL) + return -ENOMEM; + + device = ofono_modem_get_string(modem, "Device"); + if (device == NULL) + return -EINVAL; + + g_hash_table_insert(options, "Baud", "115200"); + g_hash_table_insert(options, "StopBits", "1"); + g_hash_table_insert(options, "DataBits", "8"); + g_hash_table_insert(options, "Parity", "none"); + g_hash_table_insert(options, "XonXoff", "off"); + g_hash_table_insert(options, "RtsCts", "on"); + g_hash_table_insert(options, "Local", "on"); + g_hash_table_insert(options, "Read", "on"); + + channel = g_at_tty_open(device, options); + g_hash_table_destroy(options); + + if (channel == NULL) + return -EIO; + + /* + * (Cinterion plugin is based on tc65 plugin. Comment left in but may + * not be applicable in the general case) + * + * TC65 works almost as the 27.007 says. But for example after + * AT+CRSM the modem replies with the data in the queried EF and + * writes three pairs of after the data and before OK. + */ + syntax = g_at_syntax_new_gsm_permissive(); + + chat = g_at_chat_new(channel, syntax); + g_at_syntax_unref(syntax); + g_io_channel_unref(channel); + + if (chat == NULL) + return -ENOMEM; + + if (getenv("OFONO_AT_DEBUG")) + g_at_chat_set_debug(chat, cinterion_debug, ""); + + ofono_modem_set_data(modem, chat); + + return 0; +} + +static int cinterion_disable(struct ofono_modem *modem) +{ + GAtChat *chat = ofono_modem_get_data(modem); + + DBG("%p", modem); + + ofono_modem_set_data(modem, NULL); + + g_at_chat_send(chat, "AT+CFUN=7", NULL, NULL, NULL, NULL); + + g_at_chat_unref(chat); + + return 0; +} + +static void set_online_cb(gboolean ok, GAtResult *result, gpointer user_data) +{ + struct cb_data *cbd = user_data; + ofono_modem_online_cb_t cb = cbd->cb; + struct ofono_error error; + + decode_at_error(&error, g_at_result_final_response(result)); + + cb(&error, cbd->data); +} + +static void cinterion_set_online(struct ofono_modem *modem, ofono_bool_t online, + ofono_modem_online_cb_t cb, void *user_data) +{ + GAtChat *chat = ofono_modem_get_data(modem); + struct cb_data *cbd = cb_data_new(cb, user_data); + char const *command = online ? "AT+CFUN=1" : "AT+CFUN=7"; + + DBG("modem %p %s", modem, online ? "online" : "offline"); + + if (g_at_chat_send(chat, command, NULL, set_online_cb, cbd, g_free)) + return; + + CALLBACK_WITH_FAILURE(cb, cbd->data); + + g_free(cbd); +} + +static void cinterion_pre_sim(struct ofono_modem *modem) +{ + GAtChat *chat = ofono_modem_get_data(modem); + struct ofono_sim *sim; + + DBG("%p", modem); + + ofono_devinfo_create(modem, 0, "atmodem", chat); + sim = ofono_sim_create(modem, 0, "atmodem", chat); + ofono_voicecall_create(modem, 0, "atmodem", chat); + + if (sim) + ofono_sim_inserted_notify(sim, TRUE); +} + +static void cinterion_post_sim(struct ofono_modem *modem) +{ + GAtChat *chat = ofono_modem_get_data(modem); + + DBG("%p", modem); + + ofono_phonebook_create(modem, 0, "atmodem", chat); + + ofono_sms_create(modem, 0, "atmodem", chat); +} + +static void cinterion_post_online(struct ofono_modem *modem) +{ + GAtChat *chat = ofono_modem_get_data(modem); + struct ofono_message_waiting *mw; + struct ofono_gprs *gprs; + struct ofono_gprs_context *gc; + + DBG("%p", modem); + + ofono_ussd_create(modem, 0, "atmodem", chat); + ofono_call_forwarding_create(modem, 0, "atmodem", chat); + ofono_call_settings_create(modem, 0, "atmodem", chat); + ofono_netreg_create(modem, OFONO_VENDOR_CINTERION, "atmodem", chat); + ofono_call_meter_create(modem, 0, "atmodem", chat); + ofono_call_barring_create(modem, 0, "atmodem", chat); + + gprs = ofono_gprs_create(modem, 0, "atmodem", chat); + gc = ofono_gprs_context_create(modem, 0, "atmodem", chat); + + if (gprs && gc) + ofono_gprs_add_context(gprs, gc); + + mw = ofono_message_waiting_create(modem); + if (mw) + ofono_message_waiting_register(mw); +} + +static struct ofono_modem_driver cinterion_driver = { + .name = "cinterion", + .probe = cinterion_probe, + .remove = cinterion_remove, + .enable = cinterion_enable, + .disable = cinterion_disable, + .set_online = cinterion_set_online, + .pre_sim = cinterion_pre_sim, + .post_sim = cinterion_post_sim, + .post_online = cinterion_post_online, +}; + +static int cinterion_init(void) +{ + return ofono_modem_driver_register(&cinterion_driver); +} + +static void cinterion_exit(void) +{ + ofono_modem_driver_unregister(&cinterion_driver); +} + +OFONO_PLUGIN_DEFINE(cinterion, "Cinterion driver plugin", VERSION, + OFONO_PLUGIN_PRIORITY_DEFAULT, cinterion_init, cinterion_exit) diff -Nru ofono-1.16.bzr6902+15.10.20150911/plugins/hfp_hf_bluez5.c ofono-1.17.bzr6904+15.10.20150928.1/plugins/hfp_hf_bluez5.c --- ofono-1.16.bzr6902+15.10.20150911/plugins/hfp_hf_bluez5.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/plugins/hfp_hf_bluez5.c 2015-09-28 09:27:15.000000000 +0000 @@ -69,6 +69,7 @@ struct hfp_slc_info info; DBusMessage *msg; struct ofono_handsfree_card *card; + unsigned int bcc_id; }; static const char *none_prefix[] = { NULL }; @@ -372,8 +373,12 @@ { struct cb_data *cbd = user_data; ofono_handsfree_card_connect_cb_t cb = cbd->cb; + struct ofono_handsfree_card *card = cbd->user; + struct hfp *hfp = ofono_handsfree_card_get_data(card); struct ofono_error error; + hfp->bcc_id = 0; + decode_at_error(&error, g_at_result_final_response(result)); cb(&error, cbd->data); @@ -390,7 +395,10 @@ info->ag_features & HFP_AG_FEATURE_CODEC_NEGOTIATION) { struct cb_data *cbd = cb_data_new(cb, data); - g_at_chat_send(info->chat, "AT+BCC", NULL, bcc_cb, cbd, g_free); + cbd->user = card; + hfp->bcc_id = g_at_chat_send(info->chat, "AT+BCC", + none_prefix, bcc_cb, + cbd, g_free); return; } @@ -403,11 +411,40 @@ ofono_handsfree_card_connect_sco(card); } +static void hfp16_sco_connected_hint(struct ofono_handsfree_card *card) +{ + struct hfp *hfp = ofono_handsfree_card_get_data(card); + struct hfp_slc_info *info = &hfp->info; + struct cb_data *cbd; + ofono_handsfree_card_connect_cb_t cb; + + /* + * SCO has just been connected, probably initiated by the AG. + * If we have any outstanding BCC requests, then lets cancel these + * as they're no longer needed + */ + + if (hfp->bcc_id == 0) + return; + + cbd = g_at_chat_get_userdata(info->chat, hfp->bcc_id); + if (cbd == NULL) + return; + + cb = cbd->cb; + CALLBACK_WITH_SUCCESS(cb, cbd->data); + + /* cbd will be freed once cancel is processed */ + g_at_chat_cancel(info->chat, hfp->bcc_id); + hfp->bcc_id = 0; +} + static struct ofono_handsfree_card_driver hfp16_hf_driver = { - .name = HFP16_HF_DRIVER, - .probe = hfp16_card_probe, - .remove = hfp16_card_remove, - .connect = hfp16_card_connect, + .name = HFP16_HF_DRIVER, + .probe = hfp16_card_probe, + .remove = hfp16_card_remove, + .connect = hfp16_card_connect, + .sco_connected_hint = hfp16_sco_connected_hint, }; static ofono_bool_t device_path_compare(struct ofono_modem *modem, @@ -701,8 +738,17 @@ return; dbus_message_iter_get_basic(&iter, &paired); - if (paired == FALSE) + + if (paired == FALSE) { + modem = ofono_modem_find(device_path_compare, (void *) path); + + if (modem != NULL) { + ofono_modem_remove(modem); + g_dbus_proxy_set_removed_watch(proxy, NULL, NULL); + g_dbus_proxy_set_property_watch(proxy, NULL, NULL); + } return; + } if (g_dbus_proxy_get_property(proxy, "UUIDs", &iter) == FALSE) return; diff -Nru ofono-1.16.bzr6902+15.10.20150911/plugins/isiusb.c ofono-1.17.bzr6904+15.10.20150928.1/plugins/isiusb.c --- ofono-1.16.bzr6902+15.10.20150911/plugins/isiusb.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/plugins/isiusb.c 2015-09-28 09:27:15.000000000 +0000 @@ -204,7 +204,7 @@ struct ofono_modem *om = data; struct isi_data *isi = ofono_modem_get_data(om); - if (!g_isi_msg_error(msg) < 0) + if (g_isi_msg_error(msg) < 0) return; ISI_RESOURCE_DBG(msg); diff -Nru ofono-1.16.bzr6902+15.10.20150911/plugins/n900.c ofono-1.17.bzr6904+15.10.20150928.1/plugins/n900.c --- ofono-1.16.bzr6902+15.10.20150911/plugins/n900.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/plugins/n900.c 2015-09-28 09:27:15.000000000 +0000 @@ -238,7 +238,7 @@ struct ofono_modem *modem = data; struct isi_data *isi = ofono_modem_get_data(modem); - if (!g_isi_msg_error(msg) < 0) + if (g_isi_msg_error(msg) < 0) return; ISI_RESOURCE_DBG(msg); diff -Nru ofono-1.16.bzr6902+15.10.20150911/plugins/push-notification.c ofono-1.17.bzr6904+15.10.20150928.1/plugins/push-notification.c --- ofono-1.16.bzr6902+15.10.20150911/plugins/push-notification.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/plugins/push-notification.c 2015-09-28 09:27:15.000000000 +0000 @@ -41,7 +41,7 @@ #define PUSH_NOTIFICATION_INTERFACE "org.ofono.PushNotification" #define AGENT_INTERFACE "org.ofono.PushNotificationAgent" -#define WAP_PUSH_SRC_PORT 9200 +#define WAP_PUSH_SRC_PORT -1 #define WAP_PUSH_DST_PORT 2948 static unsigned int modemwatch_id; @@ -50,21 +50,16 @@ struct ofono_modem *modem; struct ofono_sms *sms; struct sms_agent *agent; - unsigned int push_watch[2]; + unsigned int push_watch; }; static void agent_exited(void *userdata) { struct push_notification *pn = userdata; - if (pn->push_watch[0] > 0) { - __ofono_sms_datagram_watch_remove(pn->sms, pn->push_watch[0]); - pn->push_watch[0] = 0; - } - - if (pn->push_watch[1] > 0) { - __ofono_sms_datagram_watch_remove(pn->sms, pn->push_watch[1]); - pn->push_watch[1] = 0; + if (pn->push_watch > 0) { + __ofono_sms_datagram_watch_remove(pn->sms, pn->push_watch); + pn->push_watch = 0; } pn->agent = NULL; @@ -113,17 +108,12 @@ sms_agent_set_removed_notify(pn->agent, agent_exited, pn); - pn->push_watch[0] = __ofono_sms_datagram_watch_add(pn->sms, + pn->push_watch = __ofono_sms_datagram_watch_add(pn->sms, push_received, WAP_PUSH_DST_PORT, WAP_PUSH_SRC_PORT, pn, NULL); - pn->push_watch[1] = __ofono_sms_datagram_watch_add(pn->sms, - push_received, - WAP_PUSH_DST_PORT, - 0, pn, NULL); - return dbus_message_new_method_return(msg); } @@ -166,8 +156,7 @@ DBG("%p", pn); /* The push watch was already cleaned up */ - pn->push_watch[0] = 0; - pn->push_watch[1] = 0; + pn->push_watch = 0; pn->sms = NULL; sms_agent_free(pn->agent); diff -Nru ofono-1.16.bzr6902+15.10.20150911/plugins/ril.c ofono-1.17.bzr6904+15.10.20150928.1/plugins/ril.c --- ofono-1.16.bzr6902+15.10.20150911/plugins/ril.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/plugins/ril.c 2015-09-28 09:27:15.000000000 +0000 @@ -29,6 +29,8 @@ #include #include #include + +#include #include #define OFONO_API_SUBJECT_TO_CHANGE @@ -134,13 +136,17 @@ case RADIO_STATE_OFF: /* - * If radio powers off asychronously, then - * assert, and let upstart re-start the stack. + * Unexpected radio state change, as we are supposed to + * be online. UNAVAILABLE has been seen occassionally + * when powering off the phone. We wait 5 secs to avoid + * too fast re-spawns, then exit with error to make + * upstart re-start ofono. */ if (rd->ofono_online) { ofono_error("%s: radio self-powered off!", __func__); - g_assert(FALSE); + sleep(5); + exit(1); } break; default: diff -Nru ofono-1.16.bzr6902+15.10.20150911/plugins/sierra.c ofono-1.17.bzr6904+15.10.20150928.1/plugins/sierra.c --- ofono-1.16.bzr6902+15.10.20150911/plugins/sierra.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/plugins/sierra.c 2015-09-28 09:27:15.000000000 +0000 @@ -48,6 +48,8 @@ struct sierra_data { GAtChat *modem; + gboolean have_sim; + struct at_util_sim_state_query *sim_state_query; }; static void sierra_debug(const char *str, void *user_data) @@ -80,6 +82,9 @@ ofono_modem_set_data(modem, NULL); + /* Cleanup potential SIM state polling */ + at_util_sim_state_query_free(data->sim_state_query); + /* Cleanup after hot-unplug */ g_at_chat_unref(data->modem); @@ -119,6 +124,21 @@ return chat; } +static void sim_state_cb(gboolean present, gpointer user_data) +{ + struct ofono_modem *modem = user_data; + struct sierra_data *data = ofono_modem_get_data(modem); + + DBG("%p", modem); + + at_util_sim_state_query_free(data->sim_state_query); + data->sim_state_query = NULL; + + data->have_sim = present; + ofono_modem_set_powered(modem, TRUE); + +} + static void cfun_enable(gboolean ok, GAtResult *result, gpointer user_data) { struct ofono_modem *modem = user_data; @@ -131,7 +151,9 @@ data->modem = NULL; } - ofono_modem_set_powered(modem, ok); + data->sim_state_query = at_util_sim_state_query_new(data->modem, + 2, 20, sim_state_cb, modem, + NULL); } static int sierra_enable(struct ofono_modem *modem) @@ -222,7 +244,7 @@ sim = ofono_sim_create(modem, OFONO_VENDOR_SIERRA, "atmodem", data->modem); - if (sim) + if (sim && data->have_sim == TRUE) ofono_sim_inserted_notify(sim, TRUE); } diff -Nru ofono-1.16.bzr6902+15.10.20150911/plugins/ste.c ofono-1.17.bzr6904+15.10.20150928.1/plugins/ste.c --- ofono-1.16.bzr6902+15.10.20150911/plugins/ste.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/plugins/ste.c 2015-09-28 09:27:15.000000000 +0000 @@ -423,9 +423,8 @@ if (g_at_chat_send(chat, command, NULL, set_online_cb, cbd, g_free)) return; - g_free(cbd); - CALLBACK_WITH_FAILURE(cb, cbd->data); + g_free(cbd); } static void ste_pre_sim(struct ofono_modem *modem) diff -Nru ofono-1.16.bzr6902+15.10.20150911/plugins/tc65.c ofono-1.17.bzr6904+15.10.20150928.1/plugins/tc65.c --- ofono-1.16.bzr6902+15.10.20150911/plugins/tc65.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/plugins/tc65.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,245 +0,0 @@ -/* - * - * oFono - Open Source Telephony - * - * Copyright (C) 2008-2011 Intel Corporation. All rights reserved. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include - -#include -#include -#include - -#define OFONO_API_SUBJECT_TO_CHANGE -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -static int tc65_probe(struct ofono_modem *modem) -{ - return 0; -} - -static void tc65_remove(struct ofono_modem *modem) -{ -} - -static void tc65_debug(const char *str, void *user_data) -{ - const char *prefix = user_data; - - ofono_info("%s%s", prefix, str); -} - -static int tc65_enable(struct ofono_modem *modem) -{ - GAtChat *chat; - GIOChannel *channel; - GAtSyntax *syntax; - GHashTable *options; - const char *device; - - DBG("%p", modem); - - options = g_hash_table_new(g_str_hash, g_str_equal); - if (options == NULL) - return -ENOMEM; - - device = ofono_modem_get_string(modem, "Device"); - if (device == NULL) - return -EINVAL; - - g_hash_table_insert(options, "Baud", "115200"); - g_hash_table_insert(options, "StopBits", "1"); - g_hash_table_insert(options, "DataBits", "8"); - g_hash_table_insert(options, "Parity", "none"); - g_hash_table_insert(options, "XonXoff", "off"); - g_hash_table_insert(options, "RtsCts", "on"); - g_hash_table_insert(options, "Local", "on"); - g_hash_table_insert(options, "Read", "on"); - - channel = g_at_tty_open(device, options); - g_hash_table_destroy(options); - - if (channel == NULL) - return -EIO; - - /* - * TC65 works almost as the 27.007 says. But for example after - * AT+CRSM the modem replies with the data in the queried EF and - * writes three pairs of after the data and before OK. - */ - syntax = g_at_syntax_new_gsm_permissive(); - - chat = g_at_chat_new(channel, syntax); - g_at_syntax_unref(syntax); - g_io_channel_unref(channel); - - if (chat == NULL) - return -ENOMEM; - - if (getenv("OFONO_AT_DEBUG")) - g_at_chat_set_debug(chat, tc65_debug, ""); - - ofono_modem_set_data(modem, chat); - - return 0; -} - -static int tc65_disable(struct ofono_modem *modem) -{ - GAtChat *chat = ofono_modem_get_data(modem); - - DBG("%p", modem); - - ofono_modem_set_data(modem, NULL); - - g_at_chat_send(chat, "AT+CFUN=7", NULL, NULL, NULL, NULL); - - g_at_chat_unref(chat); - - return 0; -} - -static void set_online_cb(gboolean ok, GAtResult *result, gpointer user_data) -{ - struct cb_data *cbd = user_data; - ofono_modem_online_cb_t cb = cbd->cb; - struct ofono_error error; - - decode_at_error(&error, g_at_result_final_response(result)); - - cb(&error, cbd->data); -} - -static void tc65_set_online(struct ofono_modem *modem, ofono_bool_t online, - ofono_modem_online_cb_t cb, void *user_data) -{ - GAtChat *chat = ofono_modem_get_data(modem); - struct cb_data *cbd = cb_data_new(cb, user_data); - char const *command = online ? "AT+CFUN=1" : "AT+CFUN=7"; - - DBG("modem %p %s", modem, online ? "online" : "offline"); - - if (g_at_chat_send(chat, command, NULL, set_online_cb, cbd, g_free)) - return; - - g_free(cbd); - - CALLBACK_WITH_FAILURE(cb, cbd->data); -} - -static void tc65_pre_sim(struct ofono_modem *modem) -{ - GAtChat *chat = ofono_modem_get_data(modem); - struct ofono_sim *sim; - - DBG("%p", modem); - - ofono_devinfo_create(modem, 0, "atmodem", chat); - sim = ofono_sim_create(modem, 0, "atmodem", chat); - ofono_voicecall_create(modem, 0, "atmodem", chat); - - if (sim) - ofono_sim_inserted_notify(sim, TRUE); -} - -static void tc65_post_sim(struct ofono_modem *modem) -{ - GAtChat *chat = ofono_modem_get_data(modem); - - DBG("%p", modem); - - ofono_phonebook_create(modem, 0, "atmodem", chat); - - ofono_sms_create(modem, 0, "atmodem", chat); -} - -static void tc65_post_online(struct ofono_modem *modem) -{ - GAtChat *chat = ofono_modem_get_data(modem); - struct ofono_message_waiting *mw; - struct ofono_gprs *gprs; - struct ofono_gprs_context *gc; - - DBG("%p", modem); - - ofono_ussd_create(modem, 0, "atmodem", chat); - ofono_call_forwarding_create(modem, 0, "atmodem", chat); - ofono_call_settings_create(modem, 0, "atmodem", chat); - ofono_netreg_create(modem, 0, "atmodem", chat); - ofono_call_meter_create(modem, 0, "atmodem", chat); - ofono_call_barring_create(modem, 0, "atmodem", chat); - - gprs = ofono_gprs_create(modem, 0, "atmodem", chat); - gc = ofono_gprs_context_create(modem, 0, "atmodem", chat); - - if (gprs && gc) - ofono_gprs_add_context(gprs, gc); - - mw = ofono_message_waiting_create(modem); - if (mw) - ofono_message_waiting_register(mw); -} - -static struct ofono_modem_driver tc65_driver = { - .name = "tc65", - .probe = tc65_probe, - .remove = tc65_remove, - .enable = tc65_enable, - .disable = tc65_disable, - .set_online = tc65_set_online, - .pre_sim = tc65_pre_sim, - .post_sim = tc65_post_sim, - .post_online = tc65_post_online, -}; - -static int tc65_init(void) -{ - return ofono_modem_driver_register(&tc65_driver); -} - -static void tc65_exit(void) -{ - ofono_modem_driver_unregister(&tc65_driver); -} - -OFONO_PLUGIN_DEFINE(tc65, "Cinterion TC65 driver plugin", VERSION, - OFONO_PLUGIN_PRIORITY_DEFAULT, tc65_init, tc65_exit) diff -Nru ofono-1.16.bzr6902+15.10.20150911/plugins/u8500.c ofono-1.17.bzr6904+15.10.20150928.1/plugins/u8500.c --- ofono-1.16.bzr6902+15.10.20150911/plugins/u8500.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/plugins/u8500.c 2015-09-28 09:27:15.000000000 +0000 @@ -232,7 +232,7 @@ struct ofono_modem *om = data; struct isi_data *isi = ofono_modem_get_data(om); - if (!g_isi_msg_error(msg) < 0) + if (g_isi_msg_error(msg) < 0) return; ISI_RESOURCE_DBG(msg); diff -Nru ofono-1.16.bzr6902+15.10.20150911/plugins/udev.c ofono-1.17.bzr6904+15.10.20150928.1/plugins/udev.c --- ofono-1.16.bzr6902+15.10.20150911/plugins/udev.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/plugins/udev.c 2015-09-28 09:27:15.000000000 +0000 @@ -192,7 +192,7 @@ ofono_modem_register(modem); } -static void add_tc65(struct ofono_modem *modem, +static void add_cinterion(struct ofono_modem *modem, struct udev_device *udev_device) { const char *devnode; @@ -243,6 +243,11 @@ if (devpath == NULL) return; + if(g_strcmp0(driver, "tc65") == 0) + driver = "cinterion"; + if(g_strcmp0(driver, "ehs6") == 0) + driver = "cinterion"; + modem = ofono_modem_create(NULL, driver); if (modem == NULL) return; @@ -305,8 +310,8 @@ add_isi(modem, udev_device); else if (g_strcmp0(driver, "calypso") == 0) add_calypso(modem, udev_device); - else if (g_strcmp0(driver, "tc65") == 0) - add_tc65(modem, udev_device); + else if (g_strcmp0(driver, "cinterion") == 0) + add_cinterion(modem, udev_device); else if (g_strcmp0(driver, "nokiacdma") == 0) add_nokiacdma(modem, udev_device); else if (g_strcmp0(driver, "sim900") == 0) diff -Nru ofono-1.16.bzr6902+15.10.20150911/plugins/udevng.c ofono-1.17.bzr6904+15.10.20150928.1/plugins/udevng.c --- ofono-1.16.bzr6902+15.10.20150911/plugins/udevng.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/plugins/udevng.c 2015-09-28 09:27:15.000000000 +0000 @@ -119,6 +119,8 @@ } else if (g_str_has_suffix(info->sysattr, "Network Adapter") == TRUE || g_str_has_suffix(info->sysattr, + "gw") == TRUE || + g_str_has_suffix(info->sysattr, "NetworkAdapter") == TRUE || g_strcmp0(info->devtype, "wwan") == 0) { network = info->devnode; @@ -1083,14 +1085,19 @@ { "icera", "cdc_ether", "0421", "0633" }, { "mbm", "cdc_acm", "0bdb" }, { "mbm", "cdc_ether", "0bdb" }, + { "mbm", "cdc_ncm", "0bdb" }, { "mbm", "cdc_acm", "0fce" }, { "mbm", "cdc_ether", "0fce" }, + { "mbm", "cdc_ncm", "0fce" }, { "mbm", "cdc_acm", "413c" }, { "mbm", "cdc_ether", "413c" }, + { "mbm", "cdc_ncm", "413c" }, { "mbm", "cdc_acm", "03f0" }, { "mbm", "cdc_ether", "03f0" }, + { "mbm", "cdc_ncm", "03f0" }, { "mbm", "cdc_acm", "0930" }, { "mbm", "cdc_ether", "0930" }, + { "mbm", "cdc_ncm", "0930" }, { "hso", "hso" }, { "gobi", "qmi_wwan" }, { "gobi", "qcserial" }, diff -Nru ofono-1.16.bzr6902+15.10.20150911/src/cdma-connman.c ofono-1.17.bzr6904+15.10.20150928.1/src/cdma-connman.c --- ofono-1.16.bzr6902+15.10.20150911/src/cdma-connman.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/src/cdma-connman.c 2015-09-28 09:27:15.000000000 +0000 @@ -89,7 +89,7 @@ return; memset(&ifr, 0, sizeof(ifr)); - strncpy(ifr.ifr_name, interface, IFNAMSIZ); + strncpy(ifr.ifr_name, interface, IFNAMSIZ - 1); if (ioctl(sk, SIOCGIFFLAGS, &ifr) < 0) goto done; diff -Nru ofono-1.16.bzr6902+15.10.20150911/src/gprs.c ofono-1.17.bzr6904+15.10.20150928.1/src/gprs.c --- ofono-1.16.bzr6902+15.10.20150911/src/gprs.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/src/gprs.c 2015-09-28 09:27:15.000000000 +0000 @@ -1781,6 +1781,8 @@ attach = attach && gprs->powered; + DBG("attach: %u, driver_attached: %u", attach, gprs->driver_attached); + if (gprs->driver_attached == attach) return; @@ -1803,9 +1805,6 @@ DBG("%d", status); - if (gprs->netreg_status == status) - return; - gprs->netreg_status = status; gprs_netreg_update(gprs); diff -Nru ofono-1.16.bzr6902+15.10.20150911/src/handsfree-audio.c ofono-1.17.bzr6904+15.10.20150928.1/src/handsfree-audio.c --- ofono-1.16.bzr6902+15.10.20150911/src/handsfree-audio.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/src/handsfree-audio.c 2015-09-28 09:27:15.000000000 +0000 @@ -101,6 +101,8 @@ DBusMessage *msg; DBusMessageIter iter; + DBG("%p, fd: %d, codec: %hu", card, fd, codec); + msg = dbus_message_new_method_call(agent->owner, agent->path, HFP_AUDIO_AGENT_INTERFACE, "NewConnection"); if (msg == NULL) @@ -183,9 +185,15 @@ return TRUE; } + DBG("SCO connection setup between local: %s and remote: %s", + local, remote); + send_new_connection(card->path, nsk, card->selected_codec); close(nsk); + if (card->driver->sco_connected_hint) + card->driver->sco_connected_hint(card); + return TRUE; } @@ -845,6 +853,8 @@ if (ref_count != 1) return; + __ofono_handsfree_audio_manager_init(); + if (!g_dbus_register_interface(ofono_dbus_get_connection(), OFONO_MANAGER_PATH, HFP_AUDIO_MANAGER_INTERFACE, @@ -873,6 +883,8 @@ agent_release(agent); agent_free(agent); } + + __ofono_handsfree_audio_manager_cleanup(); } int __ofono_handsfree_audio_manager_init(void) @@ -882,15 +894,11 @@ void __ofono_handsfree_audio_manager_cleanup(void) { - if (ref_count == 0) + if (ref_count != 0) return; - ofono_error("Handsfree Audio manager not cleaned up properly," - "fixing..."); - - ref_count = 1; - ofono_handsfree_audio_unref(); - - if (sco_watch > 0) + if (sco_watch > 0) { g_source_remove(sco_watch); + sco_watch = 0; + } } diff -Nru ofono-1.16.bzr6902+15.10.20150911/src/handsfree.c ofono-1.17.bzr6904+15.10.20150928.1/src/handsfree.c --- ofono-1.16.bzr6902+15.10.20150911/src/handsfree.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/src/handsfree.c 2015-09-28 09:27:15.000000000 +0000 @@ -72,7 +72,11 @@ static const char **ag_features_list(unsigned int features, unsigned int chld_features) { - static const char *list[10]; + /* + * BRSF response is a 32-bit unsigned int. Only 32 entries are posible, + * and we do not ever report the presence of bit 8. + */ + static const char *list[32]; unsigned int i = 0; if (features & HFP_AG_FEATURE_3WAY) @@ -602,7 +606,7 @@ } static const GDBusMethodTable handsfree_methods[] = { - { GDBUS_METHOD("GetProperties", + { GDBUS_ASYNC_METHOD("GetProperties", NULL, GDBUS_ARGS({ "properties", "a{sv}" }), handsfree_get_properties) }, { GDBUS_ASYNC_METHOD("SetProperty", diff -Nru ofono-1.16.bzr6902+15.10.20150911/src/log.c ofono-1.17.bzr6904+15.10.20150928.1/src/log.c --- ofono-1.16.bzr6902+15.10.20150911/src/log.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/src/log.c 2015-09-28 09:27:15.000000000 +0000 @@ -30,7 +30,9 @@ #include #include #include +#ifdef __GLIBC__ #include +#endif #include #include "ofono.h" @@ -113,6 +115,7 @@ va_end(ap); } +#ifdef __GLIBC__ static void print_backtrace(unsigned int offset) __attribute__ ((used)); static void print_backtrace(unsigned int offset) @@ -216,6 +219,7 @@ close(outfd[1]); close(infd[0]); } +#endif extern struct ofono_debug_desc __start___debug[]; extern struct ofono_debug_desc __stop___debug[]; diff -Nru ofono-1.16.bzr6902+15.10.20150911/src/main.c ofono-1.17.bzr6904+15.10.20150928.1/src/main.c --- ofono-1.16.bzr6902+15.10.20150911/src/main.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/src/main.c 2015-09-28 09:27:15.000000000 +0000 @@ -239,8 +239,6 @@ __ofono_manager_init(); - __ofono_handsfree_audio_manager_init(); - __ofono_plugin_init(option_plugin, option_noplugin); g_free(option_plugin); @@ -250,8 +248,6 @@ __ofono_plugin_cleanup(); - __ofono_handsfree_audio_manager_cleanup(); - __ofono_manager_cleanup(); __ofono_modemwatch_cleanup(); diff -Nru ofono-1.16.bzr6902+15.10.20150911/src/sim.c ofono-1.17.bzr6904+15.10.20150928.1/src/sim.c --- ofono-1.16.bzr6902+15.10.20150911/src/sim.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/src/sim.c 2015-09-28 09:27:15.000000000 +0000 @@ -2532,10 +2532,13 @@ sim_inserted_update(sim); call_state_watches(sim); - if (inserted) + if (inserted) { sim_initialize(sim); - else + } else { + sim->pin_type = OFONO_SIM_PASSWORD_NONE; + sim_free_state(sim); + } } unsigned int ofono_sim_add_state_watch(struct ofono_sim *sim, @@ -2784,6 +2787,10 @@ DBusConnection *conn = ofono_dbus_get_connection(); const char *path = __ofono_atom_get_path(sim->atom); const char *pin_name; + char **locked_pins; + gboolean lock_changed; + + DBG("sim->pin_type: %d, pin_type: %d", sim->pin_type, pin_type); if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { ofono_error("Querying PIN authentication state failed"); @@ -2798,9 +2805,25 @@ password_is_pin(pin_type) == FALSE) pin_type = puk2pin(pin_type); - if (pin_type != OFONO_SIM_PASSWORD_INVALID) + if (pin_type != OFONO_SIM_PASSWORD_INVALID + && pin_type != OFONO_SIM_PASSWORD_NONE) { + lock_changed = !sim->locked_pins[pin_type]; + sim->locked_pins[pin_type] = TRUE; + if (lock_changed) { + locked_pins = get_locked_pins(sim); + + ofono_dbus_signal_array_property_changed(conn, + path, + OFONO_SIM_MANAGER_INTERFACE, + "LockedPins", DBUS_TYPE_STRING, + &locked_pins); + + g_strfreev(locked_pins); + } + } + ofono_dbus_signal_property_changed(conn, path, OFONO_SIM_MANAGER_INTERFACE, "PinRequired", DBUS_TYPE_STRING, diff -Nru ofono-1.16.bzr6902+15.10.20150911/src/sms.c ofono-1.17.bzr6904+15.10.20150928.1/src/sms.c --- ofono-1.16.bzr6902+15.10.20150911/src/sms.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/src/sms.c 2015-09-28 09:27:15.000000000 +0000 @@ -1184,6 +1184,7 @@ ofono_sms_datagram_notify_cb_t notify; struct sms_handler *h; GSList *l; + gboolean dispatched = FALSE; ts = sms_scts_to_time(scts, &remote); localtime_r(&ts, &local); @@ -1195,9 +1196,15 @@ if (!port_equal(dst, h->dst) || !port_equal(src, h->src)) continue; + dispatched = TRUE; + notify(sender, &remote, &local, dst, src, buf, len, h->item.notify_data); } + + if (!dispatched) + ofono_info("Datagram with ports [%d,%d] not delivered", + dst, src); } static void dispatch_text_message(struct ofono_sms *sms, diff -Nru ofono-1.16.bzr6902+15.10.20150911/src/smsutil.c ofono-1.17.bzr6904+15.10.20150928.1/src/smsutil.c --- ofono-1.16.bzr6902+15.10.20150911/src/smsutil.c 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/src/smsutil.c 2015-09-28 09:27:15.000000000 +0000 @@ -524,7 +524,8 @@ 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 @@ 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 @@ 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; } @@ -1935,9 +1946,6 @@ if (((addr_hdr[0] << 8) | addr_hdr[1]) > 49151) break; - if (((addr_hdr[2] << 8) | addr_hdr[3]) > 49151) - break; - dstport = (addr_hdr[0] << 8) | addr_hdr[1]; srcport = (addr_hdr[2] << 8) | addr_hdr[3]; is_addr_8bit = FALSE; diff -Nru ofono-1.16.bzr6902+15.10.20150911/src/smsutil.h ofono-1.17.bzr6904+15.10.20150928.1/src/smsutil.h --- ofono-1.16.bzr6902+15.10.20150911/src/smsutil.h 2015-09-11 13:56:20.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/src/smsutil.h 2015-09-28 09:27:15.000000000 +0000 @@ -220,7 +220,11 @@ 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 { diff -Nru ofono-1.16.bzr6902+15.10.20150911/src/voicecall.c ofono-1.17.bzr6904+15.10.20150928.1/src/voicecall.c --- ofono-1.16.bzr6902+15.10.20150911/src/voicecall.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/src/voicecall.c 2015-09-28 09:27:15.000000000 +0000 @@ -1513,6 +1513,9 @@ if (g_slist_length(vc->call_list) >= MAX_VOICE_CALLS) return -EPERM; + if (valid_ussd_string(number, vc->call_list != NULL)) + return -EINVAL; + if (!valid_long_phone_number_format(number)) return -EINVAL; diff -Nru ofono-1.16.bzr6902+15.10.20150911/unit/test-sms.c ofono-1.17.bzr6904+15.10.20150928.1/unit/test-sms.c --- ofono-1.16.bzr6902+15.10.20150911/unit/test-sms.c 2015-09-11 13:56:27.000000000 +0000 +++ ofono-1.17.bzr6904+15.10.20150928.1/unit/test-sms.c 2015-09-28 09:27:15.000000000 +0000 @@ -38,6 +38,12 @@ "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 @@ 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)