Merge lp:~phablet-team/ofono/ww13-update into lp:~phablet-team/ofono/ubuntu

Proposed by Tony Espy
Status: Merged
Approved by: Alfonso Sanchez-Beato
Approved revision: 6892
Merged at revision: 6892
Proposed branch: lp:~phablet-team/ofono/ww13-update
Merge into: lp:~phablet-team/ofono/ubuntu
Diff against target: 1314 lines (+686/-110)
16 files modified
debian/changelog (+19/-0)
doc/connman-api.txt (+8/-0)
drivers/mtkmodem/mtkrequest.h (+2/-2)
drivers/mtkmodem/mtkunsol.c (+35/-0)
drivers/mtkmodem/mtkunsol.h (+7/-0)
drivers/rilmodem/gprs-context.c (+9/-3)
gril/grilunsol.c (+75/-17)
include/modem.h (+5/-0)
plugins/bluetooth.c (+10/-0)
plugins/mtk.c (+326/-75)
plugins/ubuntu-apndb.c (+9/-10)
src/common.c (+1/-1)
src/gprs.c (+104/-1)
src/modem.c (+8/-0)
unit/test-common.c (+1/-1)
unit/test-mtkunsol.c (+67/-0)
To merge this branch: bzr merge lp:~phablet-team/ofono/ww13-update
Reviewer Review Type Date Requested Status
Ricardo Salveti (community) Approve
Alfonso Sanchez-Beato Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+254948@code.launchpad.net

Commit message

  * ubuntu-apndb.c, src/common.c, test-common.c: provision IA APNs
    LTE modems may require a new IA APN for non-GPRS operation,
    this change allows a new IA APN type to be provisioned along
    with Internet and MMS APNs.
  * gril/grilunsol.c: LTE signal strength fix (LP: #1433867)
  * ubuntu-apndb.c: load APNS w/out explict type (LP: #1437200)
  * mtkodem, plugins/mtk.c, unit/tesk-mtkunsol.c: Dynamic MTK firwmare switching
    This change causes the firmware on specific MTK-based phone to be
    dynamically switched/reset based on SIM type and roaming conditions.
  * include, plugins/mtk.c, src/modem.c, gprs.c: set data for just one slot (LP: #1413672)
    Make sure ConnectionManager.Powered property is set for only one slot in
    case the modem is of type dual SIM stand-by.
  * doc, gprs: add 'Preferred' property to GPRS contexts (LP: #1361864)

Description of the change

This change includes bug fixes, as well as a change needed for LTE, and one arale-specific feature:

 * provision IA APNs ( LTE )

 * LTE signal strength fix (LP: #1433867)

 * load APNS w/out explict type (LP: #1437200)

 * Dynamic MTK firwmare switching (arale)

 * [krillin] set data for just one slot (LP: #1413672)

 * add 'Preferred' property to GPRS contexts (LP: #1361864)

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

The changes to add the 'Preferred' property are actually missing (commits dff2e80 and 0f42b18 from github).

And there are changes in the MP that are not mentioned in changelog:

 * rilmodem/gprs.c: dynamically set authtype based on credentials (LP: #1435784)
 * src/common.c: allow empty APNs when provisioning

review: Needs Fixing
lp:~phablet-team/ofono/ww13-update updated
6892. By Tony Espy

* ubuntu-apndb.c, src/common.c, test-common.c: provision IA APNs
  LTE modems may require a new IA APN for non-GPRS operation,
  this change allows a new IA APN type to be provisioned along
  with Internet and MMS APNs.
* gril/grilunsol.c: LTE signal strength fix (LP: #1433867)
* ubuntu-apndb.c: load APNS w/out explict type (LP: #1437200)
* mtkodem, plugins/mtk.c, unit/tesk-mtkunsol.c: Dynamic MTK firwmare switching
  This change causes the firmware on specific MTK-based phone to be
  dynamically switched/reset based on SIM type and roaming conditions.
* include, plugins/mtk.c, src/modem.c, gprs.c: set data for just one slot (LP: #1413672)
  Make sure ConnectionManager.Powered property is set for only one slot in
  case the modem is of type dual SIM stand-by.
* doc, gprs: add 'Preferred' property to GPRS contexts (LP: #1361864)

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

LGTM

review: Approve
Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

All changes tested (except FW loading, as a China Mobile SIM is required for that) and sanity tests performed for:

current build number: 163
device name: m75 -> arale
channel: ubuntu-touch/vivid-proposed
last update: 2015-04-06 12:29:08
version version: 163

current build number: 177
device name: krillin
channel: ubuntu-touch/vivid-proposed
last update: 2015-04-07 10:18:29
version version: 177
version ubuntu: 20150407
version device: 20150326-f0c5ba5
version custom: 20150407

Note: USSD is not working currently due to bug #1438273 (telephony service). However, it can be tested using ofono scripts.

Revision history for this message
Alfonso Sanchez-Beato (alfonsosanchezbeato) wrote :

Bug #1441135 has been discovered while testing.

Revision history for this message
Ricardo Salveti (rsalveti) wrote :

Sanity tests fine on Mako:
current build number: 164
device name: mako
channel: ubuntu-touch/devel-proposed
alias: ubuntu-touch/vivid-proposed
last update: 2015-04-07 17:34:29
version version: 164
version ubuntu: 20150407
version device: 20150210
version custom: 20150407

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2015-03-17 11:26:04 +0000
3+++ debian/changelog 2015-04-06 14:34:59 +0000
4@@ -1,3 +1,22 @@
5+ofono (1.12.bzr6892+15.04.20150401-0ubuntu1) UNRELEASED; urgency=medium
6+
7+ [ Alfonso Sanchez-Beato ]
8+ * ubuntu-apndb.c, src/common.c, test-common.c: provision IA APNs
9+ LTE modems may require a new IA APN for non-GPRS operation,
10+ this change allows a new IA APN type to be provisioned along
11+ with Internet and MMS APNs.
12+ * gril/grilunsol.c: LTE signal strength fix (LP: #1433867)
13+ * ubuntu-apndb.c: load APNS w/out explict type (LP: #1437200)
14+ * mtkodem, plugins/mtk.c, unit/tesk-mtkunsol.c: Dynamic MTK firwmare switching
15+ This change causes the firmware on specific MTK-based phone to be
16+ dynamically switched/reset based on SIM type and roaming conditions.
17+ * include, plugins/mtk.c, src/modem.c, gprs.c: set data for just one slot (LP: #1413672)
18+ Make sure ConnectionManager.Powered property is set for only one slot in
19+ case the modem is of type dual SIM stand-by.
20+ * doc, gprs: add 'Preferred' property to GPRS contexts (LP: #1361864)
21+
22+ -- CI Train Bot <ci-train-bot@canonical.com> Wed, 01 Apr 2015 11:54:49 -0400
23+
24 ofono (1.12.bzr6890+15.04.20150317-0ubuntu1) vivid; urgency=medium
25
26 [ Alfonso Sanchez-Beato ]
27
28=== modified file 'doc/connman-api.txt'
29--- doc/connman-api.txt 2011-03-15 22:11:59 +0000
30+++ doc/connman-api.txt 2015-04-06 14:34:59 +0000
31@@ -203,6 +203,14 @@
32 context. The name should not be empty and limited
33 to a short string for display purposes.
34
35+ boolean Preferred [readwrite]
36+
37+ Holds a boolean. This value is meant to be used by
38+ clients to store an indication on whether this context
39+ is preferred compared to others. ofono just stores and
40+ shows this value, but does not use it internally. The
41+ exact way in which this is used depends on the clients.
42+
43 dict Settings [readonly, optional]
44
45 Holds all the IP network settings
46
47=== modified file 'drivers/mtkmodem/mtkrequest.h'
48--- drivers/mtkmodem/mtkrequest.h 2015-01-28 07:52:59 +0000
49+++ drivers/mtkmodem/mtkrequest.h 2015-04-06 14:34:59 +0000
50@@ -57,9 +57,9 @@
51 #define MTK_MD_TYPE_3G 2
52 #define MTK_MD_TYPE_WG 3
53 #define MTK_MD_TYPE_TG 4
54-/* FDD CSFB modem */
55+/* FDD CSFB modem: LTE FDD - WCDMA - GSM */
56 #define MTK_MD_TYPE_LWG 5
57-/* TDD CSFB modem */
58+/* TDD CSFB modem: LTE TDD - TD-SCDMA - GSM */
59 #define MTK_MD_TYPE_LTG 6
60 /* SGLTE modem */
61 #define MTK_MD_TYPE_LTNG 7
62
63=== modified file 'drivers/mtkmodem/mtkunsol.c'
64--- drivers/mtkmodem/mtkunsol.c 2015-01-28 07:52:19 +0000
65+++ drivers/mtkmodem/mtkunsol.c 2015-04-06 14:34:59 +0000
66@@ -162,3 +162,38 @@
67 return -1;
68
69 }
70+
71+struct parcel_str_array *g_mtk_unsol_parse_plmn_changed(GRil *gril,
72+ const struct ril_msg *message)
73+{
74+ struct parcel rilp;
75+ struct parcel_str_array *str_arr;
76+ int i;
77+
78+ g_ril_init_parcel(message, &rilp);
79+
80+ str_arr = parcel_r_str_array(&rilp);
81+ if (str_arr == NULL || str_arr->num_str == 0) {
82+ ofono_error("%s: parse error for %s", __func__,
83+ ril_request_id_to_string(message->req));
84+ parcel_free_str_array(str_arr);
85+ str_arr = NULL;
86+ goto out;
87+ }
88+
89+ g_ril_append_print_buf(gril, "{");
90+
91+ for (i = 0; i < str_arr->num_str; ++i) {
92+ if (i + 1 == str_arr->num_str)
93+ g_ril_append_print_buf(gril, "%s%s}", print_buf,
94+ str_arr->str[i]);
95+ else
96+ g_ril_append_print_buf(gril, "%s%s, ", print_buf,
97+ str_arr->str[i]);
98+ }
99+
100+ g_ril_print_unsol(gril, message);
101+
102+out:
103+ return str_arr;
104+}
105
106=== modified file 'drivers/mtkmodem/mtkunsol.h'
107--- drivers/mtkmodem/mtkunsol.h 2015-01-28 07:52:19 +0000
108+++ drivers/mtkmodem/mtkunsol.h 2015-04-06 14:34:59 +0000
109@@ -45,6 +45,13 @@
110 int g_mtk_unsol_parse_registration_suspended(GRil *gril,
111 const struct ril_msg *message);
112
113+/*
114+ * Returns a minimum of one PLMN or NULL. parcel_free_str_array must be invoked
115+ * to free the returned pointer.
116+ */
117+struct parcel_str_array *g_mtk_unsol_parse_plmn_changed(GRil *gril,
118+ const struct ril_msg *message);
119+
120 #ifdef __cplusplus
121 }
122 #endif
123
124=== modified file 'drivers/rilmodem/gprs-context.c'
125--- drivers/rilmodem/gprs-context.c 2014-07-30 07:30:49 +0000
126+++ drivers/rilmodem/gprs-context.c 2015-04-06 14:34:59 +0000
127@@ -272,10 +272,16 @@
128 request.username = g_strdup(ctx->username);
129 request.password = g_strdup(ctx->password);
130
131- if (g_ril_vendor(gcd->ril) == OFONO_RIL_VENDOR_MTK)
132+ /*
133+ * We do the same as in $AOSP/frameworks/opt/telephony/src/java/com/
134+ * android/internal/telephony/dataconnection/DataConnection.java,
135+ * onConnect(), and use authentication or not depending on whether
136+ * the user field is empty or not.
137+ */
138+ if (request.username != NULL && request.username[0] != '\0')
139+ request.auth_type = RIL_AUTH_BOTH;
140+ else
141 request.auth_type = RIL_AUTH_NONE;
142- else
143- request.auth_type = RIL_AUTH_BOTH;
144
145 request.protocol = ctx->proto;
146 request.req_cid = ctx->cid;
147
148=== modified file 'gril/grilunsol.c'
149--- gril/grilunsol.c 2014-08-14 15:14:18 +0000
150+++ gril/grilunsol.c 2015-04-06 14:34:59 +0000
151@@ -416,25 +416,80 @@
152 return radio_state;
153 }
154
155-inline static int is_valid_strength(int signal)
156-{
157- if (signal != 99 && signal != -1)
158- return 1;
159+/*
160+ * This function makes a similar processing to was is done by validateInput()
161+ * and getLteLevel() in $AOSP/frameworks/base/telephony/java/android/telephony/
162+ * SignalStrength.java. The main difference is that we linearly transform the
163+ * ranges to ofono's one, while AOSP gives number of bars in a non-linear way
164+ * (bins for each bar have different size). We rely on the indicator to obtain
165+ * a translation to bars that makes sense for humans.
166+ */
167+static int get_lte_strength(int signal, int rsrp, int rssnr)
168+{
169+ int s_rsrp = -1, s_rssnr = -1, s_signal = -1;
170+
171+ /*
172+ * The range of signal is specified to be [0, 31] by ril.h, but the code
173+ * in SignalStrength.java contradicts this: valid values are (0-63, 99)
174+ * as defined in TS 36.331 for E-UTRA rssi.
175+ */
176+ signal = (signal >= 0 && signal <= 63) ? signal : INT_MAX;
177+ rsrp = (rsrp >= 44 && rsrp <= 140) ? -rsrp : INT_MAX;
178+ rssnr = (rssnr >= -200 && rssnr <= 300) ? rssnr : INT_MAX;
179+
180+ /* Linearly transform [-140, -44] to [0, 100] */
181+ if (rsrp != INT_MAX)
182+ s_rsrp = (25 * rsrp + 3500) / 24;
183+
184+ /* Linearly transform [-200, 300] to [0, 100] */
185+ if (rssnr != INT_MAX)
186+ s_rssnr = (rssnr + 200) / 5;
187+
188+ if (s_rsrp != -1 && s_rssnr != -1)
189+ return s_rsrp < s_rssnr ? s_rsrp : s_rssnr;
190+
191+ if (s_rssnr != -1)
192+ return s_rssnr;
193+
194+ if (s_rsrp != -1)
195+ return s_rsrp;
196+
197+ /* Linearly transform [0, 63] to [0, 100] */
198+ if (signal != INT_MAX)
199+ s_signal = (100 * signal) / 63;
200+
201+ return s_signal;
202+}
203+
204+/*
205+ * Comments to get_lte_strength() apply here also, changing getLteLevel() with
206+ * getGsmLevel(). The atmodem driver does exactly the same transformation with
207+ * the rssi from AT+CSQ command.
208+ */
209+static int get_gsm_strength(int signal)
210+{
211+ /* Checking the range contemplates also the case signal=99 (invalid) */
212+ if (signal >= 0 && signal <= 31)
213+ return (signal * 100) / 31;
214 else
215- return 0;
216+ return -1;
217 }
218
219 int g_ril_unsol_parse_signal_strength(GRil *gril, const struct ril_msg *message,
220 int ril_tech)
221 {
222 struct parcel rilp;
223- int gw_signal, cdma_dbm, evdo_dbm, lte_signal, signal;
224+ int gw_sigstr, gw_signal, cdma_dbm, evdo_dbm;
225+ int lte_sigstr = -1, lte_rsrp = -1, lte_rssnr = -1;
226+ int lte_signal;
227+ int signal;
228
229 g_ril_init_parcel(message, &rilp);
230
231 /* RIL_SignalStrength_v5 */
232 /* GW_SignalStrength */
233- gw_signal = parcel_r_int32(&rilp);
234+ gw_sigstr = parcel_r_int32(&rilp);
235+ gw_signal = get_gsm_strength(gw_sigstr);
236 parcel_r_int32(&rilp); /* bitErrorRate */
237
238 /*
239@@ -453,17 +508,20 @@
240 /* Present only for RIL_SignalStrength_v6 or newer */
241 if (parcel_data_avail(&rilp) > 0) {
242 /* LTE_SignalStrength */
243- lte_signal = parcel_r_int32(&rilp);
244- parcel_r_int32(&rilp); /* rsrp */
245+ lte_sigstr = parcel_r_int32(&rilp);
246+ lte_rsrp = parcel_r_int32(&rilp);
247 parcel_r_int32(&rilp); /* rsrq */
248- parcel_r_int32(&rilp); /* rssnr */
249+ lte_rssnr = parcel_r_int32(&rilp);
250 parcel_r_int32(&rilp); /* cqi */
251+ lte_signal = get_lte_strength(lte_sigstr, lte_rsrp, lte_rssnr);
252 } else {
253 lte_signal = -1;
254 }
255
256- g_ril_append_print_buf(gril, "{gw: %d, cdma: %d, evdo: %d, lte: %d}",
257- gw_signal, cdma_dbm, evdo_dbm, lte_signal);
258+ g_ril_append_print_buf(gril,
259+ "{gw: %d, cdma: %d, evdo: %d, lte: %d %d %d}",
260+ gw_sigstr, cdma_dbm, evdo_dbm, lte_sigstr,
261+ lte_rsrp, lte_rssnr);
262
263 if (message->unsolicited)
264 g_ril_print_unsol(gril, message);
265@@ -471,19 +529,19 @@
266 g_ril_print_response(gril, message);
267
268 /* Return the first valid one */
269- if (is_valid_strength(gw_signal) && is_valid_strength(lte_signal))
270+ if (gw_signal != -1 && lte_signal != -1)
271 if (ril_tech == RADIO_TECH_LTE)
272 signal = lte_signal;
273 else
274 signal = gw_signal;
275- else if (is_valid_strength(gw_signal))
276+ else if (gw_signal != -1)
277 signal = gw_signal;
278- else if (is_valid_strength(lte_signal))
279+ else if (lte_signal != -1)
280 signal = lte_signal;
281 else
282- return -1;
283+ signal = -1;
284
285- return (signal * 100) / 31;
286+ return signal;
287 }
288
289 void g_ril_unsol_free_supp_svc_notif(struct unsol_supp_svc_notif *unsol)
290
291=== modified file 'include/modem.h'
292--- include/modem.h 2014-09-16 07:59:58 +0000
293+++ include/modem.h 2015-04-06 14:34:59 +0000
294@@ -69,6 +69,9 @@
295
296 /* Populate the atoms available online */
297 void (*post_online)(struct ofono_modem *modem);
298+
299+ /* Is it a multi-SIM standby modem? */
300+ ofono_bool_t (*is_standby)(struct ofono_modem *modem);
301 };
302
303 void ofono_modem_add_interface(struct ofono_modem *modem,
304@@ -116,6 +119,8 @@
305 ofono_bool_t value);
306 ofono_bool_t ofono_modem_get_driver_watches_sim(struct ofono_modem *modem);
307
308+ofono_bool_t ofono_modem_is_standby(struct ofono_modem *modem);
309+
310 int ofono_modem_driver_register(const struct ofono_modem_driver *);
311 void ofono_modem_driver_unregister(const struct ofono_modem_driver *);
312
313
314=== modified file 'plugins/bluetooth.c'
315--- plugins/bluetooth.c 2012-07-15 23:19:47 +0000
316+++ plugins/bluetooth.c 2015-04-06 14:34:59 +0000
317@@ -435,6 +435,14 @@
318 goto done;
319 }
320
321+ /*
322+ * Adapter might have been removed before the callback, for instance in
323+ * case the SIM state changes due to a modem reset (see
324+ * hfp_ag.c:sim_state_watch())
325+ */
326+ if (adapter_address_hash == NULL)
327+ goto done;
328+
329 DBG("");
330
331 bluetooth_parse_properties(reply,
332@@ -900,7 +908,9 @@
333 g_dbus_remove_watch(connection, property_watch);
334
335 g_hash_table_destroy(uuid_hash);
336+ uuid_hash = NULL;
337 g_hash_table_destroy(adapter_address_hash);
338+ adapter_address_hash = NULL;
339 }
340
341 void bluetooth_get_properties()
342
343=== modified file 'plugins/mtk.c'
344--- plugins/mtk.c 2015-03-11 14:54:36 +0000
345+++ plugins/mtk.c 2015-04-06 14:34:59 +0000
346@@ -55,6 +55,7 @@
347 #include <ofono/types.h>
348
349 #include "ofono.h"
350+#include <common.h>
351
352 #include <gril.h>
353 #include <grilreply.h>
354@@ -91,10 +92,14 @@
355 #define T_WAIT_DISCONN_MS 1000
356 #define T_SIM_SWITCH_FAILSAFE_MS 1000
357
358-enum mtk_sim_type {
359- MTK_SIM_TYPE_1 = 1,
360- MTK_SIM_TYPE_2 = 2,
361- MTK_SIM_TYPE_3 = 3
362+#define INVALID_SUSPEND_ID -1
363+#define T_FW_SWITCH_S 60
364+
365+enum mtk_plmn_type {
366+ MTK_PLMN_TYPE_UNKNOWN = 0,
367+ MTK_PLMN_TYPE_1,
368+ MTK_PLMN_TYPE_2,
369+ MTK_PLMN_TYPE_3
370 };
371
372 static const char hex_slot_0[] = "Slot 0: ";
373@@ -136,6 +141,14 @@
374 int fw_type;
375 ofono_modem_online_cb_t online_cb;
376 void *online_data;
377+ enum mtk_plmn_type sim_plmn_type;
378+ enum mtk_plmn_type sensed_plmn_type;
379+ int suspend_id;
380+ ofono_bool_t trm_pending;
381+ unsigned netreg_watch;
382+ unsigned status_watch;
383+ int netreg_status;
384+ guint switch_fw_id;
385 };
386
387 /*
388@@ -329,7 +342,7 @@
389 exec_online_callback(md);
390 }
391
392-static void reg_suspended_cb(struct ril_msg *message, gpointer user_data)
393+static void resume_reg_cb(struct ril_msg *message, gpointer user_data)
394 {
395 struct ofono_modem *modem = user_data;
396 struct mtk_data *md = ofono_modem_get_data(modem);
397@@ -343,24 +356,21 @@
398 g_ril_print_response_no_args(md->ril, message);
399 }
400
401-static void reg_suspended(struct ril_msg *message, gpointer user_data)
402+static void resume_reg(struct ofono_modem *modem)
403 {
404- struct ofono_modem *modem = user_data;
405 struct mtk_data *md = ofono_modem_get_data(modem);
406 struct parcel rilp;
407- int session_id;
408
409- session_id = g_mtk_unsol_parse_registration_suspended(md->ril, message);
410- if (session_id < 0) {
411- ofono_error("%s: parse error", __func__);
412+ if (md->suspend_id == INVALID_SUSPEND_ID)
413 return;
414- }
415
416- g_mtk_request_resume_registration(md->ril, session_id, &rilp);
417+ g_mtk_request_resume_registration(md->ril, md->suspend_id, &rilp);
418
419 if (g_ril_send(md->ril, MTK_RIL_REQUEST_RESUME_REGISTRATION, &rilp,
420- reg_suspended_cb, modem, NULL) == 0)
421+ resume_reg_cb, modem, NULL) == 0)
422 ofono_error("%s: failure sending request", __func__);
423+
424+ md->suspend_id = INVALID_SUSPEND_ID;
425 }
426
427 static void sim_removed(struct ril_msg *message, gpointer user_data)
428@@ -372,6 +382,8 @@
429
430 g_ril_print_unsol_no_args(md->ril, message);
431
432+ md->sim_plmn_type = MTK_PLMN_TYPE_UNKNOWN;
433+
434 ofono_modem_set_powered(modem, FALSE);
435 g_idle_add(mtk_connected, modem);
436 }
437@@ -403,16 +415,6 @@
438 }
439
440 g_ril_print_response_no_args(md->ril, message);
441-
442- /*
443- * rild will close now the socket, so we set our state to power off:
444- * we will set the modem to powered when we reconnect to the socket.
445- * Measurements showed that rild takes around 5 seconds to re-start, but
446- * we use an 8 seconds timeout as times can vary and that value is also
447- * compatible with krillin modem.
448- */
449- md->ofono_online = FALSE;
450- ofono_modem_set_powered(md->modem, FALSE);
451 }
452
453 static void store_type_cb(struct ril_msg *message, gpointer user_data)
454@@ -420,10 +422,12 @@
455 struct ofono_modem *modem = user_data;
456 struct mtk_data *md = ofono_modem_get_data(modem);
457 struct parcel rilp;
458+ int trm = 0;
459
460 if (message->error != RIL_E_SUCCESS) {
461 ofono_error("%s: RIL error %s", __func__,
462 ril_error_to_string(message->error));
463+ md->trm_pending = FALSE;
464 return;
465 }
466
467@@ -431,13 +435,30 @@
468
469 /*
470 * Send SET_TRM, which reloads the FW. We do not know the meaning of the
471- * magic number 0x0B.
472+ * magic TRM numbers (no source code for muxreport daemon).
473 */
474- g_mtk_request_set_trm(md->ril, 0x0B, &rilp);
475+ if (md->fw_type == MTK_MD_TYPE_LWG) {
476+ trm = 11;
477+ } else if (md->fw_type == MTK_MD_TYPE_LTG) {
478+ trm = 12;
479+ } else {
480+ ofono_error("%s: wrong modem type %d", __func__, md->fw_type);
481+ g_assert(FALSE);
482+ }
483+
484+ g_mtk_request_set_trm(md->ril, trm, &rilp);
485
486 if (g_ril_send(md->ril, MTK_RIL_REQUEST_SET_TRM, &rilp,
487 set_trm_cb, modem, NULL) == 0)
488 ofono_error("%s: failure sending request", __func__);
489+
490+ /*
491+ * rild will close now the socket, and the response to SET_TRM might be
492+ * received before that or not.
493+ * Measurements showed that rild takes around 5 seconds to re-start, but
494+ * we use an 8 seconds timeout as times can vary and that value is also
495+ * compatible with krillin modem.
496+ */
497 }
498
499 static gboolean find_in_table(const char *str,
500@@ -452,45 +473,65 @@
501 return FALSE;
502 }
503
504-static enum mtk_sim_type sim_type_for_fw_loading(const char *imsi)
505+static enum mtk_plmn_type get_plmn_type(const char *code)
506 {
507- /* China Mobile MCC/MNC codes */
508+ /* China Mobile (CMCC) MCC/MNC codes */
509 const char *table_type1[] = { "46000", "46002", "46007" };
510- /* China Unicom and China Telecom MCC/MNC codes */
511+ /* China Unicom (CU) and China Telecom MCC/MNC codes */
512 const char *table_type3[] =
513 { "46001", "46006", "46009", "45407", "46005", "45502" };
514
515- if (find_in_table(imsi, table_type1,
516- sizeof(table_type1)/sizeof(table_type1[0])))
517- return MTK_SIM_TYPE_1;
518-
519- if (find_in_table(imsi, table_type3,
520- sizeof(table_type3)/sizeof(table_type3[0])))
521- return MTK_SIM_TYPE_3;
522-
523- return MTK_SIM_TYPE_2;
524+ if (find_in_table(code, table_type1, G_N_ELEMENTS(table_type1)))
525+ return MTK_PLMN_TYPE_1;
526+
527+ if (find_in_table(code, table_type3, G_N_ELEMENTS(table_type3)))
528+ return MTK_PLMN_TYPE_3;
529+
530+ return MTK_PLMN_TYPE_2;
531 }
532
533-static int sim_modem_fw(const char *imsi)
534+static int select_modem_fw(enum mtk_plmn_type sim_plmn_type,
535+ enum mtk_plmn_type sensed_plmn_type)
536 {
537- enum mtk_sim_type sim_type;
538- int sim_fw = MTK_MD_TYPE_LWG;
539+ DBG("PLMN (sim, sensed)=(%d, %d)", sim_plmn_type, sensed_plmn_type);
540
541- /* Find out our SIM type */
542- sim_type = sim_type_for_fw_loading(imsi);
543- switch (sim_type) {
544- case MTK_SIM_TYPE_1:
545- /* LTE TDD - TD-SCDMA - GSM */
546- sim_fw = MTK_MD_TYPE_LTG;
547- break;
548- case MTK_SIM_TYPE_2:
549- case MTK_SIM_TYPE_3:
550- /* LTE FDD - WCDMA - GSM */
551- sim_fw = MTK_MD_TYPE_LWG;
552- break;
553+ /*
554+ * Outside China (sensed t2) -> FDD always
555+ * In China (sensed t1, t3) -> sim t1 is TDD, t2 or t3 is FDD,
556+ * or wait for imsi to know sim type
557+ * Unknown country -> sim t2 or t3 are FDD, wait network if t1, wait
558+ * network/imsi events if both unknown
559+ */
560+ switch (sensed_plmn_type) {
561+ case MTK_PLMN_TYPE_2:
562+ return MTK_MD_TYPE_LWG;
563+ case MTK_PLMN_TYPE_1:
564+ case MTK_PLMN_TYPE_3:
565+ switch (sim_plmn_type) {
566+ case MTK_PLMN_TYPE_1:
567+ return MTK_MD_TYPE_LTG;
568+ case MTK_PLMN_TYPE_2:
569+ case MTK_PLMN_TYPE_3:
570+ return MTK_MD_TYPE_LWG;
571+ case MTK_PLMN_TYPE_UNKNOWN:
572+ return MTK_MD_TYPE_INVALID;
573+ };
574+ case MTK_PLMN_TYPE_UNKNOWN:
575+ switch (sim_plmn_type) {
576+ case MTK_PLMN_TYPE_2:
577+ case MTK_PLMN_TYPE_3:
578+ return MTK_MD_TYPE_LWG;
579+ case MTK_PLMN_TYPE_1:
580+ case MTK_PLMN_TYPE_UNKNOWN:
581+ return MTK_MD_TYPE_INVALID;
582+ };
583 };
584
585- return sim_fw;
586+ /* We should never arrive here */
587+ ofono_error("%s: UNREACHABLE POINT REACHED, aborting", __func__);
588+ g_assert(FALSE);
589+
590+ return MTK_MD_TYPE_INVALID;
591 }
592
593 static void set_fw_type(struct ofono_modem *modem, int type)
594@@ -504,29 +545,210 @@
595 ofono_modem_set_boolean(modem, MODEM_PROP_LTE_CAPABLE, lte_cap);
596 }
597
598+static const char *fw_type_to_str(int fw_type)
599+{
600+ switch (fw_type) {
601+ case MTK_MD_TYPE_2G:
602+ return "2G";
603+ case MTK_MD_TYPE_3G:
604+ return "3G";
605+ case MTK_MD_TYPE_WG:
606+ return "WG";
607+ case MTK_MD_TYPE_TG:
608+ return "TG";
609+ case MTK_MD_TYPE_LWG:
610+ return "LWG";
611+ case MTK_MD_TYPE_LTG:
612+ return "LTG";
613+ case MTK_MD_TYPE_LTNG:
614+ return "LTNG";
615+ }
616+
617+ return "<INVALID>";
618+}
619+
620+static void switch_fw(struct ofono_modem *modem, int fw_type)
621+{
622+ struct mtk_data *md = ofono_modem_get_data(modem);
623+ struct parcel rilp;
624+
625+ ofono_info("Switching modem FW from %s to %s",
626+ fw_type_to_str(md->fw_type), fw_type_to_str(fw_type));
627+
628+ md->trm_pending = TRUE;
629+
630+ set_fw_type(modem, fw_type);
631+
632+ g_mtk_request_store_modem_type(md->ril, fw_type, &rilp);
633+
634+ if (g_ril_send(md->ril, MTK_RIL_REQUEST_STORE_MODEM_TYPE, &rilp,
635+ store_type_cb, modem, NULL) == 0) {
636+ ofono_error("%s: failure sending request", __func__);
637+ md->trm_pending = FALSE;
638+ }
639+}
640+
641 static void check_modem_fw(struct ofono_modem *modem)
642 {
643 struct mtk_data *md = ofono_modem_get_data(modem);
644- int sim_type;
645- struct parcel rilp;
646+ int best_fw;
647
648 /* We handle only LWG <-> LTG modem fw changes (arale case) */
649 if (md->fw_type != MTK_MD_TYPE_LTG && md->fw_type != MTK_MD_TYPE_LWG)
650 return;
651
652- /* Right modem fw type for our SIM */
653- sim_type = sim_modem_fw(ofono_sim_get_imsi(md->sim));
654-
655- if (md->fw_type == sim_type)
656- return;
657-
658- set_fw_type(modem, sim_type);
659-
660- g_mtk_request_store_modem_type(md->ril, sim_type, &rilp);
661-
662- if (g_ril_send(md->ril, MTK_RIL_REQUEST_STORE_MODEM_TYPE, &rilp,
663- store_type_cb, modem, NULL) == 0)
664- ofono_error("%s: failure sending request", __func__);
665+ if (md->trm_pending) {
666+ DBG("TRM pending, returning");
667+ return;
668+ }
669+
670+ /* Right modem fw type for our SIM/sensed PLMN */
671+ best_fw = select_modem_fw(md->sim_plmn_type, md->sensed_plmn_type);
672+
673+ DBG("Modem type selected is %d", best_fw);
674+
675+ /* Best FW not known yet: wait for imsi/sensed network */
676+ if (best_fw == MTK_MD_TYPE_INVALID)
677+ return;
678+
679+ if (md->fw_type == best_fw) {
680+ resume_reg(modem);
681+ return;
682+ }
683+
684+ /* We need to reload FW and reset transactionally */
685+ switch_fw(modem, best_fw);
686+}
687+
688+static void plmn_changed(struct ril_msg *message, gpointer user_data)
689+{
690+ struct ofono_modem *modem = user_data;
691+ struct mtk_data *md = ofono_modem_get_data(modem);
692+ struct parcel_str_array *plmns;
693+
694+ plmns = g_mtk_unsol_parse_plmn_changed(md->ril, message);
695+ if (plmns == NULL) {
696+ ofono_error("%s: parse error", __func__);
697+ return;
698+ }
699+
700+ md->sensed_plmn_type = get_plmn_type(plmns->str[0]);
701+
702+ DBG("Best PLMN is %s (type %d)", plmns->str[0], md->sensed_plmn_type);
703+
704+ parcel_free_str_array(plmns);
705+
706+ check_modem_fw(modem);
707+}
708+
709+static void reg_suspended(struct ril_msg *message, gpointer user_data)
710+{
711+ struct ofono_modem *modem = user_data;
712+ struct mtk_data *md = ofono_modem_get_data(modem);
713+ int suspend_id;
714+
715+ suspend_id = g_mtk_unsol_parse_registration_suspended(md->ril, message);
716+ if (suspend_id < 0) {
717+ ofono_error("%s: parse error", __func__);
718+ return;
719+ }
720+
721+ md->suspend_id = suspend_id;
722+
723+ check_modem_fw(modem);
724+}
725+
726+static gboolean tout_not_registered(gpointer user_data)
727+{
728+ struct ofono_modem *modem = user_data;
729+ struct mtk_data *md = ofono_modem_get_data(modem);
730+
731+ if (md->trm_pending)
732+ goto end;
733+
734+ DBG("type was %d", md->fw_type);
735+
736+ if (md->fw_type == MTK_MD_TYPE_LTG)
737+ switch_fw(modem, MTK_MD_TYPE_LWG);
738+ else
739+ switch_fw(modem, MTK_MD_TYPE_LTG);
740+
741+end:
742+ md->switch_fw_id = 0;
743+
744+ return FALSE;
745+}
746+
747+static void cancel_fw_load_timer(struct mtk_data *md)
748+{
749+ if (md->switch_fw_id) {
750+ g_source_remove(md->switch_fw_id);
751+ md->switch_fw_id = 0;
752+ }
753+}
754+
755+static void netreg_status_update(struct ofono_modem *modem)
756+{
757+ struct mtk_data *md = ofono_modem_get_data(modem);
758+
759+ if (md->sim_plmn_type != MTK_PLMN_TYPE_1)
760+ return;
761+
762+ if (md->fw_type != MTK_MD_TYPE_LTG && md->fw_type != MTK_MD_TYPE_LWG)
763+ return;
764+
765+ DBG("%d", md->netreg_status);
766+
767+ if (md->switch_fw_id) {
768+ if (md->netreg_status == NETWORK_REGISTRATION_STATUS_REGISTERED
769+ || md->netreg_status ==
770+ NETWORK_REGISTRATION_STATUS_ROAMING)
771+ cancel_fw_load_timer(md);
772+ return;
773+ }
774+
775+ if (md->netreg_status == NETWORK_REGISTRATION_STATUS_NOT_REGISTERED)
776+ md->switch_fw_id = g_timeout_add_seconds(T_FW_SWITCH_S,
777+ tout_not_registered, modem);
778+}
779+
780+static void netreg_status_changed(int status, int lac, int ci, int tech,
781+ const char *mcc, const char *mnc,
782+ void *data)
783+{
784+ struct ofono_modem *modem = data;
785+ struct mtk_data *md = ofono_modem_get_data(modem);
786+
787+ if (md->netreg_status == status)
788+ return;
789+
790+ md->netreg_status = status;
791+
792+ netreg_status_update(modem);
793+}
794+
795+static void netreg_watch(struct ofono_atom *atom,
796+ enum ofono_atom_watch_condition cond,
797+ void *data)
798+{
799+ struct ofono_modem *modem = data;
800+ struct mtk_data *md = ofono_modem_get_data(modem);
801+ void *netreg;
802+
803+ DBG("%d", cond);
804+
805+ if (cond == OFONO_ATOM_WATCH_CONDITION_UNREGISTERED) {
806+ cancel_fw_load_timer(md);
807+ md->status_watch = 0;
808+ return;
809+ }
810+
811+ netreg = __ofono_atom_get_data(atom);
812+ md->netreg_status = ofono_netreg_get_status(netreg);
813+ md->status_watch = __ofono_netreg_add_status_watch(netreg,
814+ netreg_status_changed, modem, NULL);
815+
816+ netreg_status_update(modem);
817 }
818
819 static int mtk_probe(struct ofono_modem *modem)
820@@ -540,6 +762,7 @@
821
822 md->ofono_online = FALSE;
823 md->radio_state = RADIO_STATE_UNAVAILABLE;
824+ md->suspend_id = INVALID_SUSPEND_ID;
825
826 md->slot = ofono_modem_get_integer(modem, "Slot");
827
828@@ -615,9 +838,7 @@
829
830 /*
831 * TODO: this function should setup:
832- * - phonebook
833 * - stk ( SIM toolkit )
834- * - radio_settings
835 */
836 md->sms = ofono_sms_create(modem, OFONO_RIL_VENDOR_MTK,
837 RILMODEM, md->ril);
838@@ -665,8 +886,10 @@
839
840 /*
841 * Now that we can access IMSI, see if a FW change is needed.
842- * TODO: Roaming case and timeout case when no network is found.
843 */
844+
845+ md->sim_plmn_type = get_plmn_type(ofono_sim_get_imsi(md->sim));
846+
847 check_modem_fw(modem);
848
849 } else if (new_state == OFONO_SIM_STATE_LOCKED_OUT) {
850@@ -728,6 +951,12 @@
851 /* Radio settings does not depend on the SIM */
852 ofono_radio_settings_create(modem, OFONO_RIL_VENDOR_MTK,
853 MTKMODEM, &rs_data);
854+
855+ if (md->netreg_watch == 0)
856+ md->netreg_watch =
857+ __ofono_modem_add_atom_watch(modem,
858+ OFONO_ATOM_TYPE_NETREG,
859+ netreg_watch, modem, NULL);
860 }
861
862 static void query_type_cb(struct ril_msg *message, gpointer user_data)
863@@ -936,11 +1165,15 @@
864 if (message->error == RIL_E_SUCCESS) {
865 g_ril_print_response_no_args(md->ril, message);
866
867- if (disconnect_expected)
868+ if (disconnect_expected) {
869+ if (not_disconn_cb_id != 0)
870+ g_source_remove(not_disconn_cb_id);
871+
872 not_disconn_cb_id = g_timeout_add(T_WAIT_DISCONN_MS,
873 no_disconnect_case, cbd);
874- else
875+ } else {
876 mtk_send_sim_mode(mtk_sim_mode_cb, cbd);
877+ }
878 } else {
879 ofono_error("%s RADIO_POWERON error %s", __func__,
880 ril_error_to_string(message->error));
881@@ -1072,7 +1305,9 @@
882 mtk_data_0->pending_cbd = cbd;
883 }
884 } else if (next_state == NO_SIM_ACTIVE) {
885- if (power_on_off(mtk_data_0->ril, FALSE, cbd))
886+ /* Disconnection expected for dual SIM only */
887+ if (power_on_off(mtk_data_0->ril, FALSE, cbd)
888+ && mtk_data_1 != NULL)
889 disconnect_expected = TRUE;
890 } else {
891 mtk_send_sim_mode(mtk_sim_mode_cb, cbd);
892@@ -1272,6 +1507,14 @@
893 g_ril_unref(md->ril);
894 md->ril = NULL;
895
896+ md->sensed_plmn_type = MTK_PLMN_TYPE_UNKNOWN;
897+ md->suspend_id = INVALID_SUSPEND_ID;
898+ if (md->trm_pending) {
899+ md->ofono_online = FALSE;
900+ ofono_modem_set_powered(md->modem, FALSE);
901+ md->trm_pending = FALSE;
902+ }
903+
904 /* Disconnection happened so we do not call failsafe function */
905 if (not_disconn_cb_id != 0) {
906 g_source_remove(not_disconn_cb_id);
907@@ -1338,6 +1581,8 @@
908 RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED,
909 radio_state_changed, sock);
910
911+ g_ril_register(sock->ril, MTK_RIL_UNSOL_RESPONSE_PLMN_CHANGED,
912+ plmn_changed, modem);
913 g_ril_register(sock->ril, MTK_RIL_UNSOL_RESPONSE_REGISTRATION_SUSPENDED,
914 reg_suspended, modem);
915
916@@ -1414,6 +1659,11 @@
917 return 0;
918 }
919
920+static ofono_bool_t mtk_is_standby(struct ofono_modem *modem)
921+{
922+ return TRUE;
923+}
924+
925 static struct ofono_modem_driver mtk_driver = {
926 .name = "mtk",
927 .probe = mtk_probe,
928@@ -1424,6 +1674,7 @@
929 .post_sim = mtk_post_sim,
930 .post_online = mtk_post_online,
931 .set_online = mtk_set_online,
932+ .is_standby = mtk_is_standby,
933 };
934
935 static int mtk_init(void)
936
937=== modified file 'plugins/ubuntu-apndb.c'
938--- plugins/ubuntu-apndb.c 2014-09-22 22:04:15 +0000
939+++ plugins/ubuntu-apndb.c 2015-04-06 14:34:59 +0000
940@@ -191,10 +191,14 @@
941 * - mms
942 */
943
944- if (g_strcmp0(types, "mms") == 0)
945+ /* Default apns can be used for mms and ia, mms can be used for ia */
946+ if (types == NULL || g_strcmp0(types, "*") == 0
947+ || strstr(types, "default") != NULL)
948+ return OFONO_GPRS_CONTEXT_TYPE_INTERNET;
949+ else if (strstr(types, "mms") != NULL)
950 return OFONO_GPRS_CONTEXT_TYPE_MMS;
951- else if (g_str_has_prefix(types, "default"))
952- return OFONO_GPRS_CONTEXT_TYPE_INTERNET;
953+ else if (strstr(types, "ia") != NULL)
954+ return OFONO_GPRS_CONTEXT_TYPE_IA;
955 else
956 return OFONO_GPRS_CONTEXT_TYPE_ANY;
957 }
958@@ -338,12 +342,6 @@
959 return;
960 }
961
962- if (types == NULL) {
963- ofono_error("%s: apn for %s missing type attribute", __func__,
964- carrier);
965- return;
966- }
967-
968 if (protocol != NULL) {
969 if (g_strcmp0(protocol, "IP") == 0) {
970 proto = OFONO_GPRS_PROTO_IP;
971@@ -401,7 +399,8 @@
972
973 if (type == OFONO_GPRS_CONTEXT_TYPE_ANY ||
974 (type == OFONO_GPRS_CONTEXT_TYPE_MMS && mmscenter == NULL)) {
975- DBG("Skipping %s context; types: %s", apn, types);
976+ DBG("Skipping %s context; types: %s",
977+ apn, types ? types : "(null)");
978 return;
979 }
980
981
982=== modified file 'src/common.c'
983--- src/common.c 2013-11-15 23:15:52 +0000
984+++ src/common.c 2015-04-06 14:34:59 +0000
985@@ -725,7 +725,7 @@
986 int i;
987 int last_period = 0;
988
989- if (apn[0] == '.' || apn[0] == '\0')
990+ if (apn[0] == '.')
991 return FALSE;
992
993 for (i = 0; apn[i] != '\0'; i++) {
994
995=== modified file 'src/gprs.c'
996--- src/gprs.c 2015-02-04 00:09:22 +0000
997+++ src/gprs.c 2015-04-06 14:34:59 +0000
998@@ -124,6 +124,7 @@
999 struct pri_context {
1000 ofono_bool_t active;
1001 enum ofono_gprs_context_type type;
1002+ gboolean preferred;
1003 char name[MAX_CONTEXT_NAME_LENGTH + 1];
1004 char message_proxy[MAX_MESSAGE_PROXY_LENGTH + 1];
1005 char message_center[MAX_MESSAGE_CENTER_LENGTH + 1];
1006@@ -758,7 +759,7 @@
1007 const char *type = gprs_context_type_to_string(ctx->type);
1008 const char *proto = gprs_proto_to_string(ctx->context.proto);
1009 const char *name = ctx->name;
1010- dbus_bool_t value;
1011+ dbus_bool_t value, preferred;
1012 const char *strvalue;
1013 struct context_settings *settings;
1014
1015@@ -767,6 +768,9 @@
1016 value = ctx->active;
1017 ofono_dbus_dict_append(dict, "Active", DBUS_TYPE_BOOLEAN, &value);
1018
1019+ preferred = ctx->preferred;
1020+ ofono_dbus_dict_append(dict, "Preferred", DBUS_TYPE_BOOLEAN, &preferred);
1021+
1022 ofono_dbus_dict_append(dict, "Type", DBUS_TYPE_STRING, &type);
1023
1024 ofono_dbus_dict_append(dict, "Protocol", DBUS_TYPE_STRING, &proto);
1025@@ -892,6 +896,33 @@
1026 "Active", DBUS_TYPE_BOOLEAN, &value);
1027 }
1028
1029+static DBusMessage *pri_set_preferred(struct pri_context *ctx,
1030+ DBusConnection *conn,
1031+ DBusMessage *msg, gboolean preferred)
1032+{
1033+ GKeyFile *settings = ctx->gprs->settings;
1034+
1035+ if (ctx->preferred == preferred)
1036+ return dbus_message_new_method_return(msg);
1037+
1038+ ctx->preferred = preferred;
1039+
1040+ if (settings) {
1041+ g_key_file_set_boolean(settings, ctx->key, "Preferred",
1042+ preferred);
1043+ storage_sync(ctx->gprs->imsi, SETTINGS_STORE, settings);
1044+ }
1045+
1046+ g_dbus_send_reply(conn, msg, DBUS_TYPE_INVALID);
1047+
1048+ ofono_dbus_signal_property_changed(conn, ctx->path,
1049+ OFONO_CONNECTION_CONTEXT_INTERFACE,
1050+ "Preferred", DBUS_TYPE_BOOLEAN,
1051+ &preferred);
1052+
1053+ return NULL;
1054+}
1055+
1056 static DBusMessage *pri_set_apn(struct pri_context *ctx, DBusConnection *conn,
1057 DBusMessage *msg, const char *apn)
1058 {
1059@@ -1190,6 +1221,15 @@
1060 return NULL;
1061 }
1062
1063+ if (!strcmp(property, "Preferred")) {
1064+ if (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_BOOLEAN)
1065+ return __ofono_error_invalid_args(msg);
1066+
1067+ dbus_message_iter_get_basic(&var, &value);
1068+
1069+ return pri_set_preferred(ctx, conn, msg, value);
1070+ }
1071+
1072 /* All other properties are read-only when context is active */
1073 if (ctx->active == TRUE)
1074 return __ofono_error_in_use(msg);
1075@@ -1593,6 +1633,58 @@
1076 gprs_netreg_update(gprs);
1077 }
1078
1079+static void notify_connection_powered(struct ofono_modem *modem, void *data)
1080+{
1081+ struct ofono_atom *atom;
1082+ struct ofono_gprs *gprs;
1083+ struct ofono_modem *modem_notif = data;
1084+ DBusConnection *conn;
1085+ const char *path = ofono_modem_get_path(modem);
1086+
1087+ if (strcmp(path, ofono_modem_get_path(modem_notif)) == 0)
1088+ return;
1089+
1090+ if (!ofono_modem_is_standby(modem))
1091+ return;
1092+
1093+ atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_GPRS);
1094+ if (atom == NULL)
1095+ return;
1096+
1097+ gprs = __ofono_atom_get_data(atom);
1098+
1099+ if (gprs->driver->set_attached == NULL)
1100+ return;
1101+
1102+ if (gprs->powered == FALSE)
1103+ return;
1104+
1105+ gprs->powered = FALSE;
1106+
1107+ if (gprs->settings) {
1108+ g_key_file_set_integer(gprs->settings, SETTINGS_GROUP,
1109+ "Powered", gprs->powered);
1110+ storage_sync(gprs->imsi, SETTINGS_STORE, gprs->settings);
1111+ }
1112+
1113+ gprs_netreg_update(gprs);
1114+
1115+ conn = ofono_dbus_get_connection();
1116+ ofono_dbus_signal_property_changed(conn, path,
1117+ OFONO_CONNECTION_MANAGER_INTERFACE,
1118+ "Powered", DBUS_TYPE_BOOLEAN,
1119+ &gprs->powered);
1120+}
1121+
1122+static void notify_powered_change(struct ofono_gprs *gprs)
1123+{
1124+ if (gprs->powered) {
1125+ struct ofono_modem *modem = __ofono_atom_get_modem(gprs->atom);
1126+
1127+ __ofono_modem_foreach(notify_connection_powered, modem);
1128+ }
1129+}
1130+
1131 static DBusMessage *gprs_get_properties(DBusConnection *conn,
1132 DBusMessage *msg, void *data)
1133 {
1134@@ -1709,6 +1801,8 @@
1135 }
1136
1137 gprs_netreg_update(gprs);
1138+
1139+ notify_powered_change(gprs);
1140 } else {
1141 return __ofono_error_invalid_args(msg);
1142 }
1143@@ -1736,6 +1830,8 @@
1144 gprs_context_type_to_string(context->type));
1145 g_key_file_set_string(gprs->settings, context->key, "Protocol",
1146 gprs_proto_to_string(context->context.proto));
1147+ g_key_file_set_boolean(gprs->settings, context->key, "Preferred",
1148+ context->preferred);
1149
1150 if (context->type == OFONO_GPRS_CONTEXT_TYPE_MMS ||
1151 (context->message_center && strlen(context->message_center) > 0)) {
1152@@ -2690,6 +2786,7 @@
1153 char *msgcenter = NULL;
1154 gboolean ret = FALSE;
1155 gboolean legacy = FALSE;
1156+ gboolean preferred;
1157 struct pri_context *context;
1158 enum ofono_gprs_context_type type;
1159 enum ofono_gprs_proto proto;
1160@@ -2724,6 +2821,9 @@
1161 if (gprs_proto_from_string(protostr, &proto) == FALSE)
1162 goto error;
1163
1164+ preferred = g_key_file_get_boolean(gprs->settings, group,
1165+ "Preferred", NULL);
1166+
1167 username = g_key_file_get_string(gprs->settings, group,
1168 "Username", NULL);
1169 if (username == NULL)
1170@@ -2775,6 +2875,7 @@
1171 strcpy(context->context.password, password);
1172 strcpy(context->context.apn, apn);
1173 context->context.proto = proto;
1174+ context->preferred = preferred;
1175
1176 if (msgproxy != NULL)
1177 strcpy(context->message_proxy, msgproxy);
1178@@ -2838,6 +2939,8 @@
1179 "Powered", gprs->powered);
1180 }
1181
1182+ notify_powered_change(gprs);
1183+
1184 error = NULL;
1185 gprs->roaming_allowed = g_key_file_get_boolean(gprs->settings,
1186 SETTINGS_GROUP,
1187
1188=== modified file 'src/modem.c'
1189--- src/modem.c 2015-01-29 13:48:44 +0000
1190+++ src/modem.c 2015-04-06 14:34:59 +0000
1191@@ -2256,3 +2256,11 @@
1192 out:
1193 modem->emergency--;
1194 }
1195+
1196+ofono_bool_t ofono_modem_is_standby(struct ofono_modem *modem)
1197+{
1198+ if (modem->driver->is_standby == NULL)
1199+ return FALSE;
1200+
1201+ return modem->driver->is_standby(modem);
1202+}
1203
1204=== modified file 'unit/test-common.c'
1205--- unit/test-common.c 2011-10-10 20:40:17 +0000
1206+++ unit/test-common.c 2015-04-06 14:34:59 +0000
1207@@ -146,6 +146,7 @@
1208 "wap.cingular",
1209 "vodafone.co.uk",
1210 "vodafone.com",
1211+ "",
1212 NULL
1213 };
1214
1215@@ -154,7 +155,6 @@
1216 "..",
1217 "f..f",
1218 "foo.bar.#",
1219- "",
1220 NULL
1221 };
1222
1223
1224=== modified file 'unit/test-mtkunsol.c'
1225--- unit/test-mtkunsol.c 2015-01-28 07:52:59 +0000
1226+++ unit/test-mtkunsol.c 2015-04-06 14:34:59 +0000
1227@@ -92,6 +92,44 @@
1228 .error = 0,
1229 };
1230
1231+/*
1232+ * The following hexadecimal data represents a serialized Binder parcel instance
1233+ * containing a valid MTK_RIL_UNSOL_RESPONSE_PLMN_CHANGED message with the
1234+ * following parameters:
1235+ *
1236+ * {21401}
1237+ */
1238+static const guchar unsol_plmn_changed_parcel1[] = {
1239+ 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x32, 0x00, 0x31, 0x00,
1240+ 0x34, 0x00, 0x30, 0x00, 0x31, 0x00, 0x00, 0x00
1241+};
1242+
1243+static const struct ril_msg unsol_plmn_changed_valid_1 = {
1244+ .buf = (gchar *) &unsol_plmn_changed_parcel1,
1245+ .buf_len = sizeof(unsol_plmn_changed_parcel1),
1246+ .unsolicited = TRUE,
1247+ .req = MTK_RIL_UNSOL_RESPONSE_PLMN_CHANGED,
1248+ .serial_no = 0,
1249+ .error = 0,
1250+};
1251+
1252+/*
1253+ * The following hexadecimal data represents a serialized Binder parcel instance
1254+ * containing a MTK_RIL_UNSOL_RESPONSE_PLMN_CHANGED message with no strings.
1255+ */
1256+static const guchar unsol_plmn_changed_parcel2[] = {
1257+ 0x00, 0x00, 0x00, 0x00
1258+};
1259+
1260+static const struct ril_msg unsol_plmn_changed_invalid_1 = {
1261+ .buf = (gchar *) &unsol_plmn_changed_parcel2,
1262+ .buf_len = sizeof(unsol_plmn_changed_parcel2),
1263+ .unsolicited = TRUE,
1264+ .req = MTK_RIL_UNSOL_RESPONSE_PLMN_CHANGED,
1265+ .serial_no = 0,
1266+ .error = 0,
1267+};
1268+
1269 static void test_unsol_incoming_call_indication_valid(gconstpointer data)
1270 {
1271 struct unsol_call_indication *unsol;
1272@@ -113,6 +151,25 @@
1273 g_assert(suspended > 0);
1274 }
1275
1276+static void test_unsol_plmn_changed_valid(gconstpointer data)
1277+{
1278+ struct parcel_str_array *plmns;
1279+
1280+ plmns = g_mtk_unsol_parse_plmn_changed(NULL, (struct ril_msg *) data);
1281+
1282+ g_assert(plmns != NULL);
1283+ parcel_free_str_array(plmns);
1284+}
1285+
1286+static void test_unsol_plmn_changed_invalid(gconstpointer data)
1287+{
1288+ struct parcel_str_array *plmns;
1289+
1290+ plmns = g_mtk_unsol_parse_plmn_changed(NULL, (struct ril_msg *) data);
1291+
1292+ g_assert(plmns == NULL);
1293+}
1294+
1295 #endif /* LITTLE_ENDIAN */
1296
1297 int main(int argc, char **argv)
1298@@ -137,6 +194,16 @@
1299 &unsol_registration_suspended_valid_1,
1300 test_unsol_registration_suspended_valid);
1301
1302+ g_test_add_data_func("/testmtkunsol/fw: "
1303+ "valid RESPONSE_PLMN_CHANGED Test 1",
1304+ &unsol_plmn_changed_valid_1,
1305+ test_unsol_plmn_changed_valid);
1306+
1307+ g_test_add_data_func("/testmtkunsol/fw: "
1308+ "invalid RESPONSE_PLMN_CHANGED Test 1",
1309+ &unsol_plmn_changed_invalid_1,
1310+ test_unsol_plmn_changed_invalid);
1311+
1312 #endif /* LITTLE_ENDIAN */
1313
1314 return g_test_run();

Subscribers

People subscribed via source and target branches

to all changes: