f94807782c39d442b0d602bd789d115a94c5c5c4
[samsung-ril.git] / gprs.c
1 /**
2  * This file is part of samsung-ril.
3  *
4  * Copyright (C) 2011-2012 Paul Kocialkowski <contact@oaulk.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 struct ril_gprs_connection **ril_gprs_connections;
37 int ril_gprs_connections_count;
38
39 #if RIL_VERSION >= 6
40 RIL_DataCallFailCause ipc2ril_gprs_fail_cause(unsigned short fail_cause)
41 #else
42 RIL_LastDataCallActivateFailCause ipc2ril_gprs_fail_cause(unsigned short fail_cause)
43 #endif
44 {
45         switch(fail_cause) {
46
47                 case IPC_GPRS_FAIL_INSUFFICIENT_RESOURCES:
48                         return PDP_FAIL_INSUFFICIENT_RESOURCES;
49                 case IPC_GPRS_FAIL_MISSING_UKNOWN_APN:
50                         return PDP_FAIL_MISSING_UKNOWN_APN;
51                 case IPC_GPRS_FAIL_UNKNOWN_PDP_ADDRESS_TYPE:
52                         return PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE;
53                 case IPC_GPRS_FAIL_USER_AUTHENTICATION:
54                         return PDP_FAIL_USER_AUTHENTICATION;
55                 case IPC_GPRS_FAIL_ACTIVATION_REJECT_GGSN:
56                         return PDP_FAIL_ACTIVATION_REJECT_GGSN;
57                 case IPC_GPRS_FAIL_ACTIVATION_REJECT_UNSPECIFIED:
58                         return PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED;
59                 case IPC_GPRS_FAIL_SERVICE_OPTION_NOT_SUPPORTED:
60                         return PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED;
61                 case IPC_GPRS_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED:
62                         return PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED;
63                 case IPC_GPRS_FAIL_SERVICE_OPTION_OUT_OF_ORDER:
64                         return PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER;
65                 case IPC_GPRS_FAIL_NSAPI_IN_USE:
66                         return PDP_FAIL_NSAPI_IN_USE;
67                 default:
68                         return PDP_FAIL_ERROR_UNSPECIFIED;
69         }
70 }
71
72 int ipc2ril_gprs_connection_active(unsigned char state)
73 {
74         switch(state) {
75                 case IPC_GPRS_STATE_DISABLED:
76                         return 1;
77                 case IPC_GPRS_STATE_ENABLED:
78                         return 2;
79                 case IPC_GPRS_STATE_NOT_ENABLED:
80                 default:
81                         return 0;
82         }
83 }
84
85 void ril_gprs_connections_init(void)
86 {
87         struct ipc_client_gprs_capabilities gprs_capabilities;
88         struct ipc_client *ipc_client;
89         int ril_gprs_connections_size = 0;
90
91         ipc_client = ((struct ipc_client_object *) ipc_fmt_client->object)->ipc_client;
92         ipc_client_gprs_get_capabilities(ipc_client, &gprs_capabilities);
93
94         ril_gprs_connections_size =
95                 gprs_capabilities.cid_max * sizeof(struct ril_gprs_connection *);
96
97         ril_gprs_connections = (struct ril_gprs_connection **)
98                 malloc(ril_gprs_connections_size);
99         memset((void *) ril_gprs_connections, 0, ril_gprs_connections_size);
100
101         ril_gprs_connections_count = gprs_capabilities.cid_max;
102 }
103
104 int ril_gprs_connection_reg_id(void)
105 {
106         struct ril_gprs_connection *gprs_connection;
107         int i;
108
109         for(i=0 ; i < ril_gprs_connections_count ; i++) {
110                 if(ril_gprs_connections[i] == NULL)
111                         return i;
112         }
113
114         LOGD("No room left for another GPRS connection, trying to clean one up");
115
116         // When all the slots are taken, see if some are in a non-working state
117         for(i=0 ; i < ril_gprs_connections_count ; i++) {
118                 if(ril_gprs_connections[i]->enabled == 0) {
119                         ril_gprs_connection_del(ril_gprs_connections[i]);
120
121                         return i;
122                 }
123         }
124
125         return -1;
126 }
127
128 struct ril_gprs_connection *ril_gprs_connection_add(void)
129 {
130         struct ril_gprs_connection *gprs_connection = NULL;
131         int id = ril_gprs_connection_reg_id();
132
133         if(id < 0) {
134                 LOGE("Unable to add another GPRS connection!");
135                 return NULL;
136         }
137
138         gprs_connection = malloc(sizeof(struct ril_gprs_connection));
139         memset(gprs_connection, 0, sizeof(struct ril_gprs_connection));
140
141         gprs_connection->cid = id + 1;
142         gprs_connection->enabled = 0;
143         gprs_connection->interface = NULL;
144         gprs_connection->token = (RIL_Token) 0x00;
145
146         ril_gprs_connections[id] = gprs_connection;
147
148         return gprs_connection;
149 }
150
151 void ril_gprs_connection_del(struct ril_gprs_connection *gprs_connection)
152 {
153         int i;
154
155         if(gprs_connection == NULL)
156                 return;
157
158         if(gprs_connection->interface != NULL)
159                 free(gprs_connection->interface);
160
161         for(i=0 ; i < ril_gprs_connections_count ; i++)
162                 if(ril_gprs_connections[i] == gprs_connection)
163                                 ril_gprs_connections[i] = NULL;
164
165         free(gprs_connection);
166 }
167
168 struct ril_gprs_connection *ril_gprs_connection_get_token(RIL_Token token)
169 {
170         int i;
171
172         for(i=0 ; i < ril_gprs_connections_count ; i++)
173                 if(ril_gprs_connections[i] != NULL)
174                         if(ril_gprs_connections[i]->token == token)
175                                 return ril_gprs_connections[i];
176
177         return NULL;
178 }
179
180 struct ril_gprs_connection *ril_gprs_connection_get_cid(int cid)
181 {
182         int i;
183
184         for(i=0 ; i < ril_gprs_connections_count ; i++)
185                 if(ril_gprs_connections[i] != NULL)
186                         if(ril_gprs_connections[i]->cid == cid)
187                                 return ril_gprs_connections[i];
188
189         return NULL;
190 }
191
192 void ipc_gprs_pdp_context_enable_complete(struct ipc_message_info *info)
193 {
194         struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
195         struct ril_gprs_connection *gprs_connection;
196         int rc;
197
198         gprs_connection = ril_gprs_connection_get_token(reqGetToken(info->aseq));
199
200         if(!gprs_connection) {
201                 LOGE("Unable to find GPRS connection, aborting");
202
203                 RIL_onRequestComplete(reqGetToken(info->aseq),
204                         RIL_E_GENERIC_FAILURE, NULL, 0);
205                 return;
206         }
207
208         rc = ipc_gen_phone_res_check(phone_res);
209         if(rc < 0) {
210                 LOGE("There was an error, aborting PDP context complete");
211
212                 gprs_connection->fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
213                 gprs_connection->token = (RIL_Token) 0x00;
214                 ril_state.gprs_last_failed_cid = gprs_connection->cid;
215
216                 RIL_onRequestComplete(reqGetToken(info->aseq),
217                         RIL_E_GENERIC_FAILURE, NULL, 0);
218                 return;
219         }
220
221         LOGD("Waiting for IP configuration!");
222 }
223
224 void ipc_gprs_define_pdp_context_complete(struct ipc_message_info *info)
225 {
226         struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
227         struct ril_gprs_connection *gprs_connection;
228         int aseq;
229         int rc;
230
231         gprs_connection = ril_gprs_connection_get_token(reqGetToken(info->aseq));
232
233         if(!gprs_connection) {
234                 LOGE("Unable to find GPRS connection, aborting");
235
236                 RIL_onRequestComplete(reqGetToken(info->aseq),
237                         RIL_E_GENERIC_FAILURE, NULL, 0);
238                 return;
239         }
240
241         rc = ipc_gen_phone_res_check(phone_res);
242         if(rc < 0) {
243                 LOGE("There was an error, aborting define PDP context complete");
244
245                 gprs_connection->fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
246                 gprs_connection->token = (RIL_Token) 0x00;
247                 ril_state.gprs_last_failed_cid = gprs_connection->cid;
248
249                 RIL_onRequestComplete(reqGetToken(info->aseq),
250                         RIL_E_GENERIC_FAILURE, NULL, 0);
251                 return;
252         }
253
254         // We need to get a clean new aseq here
255         aseq = ril_request_reg_id(reqGetToken(info->aseq));
256
257         ipc_gen_phone_res_expect_to_func(aseq, IPC_GPRS_PDP_CONTEXT,
258                 ipc_gprs_pdp_context_enable_complete);
259
260         ipc_fmt_send(IPC_GPRS_PDP_CONTEXT, IPC_TYPE_SET,
261                         (void *) &(gprs_connection->context),
262                         sizeof(struct ipc_gprs_pdp_context_set), aseq);
263 }
264
265 void ipc_gprs_port_list_complete(struct ipc_message_info *info)
266 {
267         struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
268         struct ril_gprs_connection *gprs_connection;
269         int rc;
270         int aseq;
271
272         gprs_connection = ril_gprs_connection_get_token(reqGetToken(info->aseq));
273
274         if(!gprs_connection) {
275                 LOGE("Unable to find GPRS connection, aborting");
276
277                 RIL_onRequestComplete(reqGetToken(info->aseq),
278                         RIL_E_GENERIC_FAILURE, NULL, 0);
279                 return;
280         }
281
282         rc = ipc_gen_phone_res_check(phone_res);
283         if(rc < 0) {
284                 LOGE("There was an error, aborting port list complete");
285
286                 gprs_connection->fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
287                 gprs_connection->token = (RIL_Token) 0x00;
288                 ril_state.gprs_last_failed_cid = gprs_connection->cid;
289
290                 RIL_onRequestComplete(reqGetToken(info->aseq),
291                         RIL_E_GENERIC_FAILURE, NULL, 0);
292                 return;
293         }
294
295         // We need to get a clean new aseq here
296         aseq = ril_request_reg_id(reqGetToken(info->aseq));
297
298         ipc_gen_phone_res_expect_to_func(aseq, IPC_GPRS_DEFINE_PDP_CONTEXT,
299                 ipc_gprs_define_pdp_context_complete);
300
301         ipc_fmt_send(IPC_GPRS_DEFINE_PDP_CONTEXT, IPC_TYPE_SET,
302                 (void *) &(gprs_connection->define_context),
303                 sizeof(struct ipc_gprs_define_pdp_context),
304                 aseq);
305 }
306
307 void ril_request_setup_data_call(RIL_Token t, void *data, int length)
308 {
309         struct ril_gprs_connection *gprs_connection = NULL;
310         struct ipc_client_gprs_capabilities gprs_capabilities;
311         struct ipc_gprs_port_list port_list;
312         struct ipc_client *ipc_client;
313
314         char *username = NULL;
315         char *password = NULL;
316         char *apn = NULL;
317
318         ipc_client = ((struct ipc_client_object *) ipc_fmt_client->object)->ipc_client;
319
320         apn = ((char **) data)[2];
321         username = ((char **) data)[3];
322         password = ((char **) data)[4];
323
324         LOGD("Requesting data connection to APN '%s'\n", apn);
325
326         gprs_connection = ril_gprs_connection_add();
327
328         if(!gprs_connection) {
329                 LOGE("Unable to create GPRS connection, aborting");
330
331                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
332                 return;
333         }
334
335         gprs_connection->token = t;
336
337         // Create the structs with the apn
338         ipc_gprs_define_pdp_context_setup(&(gprs_connection->define_context),
339                 gprs_connection->cid, 1, apn);
340
341         // Create the structs with the username/password tuple
342         ipc_gprs_pdp_context_setup(&(gprs_connection->context),
343                 gprs_connection->cid, 1, username, password);
344
345         ipc_client_gprs_get_capabilities(ipc_client, &gprs_capabilities);
346
347         // If the device has the capability, deal with port list
348         if(gprs_capabilities.port_list) {
349                 ipc_gprs_port_list_setup(&port_list);
350
351                 ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_GPRS_PORT_LIST,
352                         ipc_gprs_port_list_complete);
353
354                 ipc_fmt_send(IPC_GPRS_PORT_LIST, IPC_TYPE_SET,
355                         (void *) &port_list, sizeof(struct ipc_gprs_port_list), reqGetId(t));
356         } else {
357                 ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_GPRS_DEFINE_PDP_CONTEXT,
358                         ipc_gprs_define_pdp_context_complete);
359
360                 ipc_fmt_send(IPC_GPRS_DEFINE_PDP_CONTEXT, IPC_TYPE_SET,
361                         (void *) &(gprs_connection->define_context),
362                                 sizeof(struct ipc_gprs_define_pdp_context), reqGetId(t));
363         }
364 }
365
366 void ipc_gprs_ip_configuration(struct ipc_message_info *info)
367 {
368         struct ril_gprs_connection *gprs_connection;
369         struct ipc_gprs_ip_configuration *ip_configuration =
370                 (struct ipc_gprs_ip_configuration *) info->data;
371
372         gprs_connection = ril_gprs_connection_get_cid(ip_configuration->cid);
373
374         if(!gprs_connection) {
375                 LOGE("Unable to find GPRS connection, aborting");
376
377                 RIL_onRequestComplete(reqGetToken(info->aseq),
378                         RIL_E_GENERIC_FAILURE, NULL, 0);
379                 return;
380         }
381
382         LOGD("Obtained IP Configuration");
383
384         // Copy the obtained IP configuration to the GPRS connection structure
385         memcpy(&(gprs_connection->ip_configuration),
386                 ip_configuration, sizeof(struct ipc_gprs_ip_configuration));
387
388         LOGD("Waiting for GPRS call status");
389 }
390
391 void ipc_gprs_pdp_context_disable_complete(struct ipc_message_info *info)
392 {
393         struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
394         struct ril_gprs_connection *gprs_connection;
395         int rc;
396
397         gprs_connection = ril_gprs_connection_get_token(reqGetToken(info->aseq));
398
399         if(!gprs_connection) {
400                 LOGE("Unable to find GPRS connection, aborting");
401
402                 RIL_onRequestComplete(reqGetToken(info->aseq),
403                         RIL_E_GENERIC_FAILURE, NULL, 0);
404                 return;
405         }
406
407         rc = ipc_gen_phone_res_check(phone_res);
408         if(rc < 0) {
409                 LOGE("There was an error, aborting PDP context complete");
410
411                 // RILJ is not going to ask for fail reason
412                 ril_gprs_connection_del(gprs_connection);
413
414                 RIL_onRequestComplete(reqGetToken(info->aseq),
415                         RIL_E_GENERIC_FAILURE, NULL, 0);
416                 return;
417         }
418
419         LOGD("Waiting for GPRS call status");
420 }
421
422 void ril_request_deactivate_data_call(RIL_Token t, void *data, int length)
423 {
424         struct ril_gprs_connection *gprs_connection;
425         struct ipc_gprs_pdp_context_set context;
426
427         char *cid = ((char **) data)[0];
428         int rc;
429
430         gprs_connection = ril_gprs_connection_get_cid(atoi(cid));
431
432         if(!gprs_connection) {
433                 LOGE("Unable to find GPRS connection, aborting");
434
435                 RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
436                 return;
437         }
438
439         gprs_connection->token = t;
440
441         ipc_gprs_pdp_context_setup(&context, gprs_connection->cid, 0, NULL, NULL);
442
443         ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_GPRS_PDP_CONTEXT,
444                 ipc_gprs_pdp_context_disable_complete);
445
446         ipc_fmt_send(IPC_GPRS_PDP_CONTEXT, IPC_TYPE_SET,
447                 (void *) &context, sizeof(struct ipc_gprs_pdp_context_set), reqGetId(t));
448 }
449
450 #if RIL_VERSION >= 6
451 int ipc_gprs_connection_enable(struct ril_gprs_connection *gprs_connection,
452         RIL_Data_Call_Response_v6 *setup_data_call_response)
453 #else
454 int ipc_gprs_connection_enable(struct ril_gprs_connection *gprs_connection,
455         char **setup_data_call_response)
456 #endif
457 {
458         struct ipc_client *ipc_client;
459         struct ipc_gprs_ip_configuration *ip_configuration;
460
461         char *interface = NULL;
462         char *ip;
463         char *gateway;
464         char *subnet_mask;
465         in_addr_t subnet_mask_addr;
466         char *dns1;
467         char *dns2;
468
469         char prop_name[PROPERTY_KEY_MAX];
470
471         int rc;
472
473         ipc_client = ((struct ipc_client_object *) ipc_fmt_client->object)->ipc_client;
474
475         ip_configuration = &(gprs_connection->ip_configuration);
476
477         asprintf(&ip, "%i.%i.%i.%i",
478                 (ip_configuration->ip)[0],
479                 (ip_configuration->ip)[1],
480                 (ip_configuration->ip)[2],
481                 (ip_configuration->ip)[3]);
482
483         // FIXME: gateway isn't reliable!
484         asprintf(&gateway, "%i.%i.%i.%i",
485                 (ip_configuration->ip)[0],
486                 (ip_configuration->ip)[1],
487                 (ip_configuration->ip)[2],
488                 (ip_configuration->ip)[3]);
489
490         // FIXME: subnet isn't reliable!
491         asprintf(&subnet_mask, "255.255.255.255");
492
493         asprintf(&dns1, "%i.%i.%i.%i",
494                 (ip_configuration->dns1)[0],
495                 (ip_configuration->dns1)[1],
496                 (ip_configuration->dns1)[2],
497                 (ip_configuration->dns1)[3]);
498         asprintf(&dns2, "%i.%i.%i.%i",
499                 (ip_configuration->dns2)[0],
500                 (ip_configuration->dns2)[1],
501                 (ip_configuration->dns2)[2],
502                 (ip_configuration->dns2)[3]);   
503
504         if(ipc_client_gprs_handlers_available(ipc_client)) {
505                 rc = ipc_client_gprs_activate(ipc_client);
506                 if(rc < 0) {
507                         // This is not a critical issue
508                         LOGE("Failed to activate interface!");
509                 }
510         }
511
512         rc = ipc_client_gprs_get_iface(ipc_client, &interface, gprs_connection->cid);
513         if(rc < 0) {
514                 // This is not a critical issue, fallback to rmnet
515                 LOGE("Failed to get interface name!");
516                 asprintf(&interface, "rmnet%d", gprs_connection->cid - 1);
517         }
518
519         if(gprs_connection->interface == NULL && interface != NULL) {
520                 gprs_connection->interface = strdup(interface);
521         }
522
523         LOGD("Using net interface: %s\n", interface);
524
525         LOGD("GPRS configuration: iface: %s, ip:%s, "
526                         "gateway:%s, subnet_mask:%s, dns1:%s, dns2:%s",
527                 interface, ip, gateway, subnet_mask, dns1, dns2);
528
529         subnet_mask_addr = inet_addr(subnet_mask);
530
531 #if RIL_VERSION >= 6
532         rc = ifc_configure(interface, inet_addr(ip),
533                 ipv4NetmaskToPrefixLength(subnet_mask_addr),
534                 inet_addr(gateway),
535                 inet_addr(dns1), inet_addr(dns2));
536 #else
537         rc = ifc_configure(interface, inet_addr(ip),
538                 subnet_mask_addr,
539                 inet_addr(gateway),
540                 inet_addr(dns1), inet_addr(dns2));
541 #endif
542
543         if(rc < 0) {
544                 LOGE("ifc_configure failed");
545
546                 free(interface);
547                 return -1;
548         }
549
550         snprintf(prop_name, PROPERTY_KEY_MAX, "net.%s.dns1", interface);
551         property_set(prop_name, dns1);
552         snprintf(prop_name, PROPERTY_KEY_MAX, "net.%s.dns2", interface);
553         property_set(prop_name, dns2);
554         snprintf(prop_name, PROPERTY_KEY_MAX, "net.%s.gw", interface);
555         property_set(prop_name, gateway);
556
557 #if RIL_VERSION >= 6
558         setup_data_call_response->status = 0;
559         setup_data_call_response->cid = gprs_connection->cid;
560         setup_data_call_response->active = 1;
561         setup_data_call_response->type = strdup("IP");
562
563         setup_data_call_response->ifname = interface;
564         setup_data_call_response->addresses = ip;
565         setup_data_call_response->gateways = gateway;
566         asprintf(&setup_data_call_response->dnses, "%s %s", dns1, dns2);
567 #else
568         asprintf(&(setup_data_call_response[0]), "%d", gprs_connection->cid);
569         setup_data_call_response[1] = interface;
570         setup_data_call_response[2] = ip;
571
572         free(gateway);
573 #endif
574
575         free(subnet_mask);
576         free(dns1);
577         free(dns2);
578
579         return 0;
580 }
581
582 int ipc_gprs_connection_disable(struct ril_gprs_connection *gprs_connection)
583 {
584         struct ipc_client *ipc_client;
585
586         char *interface;
587         int rc;
588
589         ipc_client = ((struct ipc_client_object *) ipc_fmt_client->object)->ipc_client;
590
591         if(gprs_connection->interface == NULL) {
592                 rc = ipc_client_gprs_get_iface(ipc_client, &interface, gprs_connection->cid);
593                 if(rc < 0) {
594                         // This is not a critical issue, fallback to rmnet
595                         LOGE("Failed to get interface name!");
596                         asprintf(&interface, "rmnet%d", gprs_connection->cid);
597                 }
598         } else {
599                 interface = gprs_connection->interface;
600         }
601
602         LOGD("Using net interface: %s\n", interface);
603
604         rc = ifc_down(interface);
605
606         if(gprs_connection->interface == NULL)
607                 free(interface);
608
609         if(rc < 0) {
610                 LOGE("ifc_down failed");
611         }
612
613         if(ipc_client_gprs_handlers_available(ipc_client)) {
614                 rc = ipc_client_gprs_deactivate(ipc_client);
615                 if(rc < 0) {
616                         // This is not a critical issue
617                         LOGE("Failed to deactivate interface!");
618                 }
619         }
620
621         return 0;
622 }
623
624 #if RIL_VERSION >= 6
625 void ril_data_call_response_free(RIL_Data_Call_Response_v6 *response)
626 #else
627 void ril_data_call_response_free(RIL_Data_Call_Response *response)
628 #endif
629 {
630         if(response == NULL)
631                 return;
632
633         if(response->type != NULL)
634                 free(response->type);
635
636 #if RIL_VERSION >= 6
637         if(response->addresses)
638                 free(response->addresses);
639         if(response->ifname)
640                 free(response->ifname);
641         if(response->dnses)
642                 free(response->dnses);
643         if(response->gateways)
644                 free(response->gateways);
645 #else
646         if(response->apn)
647                 free(response->apn);
648         if(response->address)
649                 free(response->address);
650 #endif
651 }
652
653 void ipc_gprs_call_status(struct ipc_message_info *info)
654 {
655         struct ril_gprs_connection *gprs_connection;
656         struct ipc_gprs_call_status *call_status =
657                 (struct ipc_gprs_call_status *) info->data;
658
659 #if RIL_VERSION >= 6
660         RIL_Data_Call_Response_v6 setup_data_call_response;
661         memset(&setup_data_call_response, 0, sizeof(setup_data_call_response));
662 #else
663         char *setup_data_call_response[3] = { NULL, NULL, NULL };
664 #endif
665
666         int rc;
667
668         gprs_connection = ril_gprs_connection_get_cid(call_status->cid);
669
670         if(!gprs_connection) {
671                 LOGE("Unable to find GPRS connection, aborting");
672
673                 RIL_onRequestComplete(reqGetToken(info->aseq),
674                         RIL_E_GENERIC_FAILURE, NULL, 0);
675                 return;
676         }
677
678         if(call_status->fail_cause == 0) {
679                 if(!gprs_connection->enabled &&
680                         call_status->state == IPC_GPRS_STATE_ENABLED &&
681                         gprs_connection->token != (RIL_Token) 0x00) {
682                         LOGD("GPRS connection is now enabled");
683
684                         rc = ipc_gprs_connection_enable(gprs_connection,
685                                 &setup_data_call_response);
686                         if(rc < 0) {
687                                 LOGE("Failed to enable and configure GPRS interface");
688
689                                 gprs_connection->enabled = 0;
690                                 gprs_connection->fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
691                                 ril_state.gprs_last_failed_cid = gprs_connection->cid;
692
693                                 RIL_onRequestComplete(gprs_connection->token,
694                                         RIL_E_GENERIC_FAILURE, NULL, 0);
695                         } else {
696                                 LOGD("GPRS interface enabled");
697
698                                 gprs_connection->enabled = 1;
699
700                                 RIL_onRequestComplete(gprs_connection->token,
701                                         RIL_E_SUCCESS, &setup_data_call_response,
702                                         sizeof(setup_data_call_response));
703                                 gprs_connection->token = (RIL_Token) 0x00;
704                         }
705 #if RIL_VERSION >= 6
706                         ril_data_call_response_free(&setup_data_call_response);
707 #else
708                         if(setup_data_call_response[0] != NULL)
709                                 free(setup_data_call_response[0]);
710                         if(setup_data_call_response[1] != NULL)
711                                 free(setup_data_call_response[1]);
712                         if(setup_data_call_response[2] != NULL)
713                                 free(setup_data_call_response[2]);
714 #endif
715                 } else if(gprs_connection->enabled &&
716                         call_status->state == IPC_GPRS_STATE_DISABLED &&
717                         gprs_connection->token != (RIL_Token) 0x00) {
718                         LOGD("GPRS connection is now disabled");
719
720                         rc = ipc_gprs_connection_disable(gprs_connection);
721                         if(rc < 0) {
722                                 LOGE("Failed to disable GPRS interface");
723
724                                 RIL_onRequestComplete(gprs_connection->token,
725                                         RIL_E_GENERIC_FAILURE, NULL, 0);
726
727                                 // RILJ is not going to ask for fail reason
728                                 ril_gprs_connection_del(gprs_connection);
729                         } else {
730                                 LOGD("GPRS interface disabled");
731
732                                 gprs_connection->enabled = 0;
733
734                                 RIL_onRequestComplete(gprs_connection->token,
735                                         RIL_E_SUCCESS, NULL, 0);
736
737                                 ril_gprs_connection_del(gprs_connection);
738                         }
739                 } else {
740                         LOGE("GPRS connection reported as changed though state is not OK:"
741                         "\n\tgprs_connection->enabled=%d\n\tgprs_connection->token=0x%x",
742                                 gprs_connection->enabled, (unsigned)gprs_connection->token);
743
744                         ril_unsol_data_call_list_changed();
745                 }
746         } else {
747                 if(!gprs_connection->enabled &&
748                         (call_status->state == IPC_GPRS_STATE_NOT_ENABLED ||
749                         call_status->state == IPC_GPRS_STATE_DISABLED) &&
750                         gprs_connection->token != (RIL_Token) 0x00) {
751                         LOGE("Failed to enable GPRS connection");
752
753                         gprs_connection->enabled = 0;
754                         gprs_connection->fail_cause =
755                                 ipc2ril_gprs_fail_cause(call_status->fail_cause);
756                         ril_state.gprs_last_failed_cid = gprs_connection->cid;
757
758                         RIL_onRequestComplete(gprs_connection->token,
759                                 RIL_E_GENERIC_FAILURE, NULL, 0);
760                         gprs_connection->token = (RIL_Token) 0x00;
761
762                         ril_unsol_data_call_list_changed();
763                 } else if(gprs_connection->enabled &&
764                         call_status->state == IPC_GPRS_STATE_DISABLED) {
765                         LOGE("GPRS connection suddently got disabled");
766
767                         rc = ipc_gprs_connection_disable(gprs_connection);
768                         if(rc < 0) {
769                                 LOGE("Failed to disable GPRS interface");
770
771                                 // RILJ is not going to ask for fail reason
772                                 ril_gprs_connection_del(gprs_connection);
773                         } else {
774                                 LOGE("GPRS interface disabled");
775
776                                 gprs_connection->enabled = 0;
777                                 ril_gprs_connection_del(gprs_connection);
778                         }
779
780                         ril_unsol_data_call_list_changed();
781                 } else {
782                         LOGE("GPRS connection reported to have failed though state is OK:"
783                         "\n\tgprs_connection->enabled=%d\n\tgprs_connection->token=0x%x",
784                                 gprs_connection->enabled, (unsigned)gprs_connection->token);
785
786                         ril_unsol_data_call_list_changed();
787                 }
788         }
789 }
790
791 void ril_request_last_data_call_fail_cause(RIL_Token t)
792 {
793         struct ril_gprs_connection *gprs_connection;
794         int last_failed_cid;
795         int fail_cause;
796
797         last_failed_cid = ril_state.gprs_last_failed_cid;
798
799         if(!last_failed_cid) {
800                 LOGE("No GPRS connection was reported to have failed");
801
802                 goto fail_cause_unspecified;
803         }
804
805         gprs_connection = ril_gprs_connection_get_cid(last_failed_cid);
806
807         if(!gprs_connection) {
808                 LOGE("Unable to find GPRS connection");
809
810                 goto fail_cause_unspecified;
811         }
812
813         fail_cause = gprs_connection->fail_cause;
814
815         LOGD("Destroying GPRS connection with cid: %d", gprs_connection->cid);
816         ril_gprs_connection_del(gprs_connection);
817
818         goto fail_cause_return;
819
820 fail_cause_unspecified:
821         fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
822
823 fail_cause_return:
824         ril_state.gprs_last_failed_cid = 0;
825         RIL_onRequestComplete(t, RIL_E_SUCCESS, &fail_cause, sizeof(fail_cause));
826 }
827
828 /*
829  * Some modem firmwares have a bug that will make the first cid (1) overriden
830  * by the current cid, thus reporting it twice, with a wrong 2nd status.
831  *
832  * This shouldn't change anything to healthy structures.
833  */
834 #if RIL_VERSION >= 6
835 void ipc_gprs_pdp_context_fix(RIL_Data_Call_Response_v6 *data_call_list, int c)
836 #else
837 void ipc_gprs_pdp_context_fix(RIL_Data_Call_Response *data_call_list, int c)
838 #endif
839 {
840         int i, j, k;
841
842         for(i=0 ; i < c ; i++) {
843                 for(j=i-1 ; j >= 0 ; j--) {
844                         if(data_call_list[i].cid == data_call_list[j].cid) {
845                                 for(k=0 ; k < c ; k++) {
846                                         if(data_call_list[k].cid == 1) {
847                                                 data_call_list[i].cid = 0;
848                                                 break;
849                                         }
850                                 }
851
852                                 data_call_list[i].cid = 1;
853                         }
854                 }
855         }
856 }
857
858 void ipc_gprs_pdp_context(struct ipc_message_info *info)
859 {
860         struct ril_gprs_connection *gprs_connection;
861         struct ipc_gprs_ip_configuration *ip_configuration;
862         struct ipc_gprs_pdp_context_get *context =
863                 (struct ipc_gprs_pdp_context_get *) info->data;
864
865 #if RIL_VERSION >= 6
866         RIL_Data_Call_Response_v6 data_call_list[IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT];
867 #else
868         RIL_Data_Call_Response data_call_list[IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT];
869 #endif
870
871         memset(data_call_list, 0, sizeof(data_call_list));
872
873         int i;
874
875         for(i=0 ; i < IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT ; i++) {
876                 data_call_list[i].cid = context->desc[i].cid;
877                 data_call_list[i].active =
878                         ipc2ril_gprs_connection_active(context->desc[i].state);
879
880                 if(context->desc[i].state == IPC_GPRS_STATE_ENABLED) {
881                         gprs_connection = ril_gprs_connection_get_cid(context->desc[i].cid);
882
883                         if(gprs_connection == NULL) {
884                                 LOGE("CID %d reported as enabled but not listed here",
885                                         context->desc[i].cid);
886                                 continue;
887                         }
888
889                         ip_configuration = &(gprs_connection->ip_configuration);
890
891                         char *addr = NULL;
892                         asprintf(&addr, "%i.%i.%i.%i",
893                                 (ip_configuration->ip)[0],
894                                 (ip_configuration->ip)[1],
895                                 (ip_configuration->ip)[2],
896                                 (ip_configuration->ip)[3]);
897
898 #if RIL_VERSION >= 6
899                         RIL_Data_Call_Response_v6 *resp = &data_call_list[i];
900 #else
901                         RIL_Data_Call_Response *resp = &data_call_list[i];
902 #endif
903
904                         resp->type = strdup("IP");
905
906 #if RIL_VERSION < 6
907                         resp->address = addr;
908                         asprintf(&(resp->apn), "%s",
909                                 gprs_connection->define_context.apn);
910 #else
911                         resp->addresses = addr;
912                         resp->gateways = strdup(addr);
913                         resp->ifname = strdup(gprs_connection->interface);
914                         asprintf(&resp->dnses, "%i.%i.%i.%i %i.%i.%i.%i",
915                                 ip_configuration->dns1[0],
916                                 ip_configuration->dns1[1],
917                                 ip_configuration->dns1[2],
918                                 ip_configuration->dns1[3],
919
920                                 ip_configuration->dns2[0],
921                                 ip_configuration->dns2[1],
922                                 ip_configuration->dns2[2],
923                                 ip_configuration->dns2[3]);
924 #endif
925                 }
926         }
927
928         ipc_gprs_pdp_context_fix(data_call_list, IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT);
929
930         if(info->aseq == 0xff)
931                 RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED,
932                         &data_call_list, sizeof(data_call_list));
933         else
934                 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS,
935                         &data_call_list, sizeof(data_call_list));
936
937         for(i = 0; i < IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT; i++) {
938                 ril_data_call_response_free(data_call_list + i);
939         }
940 }
941
942 void ril_unsol_data_call_list_changed(void)
943 {
944         ipc_fmt_send_get(IPC_GPRS_PDP_CONTEXT, 0xff);
945 }
946
947 void ril_request_data_call_list(RIL_Token t)
948 {
949         ipc_fmt_send_get(IPC_GPRS_PDP_CONTEXT, reqGetId(t));
950 }