summaryrefslogtreecommitdiffstats
path: root/net.c
diff options
context:
space:
mode:
authorPaulK <contact@paulk.fr>2012-02-22 00:04:00 +0100
committerPaulK <contact@paulk.fr>2012-02-22 00:04:00 +0100
commit7e7138f9107eb4c3412f7d75002d86249d4456ae (patch)
tree8f0e19caf1450f94c31923d682da2111f240fd16 /net.c
parent0c854ce2959463e094229bc874c1b4cde0e6ff46 (diff)
downloadhardware_ril_samsung-ril-7e7138f9107eb4c3412f7d75002d86249d4456ae.zip
hardware_ril_samsung-ril-7e7138f9107eb4c3412f7d75002d86249d4456ae.tar.gz
hardware_ril_samsung-ril-7e7138f9107eb4c3412f7d75002d86249d4456ae.tar.bz2
Cleaned code for network type selection and added stable PLMN selection
Diffstat (limited to 'net.c')
-rw-r--r--net.c164
1 files changed, 130 insertions, 34 deletions
diff --git a/net.c b/net.c
index fd1a33b..d590522 100644
--- a/net.c
+++ b/net.c
@@ -98,16 +98,16 @@ unsigned char ipc2ril_gprs_act(unsigned char act)
/**
* Converts IPC preferred network type to Android RIL format
*/
-unsigned char ipc2ril_modesel(unsigned char mode)
+int ipc2ril_mode_sel(unsigned char mode)
{
switch(mode) {
case 0:
return 7; // auto mode
- case IPC_NET_MODE_GSM_UMTS:
+ case IPC_NET_MODE_SEL_GSM_UMTS:
return 0;
- case IPC_NET_MODE_GSM_ONLY:
+ case IPC_NET_MODE_SEL_GSM_ONLY:
return 1;
- case IPC_NET_MODE_UMTS_ONLY:
+ case IPC_NET_MODE_SEL_UMTS_ONLY:
return 2;
default:
return 255;
@@ -117,16 +117,46 @@ unsigned char ipc2ril_modesel(unsigned char mode)
/**
* Converts Android RIL preferred network type to IPC format
*/
-unsigned char ril2ipc_modesel(unsigned char mode)
+unsigned char ril2ipc_mode_sel(int mode)
{
switch(mode) {
case 1: // GSM only
- return IPC_NET_MODE_GSM_ONLY;
+ return IPC_NET_MODE_SEL_GSM_ONLY;
case 2: // WCDMA only
- return IPC_NET_MODE_UMTS_ONLY;
+ return IPC_NET_MODE_SEL_UMTS_ONLY;
case 0:
default: // GSM/WCDMA + the rest
- return IPC_NET_MODE_GSM_UMTS;
+ return IPC_NET_MODE_SEL_GSM_UMTS;
+ }
+}
+
+/**
+ * Converts IPC preferred PLMN selection type to Android RIL format
+ */
+int ipc2ril_plmn_sel(unsigned char mode)
+{
+ switch(mode) {
+ case IPC_NET_PLMN_SEL_MANUAL:
+ return 1;
+ case IPC_NET_PLMN_SEL_AUTO:
+ return 0;
+ default:
+ return 255;
+ }
+}
+
+/**
+ * Converts Android RIL preferred PLMN selection type to IPC format
+ */
+unsigned char ril2ipc_plmn_sel(int mode)
+{
+ switch(mode) {
+ case 0:
+ return IPC_NET_PLMN_SEL_AUTO;
+ case 1:
+ return IPC_NET_PLMN_SEL_MANUAL;
+ default:
+ return 255;
}
}
@@ -191,24 +221,40 @@ void ril_tokens_net_state_dump(void)
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);
}
+void ril_plmn_split(char *plmn_data, char **plmn, unsigned int *mcc, unsigned int *mnc)
+{
+ char plmn_t[7];
+ int i;
+
+ memset(plmn_t, 0, sizeof(plmn_t));
+ memcpy(plmn_t, plmn_data, 6);
+
+ if(plmn_t[5] == '#')
+ plmn_t[5] = '\0';
+
+ if(plmn != NULL) {
+ *plmn = malloc(sizeof(plmn_t));
+ memcpy(*plmn, plmn_t, sizeof(plmn_t));
+ }
+
+ if(mcc == NULL || mnc == NULL)
+ return;
+
+ sscanf(plmn_t, "%3u%2u", mcc, mnc);
+}
void ril_plmn_string(char *plmn_data, char *response[3])
{
unsigned int mcc, mnc;
- char plmn[7];
+ char *plmn;
int plmn_entries;
int i;
- memset(plmn, 0, sizeof(plmn));
- memcpy(plmn, plmn_data, 6);
-
- if(plmn[5] == '#')
- plmn[5] = '\0';
+ ril_plmn_split(plmn_data, &plmn, &mcc, &mnc);
asprintf(&response[2], "%s", plmn);
-
- sscanf(plmn, "%3u%2u", &mcc, &mnc);
+ free(plmn);
plmn_entries = sizeof(plmn_list) / sizeof(struct plmn_list_entry);
@@ -218,9 +264,9 @@ void ril_plmn_string(char *plmn_data, char *response[3])
if(plmn_list[i].mcc == mcc && plmn_list[i].mnc == mnc) {
asprintf(&response[0], "%s", plmn_list[i].operator_short);
asprintf(&response[1], "%s", plmn_list[i].operator_long);
- return;
+ return;
}
- }
+ }
response[0] = NULL;
response[1] = NULL;
@@ -235,7 +281,7 @@ void ril_plmn_string(char *plmn_data, char *response[3])
* 5- if no UNSOL data is already waiting for a token, tell RILJ NETWORK_STATE_CHANGED
* 6- set all the net tokens to RIL_TOKEN_NET_DATA_WAITING
* 7- RILJ will ask for OPERATOR, GPRS_REG_STATE and REG_STATE
- * for each request:
+ * for each request:
* 8- if token is RIL_TOKEN_NET_DATA_WAITING it's SOL request for modem UNSOL data
* 9- send back modem data and tell E_SUCCESS to RILJ request
* 10- set token to 0x00
@@ -248,7 +294,7 @@ void ril_plmn_string(char *plmn_data, char *response[3])
* 5- copy data to radio structure
* 6- send back data to RILJ with token from modem message
* 7- if token != RIL_TOKEN_NET_DATA_WAITING, reset token to 0x00
- *
+ *
* What if both are appening at the same time?
* 1- RILJ requests modem data (UNSOL)
* 2- token is 0x00 so send request to modem
@@ -278,7 +324,7 @@ void ril_request_operator(RIL_Token t)
char *response[3];
int i;
- // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
+ // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING ||
ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN ||
@@ -347,7 +393,7 @@ void ipc_net_current_plmn(struct ipc_message_info *message)
case IPC_TYPE_NOTI:
LOGD("Got UNSOL Operator message");
- // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
+ // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING ||
ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN ||
@@ -374,7 +420,7 @@ void ipc_net_current_plmn(struct ipc_message_info *message)
}
break;
case IPC_TYPE_RESP:
- // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
+ // IPC_NET_REGISTRATION_STATE_ROAMING is the biggest valid value
if(ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING ||
ril_state.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN ||
@@ -651,7 +697,7 @@ void ipc_net_regist(struct ipc_message_info *message)
/**
* In: RIL_REQUEST_QUERY_AVAILABLE_NETWORKS
- *
+ *
* Out: IPC_NET_PLMN_LIST
*/
void ril_request_query_available_networks(RIL_Token t)
@@ -713,11 +759,9 @@ void ipc_net_plmn_list(struct ipc_message_info *info)
free(resp);
}
-// FIXME: add corect implementation
-void ril_request_query_network_selection_mode(RIL_Token t)
+void ril_request_get_preferred_network_type(RIL_Token t)
{
- unsigned int mode = 0;
- RIL_onRequestComplete(t, RIL_E_SUCCESS, &mode, sizeof(mode));
+ ipc_fmt_send_get(IPC_NET_MODE_SEL, reqGetId(t));
}
void ril_request_set_preferred_network_type(RIL_Token t, void *data, size_t datalen)
@@ -725,22 +769,74 @@ void ril_request_set_preferred_network_type(RIL_Token t, void *data, size_t data
int ril_mode = *(int*)data;
struct ipc_net_mode_sel mode_sel;
- mode_sel->mode = ril2ipc_modesel(ril_mode);
+ mode_sel.mode_sel = ril2ipc_mode_sel(ril_mode);
ipc_gen_phone_res_expect_to_complete(reqGetId(t), IPC_NET_MODE_SEL);
ipc_fmt_send(IPC_NET_MODE_SEL, IPC_TYPE_SET, &mode_sel, sizeof(mode_sel), reqGetId(t));
}
-void ril_request_get_preferred_network_type(RIL_Token t)
+void ipc_net_mode_sel(struct ipc_message_info *info)
{
- ipc_fmt_send_get(IPC_NET_MODE_SEL, reqGetId(t));
+ struct ipc_net_mode_sel *mode_sel = (struct ipc_net_mode_sel *) info->data;
+ int ril_mode = ipc2ril_mode_sel(mode_sel->mode_sel);
+
+ RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &ril_mode, sizeof(int));
}
-void ipc_net_mode_sel(struct ipc_message_info *info)
+
+void ril_request_query_network_selection_mode(RIL_Token t)
{
- struct ipc_net_mode_sel *mode_sel = (struct ipc_net_mode_sel *) info->data;
- int ril_mode = ipc2ril_modesel(mode_sel->mode);
+ ipc_fmt_send_get(IPC_NET_PLMN_SEL, reqGetId(t));
+}
+
+void ipc_net_plmn_sel(struct ipc_message_info *info)
+{
+ struct ipc_net_plmn_sel_get *plmn_sel = (struct ipc_net_plmn_sel_get *) info->data;
+ int ril_mode = ipc2ril_plmn_sel(plmn_sel->plmn_sel);
RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, &ril_mode, sizeof(int));
}
+
+void ipc_net_plmn_sel_complete(struct ipc_message_info *info)
+{
+ struct ipc_gen_phone_res *phone_res = (struct ipc_gen_phone_res *) info->data;
+ int rc;
+
+ rc = ipc_gen_phone_res_check(phone_res);
+ if(rc < 0) {
+ if((phone_res->code & 0x00ff) == 0x6f) {
+ LOGE("Not authorized to register to this network!");
+ RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_ILLEGAL_SIM_OR_ME, NULL, 0);
+ } else {
+ LOGE("There was an error during operator selection!");
+ RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0);
+ }
+ return;
+ }
+
+ RIL_onRequestComplete(reqGetToken(info->aseq), RIL_E_SUCCESS, NULL, 0);
+}
+
+void ril_request_set_network_selection_automatic(RIL_Token t)
+{
+ struct ipc_net_plmn_sel_set plmn_sel;
+
+ ipc_net_plmn_sel_setup(&plmn_sel, IPC_NET_PLMN_SEL_AUTO, NULL, IPC_NET_ACCESS_TECHNOLOGY_UNKNOWN);
+
+ ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_NET_PLMN_SEL, ipc_net_plmn_sel_complete);
+
+ ipc_fmt_send(IPC_NET_PLMN_SEL, IPC_TYPE_SET, &plmn_sel, sizeof(plmn_sel), reqGetId(t));
+}
+
+void ril_request_set_network_selection_manual(RIL_Token t, void *data, size_t datalen)
+{
+ struct ipc_net_plmn_sel_set plmn_sel;
+
+ // FIXME: We always assume UMTS capability
+ ipc_net_plmn_sel_setup(&plmn_sel, IPC_NET_PLMN_SEL_MANUAL, data, IPC_NET_ACCESS_TECHNOLOGY_UMTS);
+
+ ipc_gen_phone_res_expect_to_func(reqGetId(t), IPC_NET_PLMN_SEL, ipc_net_plmn_sel_complete);
+
+ ipc_fmt_send(IPC_NET_PLMN_SEL, IPC_TYPE_SET, &plmn_sel, sizeof(plmn_sel), reqGetId(t));
+}