Define and use RIL_TOKEN_NULL
[samsung-ril.git] / gprs.c
1 /*
2  * This file is part of Samsung-RIL.
3  *
4  * Copyright (C) 2011-2012 Paul Kocialkowski <contact@paulk.fr>
5  * Copyright (C) 2011 Denis 'GNUtoo' Carikli <GNUtoo@no-log.org>
6  *
7  * Samsung-RIL is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Samsung-RIL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Samsung-RIL.  If not, see <http://www.gnu.org/licenses/>.
19  *
20  */
21
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
24
25 #define LOG_TAG "RIL-GPRS"
26 #include <utils/Log.h>
27 #include <cutils/properties.h>
28
29 #if RIL_VERSION >= 6
30 #include <netutils/ifc.h>
31 #endif
32
33 #include "samsung-ril.h"
34 #include "util.h"
35
36 #if RIL_VERSION >= 6
37 RIL_DataCallFailCause ipc2ril_gprs_fail_cause(unsigned short fail_cause)
38 #else
39 RIL_LastDataCallActivateFailCause ipc2ril_gprs_fail_cause(unsigned short fail_cause)
40 #endif
41 {
42         switch(fail_cause) {
43
44                 case IPC_GPRS_FAIL_INSUFFICIENT_RESOURCES:
45                         return PDP_FAIL_INSUFFICIENT_RESOURCES;
46                 case IPC_GPRS_FAIL_MISSING_UKNOWN_APN:
47                         return PDP_FAIL_MISSING_UKNOWN_APN;
48                 case IPC_GPRS_FAIL_UNKNOWN_PDP_ADDRESS_TYPE:
49                         return PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE;
50                 case IPC_GPRS_FAIL_USER_AUTHENTICATION:
51                         return PDP_FAIL_USER_AUTHENTICATION;
52                 case IPC_GPRS_FAIL_ACTIVATION_REJECT_GGSN:
53                         return PDP_FAIL_ACTIVATION_REJECT_GGSN;
54                 case IPC_GPRS_FAIL_ACTIVATION_REJECT_UNSPECIFIED:
55                         return PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED;
56                 case IPC_GPRS_FAIL_SERVICE_OPTION_NOT_SUPPORTED:
57                         return PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED;
58                 case IPC_GPRS_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED:
59                         return PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED;
60                 case IPC_GPRS_FAIL_SERVICE_OPTION_OUT_OF_ORDER:
61                         return PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER;
62                 case IPC_GPRS_FAIL_NSAPI_IN_USE:
63                         return PDP_FAIL_NSAPI_IN_USE;
64                 default:
65                         return PDP_FAIL_ERROR_UNSPECIFIED;
66         }
67 }
68
69 int ipc2ril_gprs_connection_active(unsigned char state)
70 {
71         switch(state) {
72                 case IPC_GPRS_STATE_DISABLED:
73                         return 1;
74                 case IPC_GPRS_STATE_ENABLED:
75                         return 2;
76                 case IPC_GPRS_STATE_NOT_ENABLED:
77                 default:
78                         return 0;
79         }
80 }
81
82 int ril_gprs_connection_register(int cid)
83 {
84         struct ril_gprs_connection *gprs_connection;
85         struct list_head *list_end;
86         struct list_head *list;
87
88         gprs_connection = calloc(1, sizeof(struct ril_gprs_connection));
89         if (gprs_connection == NULL)
90                 return -1;
91
92         gprs_connection->cid = cid;
93
94         list_end = ril_data.gprs_connections;
95         while (list_end != NULL && list_end->next != NULL)
96                 list_end = list_end->next;
97
98         list = list_head_alloc((void *) gprs_connection, list_end, NULL);
99
100         if (ril_data.gprs_connections == NULL)
101                 ril_data.gprs_connections = list;
102
103         return 0;
104 }
105
106 void ril_gprs_connection_unregister(struct ril_gprs_connection *gprs_connection)
107 {
108         struct list_head *list;
109
110         if (gprs_connection == NULL)
111                 return;
112
113         list = ril_data.gprs_connections;
114         while (list != NULL) {
115                 if (list->data == (void *) gprs_connection) {
116                         memset(gprs_connection, 0, sizeof(struct ril_gprs_connection));
117                         free(gprs_connection);
118
119                         if (list == ril_data.gprs_connections)
120                                 ril_data.gprs_connections = list->next;
121
122                         list_head_free(list);
123
124                         break;
125                 }
126 list_continue:
127                 list = list->next;
128         }
129 }
130
131 struct ril_gprs_connection *ril_gprs_connection_find_cid(int cid)
132 {
133         struct ril_gprs_connection *gprs_connection;
134         struct list_head *list;
135
136         list = ril_data.gprs_connections;
137         while (list != NULL) {
138                 gprs_connection = (struct ril_gprs_connection *) list->data;
139                 if (gprs_connection == NULL)
140                         goto list_continue;
141
142                 if (gprs_connection->cid == cid)
143                         return gprs_connection;
144
145 list_continue:
146                 list = list->next;
147         }
148
149         return NULL;
150 }
151
152 struct ril_gprs_connection *ril_gprs_connection_find_token(RIL_Token t)
153 {
154         struct ril_gprs_connection *gprs_connection;
155         struct list_head *list;
156
157         list = ril_data.gprs_connections;
158         while (list != NULL) {
159                 gprs_connection = (struct ril_gprs_connection *) list->data;
160                 if (gprs_connection == NULL)
161                         goto list_continue;
162
163                 if (gprs_connection->token == t)
164                         return gprs_connection;
165
166 list_continue:
167                 list = list->next;
168         }
169
170         return NULL;
171 }
172
173 struct ril_gprs_connection *ril_gprs_connection_start(void)
174 {
175         struct ipc_client_gprs_capabilities gprs_capabilities;
176         struct ril_gprs_connection *gprs_connection;
177         struct ipc_client_data *ipc_client_data;
178         struct ipc_client *ipc_client;
179         struct list_head *list;
180         int cid, cid_max;
181         int rc;
182         int i;
183
184         if (ril_data.ipc_fmt_client == NULL || ril_data.ipc_fmt_client->data == NULL)
185                 return NULL;
186
187         ipc_client_data = (struct ipc_client_data *) ril_data.ipc_fmt_client->data;
188
189         if (ipc_client_data->ipc_client == NULL)
190                 return NULL;
191
192         ipc_client = ipc_client_data->ipc_client;
193
194         ipc_client_gprs_get_capabilities(ipc_client, &gprs_capabilities);
195         cid_max = gprs_capabilities.cid_max;
196
197         for (i=0 ; i < cid_max ; i++) {
198                 cid = i + 1;
199                 list = ril_data.gprs_connections;
200                 while (list != NULL) {
201                         if (list->data == NULL)
202                                 goto list_continue;
203
204                         gprs_connection = (struct ril_gprs_connection *) list->data;
205                         if (gprs_connection->cid == cid) {
206                                 cid = 0;
207                                 break;
208                         }
209
210 list_continue:
211                         list = list->next;
212                 }
213
214                 if (cid > 0)
215                         break;
216         }
217
218         if (cid <= 0) {
219                 LOGE("Unable to find an unused cid, aborting");
220                 return NULL;
221         }
222
223         LOGD("Using GPRS connection cid: %d", cid);
224         rc = ril_gprs_connection_register(cid);
225         if (rc < 0)
226                 return NULL;
227
228         gprs_connection = ril_gprs_connection_find_cid(cid);
229         return gprs_connection;
230 }
231
232 void ril_gprs_connection_stop(struct ril_gprs_connection *gprs_connection)
233 {
234         if (gprs_connection == NULL)
235                 return;
236
237         if (gprs_connection->interface != NULL)
238                 free(gprs_connection->interface);
239
240         ril_gprs_connection_unregister(gprs_connection);
241 }
242
243 void ipc_gprs_pdp_context_enable_complete(struct ipc_message_info *info)
244 {
245         struct ipc_gen_phone_res *phone_res;
246         struct ril_gprs_connection *gprs_connection;
247         int rc;
248
249         phone_res = (struct ipc_gen_phone_res *) info->data;
250         gprs_connection = ril_gprs_connection_find_token(ril_request_get_token(info->aseq));
251
252         if (!gprs_connection) {
253                 LOGE("Unable to find GPRS connection, aborting");
254
255                 ril_request_complete(ril_request_get_token(info->aseq),
256                         RIL_E_GENERIC_FAILURE, NULL, 0);
257                 return;
258         }
259
260         rc = ipc_gen_phone_res_check(phone_res);
261         if (rc < 0) {
262                 LOGE("There was an error, aborting PDP context complete");
263
264                 gprs_connection->fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
265                 gprs_connection->token = RIL_TOKEN_NULL;
266                 ril_data.state.gprs_last_failed_cid = gprs_connection->cid;
267
268                 ril_request_complete(ril_request_get_token(info->aseq),
269                         RIL_E_GENERIC_FAILURE, NULL, 0);
270                 return;
271         }
272
273         LOGD("Waiting for IP configuration!");
274 }
275
276 void ipc_gprs_define_pdp_context_complete(struct ipc_message_info *info)
277 {
278         struct ipc_gen_phone_res *phone_res;
279         struct ril_gprs_connection *gprs_connection;
280         struct ril_request_info *request;
281         int aseq;
282         int rc;
283
284         phone_res = (struct ipc_gen_phone_res *) info->data;
285         gprs_connection = ril_gprs_connection_find_token(ril_request_get_token(info->aseq));
286
287         if (!gprs_connection) {
288                 LOGE("Unable to find GPRS connection, aborting");
289
290                 ril_request_complete(ril_request_get_token(info->aseq),
291                         RIL_E_GENERIC_FAILURE, NULL, 0);
292                 return;
293         }
294
295         rc = ipc_gen_phone_res_check(phone_res);
296         if (rc < 0) {
297                 LOGE("There was an error, aborting define PDP context complete");
298
299                 gprs_connection->fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
300                 gprs_connection->token = RIL_TOKEN_NULL;
301                 ril_data.state.gprs_last_failed_cid = gprs_connection->cid;
302
303                 ril_request_complete(ril_request_get_token(info->aseq),
304                         RIL_E_GENERIC_FAILURE, NULL, 0);
305                 return;
306         }
307
308         request = ril_request_info_find_id(info->aseq);
309         aseq = ril_request_id_get();
310
311         if (request != NULL)
312                 request->id = aseq;
313
314         ipc_gen_phone_res_expect_to_func(aseq, IPC_GPRS_PDP_CONTEXT,
315                 ipc_gprs_pdp_context_enable_complete);
316
317         ipc_fmt_send(IPC_GPRS_PDP_CONTEXT, IPC_TYPE_SET,
318                         (void *) &(gprs_connection->context),
319                         sizeof(struct ipc_gprs_pdp_context_set), aseq);
320 }
321
322 void ipc_gprs_port_list_complete(struct ipc_message_info *info)
323 {
324         struct ipc_gen_phone_res *phone_res;
325         struct ril_gprs_connection *gprs_connection;
326         struct ril_request_info *request;
327         int aseq;
328         int rc;
329
330         phone_res = (struct ipc_gen_phone_res *) info->data;
331         gprs_connection = ril_gprs_connection_find_token(ril_request_get_token(info->aseq));
332
333         if (!gprs_connection) {
334                 LOGE("Unable to find GPRS connection, aborting");
335
336                 ril_request_complete(ril_request_get_token(info->aseq),
337                         RIL_E_GENERIC_FAILURE, NULL, 0);
338                 return;
339         }
340
341         rc = ipc_gen_phone_res_check(phone_res);
342         if (rc < 0) {
343                 LOGE("There was an error, aborting port list complete");
344
345                 gprs_connection->fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
346                 gprs_connection->token = RIL_TOKEN_NULL;
347                 ril_data.state.gprs_last_failed_cid = gprs_connection->cid;
348
349                 ril_request_complete(ril_request_get_token(info->aseq),
350                         RIL_E_GENERIC_FAILURE, NULL, 0);
351                 return;
352         }
353
354         request = ril_request_info_find_id(info->aseq);
355         aseq = ril_request_id_get();
356
357         if (request != NULL)
358                 request->id = aseq;
359         ipc_gen_phone_res_expect_to_func(aseq, IPC_GPRS_DEFINE_PDP_CONTEXT,
360                 ipc_gprs_define_pdp_context_complete);
361
362         ipc_fmt_send(IPC_GPRS_DEFINE_PDP_CONTEXT, IPC_TYPE_SET,
363                 (void *) &(gprs_connection->define_context),
364                 sizeof(struct ipc_gprs_define_pdp_context),
365                 aseq);
366 }
367
368 void ril_request_setup_data_call(RIL_Token t, void *data, int length)
369 {
370         struct ril_gprs_connection *gprs_connection = NULL;
371         struct ipc_client_gprs_capabilities gprs_capabilities;
372         struct ipc_gprs_port_list port_list;
373         struct ipc_client_data *ipc_client_data;
374         struct ipc_client *ipc_client;
375
376         char *username = NULL;
377         char *password = NULL;
378         char *apn = NULL;
379
380         if (data == NULL || length < (int) (4 * sizeof(char *)))
381                 goto error;
382
383         if (ril_data.ipc_fmt_client == NULL || ril_data.ipc_fmt_client->data == NULL)
384                 goto error;
385
386         ipc_client_data = (struct ipc_client_data *) ril_data.ipc_fmt_client->data;
387
388         if (ipc_client_data->ipc_client == NULL)
389                 goto error;
390
391         ipc_client = ipc_client_data->ipc_client;
392
393         apn = ((char **) data)[2];
394         username = ((char **) data)[3];
395         password = ((char **) data)[4];
396
397         LOGD("Requesting data connection to APN '%s'\n", apn);
398
399         gprs_connection = ril_gprs_connection_start();
400
401         if (!gprs_connection) {
402                 LOGE("Unable to create GPRS connection, aborting");
403
404                 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
405                 return;
406         }
407
408         gprs_connection->token = t;
409
410         // Create the structs with the apn
411         ipc_gprs_define_pdp_context_setup(&(gprs_connection->define_context),
412                 gprs_connection->cid, 1, apn);
413
414         // Create the structs with the username/password tuple
415         ipc_gprs_pdp_context_setup(&(gprs_connection->context),
416                 gprs_connection->cid, 1, username, password);
417
418         ipc_client_gprs_get_capabilities(ipc_client, &gprs_capabilities);
419
420         // If the device has the capability, deal with port list
421         if (gprs_capabilities.port_list) {
422                 ipc_gprs_port_list_setup(&port_list);
423
424                 ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_GPRS_PORT_LIST,
425                         ipc_gprs_port_list_complete);
426
427                 ipc_fmt_send(IPC_GPRS_PORT_LIST, IPC_TYPE_SET,
428                         (void *) &port_list, sizeof(struct ipc_gprs_port_list), ril_request_get_id(t));
429         } else {
430                 ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_GPRS_DEFINE_PDP_CONTEXT,
431                         ipc_gprs_define_pdp_context_complete);
432
433                 ipc_fmt_send(IPC_GPRS_DEFINE_PDP_CONTEXT, IPC_TYPE_SET,
434                         (void *) &(gprs_connection->define_context),
435                                 sizeof(struct ipc_gprs_define_pdp_context), ril_request_get_id(t));
436         }
437
438         return;
439
440 error:
441         ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
442 }
443
444 void ipc_gprs_ip_configuration(struct ipc_message_info *info)
445 {
446         struct ril_gprs_connection *gprs_connection;
447         struct ipc_gprs_ip_configuration *ip_configuration;
448
449         if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_gprs_ip_configuration))
450                 goto error;
451
452         ip_configuration = (struct ipc_gprs_ip_configuration *) info->data;
453
454         gprs_connection = ril_gprs_connection_find_cid(ip_configuration->cid);
455
456         if (!gprs_connection) {
457                 LOGE("Unable to find GPRS connection, aborting");
458
459                 ril_request_complete(ril_request_get_token(info->aseq),
460                         RIL_E_GENERIC_FAILURE, NULL, 0);
461                 return;
462         }
463
464         LOGD("Obtained IP Configuration");
465
466         // Copy the obtained IP configuration to the GPRS connection structure
467         memcpy(&(gprs_connection->ip_configuration),
468                 ip_configuration, sizeof(struct ipc_gprs_ip_configuration));
469
470         LOGD("Waiting for GPRS call status");
471
472         return;
473
474 error:
475         if (info != NULL)
476                 ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
477 }
478
479 void ipc_gprs_pdp_context_disable_complete(struct ipc_message_info *info)
480 {
481         struct ipc_gen_phone_res *phone_res;
482         struct ril_gprs_connection *gprs_connection;
483         int rc;
484
485         phone_res = (struct ipc_gen_phone_res *) info->data;
486         gprs_connection = ril_gprs_connection_find_token(ril_request_get_token(info->aseq));
487
488         if (!gprs_connection) {
489                 LOGE("Unable to find GPRS connection, aborting");
490
491                 ril_request_complete(ril_request_get_token(info->aseq),
492                         RIL_E_GENERIC_FAILURE, NULL, 0);
493                 return;
494         }
495
496         rc = ipc_gen_phone_res_check(phone_res);
497         if (rc < 0) {
498                 LOGE("There was an error, aborting PDP context complete");
499
500                 // RILJ is not going to ask for fail reason
501                 ril_gprs_connection_stop(gprs_connection);
502
503                 ril_request_complete(ril_request_get_token(info->aseq),
504                         RIL_E_GENERIC_FAILURE, NULL, 0);
505                 return;
506         }
507
508         LOGD("Waiting for GPRS call status");
509 }
510
511 void ril_request_deactivate_data_call(RIL_Token t, void *data, int length)
512 {
513         struct ril_gprs_connection *gprs_connection;
514         struct ipc_gprs_pdp_context_set context;
515
516         char *cid;
517         int rc;
518
519         if (data == NULL || length < (int) sizeof(char *))
520                 goto error;
521
522         cid = ((char **) data)[0];
523
524         gprs_connection = ril_gprs_connection_find_cid(atoi(cid));
525
526         if (!gprs_connection) {
527                 LOGE("Unable to find GPRS connection, aborting");
528
529                 ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
530                 return;
531         }
532
533         gprs_connection->token = t;
534
535         ipc_gprs_pdp_context_setup(&context, gprs_connection->cid, 0, NULL, NULL);
536
537         ipc_gen_phone_res_expect_to_func(ril_request_get_id(t), IPC_GPRS_PDP_CONTEXT,
538                 ipc_gprs_pdp_context_disable_complete);
539
540         ipc_fmt_send(IPC_GPRS_PDP_CONTEXT, IPC_TYPE_SET,
541                 (void *) &context, sizeof(struct ipc_gprs_pdp_context_set), ril_request_get_id(t));
542
543         return;
544
545 error:
546         ril_request_complete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
547 }
548
549 #if RIL_VERSION >= 6
550 int ipc_gprs_connection_enable(struct ril_gprs_connection *gprs_connection,
551         RIL_Data_Call_Response_v6 *setup_data_call_response)
552 #else
553 int ipc_gprs_connection_enable(struct ril_gprs_connection *gprs_connection,
554         char **setup_data_call_response)
555 #endif
556 {
557         struct ipc_client_data *ipc_client_data;
558         struct ipc_client *ipc_client;
559         struct ipc_gprs_ip_configuration *ip_configuration;
560
561         char *interface = NULL;
562         char *ip;
563         char *gateway;
564         char *subnet_mask;
565         in_addr_t subnet_mask_addr;
566         char *dns1;
567         char *dns2;
568
569         char prop_name[PROPERTY_KEY_MAX];
570
571         int rc;
572
573         if (gprs_connection == NULL || setup_data_call_response == NULL)
574                 return -EINVAL;
575
576         if (ril_data.ipc_fmt_client == NULL || ril_data.ipc_fmt_client->data == NULL)
577                 return -EINVAL;
578
579         ipc_client_data = (struct ipc_client_data *) ril_data.ipc_fmt_client->data;
580
581         if (ipc_client_data->ipc_client == NULL)
582                 return -EINVAL;
583
584         ipc_client = ipc_client_data->ipc_client;
585
586         ip_configuration = &(gprs_connection->ip_configuration);
587
588         asprintf(&ip, "%i.%i.%i.%i",
589                 (ip_configuration->ip)[0],
590                 (ip_configuration->ip)[1],
591                 (ip_configuration->ip)[2],
592                 (ip_configuration->ip)[3]);
593
594         // FIXME: gateway isn't reliable!
595         asprintf(&gateway, "%i.%i.%i.%i",
596                 (ip_configuration->ip)[0],
597                 (ip_configuration->ip)[1],
598                 (ip_configuration->ip)[2],
599                 (ip_configuration->ip)[3]);
600
601         // FIXME: subnet isn't reliable!
602         asprintf(&subnet_mask, "255.255.255.255");
603
604         asprintf(&dns1, "%i.%i.%i.%i",
605                 (ip_configuration->dns1)[0],
606                 (ip_configuration->dns1)[1],
607                 (ip_configuration->dns1)[2],
608                 (ip_configuration->dns1)[3]);
609         asprintf(&dns2, "%i.%i.%i.%i",
610                 (ip_configuration->dns2)[0],
611                 (ip_configuration->dns2)[1],
612                 (ip_configuration->dns2)[2],
613                 (ip_configuration->dns2)[3]);   
614
615         if (ipc_client_gprs_handlers_available(ipc_client)) {
616                 rc = ipc_client_gprs_activate(ipc_client, gprs_connection->cid);
617                 if (rc < 0) {
618                         // This is not a critical issue
619                         LOGE("Failed to activate interface!");
620                 }
621         }
622
623         interface = ipc_client_gprs_get_iface(ipc_client, gprs_connection->cid);
624         if (interface == NULL) {
625                 // This is not a critical issue, fallback to rmnet
626                 LOGE("Failed to get interface name!");
627                 asprintf(&interface, "rmnet%d", gprs_connection->cid - 1);
628         }
629
630         if (gprs_connection->interface == NULL && interface != NULL) {
631                 gprs_connection->interface = strdup(interface);
632         }
633
634         LOGD("Using net interface: %s\n", interface);
635
636         LOGD("GPRS configuration: iface: %s, ip:%s, "
637                         "gateway:%s, subnet_mask:%s, dns1:%s, dns2:%s",
638                 interface, ip, gateway, subnet_mask, dns1, dns2);
639
640         subnet_mask_addr = inet_addr(subnet_mask);
641
642 #if RIL_VERSION >= 6
643         rc = ifc_configure(interface, inet_addr(ip),
644                 ipv4NetmaskToPrefixLength(subnet_mask_addr),
645                 inet_addr(gateway),
646                 inet_addr(dns1), inet_addr(dns2));
647 #else
648         rc = ifc_configure(interface, inet_addr(ip),
649                 subnet_mask_addr,
650                 inet_addr(gateway),
651                 inet_addr(dns1), inet_addr(dns2));
652 #endif
653
654         if (rc < 0) {
655                 LOGE("ifc_configure failed");
656
657                 free(interface);
658                 return -1;
659         }
660
661         snprintf(prop_name, PROPERTY_KEY_MAX, "net.%s.dns1", interface);
662         property_set(prop_name, dns1);
663         snprintf(prop_name, PROPERTY_KEY_MAX, "net.%s.dns2", interface);
664         property_set(prop_name, dns2);
665         snprintf(prop_name, PROPERTY_KEY_MAX, "net.%s.gw", interface);
666         property_set(prop_name, gateway);
667
668 #if RIL_VERSION >= 6
669         setup_data_call_response->status = 0;
670         setup_data_call_response->cid = gprs_connection->cid;
671         setup_data_call_response->active = 1;
672         setup_data_call_response->type = strdup("IP");
673
674         setup_data_call_response->ifname = interface;
675         setup_data_call_response->addresses = ip;
676         setup_data_call_response->gateways = gateway;
677         asprintf(&setup_data_call_response->dnses, "%s %s", dns1, dns2);
678 #else
679         asprintf(&(setup_data_call_response[0]), "%d", gprs_connection->cid);
680         setup_data_call_response[1] = interface;
681         setup_data_call_response[2] = ip;
682
683         free(gateway);
684 #endif
685
686         free(subnet_mask);
687         free(dns1);
688         free(dns2);
689
690         return 0;
691 }
692
693 int ipc_gprs_connection_disable(struct ril_gprs_connection *gprs_connection)
694 {
695         struct ipc_client_data *ipc_client_data;
696         struct ipc_client *ipc_client;
697
698         char *interface;
699         int rc;
700
701         if (gprs_connection == NULL)
702                 return -EINVAL;
703
704         if (ril_data.ipc_fmt_client == NULL || ril_data.ipc_fmt_client->data == NULL)
705                 return -EINVAL;
706
707         ipc_client_data = (struct ipc_client_data *) ril_data.ipc_fmt_client->data;
708
709         if (ipc_client_data->ipc_client == NULL)
710                 return -EINVAL;
711
712         ipc_client = ipc_client_data->ipc_client;
713
714         if (gprs_connection->interface == NULL) {
715                 interface = ipc_client_gprs_get_iface(ipc_client, gprs_connection->cid);
716                 if (interface == NULL) {
717                         // This is not a critical issue, fallback to rmnet
718                         LOGE("Failed to get interface name!");
719                         asprintf(&interface, "rmnet%d", gprs_connection->cid);
720                 }
721         } else {
722                 interface = gprs_connection->interface;
723         }
724
725         LOGD("Using net interface: %s\n", interface);
726
727         rc = ifc_down(interface);
728
729         if (gprs_connection->interface == NULL)
730                 free(interface);
731
732         if (rc < 0) {
733                 LOGE("ifc_down failed");
734         }
735
736         if (ipc_client_gprs_handlers_available(ipc_client)) {
737                 rc = ipc_client_gprs_deactivate(ipc_client, gprs_connection->cid);
738                 if (rc < 0) {
739                         // This is not a critical issue
740                         LOGE("Failed to deactivate interface!");
741                 }
742         }
743
744         return 0;
745 }
746
747 #if RIL_VERSION >= 6
748 void ril_data_call_response_free(RIL_Data_Call_Response_v6 *response)
749 #else
750 void ril_data_call_response_free(RIL_Data_Call_Response *response)
751 #endif
752 {
753         if (response == NULL)
754                 return;
755
756         if (response->type != NULL)
757                 free(response->type);
758
759 #if RIL_VERSION >= 6
760         if (response->addresses)
761                 free(response->addresses);
762         if (response->ifname)
763                 free(response->ifname);
764         if (response->dnses)
765                 free(response->dnses);
766         if (response->gateways)
767                 free(response->gateways);
768 #else
769         if (response->apn)
770                 free(response->apn);
771         if (response->address)
772                 free(response->address);
773 #endif
774 }
775
776 void ipc_gprs_call_status(struct ipc_message_info *info)
777 {
778         struct ril_gprs_connection *gprs_connection;
779         struct ipc_gprs_call_status *call_status;
780
781 #if RIL_VERSION >= 6
782         RIL_Data_Call_Response_v6 setup_data_call_response;
783 #else
784         char *setup_data_call_response[3] = { NULL, NULL, NULL };
785 #endif
786
787         int rc;
788
789         if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_gprs_call_status))
790                 goto error;
791
792         call_status = (struct ipc_gprs_call_status *) info->data;
793
794         memset(&setup_data_call_response, 0, sizeof(setup_data_call_response));
795
796         gprs_connection = ril_gprs_connection_find_cid(call_status->cid);
797
798         if (!gprs_connection) {
799                 LOGE("Unable to find GPRS connection, aborting");
800
801                 ril_request_complete(ril_request_get_token(info->aseq),
802                         RIL_E_GENERIC_FAILURE, NULL, 0);
803                 return;
804         }
805
806         if (call_status->fail_cause == 0) {
807                 if (!gprs_connection->enabled &&
808                         call_status->state == IPC_GPRS_STATE_ENABLED &&
809                         gprs_connection->token != RIL_TOKEN_NULL) {
810                         LOGD("GPRS connection is now enabled");
811
812                         rc = ipc_gprs_connection_enable(gprs_connection,
813                                 &setup_data_call_response);
814                         if (rc < 0) {
815                                 LOGE("Failed to enable and configure GPRS interface");
816
817                                 gprs_connection->enabled = 0;
818                                 gprs_connection->fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
819                                 ril_data.state.gprs_last_failed_cid = gprs_connection->cid;
820
821                                 ril_request_complete(gprs_connection->token,
822                                         RIL_E_GENERIC_FAILURE, NULL, 0);
823                         } else {
824                                 LOGD("GPRS interface enabled");
825
826                                 gprs_connection->enabled = 1;
827
828                                 ril_request_complete(gprs_connection->token,
829                                         RIL_E_SUCCESS, &setup_data_call_response,
830                                         sizeof(setup_data_call_response));
831                                 gprs_connection->token = RIL_TOKEN_NULL;
832                         }
833 #if RIL_VERSION >= 6
834                         ril_data_call_response_free(&setup_data_call_response);
835 #else
836                         if (setup_data_call_response[0] != NULL)
837                                 free(setup_data_call_response[0]);
838                         if (setup_data_call_response[1] != NULL)
839                                 free(setup_data_call_response[1]);
840                         if (setup_data_call_response[2] != NULL)
841                                 free(setup_data_call_response[2]);
842 #endif
843                 } else if (gprs_connection->enabled &&
844                         call_status->state == IPC_GPRS_STATE_DISABLED &&
845                         gprs_connection->token != RIL_TOKEN_NULL) {
846                         LOGD("GPRS connection is now disabled");
847
848                         rc = ipc_gprs_connection_disable(gprs_connection);
849                         if (rc < 0) {
850                                 LOGE("Failed to disable GPRS interface");
851
852                                 ril_request_complete(gprs_connection->token,
853                                         RIL_E_GENERIC_FAILURE, NULL, 0);
854
855                                 // RILJ is not going to ask for fail reason
856                                 ril_gprs_connection_stop(gprs_connection);
857                         } else {
858                                 LOGD("GPRS interface disabled");
859
860                                 gprs_connection->enabled = 0;
861
862                                 ril_request_complete(gprs_connection->token,
863                                         RIL_E_SUCCESS, NULL, 0);
864
865                                 ril_gprs_connection_stop(gprs_connection);
866                         }
867                 } else {
868                         LOGE("GPRS connection reported as changed though state is not OK:"
869                         "\n\tgprs_connection->enabled=%d\n\tgprs_connection->token=0x%x",
870                                 gprs_connection->enabled, (unsigned)gprs_connection->token);
871
872                         ril_unsol_data_call_list_changed();
873                 }
874         } else {
875                 if (!gprs_connection->enabled &&
876                         (call_status->state == IPC_GPRS_STATE_NOT_ENABLED ||
877                         call_status->state == IPC_GPRS_STATE_DISABLED) &&
878                         gprs_connection->token != RIL_TOKEN_NULL) {
879                         LOGE("Failed to enable GPRS connection");
880
881                         gprs_connection->enabled = 0;
882                         gprs_connection->fail_cause =
883                                 ipc2ril_gprs_fail_cause(call_status->fail_cause);
884                         ril_data.state.gprs_last_failed_cid = gprs_connection->cid;
885
886                         ril_request_complete(gprs_connection->token,
887                                 RIL_E_GENERIC_FAILURE, NULL, 0);
888                         gprs_connection->token = RIL_TOKEN_NULL;
889
890                         ril_unsol_data_call_list_changed();
891                 } else if (gprs_connection->enabled &&
892                         call_status->state == IPC_GPRS_STATE_DISABLED) {
893                         LOGE("GPRS connection suddently got disabled");
894
895                         rc = ipc_gprs_connection_disable(gprs_connection);
896                         if (rc < 0) {
897                                 LOGE("Failed to disable GPRS interface");
898
899                                 // RILJ is not going to ask for fail reason
900                                 ril_gprs_connection_stop(gprs_connection);
901                         } else {
902                                 LOGE("GPRS interface disabled");
903
904                                 gprs_connection->enabled = 0;
905                                 ril_gprs_connection_stop(gprs_connection);
906                         }
907
908                         ril_unsol_data_call_list_changed();
909                 } else {
910                         LOGE("GPRS connection reported to have failed though state is OK:"
911                         "\n\tgprs_connection->enabled=%d\n\tgprs_connection->token=0x%x",
912                                 gprs_connection->enabled, (unsigned)gprs_connection->token);
913
914                         ril_unsol_data_call_list_changed();
915                 }
916         }
917
918         return;
919
920 error:
921         if (info != NULL)
922                 ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
923 }
924
925 void ril_request_last_data_call_fail_cause(RIL_Token t)
926 {
927         struct ril_gprs_connection *gprs_connection;
928         int last_failed_cid;
929         int fail_cause;
930
931         last_failed_cid = ril_data.state.gprs_last_failed_cid;
932
933         if (!last_failed_cid) {
934                 LOGE("No GPRS connection was reported to have failed");
935
936                 goto fail_cause_unspecified;
937         }
938
939         gprs_connection = ril_gprs_connection_find_cid(last_failed_cid);
940
941         if (!gprs_connection) {
942                 LOGE("Unable to find GPRS connection");
943
944                 goto fail_cause_unspecified;
945         }
946
947         fail_cause = gprs_connection->fail_cause;
948
949         LOGD("Destroying GPRS connection with cid: %d", gprs_connection->cid);
950         ril_gprs_connection_stop(gprs_connection);
951
952         goto fail_cause_return;
953
954 fail_cause_unspecified:
955         fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
956
957 fail_cause_return:
958         ril_data.state.gprs_last_failed_cid = 0;
959
960         ril_request_complete(t, RIL_E_SUCCESS, &fail_cause, sizeof(fail_cause));
961 }
962
963 /*
964  * Some modem firmwares have a bug that will make the first cid (1) overriden
965  * by the current cid, thus reporting it twice, with a wrong 2nd status.
966  *
967  * This shouldn't change anything to healthy structures.
968  */
969 #if RIL_VERSION >= 6
970 void ipc_gprs_pdp_context_fix(RIL_Data_Call_Response_v6 *data_call_list, int c)
971 #else
972 void ipc_gprs_pdp_context_fix(RIL_Data_Call_Response *data_call_list, int c)
973 #endif
974 {
975         int i, j, k;
976
977         for (i=0 ; i < c ; i++) {
978                 for (j=i-1 ; j >= 0 ; j--) {
979                         if (data_call_list[i].cid == data_call_list[j].cid) {
980                                 for (k=0 ; k < c ; k++) {
981                                         if (data_call_list[k].cid == 1) {
982                                                 data_call_list[i].cid = 0;
983                                                 break;
984                                         }
985                                 }
986
987                                 data_call_list[i].cid = 1;
988                         }
989                 }
990         }
991 }
992
993 void ipc_gprs_pdp_context(struct ipc_message_info *info)
994 {
995         struct ril_gprs_connection *gprs_connection;
996         struct ipc_gprs_ip_configuration *ip_configuration;
997         struct ipc_gprs_pdp_context_get *context;
998
999 #if RIL_VERSION >= 6
1000         RIL_Data_Call_Response_v6 data_call_list[IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT];
1001 #else
1002         RIL_Data_Call_Response data_call_list[IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT];
1003 #endif
1004
1005         memset(data_call_list, 0, sizeof(data_call_list));
1006
1007         int i;
1008
1009         if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_gprs_pdp_context_get))
1010                 goto error;
1011
1012         context = (struct ipc_gprs_pdp_context_get *) info->data;
1013
1014         for (i=0 ; i < IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT ; i++) {
1015                 data_call_list[i].cid = context->desc[i].cid;
1016                 data_call_list[i].active =
1017                         ipc2ril_gprs_connection_active(context->desc[i].state);
1018
1019                 if (context->desc[i].state == IPC_GPRS_STATE_ENABLED) {
1020                         gprs_connection = ril_gprs_connection_find_cid(context->desc[i].cid);
1021
1022                         if (gprs_connection == NULL) {
1023                                 LOGE("CID %d reported as enabled but not listed here",
1024                                         context->desc[i].cid);
1025                                 continue;
1026                         }
1027
1028                         ip_configuration = &(gprs_connection->ip_configuration);
1029
1030                         char *addr = NULL;
1031                         asprintf(&addr, "%i.%i.%i.%i",
1032                                 (ip_configuration->ip)[0],
1033                                 (ip_configuration->ip)[1],
1034                                 (ip_configuration->ip)[2],
1035                                 (ip_configuration->ip)[3]);
1036
1037 #if RIL_VERSION >= 6
1038                         RIL_Data_Call_Response_v6 *resp = &data_call_list[i];
1039 #else
1040                         RIL_Data_Call_Response *resp = &data_call_list[i];
1041 #endif
1042
1043                         resp->type = strdup("IP");
1044
1045 #if RIL_VERSION < 6
1046                         resp->address = addr;
1047                         asprintf(&(resp->apn), "%s",
1048                                 gprs_connection->define_context.apn);
1049 #else
1050                         resp->addresses = addr;
1051                         resp->gateways = strdup(addr);
1052                         resp->ifname = strdup(gprs_connection->interface);
1053                         asprintf(&resp->dnses, "%i.%i.%i.%i %i.%i.%i.%i",
1054                                 ip_configuration->dns1[0],
1055                                 ip_configuration->dns1[1],
1056                                 ip_configuration->dns1[2],
1057                                 ip_configuration->dns1[3],
1058
1059                                 ip_configuration->dns2[0],
1060                                 ip_configuration->dns2[1],
1061                                 ip_configuration->dns2[2],
1062                                 ip_configuration->dns2[3]);
1063 #endif
1064                 }
1065         }
1066
1067         ipc_gprs_pdp_context_fix(data_call_list, IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT);
1068
1069         if (info->aseq == 0xff)
1070                 ril_request_unsolicited(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
1071                         &data_call_list, sizeof(data_call_list));
1072         else
1073                 ril_request_complete(ril_request_get_token(info->aseq), RIL_E_SUCCESS,
1074                         &data_call_list, sizeof(data_call_list));
1075
1076         for (i = 0; i < IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT; i++) {
1077                 ril_data_call_response_free(data_call_list + i);
1078         }
1079
1080         return;
1081
1082 error:
1083         if (info != NULL)
1084                 ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
1085 }
1086
1087 void ril_unsol_data_call_list_changed(void)
1088 {
1089         ipc_fmt_send_get(IPC_GPRS_PDP_CONTEXT, 0xff);
1090 }
1091
1092 void ril_request_data_call_list(RIL_Token t)
1093 {
1094         ipc_fmt_send_get(IPC_GPRS_PDP_CONTEXT, ril_request_get_id(t));
1095 }