Project

General

Profile

Issue #29 ยป gprs.c

Paul Kocialkowski, 07/15/2012 12:04 PM

 
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
#include "samsung-ril.h"
30
#include "util.h"
31

    
32
struct ril_gprs_connection **ril_gprs_connections;
33
int ril_gprs_connections_count;
34

    
35
RIL_LastDataCallActivateFailCause ipc2ril_gprs_fail_cause(unsigned short fail_cause)
36
{
37
	switch(fail_cause) {
38

    
39
		case IPC_GPRS_FAIL_INSUFFICIENT_RESOURCES:
40
			return PDP_FAIL_INSUFFICIENT_RESOURCES;
41
		case IPC_GPRS_FAIL_MISSING_UKNOWN_APN:
42
			return PDP_FAIL_MISSING_UKNOWN_APN;
43
		case IPC_GPRS_FAIL_UNKNOWN_PDP_ADDRESS_TYPE:
44
			return PDP_FAIL_UNKNOWN_PDP_ADDRESS_TYPE;
45
		case IPC_GPRS_FAIL_USER_AUTHENTICATION:
46
			return PDP_FAIL_USER_AUTHENTICATION;
47
		case IPC_GPRS_FAIL_ACTIVATION_REJECT_GGSN:
48
			return PDP_FAIL_ACTIVATION_REJECT_GGSN;
49
		case IPC_GPRS_FAIL_ACTIVATION_REJECT_UNSPECIFIED:
50
			return PDP_FAIL_ACTIVATION_REJECT_UNSPECIFIED;
51
		case IPC_GPRS_FAIL_SERVICE_OPTION_NOT_SUPPORTED:
52
			return PDP_FAIL_SERVICE_OPTION_NOT_SUPPORTED;
53
		case IPC_GPRS_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED:
54
			return PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED;
55
		case IPC_GPRS_FAIL_SERVICE_OPTION_OUT_OF_ORDER:
56
			return PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER;
57
		case IPC_GPRS_FAIL_NSAPI_IN_USE:
58
			return PDP_FAIL_NSAPI_IN_USE;
59
		default:
60
			return PDP_FAIL_ERROR_UNSPECIFIED;
61
	}
62
}
63

    
64
int ipc2ril_gprs_connection_active(unsigned char state)
65
{
66
	switch(state) {
67
		case IPC_GPRS_STATE_DISABLED:
68
			return 1;
69
		case IPC_GPRS_STATE_ENABLED:
70
			return 2;
71
		case IPC_GPRS_STATE_NOT_ENABLED:
72
		default:
73
			return 0;
74
	}
75
}
76

    
77
void ril_gprs_connections_init(void)
78
{
79
	struct ipc_client_gprs_capabilities gprs_capabilities;
80
	struct ipc_client *ipc_client;
81
	int ril_gprs_connections_size = 0;
82

    
83
	ipc_client = ((struct ipc_client_object *) ipc_fmt_client->object)->ipc_client;
84
	ipc_client_gprs_get_capabilities(ipc_client, &gprs_capabilities);
85

    
86
	ril_gprs_connections_size =
87
		gprs_capabilities.cid_max * sizeof(struct ril_gprs_connection *);
88

    
89
	ril_gprs_connections = (struct ril_gprs_connection **)
90
		malloc(ril_gprs_connections_size);
91
	memset((void *) ril_gprs_connections, 0, ril_gprs_connections_size);
92

    
93
	ril_gprs_connections_count = gprs_capabilities.cid_max;
94
}
95

    
96
int ril_gprs_connection_reg_id(void)
97
{
98
	struct ril_gprs_connection *gprs_connection;
99
	int i;
100

    
101
	for(i=0 ; i < ril_gprs_connections_count ; i++) {
102
		if(ril_gprs_connections[i] == NULL)
103
			return i;
104
	}
105

    
106
	LOGD("No room left for another GPRS connection, trying to clean one up");
107

    
108
	// When all the slots are taken, see if some are in a non-working state
109
	for(i=0 ; i < ril_gprs_connections_count ; i++) {
110
		if(ril_gprs_connections[i]->enabled == 0) {
111
			ril_gprs_connection_del(ril_gprs_connections[i]);
112

    
113
			return i;
114
		}
115
	}
116

    
117
	return -1;
118
}
119

    
120
struct ril_gprs_connection *ril_gprs_connection_add(void)
121
{
122
	struct ril_gprs_connection *gprs_connection = NULL;
123
	int id = ril_gprs_connection_reg_id();
124

    
125
	if(id < 0) {
126
		LOGE("Unable to add another GPRS connection!");
127
		return NULL;
128
	}
129

    
130
	gprs_connection = malloc(sizeof(struct ril_gprs_connection));
131
	memset(gprs_connection, 0, sizeof(struct ril_gprs_connection));
132

    
133
	gprs_connection->cid = id + 1;
134
	gprs_connection->enabled = 0;
135
	gprs_connection->interface = NULL;
136
	gprs_connection->token = (RIL_Token) 0x00;
137

    
138
	ril_gprs_connections[id] = gprs_connection;
139

    
140
	return gprs_connection;
141
}
142

    
143
void ril_gprs_connection_del(struct ril_gprs_connection *gprs_connection)
144
{
145
	int i;
146

    
147
	if(gprs_connection == NULL)
148
		return;
149

    
150
	if(gprs_connection->interface != NULL)
151
		free(gprs_connection->interface);
152

    
153
	for(i=0 ; i < ril_gprs_connections_count ; i++)
154
		if(ril_gprs_connections[i] == gprs_connection)
155
				ril_gprs_connections[i] = NULL;
156

    
157
	free(gprs_connection);
158
}
159

    
160
struct ril_gprs_connection *ril_gprs_connection_get_token(RIL_Token token)
161
{
162
	int i;
163

    
164
	for(i=0 ; i < ril_gprs_connections_count ; i++)
165
		if(ril_gprs_connections[i] != NULL)
166
			if(ril_gprs_connections[i]->token == token)
167
				return ril_gprs_connections[i];
168

    
169
	return NULL;
170
}
171

    
172
struct ril_gprs_connection *ril_gprs_connection_get_cid(int cid)
173
{
174
	int i;
175

    
176
	for(i=0 ; i < ril_gprs_connections_count ; i++)
177
		if(ril_gprs_connections[i] != NULL)
178
			if(ril_gprs_connections[i]->cid == cid)
179
				return ril_gprs_connections[i];
180

    
181
	return NULL;
182
}
183

    
184
void ipc_gprs_pdp_context_enable_complete(struct ipc_message_info *info)
185
{
186
	struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
187
	struct ril_gprs_connection *gprs_connection;
188
	int rc;
189

    
190
	gprs_connection = ril_gprs_connection_get_token(reqGetToken(info->aseq));
191

    
192
	if(!gprs_connection) {
193
		LOGE("Unable to find GPRS connection, aborting");
194

    
195
		RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
196
		return;
197
	}
198

    
199
	rc = ipc_gen_phone_res_check(phone_res);
200
	if(rc < 0) {
201
		LOGE("There was an error, aborting PDP context complete");
202

    
203
		gprs_connection->fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
204
		gprs_connection->token = (RIL_Token) 0x00;
205
		ril_state.gprs_last_failed_cid = gprs_connection->cid;
206

    
207
		RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
208
		return;
209
	}
210

    
211
	LOGD("Waiting for IP configuration!");
212
}
213

    
214
void ipc_gprs_define_pdp_context_complete(struct ipc_message_info *info)
215
{
216
	struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
217
	struct ril_gprs_connection *gprs_connection;
218
	int aseq;
219
	int rc;
220

    
221
	gprs_connection = ril_gprs_connection_get_token(reqGetToken(info->aseq));
222

    
223
	if(!gprs_connection) {
224
		LOGE("Unable to find GPRS connection, aborting");
225

    
226
		RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
227
		return;
228
	}
229

    
230
	rc = ipc_gen_phone_res_check(phone_res);
231
	if(rc < 0) {
232
		LOGE("There was an error, aborting define PDP context complete");
233

    
234
		gprs_connection->fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
235
		gprs_connection->token = (RIL_Token) 0x00;
236
		ril_state.gprs_last_failed_cid = gprs_connection->cid;
237

    
238
		RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
239
		return;
240
	}
241

    
242
	// We need to get a clean new aseq here
243
	aseq = ril_request_reg_id(reqGetToken(info->aseq));
244

    
245
	ipc_gen_phone_res_expect_to_func(aseq, IPC_GPRS_PDP_CONTEXT,
246
		ipc_gprs_pdp_context_enable_complete);
247

    
248
	ipc_fmt_send(IPC_GPRS_PDP_CONTEXT, IPC_TYPE_SET,
249
			(void *) &(gprs_connection->context), sizeof(struct ipc_gprs_pdp_context_set), aseq);
250
}
251

    
252
void ipc_gprs_port_list_complete(struct ipc_message_info *info)
253
{
254
	struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
255
	struct ril_gprs_connection *gprs_connection;
256
	int rc;
257
	int aseq;
258

    
259
	gprs_connection = ril_gprs_connection_get_token(reqGetToken(info->aseq));
260

    
261
	if(!gprs_connection) {
262
		LOGE("Unable to find GPRS connection, aborting");
263

    
264
		RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
265
		return;
266
	}
267

    
268
	rc = ipc_gen_phone_res_check(phone_res);
269
	if(rc < 0) {
270
		LOGE("There was an error, aborting port list complete");
271

    
272
		gprs_connection->fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
273
		gprs_connection->token = (RIL_Token) 0x00;
274
		ril_state.gprs_last_failed_cid = gprs_connection->cid;
275

    
276
		RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
277
		return;
278
	}
279

    
280
	// We need to get a clean new aseq here
281
	aseq = ril_request_reg_id(reqGetToken(info->aseq));
282

    
283
	ipc_gen_phone_res_expect_to_func(aseq, IPC_GPRS_DEFINE_PDP_CONTEXT,
284
		ipc_gprs_define_pdp_context_complete);
285

    
286
	ipc_fmt_send(IPC_GPRS_DEFINE_PDP_CONTEXT, IPC_TYPE_SET,
287
		(void *) &(gprs_connection->define_context), sizeof(struct ipc_gprs_define_pdp_context), aseq);
288
}
289

    
290
void ril_request_setup_data_call(RIL_Token t, void *data, int length)
291
{
292
	struct ril_gprs_connection *gprs_connection = NULL;
293
	struct ipc_client_gprs_capabilities gprs_capabilities;
294
	struct ipc_gprs_port_list port_list;
295
	struct ipc_client *ipc_client;
296

    
297
	char *username = NULL;
298
	char *password = NULL;
299
	char *apn = NULL;
300

    
301
	ipc_client = ((struct ipc_client_object *) ipc_fmt_client->object)->ipc_client;
302

    
303
	apn = ((char **) data)[2];
304
	username = ((char **) data)[3];
305
	password = ((char **) data)[4];
306

    
307
	LOGD("Requesting data connection to APN '%s'\n", apn);
308

    
309
	gprs_connection = ril_gprs_connection_add();
310

    
311
	if(!gprs_connection) {
312
		LOGE("Unable to create GPRS connection, aborting");
313

    
314
		RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
315
		return;
316
	}
317

    
318
	gprs_connection->token = t;
319

    
320
	// Create the structs with the apn
321
	ipc_gprs_define_pdp_context_setup(&(gprs_connection->define_context), gprs_connection->cid, 1, apn);
322

    
323
	// Create the structs with the username/password tuple
324
	ipc_gprs_pdp_context_setup(&(gprs_connection->context), gprs_connection->cid, 1, username, password);
325

    
326
	ipc_client_gprs_get_capabilities(ipc_client, &gprs_capabilities);
327

    
328
	// If the device has the capability, deal with port list
329
	if(gprs_capabilities.port_list) {
330
		ipc_gprs_port_list_setup(&port_list);
331

    
332
		ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_GPRS_PORT_LIST,
333
			ipc_gprs_port_list_complete);
334

    
335
		ipc_fmt_send(IPC_GPRS_PORT_LIST, IPC_TYPE_SET,
336
			(void *) &port_list, sizeof(struct ipc_gprs_port_list), reqGetId(t));
337
	} else {
338
		ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_GPRS_DEFINE_PDP_CONTEXT,
339
			ipc_gprs_define_pdp_context_complete);
340

    
341
		ipc_fmt_send(IPC_GPRS_DEFINE_PDP_CONTEXT, IPC_TYPE_SET,
342
			(void *) &(gprs_connection->define_context), sizeof(struct ipc_gprs_define_pdp_context), reqGetId(t));
343
	}
344
}
345

    
346
void ipc_gprs_ip_configuration(struct ipc_message_info *info)
347
{
348
	struct ril_gprs_connection *gprs_connection;
349
        struct ipc_gprs_ip_configuration *ip_configuration =
350
		(struct ipc_gprs_ip_configuration *) info->data;
351

    
352
	gprs_connection = ril_gprs_connection_get_cid(ip_configuration->cid);
353

    
354
	if(!gprs_connection) {
355
		LOGE("Unable to find GPRS connection, aborting");
356

    
357
		RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
358
		return;
359
	}
360

    
361
	LOGD("Obtained IP Configuration");
362

    
363
	// Copy the obtained IP configuration to the GPRS connection structure
364
	memcpy(&(gprs_connection->ip_configuration), ip_configuration, sizeof(struct ipc_gprs_ip_configuration));
365

    
366
	LOGD("Waiting for GPRS call status");
367
}
368

    
369
void ipc_gprs_pdp_context_disable_complete(struct ipc_message_info *info)
370
{
371
	struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
372
	struct ril_gprs_connection *gprs_connection;
373
	int rc;
374

    
375
	gprs_connection = ril_gprs_connection_get_token(reqGetToken(info->aseq));
376

    
377
	if(!gprs_connection) {
378
		LOGE("Unable to find GPRS connection, aborting");
379

    
380
		RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
381
		return;
382
	}
383

    
384
	rc = ipc_gen_phone_res_check(phone_res);
385
	if(rc < 0) {
386
		LOGE("There was an error, aborting PDP context complete");
387

    
388
		// RILJ is not going to ask for fail reason
389
		ril_gprs_connection_del(gprs_connection);
390

    
391
		RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
392
		return;
393
	}
394

    
395
	LOGD("Waiting for GPRS call status");
396
}
397

    
398
void ril_request_deactivate_data_call(RIL_Token t, void *data, int length)
399
{
400
	struct ril_gprs_connection *gprs_connection;
401
	struct ipc_gprs_pdp_context_set context;
402

    
403
	char *cid = ((char **) data)[0];
404
	int rc;
405

    
406
	gprs_connection = ril_gprs_connection_get_cid(atoi(cid));
407

    
408
	if(!gprs_connection) {
409
		LOGE("Unable to find GPRS connection, aborting");
410

    
411
		RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
412
		return;
413
	}
414

    
415
	gprs_connection->token = t;
416

    
417
	ipc_gprs_pdp_context_setup(&context, gprs_connection->cid, 0, NULL, NULL);
418

    
419
	ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_GPRS_PDP_CONTEXT,
420
		ipc_gprs_pdp_context_disable_complete);
421

    
422
	ipc_fmt_send(IPC_GPRS_PDP_CONTEXT, IPC_TYPE_SET,
423
		(void *) &context, sizeof(struct ipc_gprs_pdp_context_set), reqGetId(t));
424
}
425

    
426
int ipc_gprs_connection_enable(struct ril_gprs_connection *gprs_connection, char **setup_data_call_response)
427
{
428
	struct ipc_client *ipc_client;
429
        struct ipc_gprs_ip_configuration *ip_configuration;
430

    
431
	char *interface = NULL;
432
	char *ip;
433
	char *gateway;
434
	char *subnet_mask;
435
	char *dns1;
436
	char *dns2;
437

    
438
	char prop_name[PROPERTY_KEY_MAX];
439

    
440
	int rc;
441

    
442
	ipc_client = ((struct ipc_client_object *) ipc_fmt_client->object)->ipc_client;
443

    
444
	ip_configuration = &(gprs_connection->ip_configuration);
445

    
446
	asprintf(&ip, "%i.%i.%i.%i", (ip_configuration->ip)[0],(ip_configuration->ip)[1], (ip_configuration->ip)[2],(ip_configuration->ip)[3]);
447
	// FIXME: gateway isn't reliable!
448
        asprintf(&gateway, "%i.%i.%i.%i", (ip_configuration->ip)[0],(ip_configuration->ip)[1], (ip_configuration->ip)[2],(ip_configuration->ip)[3]);
449
	// FIXME: subnet isn't reliable!
450
        asprintf(&subnet_mask, "255.255.255.255");
451
        asprintf(&dns1, "%i.%i.%i.%i", (ip_configuration->dns1)[0],(ip_configuration->dns1)[1], (ip_configuration->dns1)[2],(ip_configuration->dns1)[3]);
452
        asprintf(&dns2, "%i.%i.%i.%i", (ip_configuration->dns2)[0],(ip_configuration->dns2)[1],(ip_configuration->dns2)[2],(ip_configuration->dns2)[3]);	
453

    
454
	if(ipc_client_gprs_handlers_available(ipc_client)) {
455
		rc = ipc_client_gprs_activate(ipc_client);
456
		if(rc < 0) {
457
			// This is not a critical issue
458
			LOGE("Failed to activate interface!");
459
		}
460
	}
461

    
462
	rc = ipc_client_gprs_get_iface(ipc_client, &interface, gprs_connection->cid);
463
	if(rc < 0) {
464
		// This is not a critical issue, fallback to rmnet
465
		LOGE("Failed to get interface name!");
466
		asprintf(&interface, "rmnet%d", gprs_connection->cid - 1);
467
	}
468

    
469
	if(gprs_connection->interface == NULL && interface != NULL) {
470
		gprs_connection->interface = strdup(interface);
471
	}
472

    
473
	LOGD("Using net interface: %s\n", interface);
474

    
475
        LOGD("GPRS configuration: iface: %s, ip:%s, gateway:%s, subnet_mask:%s, dns1:%s, dns2:%s",
476
		interface, ip, gateway, subnet_mask, dns1, dns2);
477

    
478
	rc = ifc_configure(interface, inet_addr(ip),
479
		inet_addr(subnet_mask), inet_addr(gateway),
480
		inet_addr(dns1), inet_addr(dns2));
481

    
482
	if(rc < 0) {
483
		LOGE("ifc_configure failed");
484

    
485
		free(interface);
486
		return -1;
487
	}
488

    
489
	snprintf(prop_name, PROPERTY_KEY_MAX, "net.%s.dns1", interface);
490
	property_set(prop_name, dns1);
491
	snprintf(prop_name, PROPERTY_KEY_MAX, "net.%s.dns2", interface);
492
	property_set(prop_name, dns2);
493
	snprintf(prop_name, PROPERTY_KEY_MAX, "net.%s.gw", interface);
494
	property_set(prop_name, gateway);
495

    
496
	asprintf(&(setup_data_call_response[0]), "%d", gprs_connection->cid);
497
	setup_data_call_response[1] = interface;
498
	setup_data_call_response[2] = ip;
499

    
500
	free(gateway);
501
	free(subnet_mask);
502
	free(dns1);
503
	free(dns2);
504

    
505
	return 0;
506
}
507

    
508
int ipc_gprs_connection_disable(struct ril_gprs_connection *gprs_connection)
509
{
510
	struct ipc_client *ipc_client;
511

    
512
	char *interface;
513
	int rc;
514

    
515
	ipc_client = ((struct ipc_client_object *) ipc_fmt_client->object)->ipc_client;
516

    
517
	if(gprs_connection->interface == NULL) {
518
		rc = ipc_client_gprs_get_iface(ipc_client, &interface, gprs_connection->cid);
519
		if(rc < 0) {
520
			// This is not a critical issue, fallback to rmnet
521
			LOGE("Failed to get interface name!");
522
			asprintf(&interface, "rmnet%d", gprs_connection->cid);
523
		}
524
	} else {
525
		interface = gprs_connection->interface;
526
	}
527

    
528
	LOGD("Using net interface: %s\n", interface);
529

    
530
	rc = ifc_down(interface);
531

    
532
	if(gprs_connection->interface == NULL)
533
		free(interface);
534

    
535
	if(rc < 0) {
536
		LOGE("ifc_down failed");
537
	}
538

    
539
	if(ipc_client_gprs_handlers_available(ipc_client)) {
540
		rc = ipc_client_gprs_deactivate(ipc_client);
541
		if(rc < 0) {
542
			// This is not a critical issue
543
			LOGE("Failed to deactivate interface!");
544
		}
545
	}
546

    
547
	return 0;
548
}
549

    
550
void ipc_gprs_call_status(struct ipc_message_info *info)
551
{
552
	struct ril_gprs_connection *gprs_connection;
553
	struct ipc_gprs_call_status *call_status =
554
		(struct ipc_gprs_call_status *) info->data;
555

    
556
	char *setup_data_call_response[3] = { NULL, NULL, NULL };
557
	int rc;
558

    
559
	gprs_connection = ril_gprs_connection_get_cid(call_status->cid);
560

    
561
	if(!gprs_connection) {
562
		LOGE("Unable to find GPRS connection, aborting");
563

    
564
		RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
565
		return;
566
	}
567

    
568
	if(call_status->fail_cause == 0) {
569
		if(!gprs_connection->enabled &&
570
			call_status->state == IPC_GPRS_STATE_ENABLED &&
571
			gprs_connection->token != (RIL_Token) 0x00) {
572
			LOGD("GPRS connection is now enabled");
573

    
574
			rc = ipc_gprs_connection_enable(gprs_connection, setup_data_call_response);
575
			if(rc < 0) {
576
				LOGE("Failed to enable and configure GPRS interface");
577

    
578
				gprs_connection->enabled = 0;
579
				gprs_connection->fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
580
				ril_state.gprs_last_failed_cid = gprs_connection->cid;
581

    
582
				RIL_onRequestComplete(gprs_connection->token, RIL_E_GENERIC_FAILURE, NULL, 0);
583
			} else {
584
				LOGD("GPRS interface enabled");
585

    
586
				gprs_connection->enabled = 1;
587

    
588
				RIL_onRequestComplete(gprs_connection->token, RIL_E_SUCCESS, setup_data_call_response, sizeof(setup_data_call_response));
589
				gprs_connection->token = (RIL_Token) 0x00;
590
			}
591

    
592
			if(setup_data_call_response[0] != NULL)
593
				free(setup_data_call_response[0]);
594
			if(setup_data_call_response[1] != NULL)
595
				free(setup_data_call_response[1]);
596
			if(setup_data_call_response[2] != NULL)
597
				free(setup_data_call_response[2]);
598
		} else if(gprs_connection->enabled &&
599
			call_status->state == IPC_GPRS_STATE_DISABLED &&
600
			gprs_connection->token != (RIL_Token) 0x00) {
601
			LOGD("GPRS connection is now disabled");
602

    
603
			rc = ipc_gprs_connection_disable(gprs_connection);
604
			if(rc < 0) {
605
				LOGE("Failed to disable GPRS interface");
606

    
607
				RIL_onRequestComplete(gprs_connection->token, RIL_E_GENERIC_FAILURE, NULL, 0);
608

    
609
				// RILJ is not going to ask for fail reason
610
				ril_gprs_connection_del(gprs_connection);
611
			} else {
612
				LOGD("GPRS interface disabled");
613

    
614
				gprs_connection->enabled = 0;
615

    
616
				RIL_onRequestComplete(gprs_connection->token, RIL_E_SUCCESS, NULL, 0);
617

    
618
				ril_gprs_connection_del(gprs_connection);
619
			}
620
		} else {
621
			LOGE("GPRS connection reported as changed though state is not OK:\n\tgprs_connection->enabled=%d\n\tgprs_connection->token=0x%x",
622
				gprs_connection->enabled, gprs_connection->token);
623

    
624
			ril_unsol_data_call_list_changed();
625
		}
626
	} else {
627
		if(!gprs_connection->enabled &&
628
			(call_status->state == IPC_GPRS_STATE_NOT_ENABLED ||
629
			call_status->state == IPC_GPRS_STATE_DISABLED) &&
630
			gprs_connection->token != (RIL_Token) 0x00) {
631
			LOGE("Failed to enable GPRS connection");
632

    
633
			gprs_connection->enabled = 0;
634
			gprs_connection->fail_cause = ipc2ril_gprs_fail_cause(call_status->fail_cause);
635
			ril_state.gprs_last_failed_cid = gprs_connection->cid;
636

    
637
			RIL_onRequestComplete(gprs_connection->token, RIL_E_GENERIC_FAILURE, NULL, 0);
638
			gprs_connection->token = (RIL_Token) 0x00;
639

    
640
			ril_unsol_data_call_list_changed();
641
		} else if(gprs_connection->enabled &&
642
			call_status->state == IPC_GPRS_STATE_DISABLED) {
643
			LOGE("GPRS connection suddently got disabled");
644

    
645
			rc = ipc_gprs_connection_disable(gprs_connection);
646
			if(rc < 0) {
647
				LOGE("Failed to disable GPRS interface");
648

    
649
				// RILJ is not going to ask for fail reason
650
				ril_gprs_connection_del(gprs_connection);
651
			} else {
652
				LOGE("GPRS interface disabled");
653

    
654
				gprs_connection->enabled = 0;
655
				ril_gprs_connection_del(gprs_connection);
656
			}
657

    
658
			ril_unsol_data_call_list_changed();
659
		} else {
660
			LOGE("GPRS connection reported to have failed though state is OK:\n\tgprs_connection->enabled=%d\n\tgprs_connection->token=0x%x",
661
				gprs_connection->enabled, gprs_connection->token);
662

    
663
			ril_unsol_data_call_list_changed();
664
		}
665
	}
666
}
667

    
668
void ril_request_last_data_call_fail_cause(RIL_Token t)
669
{
670
	struct ril_gprs_connection *gprs_connection;
671
	int last_failed_cid;
672
	int fail_cause;
673

    
674
	last_failed_cid = ril_state.gprs_last_failed_cid;
675

    
676
	if(!last_failed_cid) {
677
		LOGE("No GPRS connection was reported to have failed");
678

    
679
		goto fail_cause_unspecified;
680
	}
681

    
682
	gprs_connection = ril_gprs_connection_get_cid(last_failed_cid);
683

    
684
	if(!gprs_connection) {
685
		LOGE("Unable to find GPRS connection");
686

    
687
		goto fail_cause_unspecified;
688
	}
689

    
690
	fail_cause = gprs_connection->fail_cause;
691

    
692
	LOGD("Destroying GPRS connection with cid: %d", gprs_connection->cid);
693
	ril_gprs_connection_del(gprs_connection);
694

    
695
	goto fail_cause_return;
696

    
697
fail_cause_unspecified:
698
	fail_cause = PDP_FAIL_ERROR_UNSPECIFIED;
699

    
700
fail_cause_return:
701
	ril_state.gprs_last_failed_cid = 0;
702
	RIL_onRequestComplete(t, RIL_E_SUCCESS, &fail_cause, sizeof(fail_cause));
703
}
704

    
705
/*
706
 * Some modem firmwares have a bug that will make the first cid (1) overriden
707
 * by the current cid, thus reporting it twice, with a wrong 2nd status.
708
 *
709
 * This shouldn't change anything to healthy structures.
710
 */
711
void ipc_gprs_pdp_context_fix(RIL_Data_Call_Response *data_call_list, int c)
712
{
713
	int i, j, k;
714

    
715
	for(i=0 ; i < c ; i++) {
716
		for(j=i-1 ; j >= 0 ; j--) {
717
			if(data_call_list[i].cid == data_call_list[j].cid) {
718
				for(k=0 ; k < c ; k++) {
719
					if(data_call_list[k].cid == 1) {
720
						data_call_list[i].cid = 0;
721
						break;
722
					}
723
				}
724

    
725
				data_call_list[i].cid = 1;
726
			}
727
		}
728
	}
729
}
730

    
731
void ipc_gprs_pdp_context(struct ipc_message_info *info)
732
{
733
	struct ril_gprs_connection *gprs_connection;
734
        struct ipc_gprs_ip_configuration *ip_configuration;
735
	struct ipc_gprs_pdp_context_get *context =
736
		(struct ipc_gprs_pdp_context_get *) info->data;
737

    
738
	RIL_Data_Call_Response data_call_list[IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT];
739

    
740
	int i;
741

    
742
	for(i=0 ; i < IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT ; i++) {
743
		data_call_list[i].cid = context->desc[i].cid;
744
		data_call_list[i].active = ipc2ril_gprs_connection_active(context->desc[i].state);
745

    
746
		if(context->desc[i].state == IPC_GPRS_STATE_ENABLED) {
747
			gprs_connection = ril_gprs_connection_get_cid(context->desc[i].cid);
748

    
749
			if(gprs_connection == NULL) {
750
				LOGE("CID %d reported as enabled but not listed here");
751
				goto empty;
752
			}
753

    
754
			ip_configuration = &(gprs_connection->ip_configuration);
755

    
756
			asprintf(&(data_call_list[i].type), "IP");
757
			asprintf(&(data_call_list[i].apn), "%s",
758
				gprs_connection->define_context.apn);
759
			asprintf(&(data_call_list[i].address), "%i.%i.%i.%i",
760
				(ip_configuration->ip)[0],(ip_configuration->ip)[1], (ip_configuration->ip)[2],(ip_configuration->ip)[3]);
761

    
762
			continue;
763
		}
764

    
765
empty:
766
		data_call_list[i].type = NULL;
767
		data_call_list[i].apn = NULL;
768
		data_call_list[i].address = NULL;
769
	}
770

    
771
	ipc_gprs_pdp_context_fix(data_call_list, IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT);
772

    
773
	if(info->aseq == 0xff)
774
		RIL_onUnsolicitedResponse(RIL_UNSOL_DATA_CALL_LIST_CHANGED, &data_call_list, sizeof(data_call_list));
775
	else
776
		RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &data_call_list, sizeof(data_call_list));
777

    
778
	for(i=0 ; i < IPC_GPRS_PDP_CONTEXT_GET_DESC_COUNT ; i++) {
779
		if(data_call_list[i].type != NULL)
780
			free(data_call_list[i].type);
781
		if(data_call_list[i].apn != NULL)
782
			free(data_call_list[i].apn);
783
		if(data_call_list[i].address != NULL)
784
			free(data_call_list[i].address);
785
	}
786
}
787

    
788
void ril_unsol_data_call_list_changed(void)
789
{
790
	ipc_fmt_send_get(IPC_GPRS_PDP_CONTEXT, 0xff);
791
}
792

    
793
void ril_request_data_call_list(RIL_Token t)
794
{
795
	ipc_fmt_send_get(IPC_GPRS_PDP_CONTEXT, reqGetId(t));
796
}
    (1-1/1)