Merge lp:~awe/ofono/midori-switch-4g-update into lp:~phablet-team/ofono/ubuntu
- midori-switch-4g-update
- Merge into ubuntu
Status: | Merged |
---|---|
Approved by: | Scott Sweeny |
Approved revision: | 6918 |
Merged at revision: | 6918 |
Proposed branch: | lp:~awe/ofono/midori-switch-4g-update |
Merge into: | lp:~phablet-team/ofono/ubuntu |
Diff against target: |
1169 lines (+609/-171) 14 files modified
debian/changelog (+18/-0) drivers/mtk2modem/gprs.c (+0/-1) drivers/mtkmodem/gprs.c (+0/-1) drivers/mtkmodem/radio-settings.c (+5/-0) drivers/qcommsimmodem/gprs.c (+0/-1) drivers/qcommsimmodem/radio-settings.c (+3/-0) drivers/rilmodem/gprs.c (+0/-48) drivers/rilmodem/gprs.h (+0/-4) drivers/rilmodem/radio-settings.c (+514/-35) drivers/rilmodem/radio-settings.h (+19/-0) gril/grilreply.c (+9/-3) include/gprs.h (+2/-4) plugins/ril.c (+35/-55) src/gprs.c (+4/-19) |
To merge this branch: | bzr merge lp:~awe/ofono/midori-switch-4g-update |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Scott Sweeny (community) | Approve | ||
Review via email: mp+300483@code.launchpad.net |
Commit message
* Add automatic SIM slot capability switching for midori:
* include: gprs: remove set ia
* gprs: remove calls to set_ia_apn
* gril: fix memory leak, print radio_caps event
* ril: create radio settings when onlining
* rilmodem: gprs: remove set_ia_apn
* rilmodem: radio-settings: enable switch slots caps
* qcommsimmodem: remote set_ia_apn
* qcommsimmodem: adapt to radio settings changes
* mtkmodem: adapt to radio settings changes
* mtkmodem: remove set_ia_apn
* mtk2modem: remove set_ia_apn
Description of the change
This change adds support for dynamic switching of radio capabilities for dual-standby modems which use the rilmodem driver ( eg. midori ).
Instead of having to explicitly call a DBus method to switch which SIM slot has the ability use 3g or 4g, now the client just uses the standard method of changing the network technology preference. If this new setting requires the slot capabilities to be swapped, rilmodem will do this automatically on behalf of the client.
This change re-works some of the code necessary for LTE support, and as such, we should ensure that LTE still works properly on the MX4 ( EU / China only ).
Preview Diff
1 | === modified file 'debian/changelog' | |||
2 | --- debian/changelog 2016-07-01 17:31:30 +0000 | |||
3 | +++ debian/changelog 2016-07-19 15:19:28 +0000 | |||
4 | @@ -1,3 +1,21 @@ | |||
5 | 1 | ofono (1.17.bzr6919+16.10.20160719-0ubuntu1) UNRELEASED; urgency=medium | ||
6 | 2 | |||
7 | 3 | [ Alfonso Sanchez-Beato ] | ||
8 | 4 | * Add automatic SIM slot capability switching for midori: | ||
9 | 5 | * include: gprs: remove set ia | ||
10 | 6 | * gprs: remove calls to set_ia_apn | ||
11 | 7 | * gril: fix memory leak, print radio_caps event | ||
12 | 8 | * ril: create radio settings when onlining | ||
13 | 9 | * rilmodem: gprs: remove set_ia_apn | ||
14 | 10 | * rilmodem: radio-settings: enable switch slots caps | ||
15 | 11 | * qcommsimmodem: remote set_ia_apn | ||
16 | 12 | * qcommsimmodem: adapt to radio settings changes | ||
17 | 13 | * mtkmodem: adapt to radio settings changes | ||
18 | 14 | * mtkmodem: remove set_ia_apn | ||
19 | 15 | * mtk2modem: remove set_ia_apn | ||
20 | 16 | |||
21 | 17 | -- Tony Espy <espy@canonical.com> Tue, 19 Jul 2016 10:29:20 -0400 | ||
22 | 18 | |||
23 | 1 | ofono (1.17.bzr6919+16.10.20160701.2-0ubuntu1) yakkety; urgency=medium | 19 | ofono (1.17.bzr6919+16.10.20160701.2-0ubuntu1) yakkety; urgency=medium |
24 | 2 | 20 | ||
25 | 3 | [ Ratchanan Srirattanamet ] | 21 | [ Ratchanan Srirattanamet ] |
26 | 4 | 22 | ||
27 | === modified file 'drivers/mtk2modem/gprs.c' | |||
28 | --- drivers/mtk2modem/gprs.c 2016-06-28 06:50:11 +0000 | |||
29 | +++ drivers/mtk2modem/gprs.c 2016-07-19 15:19:28 +0000 | |||
30 | @@ -74,7 +74,6 @@ | |||
31 | 74 | .remove = ril_gprs_remove, | 74 | .remove = ril_gprs_remove, |
32 | 75 | .set_attached = ril_gprs_set_attached, | 75 | .set_attached = ril_gprs_set_attached, |
33 | 76 | .attached_status = ril_gprs_registration_status, | 76 | .attached_status = ril_gprs_registration_status, |
34 | 77 | .set_ia_apn = ril_gprs_set_ia_apn, | ||
35 | 78 | }; | 77 | }; |
36 | 79 | 78 | ||
37 | 80 | void mtk2_gprs_init(void) | 79 | void mtk2_gprs_init(void) |
38 | 81 | 80 | ||
39 | === modified file 'drivers/mtkmodem/gprs.c' | |||
40 | --- drivers/mtkmodem/gprs.c 2015-09-29 08:46:20 +0000 | |||
41 | +++ drivers/mtkmodem/gprs.c 2016-07-19 15:19:28 +0000 | |||
42 | @@ -175,7 +175,6 @@ | |||
43 | 175 | .remove = mtk_gprs_remove, | 175 | .remove = mtk_gprs_remove, |
44 | 176 | .set_attached = mtk_gprs_set_attached, | 176 | .set_attached = mtk_gprs_set_attached, |
45 | 177 | .attached_status = ril_gprs_registration_status, | 177 | .attached_status = ril_gprs_registration_status, |
46 | 178 | .set_ia_apn = ril_gprs_set_ia_apn, | ||
47 | 179 | }; | 178 | }; |
48 | 180 | 179 | ||
49 | 181 | void mtk_gprs_init(void) | 180 | void mtk_gprs_init(void) |
50 | 182 | 181 | ||
51 | === modified file 'drivers/mtkmodem/radio-settings.c' | |||
52 | --- drivers/mtkmodem/radio-settings.c 2015-09-29 08:46:20 +0000 | |||
53 | +++ drivers/mtkmodem/radio-settings.c 2016-07-19 15:19:28 +0000 | |||
54 | @@ -105,6 +105,8 @@ | |||
55 | 105 | } | 105 | } |
56 | 106 | } | 106 | } |
57 | 107 | 107 | ||
58 | 108 | static struct ofono_radio_settings_driver driver; | ||
59 | 109 | |||
60 | 108 | static int mtk_radio_settings_probe(struct ofono_radio_settings *rs, | 110 | static int mtk_radio_settings_probe(struct ofono_radio_settings *rs, |
61 | 109 | unsigned int vendor, void *user) | 111 | unsigned int vendor, void *user) |
62 | 110 | { | 112 | { |
63 | @@ -116,6 +118,7 @@ | |||
64 | 116 | return -ENOMEM; | 118 | return -ENOMEM; |
65 | 117 | } | 119 | } |
66 | 118 | 120 | ||
67 | 121 | rsd->virt_tbl = &driver; | ||
68 | 119 | rsd->ril = g_ril_clone(rs_init_data->gril); | 122 | rsd->ril = g_ril_clone(rs_init_data->gril); |
69 | 120 | rsd->modem = rs_init_data->modem; | 123 | rsd->modem = rs_init_data->modem; |
70 | 121 | 124 | ||
71 | @@ -159,6 +162,8 @@ | |||
72 | 159 | available_rats |= OFONO_RADIO_ACCESS_MODE_LTE; | 162 | available_rats |= OFONO_RADIO_ACCESS_MODE_LTE; |
73 | 160 | } | 163 | } |
74 | 161 | 164 | ||
75 | 165 | rd->available_rats = available_rats; | ||
76 | 166 | |||
77 | 162 | CALLBACK_WITH_SUCCESS(cb, available_rats, cbd->data); | 167 | CALLBACK_WITH_SUCCESS(cb, available_rats, cbd->data); |
78 | 163 | } | 168 | } |
79 | 164 | 169 | ||
80 | 165 | 170 | ||
81 | === modified file 'drivers/qcommsimmodem/gprs.c' | |||
82 | --- drivers/qcommsimmodem/gprs.c 2016-04-15 14:12:39 +0000 | |||
83 | +++ drivers/qcommsimmodem/gprs.c 2016-07-19 15:19:28 +0000 | |||
84 | @@ -104,7 +104,6 @@ | |||
85 | 104 | .remove = ril_gprs_remove, | 104 | .remove = ril_gprs_remove, |
86 | 105 | .set_attached = qcom_msim_gprs_set_attached, | 105 | .set_attached = qcom_msim_gprs_set_attached, |
87 | 106 | .attached_status = ril_gprs_registration_status, | 106 | .attached_status = ril_gprs_registration_status, |
88 | 107 | .set_ia_apn = ril_gprs_set_ia_apn, | ||
89 | 108 | }; | 107 | }; |
90 | 109 | 108 | ||
91 | 110 | void qcom_msim_gprs_init(void) | 109 | void qcom_msim_gprs_init(void) |
92 | 111 | 110 | ||
93 | === modified file 'drivers/qcommsimmodem/radio-settings.c' | |||
94 | --- drivers/qcommsimmodem/radio-settings.c 2016-02-25 11:59:14 +0000 | |||
95 | +++ drivers/qcommsimmodem/radio-settings.c 2016-07-19 15:19:28 +0000 | |||
96 | @@ -225,6 +225,8 @@ | |||
97 | 225 | qcom_msim_do_set_rat_mode(rs, pref, cbd); | 225 | qcom_msim_do_set_rat_mode(rs, pref, cbd); |
98 | 226 | } | 226 | } |
99 | 227 | 227 | ||
100 | 228 | static struct ofono_radio_settings_driver driver; | ||
101 | 229 | |||
102 | 228 | static int qcom_msim_radio_settings_probe(struct ofono_radio_settings *rs, | 230 | static int qcom_msim_radio_settings_probe(struct ofono_radio_settings *rs, |
103 | 229 | unsigned int vendor, void *user) | 231 | unsigned int vendor, void *user) |
104 | 230 | { | 232 | { |
105 | @@ -237,6 +239,7 @@ | |||
106 | 237 | return -ENOMEM; | 239 | return -ENOMEM; |
107 | 238 | } | 240 | } |
108 | 239 | 241 | ||
109 | 242 | rsd->virt_tbl = &driver; | ||
110 | 240 | rsd->ril = g_ril_clone(rs_init_data->gril); | 243 | rsd->ril = g_ril_clone(rs_init_data->gril); |
111 | 241 | rsd->modem = rs_init_data->modem; | 244 | rsd->modem = rs_init_data->modem; |
112 | 242 | 245 | ||
113 | 243 | 246 | ||
114 | === modified file 'drivers/rilmodem/gprs.c' | |||
115 | --- drivers/rilmodem/gprs.c 2016-06-30 17:41:18 +0000 | |||
116 | +++ drivers/rilmodem/gprs.c 2016-07-19 15:19:28 +0000 | |||
117 | @@ -106,53 +106,6 @@ | |||
118 | 106 | } | 106 | } |
119 | 107 | } | 107 | } |
120 | 108 | 108 | ||
121 | 109 | static void set_ia_apn_cb(struct ril_msg *message, gpointer user_data) | ||
122 | 110 | { | ||
123 | 111 | struct cb_data *cbd = user_data; | ||
124 | 112 | ofono_gprs_cb_t cb = cbd->cb; | ||
125 | 113 | struct ofono_gprs *gprs = cbd->user; | ||
126 | 114 | struct ril_gprs_data *gd = ofono_gprs_get_data(gprs); | ||
127 | 115 | |||
128 | 116 | if (message->error != RIL_E_SUCCESS) { | ||
129 | 117 | ofono_error("%s: reply failure: %s", __func__, | ||
130 | 118 | ril_error_to_string(message->error)); | ||
131 | 119 | CALLBACK_WITH_FAILURE(cb, cbd->data); | ||
132 | 120 | return; | ||
133 | 121 | } | ||
134 | 122 | |||
135 | 123 | g_ril_print_response_no_args(gd->ril, message); | ||
136 | 124 | |||
137 | 125 | CALLBACK_WITH_SUCCESS(cb, cbd->data); | ||
138 | 126 | } | ||
139 | 127 | |||
140 | 128 | void ril_gprs_set_ia_apn(struct ofono_gprs *gprs, const char *apn, | ||
141 | 129 | enum ofono_gprs_proto proto, const char *user, | ||
142 | 130 | const char *passwd, const char *mccmnc, | ||
143 | 131 | ofono_gprs_cb_t cb, void *data) | ||
144 | 132 | { | ||
145 | 133 | struct ril_gprs_data *gd = ofono_gprs_get_data(gprs); | ||
146 | 134 | struct cb_data *cbd; | ||
147 | 135 | struct parcel rilp; | ||
148 | 136 | |||
149 | 137 | if (!ofono_modem_get_boolean(gd->modem, MODEM_PROP_LTE_CAPABLE)) { | ||
150 | 138 | CALLBACK_WITH_SUCCESS(cb, data); | ||
151 | 139 | return; | ||
152 | 140 | } | ||
153 | 141 | |||
154 | 142 | cbd = cb_data_new(cb, data, gprs); | ||
155 | 143 | |||
156 | 144 | g_ril_request_set_initial_attach_apn(gd->ril, apn, proto, user, passwd, | ||
157 | 145 | mccmnc, &rilp); | ||
158 | 146 | |||
159 | 147 | if (g_ril_send(gd->ril, RIL_REQUEST_SET_INITIAL_ATTACH_APN, | ||
160 | 148 | &rilp, set_ia_apn_cb, cbd, g_free) == 0) { | ||
161 | 149 | ofono_error("%s: failure sending request", __func__); | ||
162 | 150 | |||
163 | 151 | g_free(cbd); | ||
164 | 152 | CALLBACK_WITH_FAILURE(cb, data); | ||
165 | 153 | } | ||
166 | 154 | } | ||
167 | 155 | |||
168 | 156 | static void ril_gprs_state_change(struct ril_msg *message, gpointer user_data) | 109 | static void ril_gprs_state_change(struct ril_msg *message, gpointer user_data) |
169 | 157 | { | 110 | { |
170 | 158 | struct ofono_gprs *gprs = user_data; | 111 | struct ofono_gprs *gprs = user_data; |
171 | @@ -604,7 +557,6 @@ | |||
172 | 604 | .remove = ril_gprs_remove, | 557 | .remove = ril_gprs_remove, |
173 | 605 | .set_attached = ril_gprs_set_attached, | 558 | .set_attached = ril_gprs_set_attached, |
174 | 606 | .attached_status = ril_gprs_registration_status, | 559 | .attached_status = ril_gprs_registration_status, |
175 | 607 | .set_ia_apn = ril_gprs_set_ia_apn, | ||
176 | 608 | }; | 560 | }; |
177 | 609 | 561 | ||
178 | 610 | void ril_gprs_init(void) | 562 | void ril_gprs_init(void) |
179 | 611 | 563 | ||
180 | === modified file 'drivers/rilmodem/gprs.h' | |||
181 | --- drivers/rilmodem/gprs.h 2016-06-16 13:29:18 +0000 | |||
182 | +++ drivers/rilmodem/gprs.h 2016-07-19 15:19:28 +0000 | |||
183 | @@ -42,7 +42,3 @@ | |||
184 | 42 | ofono_gprs_cb_t cb, void *data); | 42 | ofono_gprs_cb_t cb, void *data); |
185 | 43 | void ril_gprs_registration_status(struct ofono_gprs *gprs, | 43 | void ril_gprs_registration_status(struct ofono_gprs *gprs, |
186 | 44 | ofono_gprs_status_cb_t cb, void *data); | 44 | ofono_gprs_status_cb_t cb, void *data); |
187 | 45 | void ril_gprs_set_ia_apn(struct ofono_gprs *gprs, const char *apn, | ||
188 | 46 | enum ofono_gprs_proto proto, const char *user, | ||
189 | 47 | const char *passwd, const char *mccmnc, | ||
190 | 48 | ofono_gprs_cb_t cb, void *data); | ||
191 | 49 | 45 | ||
192 | === modified file 'drivers/rilmodem/radio-settings.c' | |||
193 | --- drivers/rilmodem/radio-settings.c 2016-06-30 16:41:34 +0000 | |||
194 | +++ drivers/rilmodem/radio-settings.c 2016-07-19 15:19:28 +0000 | |||
195 | @@ -30,9 +30,11 @@ | |||
196 | 30 | #include <stdlib.h> | 30 | #include <stdlib.h> |
197 | 31 | #include <string.h> | 31 | #include <string.h> |
198 | 32 | #include <errno.h> | 32 | #include <errno.h> |
199 | 33 | #include <stdint.h> | ||
200 | 33 | 34 | ||
201 | 34 | #include <glib.h> | 35 | #include <glib.h> |
202 | 35 | 36 | ||
203 | 37 | #include <ofono.h> | ||
204 | 36 | #include <ofono/log.h> | 38 | #include <ofono/log.h> |
205 | 37 | #include <ofono/modem.h> | 39 | #include <ofono/modem.h> |
206 | 38 | #include <ofono/radio-settings.h> | 40 | #include <ofono/radio-settings.h> |
207 | @@ -46,6 +48,63 @@ | |||
208 | 46 | #include "grilreply.h" | 48 | #include "grilreply.h" |
209 | 47 | #include "radio-settings.h" | 49 | #include "radio-settings.h" |
210 | 48 | 50 | ||
211 | 51 | struct radio_data *radio_data_0; | ||
212 | 52 | struct radio_data *radio_data_1; | ||
213 | 53 | |||
214 | 54 | static int g_session; | ||
215 | 55 | |||
216 | 56 | static struct radio_data *radio_data_complement(struct radio_data *rd) | ||
217 | 57 | { | ||
218 | 58 | if (rd == radio_data_0) | ||
219 | 59 | return radio_data_1; | ||
220 | 60 | else | ||
221 | 61 | return radio_data_0; | ||
222 | 62 | } | ||
223 | 63 | |||
224 | 64 | static void set_ia_apn_cb(struct ril_msg *message, gpointer user_data) | ||
225 | 65 | { | ||
226 | 66 | struct ofono_radio_settings *rs = user_data; | ||
227 | 67 | struct radio_data *rd = ofono_radio_settings_get_data(rs); | ||
228 | 68 | |||
229 | 69 | if (message->error != RIL_E_SUCCESS) { | ||
230 | 70 | ofono_error("%s: reply failure: %s", __func__, | ||
231 | 71 | ril_error_to_string(message->error)); | ||
232 | 72 | return; | ||
233 | 73 | } | ||
234 | 74 | |||
235 | 75 | g_ril_print_response_no_args(rd->ril, message); | ||
236 | 76 | } | ||
237 | 77 | |||
238 | 78 | static void set_ia_apn(struct ofono_radio_settings *rs) | ||
239 | 79 | { | ||
240 | 80 | char mccmnc[OFONO_MAX_MCC_LENGTH + OFONO_MAX_MNC_LENGTH + 1]; | ||
241 | 81 | struct radio_data *rd = ofono_radio_settings_get_data(rs); | ||
242 | 82 | struct parcel rilp; | ||
243 | 83 | struct ofono_gprs *gprs; | ||
244 | 84 | const struct ofono_gprs_primary_context *ia_ctx; | ||
245 | 85 | |||
246 | 86 | if ((rd->available_rats & OFONO_RADIO_ACCESS_MODE_LTE) == 0) | ||
247 | 87 | return; | ||
248 | 88 | |||
249 | 89 | gprs = __ofono_atom_find(OFONO_ATOM_TYPE_GPRS, rd->modem); | ||
250 | 90 | if (gprs == NULL) | ||
251 | 91 | return; | ||
252 | 92 | |||
253 | 93 | /* Ask for APN data */ | ||
254 | 94 | ia_ctx = ofono_gprs_get_ia_apn(gprs, mccmnc); | ||
255 | 95 | if (ia_ctx == NULL) | ||
256 | 96 | return; | ||
257 | 97 | |||
258 | 98 | g_ril_request_set_initial_attach_apn(rd->ril, ia_ctx->apn, | ||
259 | 99 | ia_ctx->proto, ia_ctx->username, | ||
260 | 100 | ia_ctx->password, mccmnc, | ||
261 | 101 | &rilp); | ||
262 | 102 | |||
263 | 103 | if (g_ril_send(rd->ril, RIL_REQUEST_SET_INITIAL_ATTACH_APN, | ||
264 | 104 | &rilp, set_ia_apn_cb, rs, NULL) == 0) | ||
265 | 105 | ofono_error("%s: failure sending request", __func__); | ||
266 | 106 | } | ||
267 | 107 | |||
268 | 49 | static void ril_set_rat_cb(struct ril_msg *message, gpointer user_data) | 108 | static void ril_set_rat_cb(struct ril_msg *message, gpointer user_data) |
269 | 50 | { | 109 | { |
270 | 51 | struct cb_data *cbd = user_data; | 110 | struct cb_data *cbd = user_data; |
271 | @@ -54,7 +113,13 @@ | |||
272 | 54 | ofono_radio_settings_rat_mode_set_cb_t cb = cbd->cb; | 113 | ofono_radio_settings_rat_mode_set_cb_t cb = cbd->cb; |
273 | 55 | 114 | ||
274 | 56 | if (message->error == RIL_E_SUCCESS) { | 115 | if (message->error == RIL_E_SUCCESS) { |
275 | 116 | rd->rat_mode = rd->pending_mode; | ||
276 | 117 | |||
277 | 57 | g_ril_print_response_no_args(rd->ril, message); | 118 | g_ril_print_response_no_args(rd->ril, message); |
278 | 119 | |||
279 | 120 | if (rd->rat_mode == OFONO_RADIO_ACCESS_MODE_LTE) | ||
280 | 121 | set_ia_apn(rs); | ||
281 | 122 | |||
282 | 58 | CALLBACK_WITH_SUCCESS(cb, cbd->data); | 123 | CALLBACK_WITH_SUCCESS(cb, cbd->data); |
283 | 59 | } else { | 124 | } else { |
284 | 60 | ofono_error("%s: rat mode setting failed", __func__); | 125 | ofono_error("%s: rat mode setting failed", __func__); |
285 | @@ -62,13 +127,10 @@ | |||
286 | 62 | } | 127 | } |
287 | 63 | } | 128 | } |
288 | 64 | 129 | ||
293 | 65 | void ril_set_rat_mode(struct ofono_radio_settings *rs, | 130 | static void set_preferred_network(struct radio_data *rd, struct cb_data *cbd, |
294 | 66 | enum ofono_radio_access_mode mode, | 131 | enum ofono_radio_access_mode mode) |
291 | 67 | ofono_radio_settings_rat_mode_set_cb_t cb, | ||
292 | 68 | void *data) | ||
295 | 69 | { | 132 | { |
298 | 70 | struct radio_data *rd = ofono_radio_settings_get_data(rs); | 133 | ofono_radio_settings_rat_mode_set_cb_t cb = cbd->cb; |
297 | 71 | struct cb_data *cbd = cb_data_new(cb, data, rs); | ||
299 | 72 | struct parcel rilp; | 134 | struct parcel rilp; |
300 | 73 | int pref = PREF_NET_TYPE_GSM_WCDMA; | 135 | int pref = PREF_NET_TYPE_GSM_WCDMA; |
301 | 74 | 136 | ||
302 | @@ -87,14 +149,340 @@ | |||
303 | 87 | break; | 149 | break; |
304 | 88 | } | 150 | } |
305 | 89 | 151 | ||
306 | 152 | rd->pending_mode = mode; | ||
307 | 153 | |||
308 | 90 | g_ril_request_set_preferred_network_type(rd->ril, pref, &rilp); | 154 | g_ril_request_set_preferred_network_type(rd->ril, pref, &rilp); |
309 | 91 | 155 | ||
310 | 92 | if (g_ril_send(rd->ril, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, | 156 | if (g_ril_send(rd->ril, RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, |
311 | 93 | &rilp, ril_set_rat_cb, cbd, g_free) == 0) { | 157 | &rilp, ril_set_rat_cb, cbd, g_free) == 0) { |
312 | 94 | ofono_error("%s: unable to set rat mode", __func__); | 158 | ofono_error("%s: unable to set rat mode", __func__); |
313 | 95 | g_free(cbd); | 159 | g_free(cbd); |
316 | 96 | CALLBACK_WITH_FAILURE(cb, data); | 160 | CALLBACK_WITH_FAILURE(cb, cbd->data); |
317 | 97 | } | 161 | } |
318 | 162 | } | ||
319 | 163 | |||
320 | 164 | static gboolean send_set_radio_cap(struct radio_data *rd, | ||
321 | 165 | int session, int phase, int ril_rats, | ||
322 | 166 | const char *logical_modem, int status, | ||
323 | 167 | GRilResponseFunc cb) | ||
324 | 168 | { | ||
325 | 169 | struct parcel rilp; | ||
326 | 170 | int version = 1; | ||
327 | 171 | |||
328 | 172 | parcel_init(&rilp); | ||
329 | 173 | |||
330 | 174 | parcel_w_int32(&rilp, version); | ||
331 | 175 | parcel_w_int32(&rilp, session); | ||
332 | 176 | parcel_w_int32(&rilp, phase); | ||
333 | 177 | parcel_w_int32(&rilp, ril_rats); | ||
334 | 178 | parcel_w_string(&rilp, logical_modem); | ||
335 | 179 | parcel_w_int32(&rilp, status); | ||
336 | 180 | |||
337 | 181 | g_ril_append_print_buf(rd->ril, "(%d,%d,%d,0x%X,%s,%d)", version, | ||
338 | 182 | session, phase, ril_rats, logical_modem, status); | ||
339 | 183 | |||
340 | 184 | if (g_ril_send(rd->ril, RIL_REQUEST_SET_RADIO_CAPABILITY, | ||
341 | 185 | &rilp, cb, rd, NULL) == 0) | ||
342 | 186 | return FALSE; | ||
343 | 187 | |||
344 | 188 | return TRUE; | ||
345 | 189 | } | ||
346 | 190 | |||
347 | 191 | static unsigned set_rat_from_ril_rat(int ril_rat) | ||
348 | 192 | { | ||
349 | 193 | unsigned rat = 0; | ||
350 | 194 | |||
351 | 195 | if (ril_rat & RIL_RAF_GSM) | ||
352 | 196 | rat |= OFONO_RADIO_ACCESS_MODE_GSM; | ||
353 | 197 | |||
354 | 198 | if (ril_rat & (RIL_RAF_UMTS | RIL_RAF_TD_SCDMA)) | ||
355 | 199 | rat |= OFONO_RADIO_ACCESS_MODE_UMTS; | ||
356 | 200 | |||
357 | 201 | if (ril_rat & RIL_RAF_LTE) | ||
358 | 202 | rat |= OFONO_RADIO_ACCESS_MODE_LTE; | ||
359 | 203 | |||
360 | 204 | return rat; | ||
361 | 205 | } | ||
362 | 206 | |||
363 | 207 | static void set_preferred_cb(const struct ofono_error *error, void *data) | ||
364 | 208 | { | ||
365 | 209 | struct radio_data *rd = data; | ||
366 | 210 | |||
367 | 211 | if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { | ||
368 | 212 | ofono_error("%s: error setting radio access mode", __func__); | ||
369 | 213 | |||
370 | 214 | return; | ||
371 | 215 | } | ||
372 | 216 | |||
373 | 217 | ofono_radio_settings_set_rat_mode(rd->radio_settings, rd->rat_mode); | ||
374 | 218 | } | ||
375 | 219 | |||
376 | 220 | static enum ofono_radio_access_mode | ||
377 | 221 | get_best_available_tech(unsigned available_rats) | ||
378 | 222 | { | ||
379 | 223 | int i; | ||
380 | 224 | uint32_t tech; | ||
381 | 225 | |||
382 | 226 | for (i = sizeof(uint32_t) * CHAR_BIT; i > 0; i--) { | ||
383 | 227 | tech = 1 << (i - 1); | ||
384 | 228 | |||
385 | 229 | if ((available_rats & tech) != 0) | ||
386 | 230 | break; | ||
387 | 231 | } | ||
388 | 232 | |||
389 | 233 | if (i == 0) | ||
390 | 234 | tech = OFONO_RADIO_ACCESS_MODE_GSM; | ||
391 | 235 | |||
392 | 236 | return tech; | ||
393 | 237 | } | ||
394 | 238 | |||
395 | 239 | static void switch_finish_cb(struct ril_msg *message, gpointer user_data) | ||
396 | 240 | { | ||
397 | 241 | struct radio_data *rd = user_data; | ||
398 | 242 | struct switch_data *sd = rd->switch_d; | ||
399 | 243 | struct radio_data *rd1 = sd->rd_1; | ||
400 | 244 | struct radio_data *rd2 = sd->rd_2; | ||
401 | 245 | struct reply_radio_capability *caps; | ||
402 | 246 | |||
403 | 247 | sd->pending_msgs--; | ||
404 | 248 | |||
405 | 249 | if (message->error != RIL_E_SUCCESS) { | ||
406 | 250 | ofono_error("%s: error %s", __func__, | ||
407 | 251 | ril_error_to_string(message->error)); | ||
408 | 252 | return; | ||
409 | 253 | } | ||
410 | 254 | |||
411 | 255 | caps = g_ril_reply_parse_get_radio_capability(rd->ril, message); | ||
412 | 256 | if (caps == NULL) { | ||
413 | 257 | ofono_error("%s: parse error", __func__); | ||
414 | 258 | return; | ||
415 | 259 | } | ||
416 | 260 | |||
417 | 261 | if (sd->pending_msgs != 0) | ||
418 | 262 | return; | ||
419 | 263 | |||
420 | 264 | ofono_info("Switching radio caps between slots - FINISH"); | ||
421 | 265 | |||
422 | 266 | set_preferred_network(rd1, sd->cbd, sd->mode_to_switch); | ||
423 | 267 | |||
424 | 268 | /* | ||
425 | 269 | * If the complementary slot does not support anymore its current | ||
426 | 270 | * technology, we change it to the best possible among available ones. | ||
427 | 271 | */ | ||
428 | 272 | if ((rd2->rat_mode & rd2->available_rats) == 0) { | ||
429 | 273 | |||
430 | 274 | struct cb_data *cbd = | ||
431 | 275 | cb_data_new(set_preferred_cb, rd2, rd2->radio_settings); | ||
432 | 276 | |||
433 | 277 | set_preferred_network(rd2, cbd, | ||
434 | 278 | get_best_available_tech(rd2->available_rats)); | ||
435 | 279 | } | ||
436 | 280 | |||
437 | 281 | rd1->switch_d = NULL; | ||
438 | 282 | rd2->switch_d = NULL; | ||
439 | 283 | g_free(sd); | ||
440 | 284 | g_free(caps); | ||
441 | 285 | } | ||
442 | 286 | |||
443 | 287 | static void radio_caps_event(struct ril_msg *message, gpointer user_data) | ||
444 | 288 | { | ||
445 | 289 | struct radio_data *rd = user_data; | ||
446 | 290 | struct switch_data *sd = rd->switch_d; | ||
447 | 291 | struct radio_data *rd1; | ||
448 | 292 | struct radio_data *rd2; | ||
449 | 293 | struct reply_radio_capability *caps; | ||
450 | 294 | |||
451 | 295 | if (sd == NULL) | ||
452 | 296 | return; | ||
453 | 297 | |||
454 | 298 | rd1 = sd->rd_1; | ||
455 | 299 | rd2 = sd->rd_2; | ||
456 | 300 | |||
457 | 301 | caps = g_ril_reply_parse_get_radio_capability(rd->ril, message); | ||
458 | 302 | if (caps == NULL) { | ||
459 | 303 | ofono_error("%s: parse error", __func__); | ||
460 | 304 | return; | ||
461 | 305 | } | ||
462 | 306 | |||
463 | 307 | /* | ||
464 | 308 | * Update rats. They come also in the replies to SET_RADIO_CAPABILITY, | ||
465 | 309 | * but those seem to be unreliable, at least for midori. | ||
466 | 310 | */ | ||
467 | 311 | rd->ril_rats = caps->rat; | ||
468 | 312 | rd->available_rats = set_rat_from_ril_rat(caps->rat); | ||
469 | 313 | |||
470 | 314 | strcpy(rd->modem_uuid, caps->modem_uuid); | ||
471 | 315 | |||
472 | 316 | sd->pending_msgs--; | ||
473 | 317 | |||
474 | 318 | if (sd->pending_msgs != 0) | ||
475 | 319 | return; | ||
476 | 320 | |||
477 | 321 | DBG("Sending requests for FINISH phase"); | ||
478 | 322 | |||
479 | 323 | send_set_radio_cap(rd1, g_session, RIL_RC_PHASE_FINISH, | ||
480 | 324 | rd1->ril_rats, rd1->modem_uuid, | ||
481 | 325 | RIL_RC_STATUS_SUCCESS, switch_finish_cb); | ||
482 | 326 | send_set_radio_cap(rd2, g_session, RIL_RC_PHASE_FINISH, | ||
483 | 327 | rd2->ril_rats, rd2->modem_uuid, | ||
484 | 328 | RIL_RC_STATUS_SUCCESS, switch_finish_cb); | ||
485 | 329 | sd->pending_msgs = 2; | ||
486 | 330 | |||
487 | 331 | g_free(caps); | ||
488 | 332 | } | ||
489 | 333 | |||
490 | 334 | /* | ||
491 | 335 | * This function is just for completeness, as we actually need to wait for the | ||
492 | 336 | * unsolocited events to continue the capabilities switch. | ||
493 | 337 | */ | ||
494 | 338 | static void switch_apply_cb(struct ril_msg *message, gpointer user_data) | ||
495 | 339 | { | ||
496 | 340 | struct radio_data *rd = user_data; | ||
497 | 341 | struct reply_radio_capability *caps; | ||
498 | 342 | |||
499 | 343 | if (message->error != RIL_E_SUCCESS) { | ||
500 | 344 | ofono_error("%s: error %s", __func__, | ||
501 | 345 | ril_error_to_string(message->error)); | ||
502 | 346 | return; | ||
503 | 347 | } | ||
504 | 348 | |||
505 | 349 | caps = g_ril_reply_parse_get_radio_capability(rd->ril, message); | ||
506 | 350 | if (caps == NULL) | ||
507 | 351 | ofono_error("%s: parse error", __func__); | ||
508 | 352 | |||
509 | 353 | g_free(caps); | ||
510 | 354 | } | ||
511 | 355 | |||
512 | 356 | static void switch_start_cb(struct ril_msg *message, gpointer user_data) | ||
513 | 357 | { | ||
514 | 358 | struct radio_data *rd = user_data; | ||
515 | 359 | struct switch_data *sd = rd->switch_d; | ||
516 | 360 | struct radio_data *rd1 = sd->rd_1; | ||
517 | 361 | struct radio_data *rd2 = sd->rd_2; | ||
518 | 362 | struct reply_radio_capability *caps; | ||
519 | 363 | |||
520 | 364 | sd->pending_msgs--; | ||
521 | 365 | |||
522 | 366 | if (message->error != RIL_E_SUCCESS) { | ||
523 | 367 | ofono_error("%s: error %s", __func__, | ||
524 | 368 | ril_error_to_string(message->error)); | ||
525 | 369 | return; | ||
526 | 370 | } | ||
527 | 371 | |||
528 | 372 | caps = g_ril_reply_parse_get_radio_capability(rd->ril, message); | ||
529 | 373 | if (caps == NULL) { | ||
530 | 374 | ofono_error("%s: parse error", __func__); | ||
531 | 375 | return; | ||
532 | 376 | } | ||
533 | 377 | |||
534 | 378 | if (sd->pending_msgs != 0) | ||
535 | 379 | return; | ||
536 | 380 | |||
537 | 381 | DBG("Sending requests for APPLY phase"); | ||
538 | 382 | |||
539 | 383 | send_set_radio_cap(rd1, g_session, RIL_RC_PHASE_APPLY, | ||
540 | 384 | rd2->ril_rats, rd2->modem_uuid, | ||
541 | 385 | RIL_RC_STATUS_NONE, switch_apply_cb); | ||
542 | 386 | send_set_radio_cap(rd2, g_session, RIL_RC_PHASE_APPLY, | ||
543 | 387 | rd1->ril_rats, rd1->modem_uuid, | ||
544 | 388 | RIL_RC_STATUS_NONE, switch_apply_cb); | ||
545 | 389 | sd->pending_msgs = 2; | ||
546 | 390 | |||
547 | 391 | g_free(caps); | ||
548 | 392 | } | ||
549 | 393 | |||
550 | 394 | static void switch_caps(struct switch_data *sd) | ||
551 | 395 | { | ||
552 | 396 | struct radio_data *rd1 = sd->rd_1; | ||
553 | 397 | struct radio_data *rd2 = sd->rd_2; | ||
554 | 398 | |||
555 | 399 | /* START phase */ | ||
556 | 400 | g_session++; | ||
557 | 401 | |||
558 | 402 | send_set_radio_cap(rd1, g_session, RIL_RC_PHASE_START, | ||
559 | 403 | rd1->ril_rats, rd1->modem_uuid, | ||
560 | 404 | RIL_RC_STATUS_NONE, switch_start_cb); | ||
561 | 405 | send_set_radio_cap(rd2, g_session, RIL_RC_PHASE_START, | ||
562 | 406 | rd2->ril_rats, rd2->modem_uuid, | ||
563 | 407 | RIL_RC_STATUS_NONE, switch_start_cb); | ||
564 | 408 | sd->pending_msgs = 2; | ||
565 | 409 | } | ||
566 | 410 | |||
567 | 411 | static void get_rs_with_mode(struct ofono_modem *modem, void *data) | ||
568 | 412 | { | ||
569 | 413 | struct switch_data *sd = data; | ||
570 | 414 | struct radio_data *rd_ref = sd->rd_1; | ||
571 | 415 | struct ofono_atom *atom; | ||
572 | 416 | struct ofono_radio_settings *rs; | ||
573 | 417 | struct radio_data *rd; | ||
574 | 418 | const char *standby_group, *modem_group; | ||
575 | 419 | |||
576 | 420 | atom = __ofono_modem_find_atom(modem, OFONO_ATOM_TYPE_RADIO_SETTINGS); | ||
577 | 421 | if (atom == NULL) | ||
578 | 422 | return; | ||
579 | 423 | |||
580 | 424 | rs = __ofono_atom_get_data(atom); | ||
581 | 425 | rd = ofono_radio_settings_get_data(rs); | ||
582 | 426 | if (rd == rd_ref) | ||
583 | 427 | return; | ||
584 | 428 | |||
585 | 429 | standby_group = ofono_modem_get_string(rd_ref->modem, "StandbyGroup"); | ||
586 | 430 | if (standby_group == NULL) | ||
587 | 431 | return; | ||
588 | 432 | |||
589 | 433 | modem_group = ofono_modem_get_string(modem, "StandbyGroup"); | ||
590 | 434 | if (g_strcmp0(standby_group, modem_group) != 0) | ||
591 | 435 | return; | ||
592 | 436 | |||
593 | 437 | if ((rd->available_rats & sd->mode_to_switch) == 0) | ||
594 | 438 | return; | ||
595 | 439 | |||
596 | 440 | sd->rd_2 = rd; | ||
597 | 441 | } | ||
598 | 442 | |||
599 | 443 | void ril_set_rat_mode(struct ofono_radio_settings *rs, | ||
600 | 444 | enum ofono_radio_access_mode mode, | ||
601 | 445 | ofono_radio_settings_rat_mode_set_cb_t cb, | ||
602 | 446 | void *data) | ||
603 | 447 | { | ||
604 | 448 | struct radio_data *rd = ofono_radio_settings_get_data(rs); | ||
605 | 449 | struct cb_data *cbd = cb_data_new(cb, data, rs); | ||
606 | 450 | struct switch_data *sd = NULL; | ||
607 | 451 | |||
608 | 452 | if (rd->switch_d != NULL) | ||
609 | 453 | goto error; | ||
610 | 454 | |||
611 | 455 | if ((rd->available_rats & mode) == 0) { | ||
612 | 456 | if (g_ril_get_version(rd->ril) < 11) | ||
613 | 457 | goto error; | ||
614 | 458 | |||
615 | 459 | /* Check if we can switch rats with other slot */ | ||
616 | 460 | sd = g_malloc0(sizeof (*sd)); | ||
617 | 461 | sd->rd_1 = rd; | ||
618 | 462 | sd->mode_to_switch = mode; | ||
619 | 463 | sd->cbd = cbd; | ||
620 | 464 | |||
621 | 465 | __ofono_modem_foreach(get_rs_with_mode, sd); | ||
622 | 466 | |||
623 | 467 | if (sd->rd_2 == NULL) | ||
624 | 468 | goto error; | ||
625 | 469 | |||
626 | 470 | ofono_info("Switching radio caps between slots - START"); | ||
627 | 471 | sd->rd_1->switch_d = sd; | ||
628 | 472 | sd->rd_2->switch_d = sd; | ||
629 | 473 | |||
630 | 474 | switch_caps(sd); | ||
631 | 475 | } else { | ||
632 | 476 | set_preferred_network(rd, cbd, mode); | ||
633 | 477 | } | ||
634 | 478 | |||
635 | 479 | return; | ||
636 | 480 | |||
637 | 481 | error: | ||
638 | 482 | ofono_error("%s: unable to set rat mode", __func__); | ||
639 | 483 | g_free(sd); | ||
640 | 484 | g_free(cbd); | ||
641 | 485 | CALLBACK_WITH_FAILURE(cb, data); | ||
642 | 98 | } | 486 | } |
643 | 99 | 487 | ||
644 | 100 | static void ril_rat_mode_cb(struct ril_msg *message, gpointer user_data) | 488 | static void ril_rat_mode_cb(struct ril_msg *message, gpointer user_data) |
645 | @@ -108,15 +496,13 @@ | |||
646 | 108 | if (message->error != RIL_E_SUCCESS) { | 496 | if (message->error != RIL_E_SUCCESS) { |
647 | 109 | ofono_error("%s: error %s", __func__, | 497 | ofono_error("%s: error %s", __func__, |
648 | 110 | ril_error_to_string(message->error)); | 498 | ril_error_to_string(message->error)); |
651 | 111 | CALLBACK_WITH_FAILURE(cb, -1, cbd->data); | 499 | goto error; |
650 | 112 | return; | ||
652 | 113 | } | 500 | } |
653 | 114 | 501 | ||
654 | 115 | pref = g_ril_reply_parse_get_preferred_network_type(rd->ril, message); | 502 | pref = g_ril_reply_parse_get_preferred_network_type(rd->ril, message); |
655 | 116 | if (pref < 0) { | 503 | if (pref < 0) { |
656 | 117 | ofono_error("%s: parse error", __func__); | 504 | ofono_error("%s: parse error", __func__); |
659 | 118 | CALLBACK_WITH_FAILURE(cb, -1, cbd->data); | 505 | goto error; |
658 | 119 | return; | ||
660 | 120 | } | 506 | } |
661 | 121 | 507 | ||
662 | 122 | /* | 508 | /* |
663 | @@ -144,7 +530,22 @@ | |||
664 | 144 | break; | 530 | break; |
665 | 145 | } | 531 | } |
666 | 146 | 532 | ||
667 | 533 | rd->rat_mode = mode; | ||
668 | 534 | |||
669 | 147 | CALLBACK_WITH_SUCCESS(cb, mode, cbd->data); | 535 | CALLBACK_WITH_SUCCESS(cb, mode, cbd->data); |
670 | 536 | |||
671 | 537 | return; | ||
672 | 538 | |||
673 | 539 | error: | ||
674 | 540 | /* | ||
675 | 541 | * If error, we assume GSM. This is preferable to not being able to | ||
676 | 542 | * access the radio settings properties. Midori returns error if we | ||
677 | 543 | * have not completed successfully a capability switch. This should | ||
678 | 544 | * not happen if there are no bugs in our implementation, but it is | ||
679 | 545 | * better to leave this here so system settings shows something that | ||
680 | 546 | * can be manually changed by the user, just in case. | ||
681 | 547 | */ | ||
682 | 548 | CALLBACK_WITH_SUCCESS(cb, OFONO_RADIO_ACCESS_MODE_GSM, cbd->data); | ||
683 | 148 | } | 549 | } |
684 | 149 | 550 | ||
685 | 150 | void ril_query_rat_mode(struct ofono_radio_settings *rs, | 551 | void ril_query_rat_mode(struct ofono_radio_settings *rs, |
686 | @@ -211,19 +612,18 @@ | |||
687 | 211 | 612 | ||
688 | 212 | static ofono_bool_t query_available_rats_cb(gpointer user_data) | 613 | static ofono_bool_t query_available_rats_cb(gpointer user_data) |
689 | 213 | { | 614 | { |
690 | 214 | unsigned int available_rats; | ||
691 | 215 | struct cb_data *cbd = user_data; | 615 | struct cb_data *cbd = user_data; |
692 | 216 | ofono_radio_settings_available_rats_query_cb_t cb = cbd->cb; | 616 | ofono_radio_settings_available_rats_query_cb_t cb = cbd->cb; |
693 | 217 | struct ofono_radio_settings *rs = cbd->user; | 617 | struct ofono_radio_settings *rs = cbd->user; |
694 | 218 | struct radio_data *rd = ofono_radio_settings_get_data(rs); | 618 | struct radio_data *rd = ofono_radio_settings_get_data(rs); |
695 | 219 | 619 | ||
703 | 220 | available_rats = OFONO_RADIO_ACCESS_MODE_GSM | 620 | rd->available_rats = OFONO_RADIO_ACCESS_MODE_GSM |
704 | 221 | | OFONO_RADIO_ACCESS_MODE_UMTS; | 621 | | OFONO_RADIO_ACCESS_MODE_UMTS; |
705 | 222 | 622 | ||
706 | 223 | if (ofono_modem_get_boolean(rd->modem, MODEM_PROP_LTE_CAPABLE)) | 623 | if (getenv("OFONO_RIL_RAT_LTE") != NULL) |
707 | 224 | available_rats |= OFONO_RADIO_ACCESS_MODE_LTE; | 624 | rd->available_rats |= OFONO_RADIO_ACCESS_MODE_LTE; |
708 | 225 | 625 | ||
709 | 226 | CALLBACK_WITH_SUCCESS(cb, available_rats, cbd->data); | 626 | CALLBACK_WITH_SUCCESS(cb, rd->available_rats, cbd->data); |
710 | 227 | 627 | ||
711 | 228 | g_free(cbd); | 628 | g_free(cbd); |
712 | 229 | 629 | ||
713 | @@ -232,12 +632,13 @@ | |||
714 | 232 | 632 | ||
715 | 233 | static void get_radio_caps_cb(struct ril_msg *message, gpointer user_data) | 633 | static void get_radio_caps_cb(struct ril_msg *message, gpointer user_data) |
716 | 234 | { | 634 | { |
717 | 235 | unsigned int available_rats = 0; | ||
718 | 236 | struct cb_data *cbd = user_data; | 635 | struct cb_data *cbd = user_data; |
719 | 237 | ofono_radio_settings_available_rats_query_cb_t cb = cbd->cb; | 636 | ofono_radio_settings_available_rats_query_cb_t cb = cbd->cb; |
720 | 238 | struct ofono_radio_settings *rs = cbd->user; | 637 | struct ofono_radio_settings *rs = cbd->user; |
721 | 239 | struct radio_data *rd = ofono_radio_settings_get_data(rs); | 638 | struct radio_data *rd = ofono_radio_settings_get_data(rs); |
722 | 639 | struct radio_data *rd_comp; | ||
723 | 240 | struct reply_radio_capability *caps; | 640 | struct reply_radio_capability *caps; |
724 | 641 | unsigned all_rats; | ||
725 | 241 | 642 | ||
726 | 242 | if (message->error != RIL_E_SUCCESS) { | 643 | if (message->error != RIL_E_SUCCESS) { |
727 | 243 | ofono_error("%s: error %s", __func__, | 644 | ofono_error("%s: error %s", __func__, |
728 | @@ -253,18 +654,21 @@ | |||
729 | 253 | return; | 654 | return; |
730 | 254 | } | 655 | } |
731 | 255 | 656 | ||
740 | 256 | if (caps->rat & RIL_RAF_GSM) | 657 | rd->ril_rats = caps->rat; |
741 | 257 | available_rats |= OFONO_RADIO_ACCESS_MODE_GSM; | 658 | rd->available_rats = set_rat_from_ril_rat(caps->rat); |
742 | 258 | 659 | ||
743 | 259 | if (caps->rat & (RIL_RAF_UMTS | RIL_RAF_TD_SCDMA)) | 660 | strcpy(rd->modem_uuid, caps->modem_uuid); |
736 | 260 | available_rats |= OFONO_RADIO_ACCESS_MODE_UMTS; | ||
737 | 261 | |||
738 | 262 | if (caps->rat & RIL_RAF_LTE) | ||
739 | 263 | available_rats |= OFONO_RADIO_ACCESS_MODE_LTE; | ||
744 | 264 | 661 | ||
745 | 265 | g_free(caps); | 662 | g_free(caps); |
746 | 266 | 663 | ||
748 | 267 | CALLBACK_WITH_SUCCESS(cb, available_rats, cbd->data); | 664 | /* We show all rats, as we can switch the ownership between slots */ |
749 | 665 | all_rats = rd->available_rats; | ||
750 | 666 | |||
751 | 667 | rd_comp = radio_data_complement(rd); | ||
752 | 668 | if (rd_comp != NULL) | ||
753 | 669 | all_rats |= rd_comp->available_rats; | ||
754 | 670 | |||
755 | 671 | CALLBACK_WITH_SUCCESS(cb, all_rats, cbd->data); | ||
756 | 268 | } | 672 | } |
757 | 269 | 673 | ||
758 | 270 | void ril_query_available_rats(struct ofono_radio_settings *rs, | 674 | void ril_query_available_rats(struct ofono_radio_settings *rs, |
759 | @@ -286,20 +690,90 @@ | |||
760 | 286 | } | 690 | } |
761 | 287 | } | 691 | } |
762 | 288 | 692 | ||
763 | 693 | static void gprs_watch_cb(struct ofono_atom *atom, | ||
764 | 694 | enum ofono_atom_watch_condition cond, | ||
765 | 695 | void *data) | ||
766 | 696 | { | ||
767 | 697 | struct ofono_radio_settings *rs = data; | ||
768 | 698 | |||
769 | 699 | if (cond != OFONO_ATOM_WATCH_CONDITION_REGISTERED) | ||
770 | 700 | return; | ||
771 | 701 | |||
772 | 702 | set_ia_apn(rs); | ||
773 | 703 | } | ||
774 | 704 | |||
775 | 705 | static void set_safe_preferred_cb(const struct ofono_error *error, void *data) | ||
776 | 706 | { | ||
777 | 707 | if (error->type != OFONO_ERROR_TYPE_NO_ERROR) { | ||
778 | 708 | ofono_error("%s: error setting radio access mode", __func__); | ||
779 | 709 | |||
780 | 710 | return; | ||
781 | 711 | } | ||
782 | 712 | } | ||
783 | 713 | |||
784 | 714 | static void radio_settings_register(const struct ofono_error *error, | ||
785 | 715 | unsigned int available_rats, | ||
786 | 716 | void *data) | ||
787 | 717 | { | ||
788 | 718 | struct ofono_radio_settings *rs = data; | ||
789 | 719 | struct radio_data *rd = ofono_radio_settings_get_data(rs); | ||
790 | 720 | |||
791 | 721 | g_ril_register(rd->ril, RIL_UNSOL_RADIO_CAPABILITY, | ||
792 | 722 | radio_caps_event, rd); | ||
793 | 723 | |||
794 | 724 | rd->gprs_atom_watch = | ||
795 | 725 | __ofono_modem_add_atom_watch(rd->modem, OFONO_ATOM_TYPE_GPRS, | ||
796 | 726 | gprs_watch_cb, rs, NULL); | ||
797 | 727 | |||
798 | 728 | /* | ||
799 | 729 | * If the preferred technology was unknown/unsupported, change to a | ||
800 | 730 | * valid one (midori can return PREF_NET_TYPE_CDMA_ONLY, for instance). | ||
801 | 731 | */ | ||
802 | 732 | if (rd->rat_mode == OFONO_RADIO_ACCESS_MODE_ANY) { | ||
803 | 733 | struct cb_data *cbd = cb_data_new(set_safe_preferred_cb, rd, | ||
804 | 734 | rd->radio_settings); | ||
805 | 735 | |||
806 | 736 | set_preferred_network(rd, cbd, | ||
807 | 737 | get_best_available_tech(rd->available_rats)); | ||
808 | 738 | } | ||
809 | 739 | |||
810 | 740 | /* | ||
811 | 741 | * We register in all cases, setting FD some times fails until radio is | ||
812 | 742 | * available (this happens on turbo and maybe in other devices). | ||
813 | 743 | */ | ||
814 | 744 | ofono_radio_settings_register(rs); | ||
815 | 745 | } | ||
816 | 746 | |||
817 | 747 | static void ril_after_query_rat_mode(const struct ofono_error *error, | ||
818 | 748 | enum ofono_radio_access_mode mode, | ||
819 | 749 | void *data) | ||
820 | 750 | { | ||
821 | 751 | struct ofono_radio_settings *rs = data; | ||
822 | 752 | struct radio_data *rd = ofono_radio_settings_get_data(rs); | ||
823 | 753 | |||
824 | 754 | rd->virt_tbl->query_available_rats(rs, radio_settings_register, rs); | ||
825 | 755 | } | ||
826 | 756 | |||
827 | 289 | void ril_delayed_register(const struct ofono_error *error, void *user_data) | 757 | void ril_delayed_register(const struct ofono_error *error, void *user_data) |
828 | 290 | { | 758 | { |
829 | 291 | struct ofono_radio_settings *rs = user_data; | 759 | struct ofono_radio_settings *rs = user_data; |
830 | 760 | struct radio_data *rd = ofono_radio_settings_get_data(rs); | ||
831 | 292 | 761 | ||
832 | 293 | if (error->type != OFONO_ERROR_TYPE_NO_ERROR) | 762 | if (error->type != OFONO_ERROR_TYPE_NO_ERROR) |
833 | 294 | ofono_error("%s: cannot set default fast dormancy", __func__); | 763 | ofono_error("%s: cannot set default fast dormancy", __func__); |
834 | 295 | 764 | ||
840 | 296 | /* | 765 | rd->radio_settings = rs; |
841 | 297 | * We register in all cases, setting FD some times fails until radio is | 766 | |
842 | 298 | * available (this happens on turbo and maybe in other devices). | 767 | if (ofono_modem_get_integer(rd->modem, "Slot") == 0) |
843 | 299 | */ | 768 | radio_data_0 = rd; |
844 | 300 | ofono_radio_settings_register(rs); | 769 | else |
845 | 770 | radio_data_1 = rd; | ||
846 | 771 | |||
847 | 772 | rd->virt_tbl->query_rat_mode(rs, ril_after_query_rat_mode, rs); | ||
848 | 301 | } | 773 | } |
849 | 302 | 774 | ||
850 | 775 | static struct ofono_radio_settings_driver driver; | ||
851 | 776 | |||
852 | 303 | static int ril_radio_settings_probe(struct ofono_radio_settings *rs, | 777 | static int ril_radio_settings_probe(struct ofono_radio_settings *rs, |
853 | 304 | unsigned int vendor, void *user) | 778 | unsigned int vendor, void *user) |
854 | 305 | { | 779 | { |
855 | @@ -311,6 +785,7 @@ | |||
856 | 311 | return -ENOMEM; | 785 | return -ENOMEM; |
857 | 312 | } | 786 | } |
858 | 313 | 787 | ||
859 | 788 | rsd->virt_tbl = &driver; | ||
860 | 314 | rsd->ril = g_ril_clone(rs_init_data->gril); | 789 | rsd->ril = g_ril_clone(rs_init_data->gril); |
861 | 315 | rsd->modem = rs_init_data->modem; | 790 | rsd->modem = rs_init_data->modem; |
862 | 316 | 791 | ||
863 | @@ -324,8 +799,12 @@ | |||
864 | 324 | void ril_radio_settings_remove(struct ofono_radio_settings *rs) | 799 | void ril_radio_settings_remove(struct ofono_radio_settings *rs) |
865 | 325 | { | 800 | { |
866 | 326 | struct radio_data *rd = ofono_radio_settings_get_data(rs); | 801 | struct radio_data *rd = ofono_radio_settings_get_data(rs); |
867 | 802 | |||
868 | 327 | ofono_radio_settings_set_data(rs, NULL); | 803 | ofono_radio_settings_set_data(rs, NULL); |
869 | 328 | 804 | ||
870 | 805 | if (rd->gprs_atom_watch) | ||
871 | 806 | __ofono_modem_remove_atom_watch(rd->modem, rd->gprs_atom_watch); | ||
872 | 807 | |||
873 | 329 | g_ril_unref(rd->ril); | 808 | g_ril_unref(rd->ril); |
874 | 330 | g_free(rd); | 809 | g_free(rd); |
875 | 331 | } | 810 | } |
876 | 332 | 811 | ||
877 | === modified file 'drivers/rilmodem/radio-settings.h' | |||
878 | --- drivers/rilmodem/radio-settings.h 2015-07-31 13:44:26 +0000 | |||
879 | +++ drivers/rilmodem/radio-settings.h 2016-07-19 15:19:28 +0000 | |||
880 | @@ -19,11 +19,30 @@ | |||
881 | 19 | * | 19 | * |
882 | 20 | */ | 20 | */ |
883 | 21 | 21 | ||
884 | 22 | struct switch_data; | ||
885 | 23 | |||
886 | 22 | struct radio_data { | 24 | struct radio_data { |
887 | 25 | struct ofono_radio_settings_driver *virt_tbl; | ||
888 | 23 | GRil *ril; | 26 | GRil *ril; |
889 | 24 | struct ofono_modem *modem; | 27 | struct ofono_modem *modem; |
890 | 28 | struct ofono_radio_settings *radio_settings; | ||
891 | 25 | gboolean fast_dormancy; | 29 | gboolean fast_dormancy; |
892 | 26 | gboolean pending_fd; | 30 | gboolean pending_fd; |
893 | 31 | int rat_mode; | ||
894 | 32 | int pending_mode; | ||
895 | 33 | unsigned available_rats; | ||
896 | 34 | int ril_rats; | ||
897 | 35 | char modem_uuid[RIL_MAX_UUID_LENGTH]; | ||
898 | 36 | struct switch_data *switch_d; | ||
899 | 37 | unsigned gprs_atom_watch; | ||
900 | 38 | }; | ||
901 | 39 | |||
902 | 40 | struct switch_data { | ||
903 | 41 | struct radio_data *rd_1; | ||
904 | 42 | struct radio_data *rd_2; | ||
905 | 43 | enum ofono_radio_access_mode mode_to_switch; | ||
906 | 44 | int pending_msgs; | ||
907 | 45 | struct cb_data *cbd; | ||
908 | 27 | }; | 46 | }; |
909 | 28 | 47 | ||
910 | 29 | void ril_delayed_register(const struct ofono_error *error, void *user_data); | 48 | void ril_delayed_register(const struct ofono_error *error, void *user_data); |
911 | 30 | 49 | ||
912 | === modified file 'gril/grilreply.c' | |||
913 | --- gril/grilreply.c 2016-06-28 15:26:37 +0000 | |||
914 | +++ gril/grilreply.c 2016-07-19 15:19:28 +0000 | |||
915 | @@ -1477,8 +1477,11 @@ | |||
916 | 1477 | reply->phase = parcel_r_int32(&rilp); | 1477 | reply->phase = parcel_r_int32(&rilp); |
917 | 1478 | reply->rat = parcel_r_int32(&rilp); | 1478 | reply->rat = parcel_r_int32(&rilp); |
918 | 1479 | modem_uuid = parcel_r_string(&rilp); | 1479 | modem_uuid = parcel_r_string(&rilp); |
921 | 1480 | if (modem_uuid != NULL) | 1480 | if (modem_uuid != NULL) { |
922 | 1481 | strcpy(reply->modem_uuid, modem_uuid); | 1481 | strncpy(reply->modem_uuid, modem_uuid, |
923 | 1482 | sizeof(reply->modem_uuid) - 1); | ||
924 | 1483 | g_free(modem_uuid); | ||
925 | 1484 | } | ||
926 | 1482 | 1485 | ||
927 | 1483 | reply->status = parcel_r_int32(&rilp); | 1486 | reply->status = parcel_r_int32(&rilp); |
928 | 1484 | 1487 | ||
929 | @@ -1552,7 +1555,10 @@ | |||
930 | 1552 | reply->modem_uuid, | 1555 | reply->modem_uuid, |
931 | 1553 | ril_rc_status_to_string(reply->status)); | 1556 | ril_rc_status_to_string(reply->status)); |
932 | 1554 | 1557 | ||
934 | 1555 | g_ril_print_response(gril, message); | 1558 | if (message->unsolicited) |
935 | 1559 | g_ril_print_unsol(gril, message); | ||
936 | 1560 | else | ||
937 | 1561 | g_ril_print_response(gril, message); | ||
938 | 1556 | 1562 | ||
939 | 1557 | end: | 1563 | end: |
940 | 1558 | return reply; | 1564 | return reply; |
941 | 1559 | 1565 | ||
942 | === modified file 'include/gprs.h' | |||
943 | --- include/gprs.h 2015-01-28 13:58:34 +0000 | |||
944 | +++ include/gprs.h 2016-07-19 15:19:28 +0000 | |||
945 | @@ -46,10 +46,6 @@ | |||
946 | 46 | ofono_gprs_cb_t cb, void *data); | 46 | ofono_gprs_cb_t cb, void *data); |
947 | 47 | void (*attached_status)(struct ofono_gprs *gprs, | 47 | void (*attached_status)(struct ofono_gprs *gprs, |
948 | 48 | ofono_gprs_status_cb_t cb, void *data); | 48 | ofono_gprs_status_cb_t cb, void *data); |
949 | 49 | void (*set_ia_apn)(struct ofono_gprs *gprs, const char *apn, | ||
950 | 50 | enum ofono_gprs_proto proto, const char *user, | ||
951 | 51 | const char *passwd, const char *mccmnc, | ||
952 | 52 | ofono_gprs_cb_t cb, void *data); | ||
953 | 53 | }; | 49 | }; |
954 | 54 | 50 | ||
955 | 55 | enum gprs_suspend_cause { | 51 | enum gprs_suspend_cause { |
956 | @@ -82,6 +78,8 @@ | |||
957 | 82 | unsigned int min, unsigned int max); | 78 | unsigned int min, unsigned int max); |
958 | 83 | void ofono_gprs_add_context(struct ofono_gprs *gprs, | 79 | void ofono_gprs_add_context(struct ofono_gprs *gprs, |
959 | 84 | struct ofono_gprs_context *gc); | 80 | struct ofono_gprs_context *gc); |
960 | 81 | const struct ofono_gprs_primary_context *ofono_gprs_get_ia_apn( | ||
961 | 82 | struct ofono_gprs *gprs, char *mccmnc); | ||
962 | 85 | 83 | ||
963 | 86 | #ifdef __cplusplus | 84 | #ifdef __cplusplus |
964 | 87 | } | 85 | } |
965 | 88 | 86 | ||
966 | === modified file 'plugins/ril.c' | |||
967 | --- plugins/ril.c 2016-06-30 17:41:18 +0000 | |||
968 | +++ plugins/ril.c 2016-07-19 15:19:28 +0000 | |||
969 | @@ -128,6 +128,33 @@ | |||
970 | 128 | return RILMODEM; | 128 | return RILMODEM; |
971 | 129 | } | 129 | } |
972 | 130 | 130 | ||
973 | 131 | /* | ||
974 | 132 | * oFono moves to "Online" state only when told to online the modem AND there is | ||
975 | 133 | * a SIM a card. However, we want to have RadioSettings even when there is no | ||
976 | 134 | * SIM, but we also want it *only* when we are online. Normally, ofono atoms are | ||
977 | 135 | * created/destroyed when the ofono state changes, but for this atom the ofono | ||
978 | 136 | * states do not fit, as we do never move from Offline state if there is no SIM. | ||
979 | 137 | * Therefore, we handle this atom on modem onlining/offlining. | ||
980 | 138 | */ | ||
981 | 139 | static void manage_radio_settings_atom(struct ofono_modem *modem) | ||
982 | 140 | { | ||
983 | 141 | struct ril_data *rd = ofono_modem_get_data(modem); | ||
984 | 142 | struct ofono_radio_settings *rs; | ||
985 | 143 | |||
986 | 144 | rs = __ofono_atom_find(OFONO_ATOM_TYPE_RADIO_SETTINGS, modem); | ||
987 | 145 | |||
988 | 146 | if (rd->ofono_online && rs == NULL) { | ||
989 | 147 | struct ril_radio_settings_driver_data rs_data = | ||
990 | 148 | { rd->ril, modem }; | ||
991 | 149 | |||
992 | 150 | ofono_radio_settings_create(modem, rd->vendor, | ||
993 | 151 | get_driver_type(rd, OFONO_ATOM_TYPE_RADIO_SETTINGS), | ||
994 | 152 | &rs_data); | ||
995 | 153 | } else if(!rd->ofono_online && rs != NULL) { | ||
996 | 154 | ofono_radio_settings_remove(rs); | ||
997 | 155 | } | ||
998 | 156 | } | ||
999 | 157 | |||
1000 | 131 | static void ril_send_power(struct ril_data *rd, ofono_bool_t online, | 158 | static void ril_send_power(struct ril_data *rd, ofono_bool_t online, |
1001 | 132 | GRilResponseFunc func, gpointer user_data) | 159 | GRilResponseFunc func, gpointer user_data) |
1002 | 133 | { | 160 | { |
1003 | @@ -206,6 +233,8 @@ | |||
1004 | 206 | 233 | ||
1005 | 207 | DBG("%s: set_online OK: rd->ofono_online: %d", | 234 | DBG("%s: set_online OK: rd->ofono_online: %d", |
1006 | 208 | __func__, rd->ofono_online); | 235 | __func__, rd->ofono_online); |
1007 | 236 | manage_radio_settings_atom(modem); | ||
1008 | 237 | |||
1009 | 209 | CALLBACK_WITH_SUCCESS(cb, rd->set_online_cbd->data); | 238 | CALLBACK_WITH_SUCCESS(cb, rd->set_online_cbd->data); |
1010 | 210 | 239 | ||
1011 | 211 | g_free(rd->set_online_cbd); | 240 | g_free(rd->set_online_cbd); |
1012 | @@ -286,7 +315,6 @@ | |||
1013 | 286 | struct ril_data *rd = ofono_modem_get_data(modem); | 315 | struct ril_data *rd = ofono_modem_get_data(modem); |
1014 | 287 | struct ril_voicecall_driver_data vc_data = { rd->ril, modem }; | 316 | struct ril_voicecall_driver_data vc_data = { rd->ril, modem }; |
1015 | 288 | struct ril_sim_data sim_data; | 317 | struct ril_sim_data sim_data; |
1016 | 289 | struct ril_radio_settings_driver_data rs_data = { rd->ril, modem }; | ||
1017 | 290 | 318 | ||
1018 | 291 | DBG(""); | 319 | DBG(""); |
1019 | 292 | 320 | ||
1020 | @@ -306,16 +334,6 @@ | |||
1021 | 306 | 334 | ||
1022 | 307 | rd->sim = ofono_sim_create(modem, rd->vendor, | 335 | rd->sim = ofono_sim_create(modem, rd->vendor, |
1023 | 308 | get_driver_type(rd, OFONO_ATOM_TYPE_SIM), &sim_data); | 336 | get_driver_type(rd, OFONO_ATOM_TYPE_SIM), &sim_data); |
1024 | 309 | |||
1025 | 310 | /* | ||
1026 | 311 | * We need to create radio settings here so FastDormancy property is | ||
1027 | 312 | * available even when there is no SIM (no SIM -> post_sim and | ||
1028 | 313 | * post_online are not called) so we can make the modem enter low power | ||
1029 | 314 | * state in that case. | ||
1030 | 315 | */ | ||
1031 | 316 | ofono_radio_settings_create(modem, rd->vendor, | ||
1032 | 317 | get_driver_type(rd, OFONO_ATOM_TYPE_RADIO_SETTINGS), | ||
1033 | 318 | &rs_data); | ||
1034 | 319 | } | 337 | } |
1035 | 320 | 338 | ||
1036 | 321 | void ril_post_sim(struct ofono_modem *modem) | 339 | void ril_post_sim(struct ofono_modem *modem) |
1037 | @@ -334,7 +352,7 @@ | |||
1038 | 334 | get_driver_type(rd, OFONO_ATOM_TYPE_PHONEBOOK), modem); | 352 | get_driver_type(rd, OFONO_ATOM_TYPE_PHONEBOOK), modem); |
1039 | 335 | } | 353 | } |
1040 | 336 | 354 | ||
1042 | 337 | static void create_post_online_atoms(struct ofono_modem *modem) | 355 | void ril_post_online(struct ofono_modem *modem) |
1043 | 338 | { | 356 | { |
1044 | 339 | struct ril_data *rd = ofono_modem_get_data(modem); | 357 | struct ril_data *rd = ofono_modem_get_data(modem); |
1045 | 340 | struct ofono_gprs *gprs; | 358 | struct ofono_gprs *gprs; |
1046 | @@ -382,47 +400,6 @@ | |||
1047 | 382 | } | 400 | } |
1048 | 383 | } | 401 | } |
1049 | 384 | 402 | ||
1050 | 385 | static void get_radio_caps_cb(struct ril_msg *message, gpointer user_data) | ||
1051 | 386 | { | ||
1052 | 387 | struct ofono_modem *modem = user_data; | ||
1053 | 388 | struct ril_data *rd = ofono_modem_get_data(modem); | ||
1054 | 389 | struct reply_radio_capability *caps; | ||
1055 | 390 | |||
1056 | 391 | if (message->error == RIL_E_SUCCESS) { | ||
1057 | 392 | caps = g_ril_reply_parse_get_radio_capability(rd->ril, message); | ||
1058 | 393 | if (caps != NULL && (caps->rat & RIL_RAF_LTE)) { | ||
1059 | 394 | ofono_modem_set_boolean(modem, | ||
1060 | 395 | MODEM_PROP_LTE_CAPABLE, TRUE); | ||
1061 | 396 | g_free(caps); | ||
1062 | 397 | } | ||
1063 | 398 | } else { | ||
1064 | 399 | ofono_error("%s: RIL error %s", __func__, | ||
1065 | 400 | ril_error_to_string(message->error)); | ||
1066 | 401 | } | ||
1067 | 402 | |||
1068 | 403 | create_post_online_atoms(modem); | ||
1069 | 404 | } | ||
1070 | 405 | |||
1071 | 406 | void ril_post_online(struct ofono_modem *modem) | ||
1072 | 407 | { | ||
1073 | 408 | struct ril_data *rd = ofono_modem_get_data(modem); | ||
1074 | 409 | ofono_bool_t lte_cap; | ||
1075 | 410 | |||
1076 | 411 | /* Radio ON -> we can ask for capabilities */ | ||
1077 | 412 | if (g_ril_get_version(rd->ril) >= 11) { | ||
1078 | 413 | if (g_ril_send(rd->ril, RIL_REQUEST_GET_RADIO_CAPABILITY, NULL, | ||
1079 | 414 | get_radio_caps_cb, modem, NULL)) | ||
1080 | 415 | return; | ||
1081 | 416 | |||
1082 | 417 | ofono_error("%s: error sending GET_RADIO_CAPABILITY", __func__); | ||
1083 | 418 | } | ||
1084 | 419 | |||
1085 | 420 | lte_cap = getenv("OFONO_RIL_RAT_LTE") ? TRUE : FALSE; | ||
1086 | 421 | ofono_modem_set_boolean(modem, MODEM_PROP_LTE_CAPABLE, lte_cap); | ||
1087 | 422 | |||
1088 | 423 | create_post_online_atoms(modem); | ||
1089 | 424 | } | ||
1090 | 425 | |||
1091 | 426 | static void ril_set_online_cb(struct ril_msg *message, gpointer user_data) | 403 | static void ril_set_online_cb(struct ril_msg *message, gpointer user_data) |
1092 | 427 | { | 404 | { |
1093 | 428 | struct ril_data *rd = user_data; | 405 | struct ril_data *rd = user_data; |
1094 | @@ -449,11 +426,14 @@ | |||
1095 | 449 | static gboolean set_online_done_cb(gpointer user_data) | 426 | static gboolean set_online_done_cb(gpointer user_data) |
1096 | 450 | { | 427 | { |
1097 | 451 | struct cb_data *cbd = user_data; | 428 | struct cb_data *cbd = user_data; |
1099 | 452 | struct ril_data *rd = cbd->user; | 429 | struct ofono_modem *modem = cbd->user; |
1100 | 430 | struct ril_data *rd = ofono_modem_get_data(modem); | ||
1101 | 453 | ofono_modem_online_cb_t cb = cbd->cb; | 431 | ofono_modem_online_cb_t cb = cbd->cb; |
1102 | 454 | 432 | ||
1103 | 455 | DBG("%s: set_online OK: rd->ofono_online: %d", | 433 | DBG("%s: set_online OK: rd->ofono_online: %d", |
1104 | 456 | __func__, rd->ofono_online); | 434 | __func__, rd->ofono_online); |
1105 | 435 | manage_radio_settings_atom(modem); | ||
1106 | 436 | |||
1107 | 457 | CALLBACK_WITH_SUCCESS(cb, cbd->data); | 437 | CALLBACK_WITH_SUCCESS(cb, cbd->data); |
1108 | 458 | g_free(cbd); | 438 | g_free(cbd); |
1109 | 459 | 439 | ||
1110 | @@ -464,7 +444,7 @@ | |||
1111 | 464 | ofono_modem_online_cb_t callback, void *data) | 444 | ofono_modem_online_cb_t callback, void *data) |
1112 | 465 | { | 445 | { |
1113 | 466 | struct ril_data *rd = ofono_modem_get_data(modem); | 446 | struct ril_data *rd = ofono_modem_get_data(modem); |
1115 | 467 | struct cb_data *cbd = cb_data_new(callback, data, rd); | 447 | struct cb_data *cbd = cb_data_new(callback, data, modem); |
1116 | 468 | 448 | ||
1117 | 469 | rd->ofono_online = online; | 449 | rd->ofono_online = online; |
1118 | 470 | 450 | ||
1119 | 471 | 451 | ||
1120 | === modified file 'src/gprs.c' | |||
1121 | --- src/gprs.c 2016-06-28 15:26:37 +0000 | |||
1122 | +++ src/gprs.c 2016-07-19 15:19:28 +0000 | |||
1123 | @@ -3444,32 +3444,20 @@ | |||
1124 | 3444 | return gprs->contexts->data; | 3444 | return gprs->contexts->data; |
1125 | 3445 | } | 3445 | } |
1126 | 3446 | 3446 | ||
1134 | 3447 | static void set_ia_apn_cb(const struct ofono_error *error, void *data) | 3447 | const struct ofono_gprs_primary_context *ofono_gprs_get_ia_apn( |
1135 | 3448 | { | 3448 | struct ofono_gprs *gprs, char *mccmnc) |
1129 | 3449 | if (error->type != OFONO_ERROR_TYPE_NO_ERROR) | ||
1130 | 3450 | ofono_error("Could not set IA APN"); | ||
1131 | 3451 | } | ||
1132 | 3452 | |||
1133 | 3453 | static void set_ia_apn(struct ofono_gprs *gprs) | ||
1136 | 3454 | { | 3449 | { |
1137 | 3455 | struct pri_context *ctx = gprs_context_for_ia(gprs); | 3450 | struct pri_context *ctx = gprs_context_for_ia(gprs); |
1138 | 3456 | struct ofono_gprs_primary_context *ofono_ctx; | ||
1139 | 3457 | char mccmnc[OFONO_MAX_MCC_LENGTH + OFONO_MAX_MNC_LENGTH + 1]; | ||
1140 | 3458 | const char *mcc = ofono_sim_get_mcc(gprs->sim); | 3451 | const char *mcc = ofono_sim_get_mcc(gprs->sim); |
1141 | 3459 | const char *mnc = ofono_sim_get_mnc(gprs->sim); | 3452 | const char *mnc = ofono_sim_get_mnc(gprs->sim); |
1142 | 3460 | 3453 | ||
1143 | 3461 | if (ctx == NULL) | 3454 | if (ctx == NULL) |
1147 | 3462 | return; | 3455 | return NULL; |
1145 | 3463 | |||
1146 | 3464 | ofono_ctx = &ctx->context; | ||
1148 | 3465 | 3456 | ||
1149 | 3466 | strcpy(mccmnc, mcc); | 3457 | strcpy(mccmnc, mcc); |
1150 | 3467 | strcpy(mccmnc + strlen(mcc), mnc); | 3458 | strcpy(mccmnc + strlen(mcc), mnc); |
1151 | 3468 | 3459 | ||
1156 | 3469 | gprs->driver->set_ia_apn(gprs, ofono_ctx->apn, ofono_ctx->proto, | 3460 | return &ctx->context; |
1153 | 3470 | ofono_ctx->username, | ||
1154 | 3471 | ofono_ctx->password, mccmnc, | ||
1155 | 3472 | set_ia_apn_cb, gprs); | ||
1157 | 3473 | } | 3461 | } |
1158 | 3474 | 3462 | ||
1159 | 3475 | static void ofono_gprs_finish_register(struct ofono_gprs *gprs) | 3463 | static void ofono_gprs_finish_register(struct ofono_gprs *gprs) |
1160 | @@ -3481,9 +3469,6 @@ | |||
1161 | 3481 | if (gprs->contexts == NULL) /* Automatic provisioning failed */ | 3469 | if (gprs->contexts == NULL) /* Automatic provisioning failed */ |
1162 | 3482 | add_context(gprs, NULL, OFONO_GPRS_CONTEXT_TYPE_INTERNET); | 3470 | add_context(gprs, NULL, OFONO_GPRS_CONTEXT_TYPE_INTERNET); |
1163 | 3483 | 3471 | ||
1164 | 3484 | if (gprs->driver->set_ia_apn) | ||
1165 | 3485 | set_ia_apn(gprs); | ||
1166 | 3486 | |||
1167 | 3487 | if (!g_dbus_register_interface(conn, path, | 3472 | if (!g_dbus_register_interface(conn, path, |
1168 | 3488 | OFONO_CONNECTION_MANAGER_INTERFACE, | 3473 | OFONO_CONNECTION_MANAGER_INTERFACE, |
1169 | 3489 | manager_methods, manager_signals, NULL, | 3474 | manager_methods, manager_signals, NULL, |
LGTM