2 * This file is part of samsung-ril.
4 * Copyright (C) 2010-2011 Joerie de Gram <j.de.gram@gmail.com>
5 * Copyright (C) 2011 Paul Kocialkowski <contact@oaulk.fr>
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.
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.
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/>.
22 #define LOG_TAG "RIL-NET"
23 #include <utils/Log.h>
25 #include "samsung-ril.h"
28 #include <plmn_list.h>
30 #define RIL_TOKEN_NET_DATA_WAITING (RIL_Token) 0xff
33 * Format conversion utils
37 * Converts IPC network registration status to Android RIL format
39 unsigned char ipc2ril_reg_state(unsigned char reg_state)
42 case IPC_NET_REGISTRATION_STATE_NONE:
44 case IPC_NET_REGISTRATION_STATE_HOME:
46 case IPC_NET_REGISTRATION_STATE_SEARCHING:
48 case IPC_NET_REGISTRATION_STATE_EMERGENCY:
50 case IPC_NET_REGISTRATION_STATE_ROAMING:
52 case IPC_NET_REGISTRATION_STATE_UNKNOWN:
55 LOGE("%s: invalid reg_state: %d", __FUNCTION__, reg_state);
61 * Converts IPC network access technology to Android RIL format
63 unsigned char ipc2ril_act(unsigned char act)
66 case IPC_NET_ACCESS_TECHNOLOGY_GPRS:
68 case IPC_NET_ACCESS_TECHNOLOGY_EDGE:
70 case IPC_NET_ACCESS_TECHNOLOGY_UMTS:
72 case IPC_NET_ACCESS_TECHNOLOGY_GSM:
73 case IPC_NET_ACCESS_TECHNOLOGY_GSM2:
80 * Converts IPC GPRS network access technology to Android RIL format
82 unsigned char ipc2ril_gprs_act(unsigned char act)
85 case IPC_NET_ACCESS_TECHNOLOGY_GPRS:
87 case IPC_NET_ACCESS_TECHNOLOGY_EDGE:
89 case IPC_NET_ACCESS_TECHNOLOGY_UMTS:
91 case IPC_NET_ACCESS_TECHNOLOGY_GSM:
92 case IPC_NET_ACCESS_TECHNOLOGY_GSM2:
99 * Converts IPC preferred network type to Android RIL format
101 int ipc2ril_mode_sel(unsigned char mode)
105 return 7; // auto mode
106 case IPC_NET_MODE_SEL_GSM_UMTS:
108 case IPC_NET_MODE_SEL_GSM_ONLY:
110 case IPC_NET_MODE_SEL_UMTS_ONLY:
118 * Converts Android RIL preferred network type to IPC format
120 unsigned char ril2ipc_mode_sel(int mode)
124 return IPC_NET_MODE_SEL_GSM_ONLY;
125 case 2: // WCDMA only
126 return IPC_NET_MODE_SEL_UMTS_ONLY;
128 default: // GSM/WCDMA + the rest
129 return IPC_NET_MODE_SEL_GSM_UMTS;
134 * Converts IPC preferred PLMN selection type to Android RIL format
136 int ipc2ril_plmn_sel(unsigned char mode)
139 case IPC_NET_PLMN_SEL_MANUAL:
141 case IPC_NET_PLMN_SEL_AUTO:
149 * Converts Android RIL preferred PLMN selection type to IPC format
151 unsigned char ril2ipc_plmn_sel(int mode)
155 return IPC_NET_PLMN_SEL_AUTO;
157 return IPC_NET_PLMN_SEL_MANUAL;
164 * Converts IPC reg state to Android format
166 void ipc2ril_reg_state_resp(struct ipc_net_regist *netinfo, char *response[15])
168 unsigned char reg_state = ipc2ril_reg_state(netinfo->reg_state);
169 unsigned char act = ipc2ril_act(netinfo->act);
171 memset(response, 0, sizeof(response));
173 asprintf(&response[0], "%d", reg_state);
174 asprintf(&response[1], "%x", netinfo->lac);
175 asprintf(&response[2], "%x", netinfo->cid);
176 asprintf(&response[3], "%d", act);
180 * Converts IPC GPRS reg state to Android format
182 void ipc2ril_gprs_reg_state_resp(struct ipc_net_regist *netinfo, char *response[4])
184 unsigned char reg_state = ipc2ril_reg_state(netinfo->reg_state);
185 unsigned char act = ipc2ril_gprs_act(netinfo->act);
187 memset(response, 0, sizeof(response));
189 asprintf(&response[0], "%d", reg_state);
190 asprintf(&response[1], "%x", netinfo->lac);
191 asprintf(&response[2], "%x", netinfo->cid);
192 asprintf(&response[3], "%d", act);
196 * Set all the tokens to data waiting.
197 * For instance when only operator is updated by modem NOTI, we don't need
198 * to ask the modem new NET Regist and GPRS Net Regist states so act like we got
199 * these from modem NOTI too so we don't have to make the requests
201 void ril_tokens_net_set_data_waiting(void)
203 ril_state.tokens.registration_state = RIL_TOKEN_NET_DATA_WAITING;
204 ril_state.tokens.gprs_registration_state = RIL_TOKEN_NET_DATA_WAITING;
205 ril_state.tokens.operator = RIL_TOKEN_NET_DATA_WAITING;
209 * Returns 1 if unsol data is waiting, 0 if not
211 int ril_tokens_net_get_data_waiting(void)
213 return ril_state.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING || ril_state.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING || ril_state.tokens.operator == RIL_TOKEN_NET_DATA_WAITING;
217 * Print net tokens values
219 void ril_tokens_net_state_dump(void)
221 LOGD("ril_tokens_net_state_dump:\n\tril_state.tokens.registration_state = 0x%x\n\tril_state.tokens.gprs_registration_state = 0x%x\n\tril_state.tokens.operator = 0x%x\n", ril_state.tokens.registration_state, ril_state.tokens.gprs_registration_state, ril_state.tokens.operator);
224 void ril_plmn_split(char *plmn_data, char **plmn, unsigned int *mcc, unsigned int *mnc)
229 memset(plmn_t, 0, sizeof(plmn_t));
230 memcpy(plmn_t, plmn_data, 6);
236 *plmn = malloc(sizeof(plmn_t));
237 memcpy(*plmn, plmn_t, sizeof(plmn_t));
240 if(mcc == NULL || mnc == NULL)
243 sscanf(plmn_t, "%3u%2u", mcc, mnc);
246 void ril_plmn_string(char *plmn_data, char *response[3])
248 unsigned int mcc, mnc;
254 ril_plmn_split(plmn_data, &plmn, &mcc, &mnc);
256 asprintf(&response[2], "%s", plmn);
259 plmn_entries = sizeof(plmn_list) / sizeof(struct plmn_list_entry);
261 LOGD("Found %d plmn records", plmn_entries);
263 for(i=0 ; i < plmn_entries ; i++) {
264 if(plmn_list[i].mcc == mcc && plmn_list[i].mnc == mnc) {
265 asprintf(&response[0], "%s", plmn_list[i].operator_short);
266 asprintf(&response[1], "%s", plmn_list[i].operator_long);
276 * How to handle NET unsol data from modem:
277 * 1- Rx UNSOL (NOTI) data from modem
278 * 2- copy data in a sized variable stored in radio
279 * 3- make sure no SOL request is going on for this token
280 * 4- copy data to radio structure
281 * 5- if no UNSOL data is already waiting for a token, tell RILJ NETWORK_STATE_CHANGED
282 * 6- set all the net tokens to RIL_TOKEN_NET_DATA_WAITING
283 * 7- RILJ will ask for OPERATOR, GPRS_REG_STATE and REG_STATE
285 * 8- if token is RIL_TOKEN_NET_DATA_WAITING it's SOL request for modem UNSOL data
286 * 9- send back modem data and tell E_SUCCESS to RILJ request
287 * 10- set token to 0x00
289 * How to handle NET sol requests from RILJ:
290 * 1- if token is 0x00 it's UNSOL RILJ request for modem data
291 * 2- put RIL_Token in token
292 * 3- request data to the modem
293 * 4- Rx SOL (RESP) data from modem
294 * 5- copy data to radio structure
295 * 6- send back data to RILJ with token from modem message
296 * 7- if token != RIL_TOKEN_NET_DATA_WAITING, reset token to 0x00
298 * What if both are appening at the same time?
299 * 1- RILJ requests modem data (UNSOL)
300 * 2- token is 0x00 so send request to modem
301 * 3- UNSOL data arrives from modem
302 * 4- set all tokens to RIL_TOKEN_NET_DATA_WAITING
303 * 5- store data, tell RILJ NETWORK_STATE_CHANGED
304 * 6- Rx requested data from modem
305 * 7- copy data to radio structure
306 * 8- token mismatch (is now RIL_TOKEN_NET_DATA_WAITING)
307 * 9- send back data to RIL with token from IPC message
308 * 10- don't reset token to 0x00
309 * 11- RILJ does SOL request for modem data (we know it's SOL because we didn't reset token)
310 * 12- send back last data we have (from UNSOL RILJ request here)
314 * In: RIL_REQUEST_OPERATOR
315 * Request Operator name
317 * Out: IPC_NET_CURRENT_PLMN
318 * return modem UNSOL data if available
319 * request IPC_NET_CURRENT_PLMN if no data is there
320 * return RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW if not registered
322 void ril_request_operator(RIL_Token t)
327 // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
328 if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
329 ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING ||
330 ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN ||
331 ril_state.netinfo.reg_state > IPC_NET_REGISTRATION_STATE_ROAMING) {
332 RIL_onRequestComplete(t, RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW, NULL, 0);
334 ril_state.tokens.operator = (RIL_Token) 0x00;
338 if(ril_state.tokens.operator == RIL_TOKEN_NET_DATA_WAITING) {
339 LOGD("Got RILJ request for UNSOL data");
341 /* Send back the data we got UNSOL */
342 ril_plmn_string(ril_state.plmndata.plmn, response);
344 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
346 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
347 if(response[i] != NULL)
351 ril_state.tokens.operator = (RIL_Token) 0x00;
352 } else if(ril_state.tokens.operator == (RIL_Token) 0x00) {
353 LOGD("Got RILJ request for SOL data");
354 /* Request data to the modem */
355 ril_state.tokens.operator = t;
357 ipc_fmt_send_get(IPC_NET_CURRENT_PLMN, reqGetId(t));
359 LOGE("Another request is going on, returning UNSOL data");
361 /* Send back the data we got UNSOL */
362 ril_plmn_string(ril_state.plmndata.plmn, response);
364 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
366 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
367 if(response[i] != NULL)
372 ril_tokens_net_state_dump();
376 * In: IPC_NET_CURRENT_PLMN
377 * This can be SOL (RESP) or UNSOL (NOTI) message from modem
379 * Out: RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED
380 * enqueue modem data if UNSOL modem message and then call
381 * RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED
382 * if SOL message, send back data to RILJ
384 void ipc_net_current_plmn(struct ipc_message_info *message)
386 RIL_Token t = reqGetToken(message->aseq);
387 struct ipc_net_current_plmn *plmndata = (struct ipc_net_current_plmn *) message->data;
392 switch(message->type) {
394 LOGD("Got UNSOL Operator message");
396 // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
397 if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
398 ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING ||
399 ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN ||
400 ril_state.netinfo.reg_state > IPC_NET_REGISTRATION_STATE_ROAMING) {
401 /* Better keeping it up to date */
402 memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn));
406 if(ril_state.tokens.operator != (RIL_Token) 0x00 && ril_state.tokens.operator != RIL_TOKEN_NET_DATA_WAITING) {
407 LOGE("Another Operator Req is in progress, skipping");
411 memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn));
413 /* we already told RILJ to get the new data but it wasn't done yet */
414 if(ril_tokens_net_get_data_waiting() && ril_state.tokens.operator == RIL_TOKEN_NET_DATA_WAITING) {
415 LOGD("Updating Operator data in background");
417 ril_tokens_net_set_data_waiting();
418 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0);
423 // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
424 if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
425 ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING ||
426 ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN ||
427 ril_state.netinfo.reg_state > IPC_NET_REGISTRATION_STATE_ROAMING) {
428 /* Better keeping it up to date */
429 memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn));
431 RIL_onRequestComplete(t, RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW, NULL, 0);
433 if(ril_state.tokens.operator != RIL_TOKEN_NET_DATA_WAITING)
434 ril_state.tokens.operator = (RIL_Token) 0x00;
437 if(ril_state.tokens.operator != t)
438 LOGE("Operator tokens mismatch");
440 /* Better keeping it up to date */
441 memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn));
443 ril_plmn_string(plmndata->plmn, response);
445 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
447 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
448 if(response[i] != NULL)
452 if(ril_state.tokens.operator != RIL_TOKEN_NET_DATA_WAITING)
453 ril_state.tokens.operator = (RIL_Token) 0x00;
457 LOGE("%s: unhandled ipc method: %d", __FUNCTION__, message->type);
461 ril_tokens_net_state_dump();
465 * In: RIL_REQUEST_REGISTRATION_STATE
468 * Out: IPC_NET_REGIST
469 * return modem UNSOL data if available
470 * request IPC_NET_REGIST if no data is there
472 void ril_request_registration_state(RIL_Token t)
474 struct ipc_net_regist_get regist_req;
478 if(ril_state.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING) {
479 LOGD("Got RILJ request for UNSOL data");
481 /* Send back the data we got UNSOL */
482 ipc2ril_reg_state_resp(&(ril_state.netinfo), response);
484 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
486 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
487 if(response[i] != NULL)
491 ril_state.tokens.registration_state = (RIL_Token) 0x00;
492 } else if(ril_state.tokens.registration_state == (RIL_Token) 0x00) {
493 LOGD("Got RILJ request for SOL data");
494 /* Request data to the modem */
495 ril_state.tokens.registration_state = t;
497 ipc_net_regist_setup(®ist_req, IPC_NET_SERVICE_DOMAIN_GSM);
498 ipc_fmt_send(IPC_NET_REGIST, IPC_TYPE_GET, (void *)®ist_req, sizeof(struct ipc_net_regist_get), reqGetId(t));
500 LOGE("Another request is going on, returning UNSOL data");
502 /* Send back the data we got UNSOL */
503 ipc2ril_reg_state_resp(&(ril_state.netinfo), response);
505 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
507 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
508 if(response[i] != NULL)
513 ril_tokens_net_state_dump();
517 * In: RIL_REQUEST_GPRS_REGISTRATION_STATE
518 * Request GPRS reg state
520 * Out: IPC_NET_REGIST
521 * return modem UNSOL data if available
522 * request IPC_NET_REGIST if no data is there
524 void ril_request_gprs_registration_state(RIL_Token t)
526 struct ipc_net_regist_get regist_req;
530 if(ril_state.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING) {
531 LOGD("Got RILJ request for UNSOL data");
533 /* Send back the data we got UNSOL */
534 ipc2ril_gprs_reg_state_resp(&(ril_state.gprs_netinfo), response);
536 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
538 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
539 if(response[i] != NULL)
543 ril_state.tokens.gprs_registration_state = (RIL_Token) 0x00;
544 } else if(ril_state.tokens.gprs_registration_state == (RIL_Token) 0x00) {
545 LOGD("Got RILJ request for SOL data");
547 /* Request data to the modem */
548 ril_state.tokens.gprs_registration_state = t;
550 ipc_net_regist_setup(®ist_req, IPC_NET_SERVICE_DOMAIN_GPRS);
551 ipc_fmt_send(IPC_NET_REGIST, IPC_TYPE_GET, (void *)®ist_req, sizeof(struct ipc_net_regist_get), reqGetId(t));
553 LOGE("Another request is going on, returning UNSOL data");
555 /* Send back the data we got UNSOL */
556 ipc2ril_gprs_reg_state_resp(&(ril_state.gprs_netinfo), response);
558 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
560 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
561 if(response[i] != NULL)
566 ril_tokens_net_state_dump();
569 void ipc_net_regist_unsol(struct ipc_message_info *message)
571 struct ipc_net_regist *netinfo;
572 netinfo = (struct ipc_net_regist *) message->data;
574 LOGD("Got UNSOL NetRegist message");
576 switch(netinfo->domain) {
577 case IPC_NET_SERVICE_DOMAIN_GSM:
578 if(ril_state.tokens.registration_state != (RIL_Token) 0 && ril_state.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING) {
579 LOGE("Another NetRegist Req is in progress, skipping");
583 memcpy(&(ril_state.netinfo), netinfo, sizeof(struct ipc_net_regist));
585 /* we already told RILJ to get the new data but it wasn't done yet */
586 if(ril_tokens_net_get_data_waiting() && ril_state.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING) {
587 LOGD("Updating NetRegist data in background");
589 ril_tokens_net_set_data_waiting();
590 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0);
594 case IPC_NET_SERVICE_DOMAIN_GPRS:
595 if(ril_state.tokens.gprs_registration_state != (RIL_Token) 0 && ril_state.tokens.gprs_registration_state != RIL_TOKEN_NET_DATA_WAITING) {
596 LOGE("Another GPRS NetRegist Req is in progress, skipping");
600 memcpy(&(ril_state.gprs_netinfo), netinfo, sizeof(struct ipc_net_regist));
602 /* we already told RILJ to get the new data but it wasn't done yet */
603 if(ril_tokens_net_get_data_waiting() && ril_state.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING) {
604 LOGD("Updating GPRSNetRegist data in background");
606 ril_tokens_net_set_data_waiting();
607 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0);
611 LOGE("%s: unhandled service domain: %d", __FUNCTION__, netinfo->domain);
615 ril_tokens_net_state_dump();
618 void ipc_net_regist_sol(struct ipc_message_info *message)
623 struct ipc_net_regist *netinfo = (struct ipc_net_regist *) message->data;
624 RIL_Token t = reqGetToken(message->aseq);
626 LOGD("Got SOL NetRegist message");
628 switch(netinfo->domain) {
629 case IPC_NET_SERVICE_DOMAIN_GSM:
630 if(ril_state.tokens.registration_state != t)
631 LOGE("Registration state tokens mismatch");
633 /* Better keeping it up to date */
634 memcpy(&(ril_state.netinfo), netinfo, sizeof(struct ipc_net_regist));
636 ipc2ril_reg_state_resp(netinfo, response);
638 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
640 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
641 if(response[i] != NULL)
645 if(ril_state.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING)
646 ril_state.tokens.registration_state = (RIL_Token) 0x00;
648 case IPC_NET_SERVICE_DOMAIN_GPRS:
649 if(ril_state.tokens.gprs_registration_state != t)
650 LOGE("GPRS registration state tokens mismatch");
652 /* Better keeping it up to date */
653 memcpy(&(ril_state.gprs_netinfo), netinfo, sizeof(struct ipc_net_regist));
655 ipc2ril_gprs_reg_state_resp(netinfo, response);
657 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
659 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
660 if(response[i] != NULL)
663 if(ril_state.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING)
664 ril_state.tokens.gprs_registration_state = (RIL_Token) 0x00;
667 LOGE("%s: unhandled service domain: %d", __FUNCTION__, netinfo->domain);
671 ril_tokens_net_state_dump();
676 * This can be SOL (RESP) or UNSOL (NOTI) message from modem
678 void ipc_net_regist(struct ipc_message_info *message)
680 /* Don't consider this if modem isn't in normal power mode. */
681 if(ril_state.power_mode < POWER_MODE_NORMAL)
684 switch(message->type) {
686 ipc_net_regist_unsol(message);
689 ipc_net_regist_sol(message);
692 LOGE("%s: unhandled ipc method: %d", __FUNCTION__, message->type);
699 * In: RIL_REQUEST_QUERY_AVAILABLE_NETWORKS
701 * Out: IPC_NET_PLMN_LIST
703 void ril_request_query_available_networks(RIL_Token t)
705 ipc_fmt_send_get(IPC_NET_PLMN_LIST, reqGetId(t));
708 /* FIXME: cleanup struct names & resp[] addressing */
710 * In: IPC_NET_PLMN_LIST
711 * Send back available PLMN list
714 void ipc_net_plmn_list(struct ipc_message_info *info)
716 struct ipc_net_plmn_entries *entries_info = (struct ipc_net_plmn_entries *) info->data;
717 struct ipc_net_plmn_entry *entries = (struct ipc_net_plmn_entry *)
718 (info->data + sizeof(struct ipc_net_plmn_entries));
721 int size = (4 * entries_info->num * sizeof(char*));
724 char **resp = malloc(size);
725 char **resp_ptr = resp;
727 LOGD("Listed %d PLMNs\n", entries_info->num);
729 for(i = 0; i < entries_info->num; i++) {
730 /* Assumed type for 'emergency only' PLMNs */
731 if(entries[i].type == 0x01)
734 ril_plmn_string(entries[i].plmn, resp_ptr);
737 switch(entries[i].status) {
738 case IPC_NET_PLMN_STATUS_AVAILABLE:
739 asprintf(&resp_ptr[3], "available");
741 case IPC_NET_PLMN_STATUS_CURRENT:
742 asprintf(&resp_ptr[3], "current");
744 case IPC_NET_PLMN_STATUS_FORBIDDEN:
745 asprintf(&resp_ptr[3], "forbidden");
748 asprintf(&resp_ptr[3], "unknown");
756 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, resp, (4 * sizeof(char*) * actual_size));
758 /* FIXME: free individual strings */
762 void ril_request_get_preferred_network_type(RIL_Token t)
764 ipc_fmt_send_get(IPC_NET_MODE_SEL, reqGetId(t));
767 void ril_request_set_preferred_network_type(RIL_Token t, void *data, size_t datalen)
769 int ril_mode = *(int*)data;
770 struct ipc_net_mode_sel mode_sel;
772 mode_sel.mode_sel = ril2ipc_mode_sel(ril_mode);
774 ipc_gen_phone_res_expect_to_complete(reqGetId(t), IPC_NET_MODE_SEL);
776 ipc_fmt_send(IPC_NET_MODE_SEL, IPC_TYPE_SET, &mode_sel, sizeof(mode_sel), reqGetId(t));
779 void ipc_net_mode_sel(struct ipc_message_info *info)
781 struct ipc_net_mode_sel *mode_sel = (struct ipc_net_mode_sel *) info->data;
782 int ril_mode = ipc2ril_mode_sel(mode_sel->mode_sel);
784 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &ril_mode, sizeof(int));
788 void ril_request_query_network_selection_mode(RIL_Token t)
790 ipc_fmt_send_get(IPC_NET_PLMN_SEL, reqGetId(t));
793 void ipc_net_plmn_sel(struct ipc_message_info *info)
795 struct ipc_net_plmn_sel_get *plmn_sel = (struct ipc_net_plmn_sel_get *) info->data;
796 int ril_mode = ipc2ril_plmn_sel(plmn_sel->plmn_sel);
798 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &ril_mode, sizeof(int));
801 void ipc_net_plmn_sel_complete(struct ipc_message_info *info)
803 struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
806 rc = ipc_gen_phone_res_check(phone_res);
808 if((phone_res->code & 0x00ff) == 0x6f) {
809 LOGE("Not authorized to register to this network!");
810 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_ILLEGAL_SIM_OR_ME, NULL, 0);
812 LOGE("There was an error during operator selection!");
813 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
818 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, NULL, 0);
821 void ril_request_set_network_selection_automatic(RIL_Token t)
823 struct ipc_net_plmn_sel_set plmn_sel;
825 ipc_net_plmn_sel_setup(&plmn_sel, IPC_NET_PLMN_SEL_AUTO, NULL, IPC_NET_ACCESS_TECHNOLOGY_UNKNOWN);
827 ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_NET_PLMN_SEL, ipc_net_plmn_sel_complete);
829 ipc_fmt_send(IPC_NET_PLMN_SEL, IPC_TYPE_SET, &plmn_sel, sizeof(plmn_sel), reqGetId(t));
832 void ril_request_set_network_selection_manual(RIL_Token t, void *data, size_t datalen)
834 struct ipc_net_plmn_sel_set plmn_sel;
836 // FIXME: We always assume UMTS capability
837 ipc_net_plmn_sel_setup(&plmn_sel, IPC_NET_PLMN_SEL_MANUAL, data, IPC_NET_ACCESS_TECHNOLOGY_UMTS);
839 ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_NET_PLMN_SEL, ipc_net_plmn_sel_complete);
841 ipc_fmt_send(IPC_NET_PLMN_SEL, IPC_TYPE_SET, &plmn_sel, sizeof(plmn_sel), reqGetId(t));