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>
31 * Format conversion utils
35 * Converts IPC network registration status to Android RIL format
37 unsigned char ipc2ril_reg_state(unsigned char reg_state)
40 case IPC_NET_REGISTRATION_STATE_NONE:
42 case IPC_NET_REGISTRATION_STATE_HOME:
44 case IPC_NET_REGISTRATION_STATE_SEARCHING:
46 case IPC_NET_REGISTRATION_STATE_EMERGENCY:
48 case IPC_NET_REGISTRATION_STATE_ROAMING:
50 case IPC_NET_REGISTRATION_STATE_UNKNOWN:
53 LOGE("%s: invalid reg_state: %d", __FUNCTION__, reg_state);
59 * Converts IPC network access technology to Android RIL format
61 unsigned char ipc2ril_act(unsigned char act)
64 case IPC_NET_ACCESS_TECHNOLOGY_GPRS:
66 case IPC_NET_ACCESS_TECHNOLOGY_EDGE:
68 case IPC_NET_ACCESS_TECHNOLOGY_UMTS:
70 case IPC_NET_ACCESS_TECHNOLOGY_GSM:
71 case IPC_NET_ACCESS_TECHNOLOGY_GSM2:
78 * Converts IPC GPRS network access technology to Android RIL format
80 unsigned char ipc2ril_gprs_act(unsigned char act)
83 case IPC_NET_ACCESS_TECHNOLOGY_GPRS:
85 case IPC_NET_ACCESS_TECHNOLOGY_EDGE:
87 case IPC_NET_ACCESS_TECHNOLOGY_UMTS:
89 case IPC_NET_ACCESS_TECHNOLOGY_GSM:
90 case IPC_NET_ACCESS_TECHNOLOGY_GSM2:
97 * Converts IPC preferred network type to Android RIL format
99 int ipc2ril_mode_sel(unsigned char mode)
103 return 7; // auto mode
104 case IPC_NET_MODE_SEL_GSM_UMTS:
106 case IPC_NET_MODE_SEL_GSM_ONLY:
108 case IPC_NET_MODE_SEL_UMTS_ONLY:
116 * Converts Android RIL preferred network type to IPC format
118 unsigned char ril2ipc_mode_sel(int mode)
122 return IPC_NET_MODE_SEL_GSM_ONLY;
123 case 2: // WCDMA only
124 return IPC_NET_MODE_SEL_UMTS_ONLY;
126 default: // GSM/WCDMA + the rest
127 return IPC_NET_MODE_SEL_GSM_UMTS;
132 * Converts IPC preferred PLMN selection type to Android RIL format
134 int ipc2ril_plmn_sel(unsigned char mode)
137 case IPC_NET_PLMN_SEL_MANUAL:
139 case IPC_NET_PLMN_SEL_AUTO:
147 * Converts Android RIL preferred PLMN selection type to IPC format
149 unsigned char ril2ipc_plmn_sel(int mode)
153 return IPC_NET_PLMN_SEL_AUTO;
155 return IPC_NET_PLMN_SEL_MANUAL;
162 * Converts IPC reg state to Android format
164 void ipc2ril_reg_state_resp(struct ipc_net_regist *netinfo, char *response[15])
166 unsigned char reg_state = ipc2ril_reg_state(netinfo->reg_state);
167 unsigned char act = ipc2ril_act(netinfo->act);
169 memset(response, 0, sizeof(response));
171 asprintf(&response[0], "%d", reg_state);
172 asprintf(&response[1], "%x", netinfo->lac);
173 asprintf(&response[2], "%x", netinfo->cid);
174 asprintf(&response[3], "%d", act);
178 * Converts IPC GPRS reg state to Android format
180 void ipc2ril_gprs_reg_state_resp(struct ipc_net_regist *netinfo, char *response[4])
182 unsigned char reg_state = ipc2ril_reg_state(netinfo->reg_state);
183 unsigned char act = ipc2ril_gprs_act(netinfo->act);
185 memset(response, 0, sizeof(response));
187 asprintf(&response[0], "%d", reg_state);
188 asprintf(&response[1], "%x", netinfo->lac);
189 asprintf(&response[2], "%x", netinfo->cid);
190 asprintf(&response[3], "%d", act);
194 * Set all the tokens to data waiting.
195 * For instance when only operator is updated by modem NOTI, we don't need
196 * to ask the modem new NET Regist and GPRS Net Regist states so act like we got
197 * these from modem NOTI too so we don't have to make the requests
199 void ril_tokens_net_set_data_waiting(void)
201 ril_state.tokens.registration_state = RIL_TOKEN_DATA_WAITING;
202 ril_state.tokens.gprs_registration_state = RIL_TOKEN_DATA_WAITING;
203 ril_state.tokens.operator = RIL_TOKEN_DATA_WAITING;
207 * Returns 1 if unsol data is waiting, 0 if not
209 int ril_tokens_net_get_data_waiting(void)
211 return ril_state.tokens.registration_state == RIL_TOKEN_DATA_WAITING || ril_state.tokens.gprs_registration_state == RIL_TOKEN_DATA_WAITING || ril_state.tokens.operator == RIL_TOKEN_DATA_WAITING;
215 * Print net tokens values
217 void ril_tokens_net_state_dump(void)
219 LOGD("ril_tokens_net_state_dump:\n\
220 \tril_state.tokens.registration_state = 0x%p\n\
221 \tril_state.tokens.gprs_registration_state = 0x%p\n\
222 \tril_state.tokens.operator = 0x%p\n", ril_state.tokens.registration_state, ril_state.tokens.gprs_registration_state, ril_state.tokens.operator);
225 void ril_plmn_split(char *plmn_data, char **plmn, unsigned int *mcc, unsigned int *mnc)
230 memset(plmn_t, 0, sizeof(plmn_t));
231 memcpy(plmn_t, plmn_data, 6);
237 *plmn = malloc(sizeof(plmn_t));
238 memcpy(*plmn, plmn_t, sizeof(plmn_t));
241 if(mcc == NULL || mnc == NULL)
244 sscanf(plmn_t, "%3u%2u", mcc, mnc);
247 void ril_plmn_string(char *plmn_data, char *response[3])
249 unsigned int mcc, mnc;
255 ril_plmn_split(plmn_data, &plmn, &mcc, &mnc);
257 asprintf(&response[2], "%s", plmn);
260 plmn_entries = sizeof(plmn_list) / sizeof(struct plmn_list_entry);
262 LOGD("Found %d plmn records", plmn_entries);
264 for(i=0 ; i < plmn_entries ; i++) {
265 if(plmn_list[i].mcc == mcc && plmn_list[i].mnc == mnc) {
266 asprintf(&response[0], "%s", plmn_list[i].operator_short);
267 asprintf(&response[1], "%s", plmn_list[i].operator_long);
277 * How to handle NET unsol data from modem:
278 * 1- Rx UNSOL (NOTI) data from modem
279 * 2- copy data in a sized variable stored in radio
280 * 3- make sure no SOL request is going on for this token
281 * 4- copy data to radio structure
282 * 5- if no UNSOL data is already waiting for a token, tell RILJ NETWORK_STATE_CHANGED
283 * 6- set all the net tokens to RIL_TOKEN_DATA_WAITING
284 * 7- RILJ will ask for OPERATOR, GPRS_REG_STATE and REG_STATE
286 * 8- if token is RIL_TOKEN_DATA_WAITING it's SOL request for modem UNSOL data
287 * 9- send back modem data and tell E_SUCCESS to RILJ request
288 * 10- set token to 0x00
290 * How to handle NET sol requests from RILJ:
291 * 1- if token is 0x00 it's UNSOL RILJ request for modem data
292 * 2- put RIL_Token in token
293 * 3- request data to the modem
294 * 4- Rx SOL (RESP) data from modem
295 * 5- copy data to radio structure
296 * 6- send back data to RILJ with token from modem message
297 * 7- if token != RIL_TOKEN_DATA_WAITING, reset token to 0x00
299 * What if both are appening at the same time?
300 * 1- RILJ requests modem data (UNSOL)
301 * 2- token is 0x00 so send request to modem
302 * 3- UNSOL data arrives from modem
303 * 4- set all tokens to RIL_TOKEN_DATA_WAITING
304 * 5- store data, tell RILJ NETWORK_STATE_CHANGED
305 * 6- Rx requested data from modem
306 * 7- copy data to radio structure
307 * 8- token mismatch (is now RIL_TOKEN_DATA_WAITING)
308 * 9- send back data to RIL with token from IPC message
309 * 10- don't reset token to 0x00
310 * 11- RILJ does SOL request for modem data (we know it's SOL because we didn't reset token)
311 * 12- send back last data we have (from UNSOL RILJ request here)
315 * In: RIL_REQUEST_OPERATOR
316 * Request Operator name
318 * Out: IPC_NET_CURRENT_PLMN
319 * return modem UNSOL data if available
320 * request IPC_NET_CURRENT_PLMN if no data is there
321 * return RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW if not registered
323 void ril_request_operator(RIL_Token t)
328 // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
329 if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
330 ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING ||
331 ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN ||
332 ril_state.netinfo.reg_state > IPC_NET_REGISTRATION_STATE_ROAMING) {
333 RIL_onRequestComplete(t, RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW, NULL, 0);
335 ril_state.tokens.operator = (RIL_Token) 0x00;
339 if(ril_state.tokens.operator == RIL_TOKEN_DATA_WAITING) {
340 LOGD("Got RILJ request for UNSOL data");
342 /* Send back the data we got UNSOL */
343 ril_plmn_string(ril_state.plmndata.plmn, response);
345 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
347 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
348 if(response[i] != NULL)
352 ril_state.tokens.operator = (RIL_Token) 0x00;
353 } else if(ril_state.tokens.operator == (RIL_Token) 0x00) {
354 LOGD("Got RILJ request for SOL data");
355 /* Request data to the modem */
356 ril_state.tokens.operator = t;
358 ipc_fmt_send_get(IPC_NET_CURRENT_PLMN, reqGetId(t));
360 LOGE("Another request is going on, returning UNSOL data");
362 /* Send back the data we got UNSOL */
363 ril_plmn_string(ril_state.plmndata.plmn, response);
365 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
367 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
368 if(response[i] != NULL)
373 ril_tokens_net_state_dump();
377 * In: IPC_NET_CURRENT_PLMN
378 * This can be SOL (RESP) or UNSOL (NOTI) message from modem
380 * Out: RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED
381 * enqueue modem data if UNSOL modem message and then call
382 * RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED
383 * if SOL message, send back data to RILJ
385 void ipc_net_current_plmn(struct ipc_message_info *message)
387 RIL_Token t = reqGetToken(message->aseq);
388 struct ipc_net_current_plmn *plmndata = (struct ipc_net_current_plmn *) message->data;
393 switch(message->type) {
395 LOGD("Got UNSOL Operator message");
397 // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
398 if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
399 ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING ||
400 ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN ||
401 ril_state.netinfo.reg_state > IPC_NET_REGISTRATION_STATE_ROAMING) {
402 /* Better keeping it up to date */
403 memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn));
407 if(ril_state.tokens.operator != (RIL_Token) 0x00 && ril_state.tokens.operator != RIL_TOKEN_DATA_WAITING) {
408 LOGE("Another Operator Req is in progress, skipping");
412 memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn));
414 /* we already told RILJ to get the new data but it wasn't done yet */
415 if(ril_tokens_net_get_data_waiting() && ril_state.tokens.operator == RIL_TOKEN_DATA_WAITING) {
416 LOGD("Updating Operator data in background");
418 ril_tokens_net_set_data_waiting();
419 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0);
424 LOGD("Got SOL Operator message");
426 // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
427 if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
428 ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING ||
429 ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN ||
430 ril_state.netinfo.reg_state > IPC_NET_REGISTRATION_STATE_ROAMING) {
431 /* Better keeping it up to date */
432 memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn));
434 RIL_onRequestComplete(t, RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW, NULL, 0);
436 if(ril_state.tokens.operator != RIL_TOKEN_DATA_WAITING)
437 ril_state.tokens.operator = (RIL_Token) 0x00;
440 if(ril_state.tokens.operator != t)
441 LOGE("Operator tokens mismatch");
443 /* Better keeping it up to date */
444 memcpy(&(ril_state.plmndata), plmndata, sizeof(struct ipc_net_current_plmn));
446 ril_plmn_string(plmndata->plmn, response);
448 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
450 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
451 if(response[i] != NULL)
455 if(ril_state.tokens.operator != RIL_TOKEN_DATA_WAITING)
456 ril_state.tokens.operator = (RIL_Token) 0x00;
460 LOGE("%s: unhandled ipc method: %d", __FUNCTION__, message->type);
464 ril_tokens_net_state_dump();
468 * In: RIL_REQUEST_REGISTRATION_STATE
471 * Out: IPC_NET_REGIST
472 * return modem UNSOL data if available
473 * request IPC_NET_REGIST if no data is there
475 void ril_request_registration_state(RIL_Token t)
477 struct ipc_net_regist_get regist_req;
481 if(ril_state.tokens.registration_state == RIL_TOKEN_DATA_WAITING) {
482 LOGD("Got RILJ request for UNSOL data");
484 /* Send back the data we got UNSOL */
485 ipc2ril_reg_state_resp(&(ril_state.netinfo), response);
487 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
489 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
490 if(response[i] != NULL)
494 ril_state.tokens.registration_state = (RIL_Token) 0x00;
495 } else if(ril_state.tokens.registration_state == (RIL_Token) 0x00) {
496 LOGD("Got RILJ request for SOL data");
497 /* Request data to the modem */
498 ril_state.tokens.registration_state = t;
500 ipc_net_regist_setup(®ist_req, IPC_NET_SERVICE_DOMAIN_GSM);
501 ipc_fmt_send(IPC_NET_REGIST, IPC_TYPE_GET, (void *)®ist_req, sizeof(struct ipc_net_regist_get), reqGetId(t));
503 LOGE("Another request is going on, returning UNSOL data");
505 /* Send back the data we got UNSOL */
506 ipc2ril_reg_state_resp(&(ril_state.netinfo), response);
508 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
510 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
511 if(response[i] != NULL)
516 ril_tokens_net_state_dump();
520 * In: RIL_REQUEST_GPRS_REGISTRATION_STATE
521 * Request GPRS reg state
523 * Out: IPC_NET_REGIST
524 * return modem UNSOL data if available
525 * request IPC_NET_REGIST if no data is there
527 void ril_request_gprs_registration_state(RIL_Token t)
529 struct ipc_net_regist_get regist_req;
533 if(ril_state.tokens.gprs_registration_state == RIL_TOKEN_DATA_WAITING) {
534 LOGD("Got RILJ request for UNSOL data");
536 /* Send back the data we got UNSOL */
537 ipc2ril_gprs_reg_state_resp(&(ril_state.gprs_netinfo), response);
539 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
541 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
542 if(response[i] != NULL)
546 ril_state.tokens.gprs_registration_state = (RIL_Token) 0x00;
547 } else if(ril_state.tokens.gprs_registration_state == (RIL_Token) 0x00) {
548 LOGD("Got RILJ request for SOL data");
550 /* Request data to the modem */
551 ril_state.tokens.gprs_registration_state = t;
553 ipc_net_regist_setup(®ist_req, IPC_NET_SERVICE_DOMAIN_GPRS);
554 ipc_fmt_send(IPC_NET_REGIST, IPC_TYPE_GET, (void *)®ist_req, sizeof(struct ipc_net_regist_get), reqGetId(t));
556 LOGE("Another request is going on, returning UNSOL data");
558 /* Send back the data we got UNSOL */
559 ipc2ril_gprs_reg_state_resp(&(ril_state.gprs_netinfo), response);
561 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
563 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
564 if(response[i] != NULL)
569 ril_tokens_net_state_dump();
572 void ipc_net_regist_unsol(struct ipc_message_info *message)
574 struct ipc_net_regist *netinfo;
575 netinfo = (struct ipc_net_regist *) message->data;
577 LOGD("Got UNSOL NetRegist message");
579 switch(netinfo->domain) {
580 case IPC_NET_SERVICE_DOMAIN_GSM:
581 if(ril_state.tokens.registration_state != (RIL_Token) 0 && ril_state.tokens.registration_state != RIL_TOKEN_DATA_WAITING) {
582 LOGE("Another NetRegist Req is in progress, skipping");
586 memcpy(&(ril_state.netinfo), netinfo, sizeof(struct ipc_net_regist));
588 /* we already told RILJ to get the new data but it wasn't done yet */
589 if(ril_tokens_net_get_data_waiting() && ril_state.tokens.registration_state == RIL_TOKEN_DATA_WAITING) {
590 LOGD("Updating NetRegist data in background");
592 ril_tokens_net_set_data_waiting();
593 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0);
597 case IPC_NET_SERVICE_DOMAIN_GPRS:
598 if(ril_state.tokens.gprs_registration_state != (RIL_Token) 0 && ril_state.tokens.gprs_registration_state != RIL_TOKEN_DATA_WAITING) {
599 LOGE("Another GPRS NetRegist Req is in progress, skipping");
603 memcpy(&(ril_state.gprs_netinfo), netinfo, sizeof(struct ipc_net_regist));
605 /* we already told RILJ to get the new data but it wasn't done yet */
606 if(ril_tokens_net_get_data_waiting() && ril_state.tokens.gprs_registration_state == RIL_TOKEN_DATA_WAITING) {
607 LOGD("Updating GPRSNetRegist data in background");
609 ril_tokens_net_set_data_waiting();
610 RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0);
614 LOGE("%s: unhandled service domain: %d", __FUNCTION__, netinfo->domain);
618 ril_tokens_net_state_dump();
621 void ipc_net_regist_sol(struct ipc_message_info *message)
626 struct ipc_net_regist *netinfo = (struct ipc_net_regist *) message->data;
627 RIL_Token t = reqGetToken(message->aseq);
629 LOGD("Got SOL NetRegist message");
631 switch(netinfo->domain) {
632 case IPC_NET_SERVICE_DOMAIN_GSM:
633 if(ril_state.tokens.registration_state != t)
634 LOGE("Registration state tokens mismatch");
636 /* Better keeping it up to date */
637 memcpy(&(ril_state.netinfo), netinfo, sizeof(struct ipc_net_regist));
639 ipc2ril_reg_state_resp(netinfo, response);
641 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
643 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
644 if(response[i] != NULL)
648 if(ril_state.tokens.registration_state != RIL_TOKEN_DATA_WAITING)
649 ril_state.tokens.registration_state = (RIL_Token) 0x00;
651 case IPC_NET_SERVICE_DOMAIN_GPRS:
652 if(ril_state.tokens.gprs_registration_state != t)
653 LOGE("GPRS registration state tokens mismatch");
655 /* Better keeping it up to date */
656 memcpy(&(ril_state.gprs_netinfo), netinfo, sizeof(struct ipc_net_regist));
658 ipc2ril_gprs_reg_state_resp(netinfo, response);
660 RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
662 for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
663 if(response[i] != NULL)
666 if(ril_state.tokens.registration_state != RIL_TOKEN_DATA_WAITING)
667 ril_state.tokens.gprs_registration_state = (RIL_Token) 0x00;
670 LOGE("%s: unhandled service domain: %d", __FUNCTION__, netinfo->domain);
674 ril_tokens_net_state_dump();
679 * This can be SOL (RESP) or UNSOL (NOTI) message from modem
681 void ipc_net_regist(struct ipc_message_info *message)
683 /* Don't consider this if modem isn't in normal power mode. */
684 if(ril_state.power_mode < POWER_MODE_NORMAL)
687 switch(message->type) {
689 ipc_net_regist_unsol(message);
692 ipc_net_regist_sol(message);
695 LOGE("%s: unhandled ipc method: %d", __FUNCTION__, message->type);
702 * In: RIL_REQUEST_QUERY_AVAILABLE_NETWORKS
704 * Out: IPC_NET_PLMN_LIST
706 void ril_request_query_available_networks(RIL_Token t)
708 ipc_fmt_send_get(IPC_NET_PLMN_LIST, reqGetId(t));
711 /* FIXME: cleanup struct names & resp[] addressing */
713 * In: IPC_NET_PLMN_LIST
714 * Send back available PLMN list
717 void ipc_net_plmn_list(struct ipc_message_info *info)
719 struct ipc_net_plmn_entries *entries_info = (struct ipc_net_plmn_entries *) info->data;
720 struct ipc_net_plmn_entry *entries = (struct ipc_net_plmn_entry *)
721 (info->data + sizeof(struct ipc_net_plmn_entries));
724 int size = (4 * entries_info->num * sizeof(char*));
727 char **resp = malloc(size);
728 char **resp_ptr = resp;
730 LOGD("Listed %d PLMNs\n", entries_info->num);
732 for(i = 0; i < entries_info->num; i++) {
733 /* Assumed type for 'emergency only' PLMNs */
734 if(entries[i].type == 0x01)
737 ril_plmn_string(entries[i].plmn, resp_ptr);
740 switch(entries[i].status) {
741 case IPC_NET_PLMN_STATUS_AVAILABLE:
742 asprintf(&resp_ptr[3], "available");
744 case IPC_NET_PLMN_STATUS_CURRENT:
745 asprintf(&resp_ptr[3], "current");
747 case IPC_NET_PLMN_STATUS_FORBIDDEN:
748 asprintf(&resp_ptr[3], "forbidden");
751 asprintf(&resp_ptr[3], "unknown");
759 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, resp, (4 * sizeof(char*) * actual_size));
761 /* FIXME: free individual strings */
765 void ril_request_get_preferred_network_type(RIL_Token t)
767 ipc_fmt_send_get(IPC_NET_MODE_SEL, reqGetId(t));
770 void ril_request_set_preferred_network_type(RIL_Token t, void *data, size_t datalen)
772 int ril_mode = *(int*)data;
773 struct ipc_net_mode_sel mode_sel;
775 mode_sel.mode_sel = ril2ipc_mode_sel(ril_mode);
777 ipc_gen_phone_res_expect_to_complete(reqGetId(t), IPC_NET_MODE_SEL);
779 ipc_fmt_send(IPC_NET_MODE_SEL, IPC_TYPE_SET, &mode_sel, sizeof(mode_sel), reqGetId(t));
782 void ipc_net_mode_sel(struct ipc_message_info *info)
784 struct ipc_net_mode_sel *mode_sel = (struct ipc_net_mode_sel *) info->data;
785 int ril_mode = ipc2ril_mode_sel(mode_sel->mode_sel);
787 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &ril_mode, sizeof(int));
791 void ril_request_query_network_selection_mode(RIL_Token t)
793 ipc_fmt_send_get(IPC_NET_PLMN_SEL, reqGetId(t));
796 void ipc_net_plmn_sel(struct ipc_message_info *info)
798 struct ipc_net_plmn_sel_get *plmn_sel = (struct ipc_net_plmn_sel_get *) info->data;
799 int ril_mode = ipc2ril_plmn_sel(plmn_sel->plmn_sel);
801 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &ril_mode, sizeof(int));
804 void ipc_net_plmn_sel_complete(struct ipc_message_info *info)
806 struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
809 rc = ipc_gen_phone_res_check(phone_res);
811 if((phone_res->code & 0x00ff) == 0x6f) {
812 LOGE("Not authorized to register to this network!");
813 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_ILLEGAL_SIM_OR_ME, NULL, 0);
815 LOGE("There was an error during operator selection!");
816 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
821 RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, NULL, 0);
824 void ril_request_set_network_selection_automatic(RIL_Token t)
826 struct ipc_net_plmn_sel_set plmn_sel;
828 ipc_net_plmn_sel_setup(&plmn_sel, IPC_NET_PLMN_SEL_AUTO, NULL, IPC_NET_ACCESS_TECHNOLOGY_UNKNOWN);
830 ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_NET_PLMN_SEL, ipc_net_plmn_sel_complete);
832 ipc_fmt_send(IPC_NET_PLMN_SEL, IPC_TYPE_SET, &plmn_sel, sizeof(plmn_sel), reqGetId(t));
835 void ril_request_set_network_selection_manual(RIL_Token t, void *data, size_t datalen)
837 struct ipc_net_plmn_sel_set plmn_sel;
839 // FIXME: We always assume UMTS capability
840 ipc_net_plmn_sel_setup(&plmn_sel, IPC_NET_PLMN_SEL_MANUAL, data, IPC_NET_ACCESS_TECHNOLOGY_UMTS);
842 ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_NET_PLMN_SEL, ipc_net_plmn_sel_complete);
844 ipc_fmt_send(IPC_NET_PLMN_SEL, IPC_TYPE_SET, &plmn_sel, sizeof(plmn_sel), reqGetId(t));