qmi: fix whitespace
[platform/upstream/ofono.git] / drivers / qmimodem / gprs-context.c
1 /*
2  *
3  *  oFono - Open Source Telephony
4  *
5  *  Copyright (C) 2011-2012  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License version 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27
28 #include <ofono/log.h>
29 #include <ofono/modem.h>
30 #include <ofono/gprs-context.h>
31
32 #include "qmi.h"
33 #include "wds.h"
34
35 #include "qmimodem.h"
36
37 struct gprs_context_data {
38         struct qmi_service *wds;
39         unsigned int active_context;
40         uint32_t pkt_handle;
41 };
42
43 static void pkt_status_notify(struct qmi_result *result, void *user_data)
44 {
45         struct ofono_gprs_context *gc = user_data;
46         struct gprs_context_data *data = ofono_gprs_context_get_data(gc);
47         const struct qmi_wds_notify_conn_status *status;
48         uint16_t len;
49         uint8_t ip_family;
50
51         DBG("");
52
53         status = qmi_result_get(result, QMI_WDS_NOTIFY_CONN_STATUS, &len);
54         if (!status)
55                 return;
56
57         DBG("conn status %d", status->status);
58
59         if (qmi_result_get_uint8(result, QMI_WDS_NOTIFY_IP_FAMILY, &ip_family))
60                 DBG("ip family %d", ip_family);
61
62         switch (status->status) {
63         case QMI_WDS_CONN_STATUS_DISCONNECTED:
64                 ofono_gprs_context_deactivated(gc, data->active_context);
65                 data->active_context = 0;
66                 break;
67         }
68 }
69
70 static void get_settings_cb(struct qmi_result *result, void *user_data)
71 {
72         struct cb_data *cbd = user_data;
73         ofono_gprs_context_cb_t cb = cbd->cb;
74         struct ofono_gprs_context *gc = cbd->user;
75         struct ofono_modem *modem;
76         const char *interface;
77         uint8_t pdp_type, ip_family;
78
79         DBG("");
80
81         if (qmi_result_set_error(result, NULL))
82                 goto done;
83
84         if (qmi_result_get_uint8(result, QMI_WDS_RESULT_PDP_TYPE, &pdp_type))
85                 DBG("PDP type %d", pdp_type);
86
87         if (qmi_result_get_uint8(result, QMI_WDS_RESULT_IP_FAMILY, &ip_family))
88                 DBG("IP family %d", ip_family);
89
90 done:
91         modem = ofono_gprs_context_get_modem(gc);
92         interface = ofono_modem_get_string(modem, "NetworkInterface");
93
94         ofono_gprs_context_set_interface(gc, interface);
95
96         CALLBACK_WITH_SUCCESS(cb, cbd->data);
97
98         g_free(cbd);
99 }
100
101 static void start_net_cb(struct qmi_result *result, void *user_data)
102 {
103         struct cb_data *cbd = user_data;
104         ofono_gprs_context_cb_t cb = cbd->cb;
105         struct ofono_gprs_context *gc = cbd->user;
106         struct gprs_context_data *data = ofono_gprs_context_get_data(gc);
107         struct ofono_modem *modem;
108         const char *interface;
109         uint32_t handle;
110
111         DBG("");
112
113         if (qmi_result_set_error(result, NULL))
114                 goto error;
115
116         if (!qmi_result_get_uint32(result, QMI_WDS_RESULT_PKT_HANDLE, &handle))
117                 goto error;
118
119         DBG("packet handle %d", handle);
120
121         data->pkt_handle = handle;
122
123         if (qmi_service_send(data->wds, QMI_WDS_GET_SETTINGS, NULL,
124                                         get_settings_cb, cbd, NULL) > 0)
125                 return;
126
127         modem = ofono_gprs_context_get_modem(gc);
128         interface = ofono_modem_get_string(modem, "NetworkInterface");
129
130         ofono_gprs_context_set_interface(gc, interface);
131
132         CALLBACK_WITH_SUCCESS(cb, cbd->data);
133
134         g_free(cbd);
135
136         return;
137
138 error:
139         data->active_context = 0;
140
141         CALLBACK_WITH_FAILURE(cb, cbd->data);
142
143         g_free(cbd);
144 }
145
146 static void qmi_activate_primary(struct ofono_gprs_context *gc,
147                                 const struct ofono_gprs_primary_context *ctx,
148                                 ofono_gprs_context_cb_t cb, void *user_data)
149 {
150         struct gprs_context_data *data = ofono_gprs_context_get_data(gc);
151         struct cb_data *cbd = cb_data_new(cb, user_data);
152         struct qmi_param *param;
153         uint8_t ip_family;
154
155         DBG("cid %u", ctx->cid);
156
157         cbd->user = gc;
158
159         data->active_context = ctx->cid;
160
161         switch (ctx->proto) {
162         case OFONO_GPRS_PROTO_IP:
163                 ip_family = 4;
164                 break;
165         case OFONO_GPRS_PROTO_IPV6:
166                 ip_family = 6;
167                 break;
168         default:
169                 goto error;
170         }
171
172         param = qmi_param_new();
173         if (!param)
174                 goto error;
175
176         qmi_param_append(param, QMI_WDS_PARAM_APN,
177                                         strlen(ctx->apn), ctx->apn);
178
179         qmi_param_append_uint8(param, QMI_WDS_PARAM_IP_FAMILY, ip_family);
180
181         if (qmi_service_send(data->wds, QMI_WDS_START_NET, param,
182                                         start_net_cb, cbd, NULL) > 0)
183                 return;
184
185         qmi_param_free(param);
186
187 error:
188         data->active_context = 0;
189
190         CALLBACK_WITH_FAILURE(cb, cbd->data);
191
192         g_free(cbd);
193 }
194
195 static void stop_net_cb(struct qmi_result *result, void *user_data)
196 {
197         struct cb_data *cbd = user_data;
198         ofono_gprs_context_cb_t cb = cbd->cb;
199         struct ofono_gprs_context *gc = cbd->user;
200         struct gprs_context_data *data = ofono_gprs_context_get_data(gc);
201
202         DBG("");
203
204         if (qmi_result_set_error(result, NULL)) {
205                 CALLBACK_WITH_FAILURE(cb, cbd->data);
206                 return;
207         }
208
209         data->active_context = 0;
210
211         data->pkt_handle = 0;
212
213         CALLBACK_WITH_SUCCESS(cb, cbd->data);
214
215         g_free(cbd);
216 }
217
218 static void qmi_deactivate_primary(struct ofono_gprs_context *gc,
219                                 unsigned int cid,
220                                 ofono_gprs_context_cb_t cb, void *user_data)
221 {
222         struct gprs_context_data *data = ofono_gprs_context_get_data(gc);
223         struct cb_data *cbd = cb_data_new(cb, user_data);
224         struct qmi_param *param;
225
226         DBG("cid %u", cid);
227
228         cbd->user = gc;
229
230         param = qmi_param_new_uint32(QMI_WDS_PARAM_PKT_HANDLE,
231                                                 data->pkt_handle);
232         if (!param)
233                 goto error;
234
235         if (qmi_service_send(data->wds, QMI_WDS_STOP_NET, param,
236                                         stop_net_cb, cbd, NULL) > 0)
237                 return;
238
239         qmi_param_free(param);
240
241 error:
242         CALLBACK_WITH_FAILURE(cb, cbd->data);
243
244         g_free(cbd);
245 }
246
247 static void create_wds_cb(struct qmi_service *service, void *user_data)
248 {
249         struct ofono_gprs_context *gc = user_data;
250         struct gprs_context_data *data = ofono_gprs_context_get_data(gc);
251
252         DBG("");
253
254         if (!service) {
255                 ofono_error("Failed to request WDS service");
256                 ofono_gprs_context_remove(gc);
257                 return;
258         }
259
260         data->wds = qmi_service_ref(service);
261
262         qmi_service_register(data->wds, QMI_WDS_PKT_STATUS_IND,
263                                         pkt_status_notify, gc, NULL);
264 }
265
266 static int qmi_gprs_context_probe(struct ofono_gprs_context *gc,
267                                         unsigned int vendor, void *user_data)
268 {
269         struct qmi_device *device = user_data;
270         struct gprs_context_data *data;
271
272         DBG("");
273
274         data = g_new0(struct gprs_context_data, 1);
275
276         ofono_gprs_context_set_data(gc, data);
277
278         qmi_service_create(device, QMI_SERVICE_WDS, create_wds_cb, gc, NULL);
279
280         return 0;
281 }
282
283 static void qmi_gprs_context_remove(struct ofono_gprs_context *gc)
284 {
285         struct gprs_context_data *data = ofono_gprs_context_get_data(gc);
286
287         DBG("");
288
289         ofono_gprs_context_set_data(gc, NULL);
290
291         qmi_service_unregister_all(data->wds);
292
293         qmi_service_unref(data->wds);
294
295         g_free(data);
296 }
297
298 static struct ofono_gprs_context_driver driver = {
299         .name                   = "qmimodem",
300         .probe                  = qmi_gprs_context_probe,
301         .remove                 = qmi_gprs_context_remove,
302         .activate_primary       = qmi_activate_primary,
303         .deactivate_primary     = qmi_deactivate_primary,
304 };
305
306 void qmi_gprs_context_init(void)
307 {
308         ofono_gprs_context_driver_register(&driver);
309 }
310
311 void qmi_gprs_context_exit(void)
312 {
313         ofono_gprs_context_driver_unregister(&driver);
314 }