Merge lp:~rsalveti/ofono/gprs-attach-fix into lp:~phablet-team/ofono/ubuntu

Proposed by Ricardo Salveti
Status: Merged
Merged at revision: 6838
Proposed branch: lp:~rsalveti/ofono/gprs-attach-fix
Merge into: lp:~phablet-team/ofono/ubuntu
Diff against target: 260 lines (+93/-39)
2 files modified
drivers/rilmodem/gprs-context.c (+21/-16)
drivers/rilmodem/gprs.c (+72/-23)
To merge this branch: bzr merge lp:~rsalveti/ofono/gprs-attach-fix
Reviewer Review Type Date Requested Status
Dave Morley (community) tested it in real life on maguro Approve
Alfonso Sanchez-Beato Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+191331@code.launchpad.net

Commit message

Fix GPRS attach/detach logic (offline/online)

Description of the change

Fix GPRS attach/detach logic

Previously the modem would always show itself as attached, even after disabling gprs.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
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 :

Tested the branch in the following way:

* Cover the phone with tin foil
* Put it in an oven

The phone loses coverage, but after a few seconds it recovers the data connection.

review: Approve
Revision history for this message
Dave Morley (davmor2) wrote :

Test the fix on maguro. This fix meant I had consistent 3g ofono conncetion.

review: Approve (tested it in real life on maguro)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'drivers/rilmodem/gprs-context.c'
2--- drivers/rilmodem/gprs-context.c 2013-09-09 19:21:32 +0000
3+++ drivers/rilmodem/gprs-context.c 2013-10-16 03:46:52 +0000
4@@ -53,7 +53,7 @@
5
6 struct gprs_context_data {
7 GRil *ril;
8- guint active_ctx_cid;
9+ gint active_ctx_cid;
10 gint active_rild_cid;
11 enum state state;
12 };
13@@ -66,8 +66,8 @@
14 {
15 DBG("");
16
17- gcd->active_ctx_cid = -1;
18- gcd->active_rild_cid = -1;
19+ gcd->active_ctx_cid = 0;
20+ gcd->active_rild_cid = 0;
21 gcd->state = STATE_IDLE;
22 }
23
24@@ -100,14 +100,17 @@
25 for (iterator = unsol->call_list; iterator; iterator = iterator->next) {
26 call = (struct data_call *) iterator->data;
27
28- if (call->cid == gcd->active_rild_cid) {
29+ if (call->cid == gcd->active_rild_cid &&
30+ gcd->state != STATE_IDLE) {
31 DBG("Found current call in call list: %d", call->cid);
32 active_cid_found = TRUE;
33
34 if (call->active == 0) {
35- DBG("call->status is DISCONNECTED for cid: %d", call->cid);
36+ DBG("call->status is DISCONNECTED for cid: %d",
37+ call->cid);
38 disconnect = TRUE;
39- ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
40+ ofono_gprs_context_deactivated(gc,
41+ gcd->active_ctx_cid);
42 }
43
44 break;
45@@ -149,9 +152,8 @@
46 gcd->active_rild_cid = reply->cid;
47
48 if (error.type != OFONO_ERROR_TYPE_NO_ERROR) {
49- if (gcd->active_rild_cid != -1)
50- disconnect_context(gc);
51-
52+ /* parsing failed, need to actually disconnect */
53+ disconnect_context(gc);
54 goto error;
55 }
56
57@@ -185,7 +187,7 @@
58 error.type = OFONO_ERROR_TYPE_FAILURE;
59 error.error = EINVAL;
60
61- set_context_disconnected(gcd);
62+ disconnect_context(gc);
63 goto error;
64 }
65
66@@ -289,6 +291,7 @@
67 ofono_gprs_context_cb_t cb = cbd->cb;
68 struct ofono_gprs_context *gc = cbd->user;
69 struct gprs_context_data *gcd = ofono_gprs_context_get_data(gc);
70+ gint active_ctx_cid;
71
72 DBG("");
73
74@@ -297,6 +300,7 @@
75
76 g_ril_print_response_no_args(gcd->ril, message);
77
78+ active_ctx_cid = gcd->active_ctx_cid;
79 set_context_disconnected(gcd);
80
81 /* If the deactivate was a result of a shutdown,
82@@ -306,10 +310,10 @@
83 if (cb)
84 CALLBACK_WITH_SUCCESS(cb, cbd->data);
85 else
86- ofono_gprs_context_deactivated(gc, gcd->active_ctx_cid);
87+ ofono_gprs_context_deactivated(gc, active_ctx_cid);
88
89 } else {
90- ofono_error("%s: replay failure: %s",
91+ ofono_error("%s: reply failure: %s",
92 __func__,
93 ril_error_to_string(message->error));
94
95@@ -330,10 +334,10 @@
96 int reqid = RIL_REQUEST_DEACTIVATE_DATA_CALL;
97 int ret = 0;
98
99- DBG("");
100+ DBG("cid: %d active_rild_cid: %d", id, gcd->active_rild_cid);
101
102- if (gcd->active_rild_cid == -1) {
103- set_context_disconnected(gcd);
104+ if (gcd->state == STATE_IDLE || gcd->state == STATE_DISABLING) {
105+ /* nothing to do */
106
107 if (cb) {
108 CALLBACK_WITH_SUCCESS(cb, data);
109@@ -343,7 +347,6 @@
110 return;
111 }
112
113-
114 cbd = cb_data_new(cb, data);
115 cbd->user = gc;
116
117@@ -371,6 +374,8 @@
118
119 error:
120 if (ret <= 0) {
121+ /* TODO: should we force state to disconnected here? */
122+
123 ofono_error("Send RIL_REQUEST_DEACTIVATE_DATA_CALL failed.");
124 g_free(cbd);
125 if (cb)
126
127=== modified file 'drivers/rilmodem/gprs.c'
128--- drivers/rilmodem/gprs.c 2013-09-09 19:21:32 +0000
129+++ drivers/rilmodem/gprs.c 2013-10-16 03:46:52 +0000
130@@ -121,10 +121,14 @@
131 struct ofono_gprs *gprs = cbd->user;
132 struct gprs_data *gd = ofono_gprs_get_data(gprs);
133 struct ofono_error error;
134- gboolean attached;
135- int status, lac, ci, tech;
136+ gboolean attached = FALSE;
137+ gboolean notify = FALSE;
138+ int lac, ci, tech;
139+ int old_status, status;
140 int max_cids = 1;
141
142+ DBG("");
143+
144 if (message->error == RIL_E_SUCCESS) {
145 decode_ril_error(&error, "OK");
146 } else {
147@@ -136,6 +140,8 @@
148 goto error;
149 }
150
151+ old_status = gd->rild_status;
152+
153 if (ril_util_parse_reg(gd->ril, message, &status,
154 &lac, &ci, &tech, &max_cids) == FALSE) {
155 ofono_error("Failure parsing data registration response.");
156@@ -144,26 +150,27 @@
157 goto error;
158 }
159
160- if (gd->rild_status == -1) {
161- ofono_gprs_register(gprs);
162-
163- /* RILD tracks data network state together with voice */
164- g_ril_register(gd->ril, RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
165- ril_gprs_state_change, gprs);
166- }
167-
168- if (max_cids > gd->max_cids) {
169- DBG("Setting max cids to %d", max_cids);
170- gd->max_cids = max_cids;
171- ofono_gprs_set_cid_range(gprs, 1, max_cids);
172- }
173-
174- /* Just need to notify ofono if it's already attached */
175- if (gd->ofono_attached && (gd->rild_status != status)) {
176- ofono_gprs_status_notify(gprs, status);
177- }
178-
179- gd->rild_status = status;
180+ /*
181+ * There are three cases that can result in this callback
182+ * running:
183+ *
184+ * 1) The driver's probe() method was called, and thus an
185+ * internal call to ril_gprs_registration_status() is
186+ * generated. No ofono cb exists.
187+ *
188+ * 2) ril_gprs_state_change() is called due to an unsolicited
189+ * event from RILD. No ofono cb exists.
190+ *
191+ * 3) The ofono code code calls the driver's attached_status()
192+ * function. A valid ofono cb exists.
193+ */
194+
195+ if (gd->rild_status != status) {
196+ gd->rild_status = status;
197+
198+ if (cb == NULL)
199+ notify = TRUE;
200+ }
201
202 /*
203 * Override the actual status based upon the desired
204@@ -176,7 +183,41 @@
205 if (attached && gd->ofono_attached == FALSE) {
206 DBG("attached=true; ofono_attached=false; return !REGISTERED");
207 status = NETWORK_REGISTRATION_STATUS_NOT_REGISTERED;
208- }
209+
210+ /* Further optimization so that if ril_status ==
211+ * NOT_REGISTERED, ofono_attached == false, and status ==
212+ * ROAMING | REGISTERED, then notify gets cleared...
213+ *
214+ * As is, this results in unecessary status notify calls
215+ * when nothing has changed.
216+ */
217+ if (status == old_status && notify)
218+ notify = FALSE;
219+ }
220+
221+ if (old_status == -1) {
222+ ofono_gprs_register(gprs);
223+
224+ /* RILD tracks data network state together with voice */
225+ g_ril_register(gd->ril, RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED,
226+ ril_gprs_state_change, gprs);
227+
228+ if (max_cids > gd->max_cids) {
229+ DBG("Setting max cids to %d", max_cids);
230+ gd->max_cids = max_cids;
231+ ofono_gprs_set_cid_range(gprs, 1, max_cids);
232+ }
233+
234+ /*
235+ * This callback is a result of the inital call
236+ * to probe(), so should return after registration.
237+ */
238+ return;
239+ }
240+
241+ /* Just need to notify ofono if it's already attached */
242+ if (notify)
243+ ofono_gprs_status_notify(gprs, status);
244
245 error:
246 if (cb)
247@@ -194,6 +235,14 @@
248
249 cbd->user = gprs;
250
251+ DBG("");
252+
253+ /*
254+ * TODO (optimization): if gd->ofono_attached == FALSE, don't
255+ * send REQ_DATA_REG; just invoke with the callback with
256+ * status == !REGISTERED!!!
257+ */
258+
259 ret = g_ril_send(gd->ril, request,
260 NULL, 0, ril_data_reg_cb, cbd, g_free);
261

Subscribers

People subscribed via source and target branches