summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulK <contact@paulk.fr>2011-11-22 21:50:42 +0100
committerPaulK <contact@paulk.fr>2011-11-22 21:50:42 +0100
commit233f0f23c75971de36d77605572c9df6b344ca73 (patch)
tree06598ad50aa97a30041d05ab9c0e8d13c797ea51
parent791fd3e4a946c05d6598f5054075515df6327b7d (diff)
downloadhardware_ril_samsung-ril-233f0f23c75971de36d77605572c9df6b344ca73.zip
hardware_ril_samsung-ril-233f0f23c75971de36d77605572c9df6b344ca73.tar.gz
hardware_ril_samsung-ril-233f0f23c75971de36d77605572c9df6b344ca73.tar.bz2
Modified samsung-ril to work on Nexus S.
Currently, the following is working: * (automatic) network registration (clean and stable) * SMS (no clean queue engine and no support for multiple message SMS) * SIM I/O * Other minor stuff And the following is left to do: * DATA (3G) * airplane to normal power mode * calls (including audio routing) * RFS messages handling (mostly to be done at IPC level) * Other minor stuff
-rw-r--r--Android.mk11
-rw-r--r--disp.c76
-rw-r--r--misc.c82
-rw-r--r--net.c658
-rw-r--r--pwr.c98
-rw-r--r--samsung-ril.c374
-rw-r--r--samsung-ril.h51
-rw-r--r--sim.c20
-rw-r--r--sms.c211
-rw-r--r--util.c77
-rw-r--r--util.h6
11 files changed, 1235 insertions, 429 deletions
diff --git a/Android.mk b/Android.mk
index 1cee136..4e3c9a0 100644
--- a/Android.mk
+++ b/Android.mk
@@ -12,7 +12,8 @@ LOCAL_SRC_FILES := \
sim.c \
sms.c \
util.c \
-
+ pwr.c \
+ disp.c
LOCAL_SHARED_LIBRARIES := \
libcutils libutils libril
@@ -21,7 +22,15 @@ LOCAL_STATIC_LIBRARIES := libsamsung-ipc
# for asprinf
LOCAL_CFLAGS := -D_GNU_SOURCE
+ifeq ($(TARGET_DEVICE),crespo)
+ LOCAL_CFLAGS += -DDEVICE_CRESPO
+endif
+ifeq ($(TARGET_DEVICE),h1)
+ LOCAL_CFLAGS += -DDEVICE_H1
+endif
+
LOCAL_C_INCLUDES := external/libsamsung-ipc/include
+LOCAL_C_INCLUDES += hardware/ril/libsamsung-ipc/include
LOCAL_MODULE_TAGS := optional
diff --git a/disp.c b/disp.c
new file mode 100644
index 0000000..de533ca
--- /dev/null
+++ b/disp.c
@@ -0,0 +1,76 @@
+#define LOG_TAG "RIL-DISP"
+#include <utils/Log.h>
+
+#include "samsung-ril.h"
+#include "util.h"
+
+extern const struct RIL_Env *rilenv;
+extern struct radio_state radio;
+extern struct ipc_client *ipc_client;
+
+void respondIconSignalStrength(RIL_Token t, void *data, int length)
+{
+ struct ipc_disp_icon_info *signal_info = (struct ipc_disp_icon_info*)data;
+ RIL_SignalStrength ss;
+ int rssi;
+
+ /* Don't consider this if modem isn't in normal power mode. */
+ if(radio.power_mode < POWER_MODE_NORMAL)
+ return;
+
+ memset(&ss, 0, sizeof(ss));
+
+ /* Multiplying the number of bars by 3 yields
+ * an asu with an equal number of bars in Android
+ */
+ rssi = (3 * signal_info->rssi);
+
+ ss.GW_SignalStrength.signalStrength = rssi;
+ ss.GW_SignalStrength.bitErrorRate = 99;
+
+ /* Send CDMA and EVDO levels even in GSM mode */
+ ss.CDMA_SignalStrength.dbm = rssi;
+ ss.CDMA_SignalStrength.ecio = 200;
+
+ ss.EVDO_SignalStrength.dbm = rssi;
+ ss.EVDO_SignalStrength.ecio = 200;
+
+ LOGD("Signal Strength is %d\n", rssi);
+
+ RIL_onUnsolicitedResponse(RIL_UNSOL_SIGNAL_STRENGTH, &ss, sizeof(ss));
+}
+
+void respondSignalStrength(RIL_Token t, void *data, int length)
+{
+ struct ipc_disp_rssi_info *rssi_info = (struct ipc_disp_rssi_info*)data;
+ RIL_SignalStrength ss;
+ int rssi;
+
+ /* Don't consider this if modem isn't in normal power mode. */
+ if(radio.power_mode < POWER_MODE_NORMAL)
+ return;
+
+ memset(&ss, 0, sizeof(ss));
+
+ if(rssi_info->rssi > 0x6f) {
+ rssi = 0;
+ } else {
+ rssi = (((rssi_info->rssi - 0x71) * -1) - ((rssi_info->rssi - 0x71) * -1) % 2) / 2;
+ if(rssi > 31)
+ rssi = 31;
+ }
+
+ /* Send CDMA and EVDO levels even in GSM mode */
+ ss.GW_SignalStrength.signalStrength = rssi;
+ ss.GW_SignalStrength.bitErrorRate = 99;
+
+ ss.CDMA_SignalStrength.dbm = rssi;
+ ss.CDMA_SignalStrength.ecio = 200;
+
+ ss.EVDO_SignalStrength.dbm = rssi;
+ ss.EVDO_SignalStrength.ecio = 200;
+
+ LOGD("Signal Strength is %d\n", rssi);
+
+ RIL_onUnsolicitedResponse(RIL_UNSOL_SIGNAL_STRENGTH, &ss, sizeof(ss));
+}
diff --git a/misc.c b/misc.c
index 4f745eb..68862f2 100644
--- a/misc.c
+++ b/misc.c
@@ -7,12 +7,92 @@ extern const struct RIL_Env *rilenv;
extern struct radio_state radio;
extern struct ipc_client *ipc_client;
+void respondNitz(void *data, int length)
+{
+ struct ipc_misc_time_info *nitz = (struct ipc_misc_time_info*)data;
+ char str[128];
+
+ sprintf(str, "%02u/%02u/%02u,%02u:%02u:%02u+%02d,%02d",
+ nitz->year, nitz->mon, nitz->day, nitz->hour, nitz->min, nitz->sec, nitz->tz, 0);
+
+ RIL_onUnsolicitedResponse(RIL_UNSOL_NITZ_TIME_RECEIVED, str, strlen(str) + 1);
+}
+
+// TODO: implement RIL_REQUEST_DEVICE_IDENTITY also
+
+void respondIMEI(RIL_Token t, void *data, int length)
+{
+ struct ipc_misc_me_sn *imei_info;
+ char imei[33];
+ char imeisv[3];
+
+ imei_info = (struct ipc_misc_me_sn *) data;
+
+ if(radio.tokens.get_imei != 0 && radio.tokens.get_imei != t)
+ LOGE("IMEI tokens mismatch");
+
+ if(imei_info->length > 32)
+ return;
+
+ memset(imei, 0, sizeof(imei));
+ memset(imeisv, 0, sizeof(imeisv));
+
+ memcpy(imei, imei_info->data, imei_info->length);
+
+ /* Last two bytes of IMEI in imei_info are the SV bytes */
+ memcpy(imeisv, (imei_info->data + imei_info->length - 2), 2);
+
+ /* IMEI */
+ RIL_onRequestComplete(t, RIL_E_SUCCESS, imei, sizeof(char *));
+ radio.tokens.get_imei = 0;
+
+ /* IMEI SV */
+ if(radio.tokens.get_imeisv != 0) {
+ RIL_onRequestComplete(radio.tokens.get_imeisv, RIL_E_SUCCESS, imeisv, sizeof(char *));
+ radio.tokens.get_imeisv = 0;
+ }
+}
+
+void respondMeSn(RIL_Token t, void *data, int length)
+{
+ struct ipc_misc_me_sn *me_sn_info;
+
+ me_sn_info = (struct ipc_misc_me_sn *) data;
+
+ switch(me_sn_info->type) {
+ case IPC_MISC_ME_SN_SERIAL_NUM:
+ respondIMEI(t, data, length);
+ break;
+ case IPC_MISC_ME_SN_SERIAL_NUM_SERIAL:
+ LOGD("Got IPC_MISC_ME_SN_SERIAL_NUM_SERIAL: %s\n", me_sn_info->data);
+ break;
+ }
+}
+
+void requestIMEI(RIL_Token t)
+{
+ char data;
+
+ if(radio.radio_state != RADIO_STATE_OFF) {
+ data = IPC_MISC_ME_SN_SERIAL_NUM;
+
+ ipc_client_send(ipc_client, IPC_MISC_ME_SN, IPC_TYPE_GET, (unsigned char *) &data, sizeof(data), getRequestId(t));
+ } else {
+ radio.tokens.get_imei = t;
+ }
+}
+
+void requestIMEISV(RIL_Token t)
+{
+ radio.tokens.get_imeisv = t;
+}
+
void requestBasebandVersion(RIL_Token t)
{
if(radio.radio_state != RADIO_STATE_OFF) {
ipc_client_send_get(IPC_MISC_ME_VERSION, getRequestId(t));
} else {
- radio.token_baseband_ver = t;
+ radio.tokens.baseband_version = t;
}
}
diff --git a/net.c b/net.c
index 5f0e2c9..c1bb65d 100644
--- a/net.c
+++ b/net.c
@@ -4,62 +4,578 @@
#include "samsung-ril.h"
#include "util.h"
+#define RIL_TOKEN_NET_DATA_WAITING (RIL_Token) 0xff
+
extern const struct RIL_Env *rilenv;
extern struct radio_state radio;
extern struct ipc_client *ipc_client;
-void requestGPRSRegistrationState(RIL_Token t)
+/**
+ * NET Utility functions
+ */
+
+/**
+ * Converts IPC network registration status to Android RIL format
+ */
+unsigned char reg_state_ipc2ril(unsigned char reg_state)
{
- struct ipc_net_regist_get message;
+ switch(reg_state) {
+ case IPC_NET_REGISTRATION_STATE_NONE:
+ return 0;
+ case IPC_NET_REGISTRATION_STATE_HOME:
+ return 1;
+ case IPC_NET_REGISTRATION_STATE_SEARCHING:
+ return 2;
+ case IPC_NET_REGISTRATION_STATE_EMERGENCY:
+ return 10;
+ case IPC_NET_REGISTRATION_STATE_ROAMING:
+ return 5;
+ case IPC_NET_REGISTRATION_STATE_UNKNOWN:
+ return 4;
+ default:
+ LOGE("%s: invalid reg_state: %d", __FUNCTION__, reg_state);
+ return 255;
+ }
+}
- /* We only support one active GPRS registration state request */
- if(!radio.token_ps) {
- radio.token_ps = t;
+/**
+ * Converts IPC network access technology to Android RIL format
+ */
+unsigned char act_ipc2ril(unsigned char act)
+{
+ switch(act) {
+ case IPC_NET_ACCESS_TECHNOLOGY_GPRS:
+ return 1;
+ case IPC_NET_ACCESS_TECHNOLOGY_EDGE:
+ return 2;
+ case IPC_NET_ACCESS_TECHNOLOGY_UMTS:
+ return 3;
+ case IPC_NET_ACCESS_TECHNOLOGY_GSM:
+ case IPC_NET_ACCESS_TECHNOLOGY_GSM2:
+ default:
+ return 0;
+ }
+}
- ipc_net_regist_get(&message, IPC_NET_SERVICE_DOMAIN_GPRS);
- LOGD("ipc_net_regist [net = %d; domain = %d]", message.net, message.domain);
- ipc_client_send(ipc_client, IPC_NET_REGIST, IPC_TYPE_GET, (unsigned char*)&message, sizeof(message), getRequestId(t));
+/**
+ * Converts IPC GPRS network access technology to Android RIL format
+ */
+unsigned char gprs_act_ipc2ril(unsigned char act)
+{
+ switch(act) {
+ case IPC_NET_ACCESS_TECHNOLOGY_GPRS:
+ return 1;
+ case IPC_NET_ACCESS_TECHNOLOGY_EDGE:
+ return 2;
+ case IPC_NET_ACCESS_TECHNOLOGY_UMTS:
+ return 3;
+ case IPC_NET_ACCESS_TECHNOLOGY_GSM:
+ case IPC_NET_ACCESS_TECHNOLOGY_GSM2:
+ default:
+ return 0;
+ }
+}
+
+/**
+ * Converts IPC preferred network type to Android RIL format
+ */
+unsigned char modesel_ipc2ril(unsigned char mode)
+{
+ switch(mode) {
+ case 0:
+ return 7;
+ case 1:
+ case 3:
+ return 1;
+ case 2:
+ case 4:
+ return 2;
+ default:
+ return 255;
+ }
+}
+
+/**
+ * Converts Android RIL preferred network type to IPC format
+ */
+unsigned char modesel_ril2ipc(unsigned char mode)
+{
+ switch(mode) {
+ case 1:
+ return 2;
+ case 2:
+ return 3;
+ default:
+ return 1;
+ }
+}
+
+/**
+ * Converts IPC PLMC to Android format
+ */
+void plmn_ipc2ril(struct ipc_net_current_plmn *plmndata, char *response[3])
+{
+ char plmn[7];
+
+ memset(plmn, 0, sizeof(plmn));
+
+ memcpy(plmn, plmndata->plmn, 6);
+
+ if(plmn[5] == '#')
+ plmn[5] = '\0'; //FIXME: remove #?
+
+ asprintf(&response[0], "%s", plmn_lookup(plmn));
+ //asprintf(&response[1], "%s", "Voda NL");
+ response[1] = NULL;
+ asprintf(&response[2], "%s", plmn);
+}
+
+/**
+ * Converts IPC reg state to Android format
+ */
+void reg_state_resp_ipc2ril(struct ipc_net_regist *netinfo, char *response[15])
+{
+ memset(response, 0, sizeof(response));
+
+ asprintf(&response[0], "%d", reg_state_ipc2ril(netinfo->reg_state));
+ asprintf(&response[1], "%x", netinfo->lac);
+ asprintf(&response[2], "%x", netinfo->cid);
+ asprintf(&response[3], "%d", act_ipc2ril(netinfo->act));
+}
+
+/**
+ * Converts IPC GPRS reg state to Android format
+ */
+void gprs_reg_state_resp_ipc2ril(struct ipc_net_regist *netinfo, char *response[4])
+{
+ memset(response, 0, sizeof(response));
+
+ asprintf(&response[0], "%d", reg_state_ipc2ril(netinfo->reg_state));
+ asprintf(&response[1], "%x", netinfo->lac);
+ asprintf(&response[2], "%x", netinfo->cid);
+ asprintf(&response[3], "%d", gprs_act_ipc2ril(netinfo->act));
+}
+
+/**
+ * Set all the tokens to data waiting.
+ * For instance when only operator is updated by modem NOTI, we don't need
+ * to ask the modem new NET Regist and GPRS Net Regist states so act like we got
+ * these from modem NOTI too so we don't have to make the requests
+ */
+void net_set_tokens_data_waiting(void)
+{
+ radio.tokens.registration_state = RIL_TOKEN_NET_DATA_WAITING;
+ radio.tokens.gprs_registration_state = RIL_TOKEN_NET_DATA_WAITING;
+ radio.tokens.operator = RIL_TOKEN_NET_DATA_WAITING;
+}
+
+/**
+ * Returns 1 if unsol data is waiting, 0 if not
+ */
+int net_get_tokens_data_waiting(void)
+{
+ return radio.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING || radio.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING || radio.tokens.operator == RIL_TOKEN_NET_DATA_WAITING;
+}
+
+/**
+ * Print net tokens values
+ */
+void net_tokens_state_dump(void)
+{
+ LOGD("NET_TOKENS_STATE_DUMP:\n\tradio.tokens.registration_state = 0x%x\n\tradio.tokens.gprs_registration_state = 0x%x\n\tradio.tokens.operator = 0x%x\n", radio.tokens.registration_state, radio.tokens.gprs_registration_state, radio.tokens.operator);
+}
+
+/**
+ * How to handle NET unsol data from modem:
+ * 1- Rx UNSOL (NOTI) data from modem
+ * 2- copy data in a sized variable stored in radio
+ * 3- make sure no SOL request is going on for this token
+ * 4- copy data to radio structure
+ * 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:
+ * 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
+ *
+ * How to handle NET sol requests from RILJ:
+ * 1- if token is 0x00 it's UNSOL RILJ request for modem data
+ * 2- put RIL_Token in token
+ * 3- request data to the modem
+ * 4- Rx SOL (RESP) data from modem
+ * 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
+ * 3- UNSOL data arrives from modem
+ * 4- set all tokens to RIL_TOKEN_NET_DATA_WAITING
+ * 5- store data, tell RILJ NETWORK_STATE_CHANGED
+ * 6- Rx requested data from modem
+ * 7- copy data to radio structure
+ * 8- token mismatch (is now RIL_TOKEN_NET_DATA_WAITING)
+ * 9- send back data to RIL with token from IPC message
+ * 10- don't reset token to 0x00
+ * 11- RILJ does SOL request for modem data (we know it's SOL because we didn't reset token)
+ * 12- send back last data we have (from UNSOL RILJ request here)
+ */
+
+/**
+ * In: RIL_REQUEST_OPERATOR
+ * Request Operator name
+ *
+ * Out: IPC_NET_CURRENT_PLMN
+ * return modem UNSOL data if available
+ * request IPC_NET_CURRENT_PLMN if no data is there
+ * return RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW if not registered
+ */
+void requestOperator(RIL_Token t)
+{
+ char *response[3];
+ int i;
+
+ if(radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_EMERGENCY ||
+ radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
+ radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING ||
+ radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN) {
+ RIL_onRequestComplete(t, RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW, NULL, 0);
+
+ radio.tokens.operator = (RIL_Token) 0x00;
+ return;
+ }
+
+ if(radio.tokens.operator == RIL_TOKEN_NET_DATA_WAITING) {
+ LOGD("Got RILJ request for UNSOL data");
+
+ /* Send back the data we got UNSOL */
+ plmn_ipc2ril(&(radio.plmndata), response);
+
+ RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
+
+ for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
+ if(response[i] != NULL)
+ free(response[i]);
+ }
+
+ radio.tokens.operator = (RIL_Token) 0x00;
+ } else if(radio.tokens.operator == (RIL_Token) 0x00) {
+ LOGD("Got RILJ request for SOL data");
+ /* Request data to the modem */
+ radio.tokens.operator = t;
+
+ ipc_client_send_get(IPC_NET_CURRENT_PLMN, getRequestId(t));
} else {
- RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
+ LOGE("Another request is going on, reporting failure");
+ RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, response, sizeof(response));
}
+
+ net_tokens_state_dump();
}
-void respondGPRSRegistrationState(struct ipc_message_info *request, struct ipc_net_regist *netinfo)
+/**
+ * In: IPC_NET_CURRENT_PLMN
+ * This can be SOL (RESP) or UNSOL (NOTI) message from modem
+ *
+ * Out: RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED
+ * enqueue modem data if UNSOL modem message and then call
+ * RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED
+ * if SOL message, send back data to RILJ
+ */
+void respondOperator(struct ipc_message_info *message)
{
+ RIL_Token t = getToken(message->aseq);
+ struct ipc_net_current_plmn *plmndata = (struct ipc_net_current_plmn *) message->data;
+
+ char *response[3];
int i;
+
+ switch(message->type) {
+ case IPC_TYPE_NOTI:
+ LOGD("Got UNSOL Operator message");
+
+ if(radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_EMERGENCY ||
+ radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
+ radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING ||
+ radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN) {
+ /* Better keeping it up to date */
+ memcpy(&(radio.plmndata), plmndata, sizeof(struct ipc_net_current_plmn));
+
+ return;
+ } else {
+ if(radio.tokens.operator != (RIL_Token) 0x00 && radio.tokens.operator != RIL_TOKEN_NET_DATA_WAITING) {
+ LOGE("Another Operator Req is in progress, skipping");
+ return;
+ }
+
+ memcpy(&(radio.plmndata), plmndata, sizeof(struct ipc_net_current_plmn));
+
+ /* we already told RILJ to get the new data but it wasn't done yet */
+ if(net_get_tokens_data_waiting() && radio.tokens.operator == RIL_TOKEN_NET_DATA_WAITING) {
+ LOGD("Updating Operator data in background");
+ } else {
+ net_set_tokens_data_waiting();
+ RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0);
+ }
+ }
+ break;
+ case IPC_TYPE_RESP:
+ if(radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_EMERGENCY ||
+ radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_NONE ||
+ radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_SEARCHING ||
+ radio.netinfo.reg_state == IPC_NET_REGISTRATION_STATE_UNKNOWN) {
+ /* Better keeping it up to date */
+ memcpy(&(radio.plmndata), plmndata, sizeof(struct ipc_net_current_plmn));
+
+ RIL_onRequestComplete(t, RIL_E_OP_NOT_ALLOWED_BEFORE_REG_TO_NW, NULL, 0);
+
+ if(radio.tokens.operator != RIL_TOKEN_NET_DATA_WAITING)
+ radio.tokens.operator = (RIL_Token) 0x00;
+ return;
+ } else {
+ if(radio.tokens.operator != t)
+ LOGE("Operator tokens mismatch");
+
+ /* Better keeping it up to date */
+ memcpy(&(radio.plmndata), plmndata, sizeof(struct ipc_net_current_plmn));
+
+ plmn_ipc2ril(plmndata, response);
+
+ RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
+
+ for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
+ if(response[i] != NULL)
+ free(response[i]);
+ }
+
+ if(radio.tokens.operator != RIL_TOKEN_NET_DATA_WAITING)
+ radio.tokens.operator = (RIL_Token) 0x00;
+ }
+ break;
+ default:
+ LOGE("%s: unhandled ipc method: %d", __FUNCTION__, message->type);
+ break;
+ }
+
+ net_tokens_state_dump();
+}
+
+/**
+ * In: RIL_REQUEST_REGISTRATION_STATE
+ * Request reg state
+ *
+ * Out: IPC_NET_REGIST
+ * return modem UNSOL data if available
+ * request IPC_NET_REGIST if no data is there
+ */
+void requestRegistrationState(RIL_Token t)
+{
+ struct ipc_net_regist_get regist_req;
char *response[4];
+ int i;
- asprintf(&response[0], "%d", registatus_ipc2ril(netinfo->reg_state));
- asprintf(&response[1], "%04x", netinfo->lac);
- asprintf(&response[2], "%08x", netinfo->cid);
- asprintf(&response[3], "%d", act_ipc2ril(netinfo->act));
+ if(radio.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING) {
+ LOGD("Got RILJ request for UNSOL data");
- RIL_onRequestComplete(radio.token_ps, RIL_E_SUCCESS, response, sizeof(response));
+ /* Send back the data we got UNSOL */
+ reg_state_resp_ipc2ril(&(radio.netinfo), response);
- radio.token_ps = 0;
+ RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
- for(i = 0; i < 4; i++) {
- free(response[i]);
+ for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
+ if(response[i] != NULL)
+ free(response[i]);
+ }
+
+ radio.tokens.registration_state = (RIL_Token) 0x00;
+ } else if(radio.tokens.registration_state == (RIL_Token) 0x00) {
+ LOGD("Got RILJ request for SOL data");
+ /* Request data to the modem */
+ radio.tokens.registration_state = t;
+
+ ipc_net_regist_get(&regist_req, IPC_NET_SERVICE_DOMAIN_GSM);
+ ipc_client_send(ipc_client, IPC_NET_REGIST, IPC_TYPE_GET, (void *)&regist_req, sizeof(struct ipc_net_regist_get), getRequestId(t));
+ } else {
+ LOGE("Another request is going on, reporting failure");
+ RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
}
+
+ net_tokens_state_dump();
}
-void respondNetRegist(struct ipc_message_info *request)
+/**
+ * In: RIL_REQUEST_GPRS_REGISTRATION_STATE
+ * Request GPRS reg state
+ *
+ * Out: IPC_NET_REGIST
+ * return modem UNSOL data if available
+ * request IPC_NET_REGIST if no data is there
+ */
+void requestGPRSRegistrationState(RIL_Token t)
{
- if(request->type == IPC_TYPE_NOTI) {
- memcpy(&radio.netinfo, request->data, sizeof(radio.netinfo));
- RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0);
- } else if(request->type == IPC_TYPE_RESP) {
- struct ipc_net_regist *netinfo = (struct ipc_net_regist*)request->data;
+ struct ipc_net_regist_get regist_req;
+ char *response[4];
+ int i;
- if(netinfo->domain == 3) {
- LOGD("%s: netinfo service domain = ps", __FUNCTION__);
- respondGPRSRegistrationState(request, netinfo);
- } else {
- LOGE("%s: unhandled service domain: %d", __FUNCTION__, netinfo->domain);
+ if(radio.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING) {
+ LOGD("Got RILJ request for UNSOL data");
+
+ /* Send back the data we got UNSOL */
+ gprs_reg_state_resp_ipc2ril(&(radio.gprs_netinfo), response);
+
+ RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
+
+ for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
+ if(response[i] != NULL)
+ free(response[i]);
}
+
+ radio.tokens.gprs_registration_state = (RIL_Token) 0x00;
+ } else if(radio.tokens.gprs_registration_state == (RIL_Token) 0x00) {
+ LOGD("Got RILJ request for SOL data");
+
+ /* Request data to the modem */
+ radio.tokens.gprs_registration_state = t;
+
+ ipc_net_regist_get(&regist_req, IPC_NET_SERVICE_DOMAIN_GPRS);
+ ipc_client_send(ipc_client, IPC_NET_REGIST, IPC_TYPE_GET, (void *)&regist_req, sizeof(struct ipc_net_regist_get), getRequestId(t));
} else {
- LOGE("%s: unhandled ipc method: %d", __FUNCTION__, request->type);
+ LOGE("Another request is going on, reporting failure");
+ RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
+ }
+
+ net_tokens_state_dump();
+}
+
+void respondNetRegistUnsol(struct ipc_message_info *message)
+{
+ struct ipc_net_regist *netinfo;
+ netinfo = (struct ipc_net_regist *) message->data;
+
+ LOGD("Got UNSOL NetRegist message");
+
+ switch(netinfo->domain) {
+ case IPC_NET_SERVICE_DOMAIN_GSM:
+ if(radio.tokens.registration_state != (RIL_Token) 0 && radio.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING) {
+ LOGE("Another NetRegist Req is in progress, skipping");
+ return;
+ }
+
+ memcpy(&(radio.netinfo), netinfo, sizeof(struct ipc_net_regist));
+
+ /* we already told RILJ to get the new data but it wasn't done yet */
+ if(net_get_tokens_data_waiting() && radio.tokens.registration_state == RIL_TOKEN_NET_DATA_WAITING) {
+ LOGD("Updating NetRegist data in background");
+ } else {
+ net_set_tokens_data_waiting();
+ RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0);
+ }
+ break;
+
+ case IPC_NET_SERVICE_DOMAIN_GPRS:
+ if(radio.tokens.gprs_registration_state != (RIL_Token) 0 && radio.tokens.gprs_registration_state != RIL_TOKEN_NET_DATA_WAITING) {
+ LOGE("Another GPRS NetRegist Req is in progress, skipping");
+ return;
+ }
+
+ memcpy(&(radio.gprs_netinfo), netinfo, sizeof(struct ipc_net_regist));
+
+ /* we already told RILJ to get the new data but it wasn't done yet */
+ if(net_get_tokens_data_waiting() && radio.tokens.gprs_registration_state == RIL_TOKEN_NET_DATA_WAITING) {
+ LOGD("Updating GPRSNetRegist data in background");
+ } else {
+ net_set_tokens_data_waiting();
+ RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, NULL, 0);
+ }
+ break;
+ default:
+ LOGE("%s: unhandled service domain: %d", __FUNCTION__, netinfo->domain);
+ break;
+ }
+
+ net_tokens_state_dump();
+}
+
+void respondNetRegistSol(struct ipc_message_info *message)
+{
+ char *response[4];
+ int i;
+
+ struct ipc_net_regist *netinfo = (struct ipc_net_regist *) message->data;
+ RIL_Token t = getToken(message->aseq);
+
+ LOGD("Got SOL NetRegist message");
+
+ switch(netinfo->domain) {
+ case IPC_NET_SERVICE_DOMAIN_GSM:
+ if(radio.tokens.registration_state != t)
+ LOGE("Registration state tokens mismatch");
+
+ /* Better keeping it up to date */
+ memcpy(&(radio.netinfo), netinfo, sizeof(struct ipc_net_regist));
+
+ reg_state_resp_ipc2ril(netinfo, response);
+
+ RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
+
+ for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
+ if(response[i] != NULL)
+ free(response[i]);
+ }
+
+ if(radio.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING)
+ radio.tokens.registration_state = (RIL_Token) 0x00;
+ break;
+ case IPC_NET_SERVICE_DOMAIN_GPRS:
+ if(radio.tokens.gprs_registration_state != t)
+ LOGE("GPRS registration state tokens mismatch");
+
+ /* Better keeping it up to date */
+ memcpy(&(radio.gprs_netinfo), netinfo, sizeof(struct ipc_net_regist));
+
+ gprs_reg_state_resp_ipc2ril(netinfo, response);
+
+ RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
+
+ for(i = 0; i < sizeof(response) / sizeof(char *) ; i++) {
+ if(response[i] != NULL)
+ free(response[i]);
+ }
+ if(radio.tokens.registration_state != RIL_TOKEN_NET_DATA_WAITING)
+ radio.tokens.gprs_registration_state = (RIL_Token) 0x00;
+ break;
+ default:
+ LOGE("%s: unhandled service domain: %d", __FUNCTION__, netinfo->domain);
+ break;
+ }
+
+ net_tokens_state_dump();
+}
+
+/**
+ * In: IPC_NET_REGIST
+ * This can be SOL (RESP) or UNSOL (NOTI) message from modem
+ */
+void respondNetRegist(struct ipc_message_info *message)
+{
+ /* Don't consider this if modem isn't in normal power mode. */
+ if(radio.power_mode < POWER_MODE_NORMAL)
+ return;
+
+ switch(message->type) {
+ case IPC_TYPE_NOTI:
+ respondNetRegistUnsol(message);
+ break;
+ case IPC_TYPE_RESP:
+ respondNetRegistSol(message);
+ break;
+ default:
+ LOGE("%s: unhandled ipc method: %d", __FUNCTION__, message->type);
+ break;
}
+
}
void requestGetPreferredNetworkType(RIL_Token t)
@@ -82,3 +598,85 @@ void requestSetPreferredNetworkType(RIL_Token t, void *data, size_t datalen)
ipc_client_send(ipc_client, IPC_NET_MODE_SEL, IPC_TYPE_SET, &ipc_mode, sizeof(ipc_mode), getRequestId(t));
}
+
+// FIXME: add corect implementation
+void requestNwSelectionMode(RIL_Token t)
+{
+ unsigned int mode = 0;
+ RIL_onRequestComplete(t, RIL_E_SUCCESS, &mode, sizeof(mode));
+}
+
+/**
+ * In: RIL_REQUEST_QUERY_AVAILABLE_NETWORKS
+ *
+ * Out: IPC_NET_PLMN_LIST
+ */
+void requestAvailNetworks(RIL_Token t)
+{
+ ipc_client_send_get(IPC_NET_PLMN_LIST, getRequestId(t));
+}
+
+/* FIXME: cleanup struct names & resp[] addressing */
+/**
+ * In: IPC_NET_PLMN_LIST
+ * Send back available PLMN list
+ *
+ */
+void respondAvailNetworks(RIL_Token t, void *data, int length)
+{
+ struct ipc_net_plmn_entries *entries_info = (struct ipc_net_plmn_entries*)data;
+ struct ipc_net_plmn_entry *entries = (struct ipc_net_plmn_entry *)
+ (data + sizeof(struct ipc_net_plmn_entries));
+
+ int i;
+ int size = (4 * entries_info->num * sizeof(char*));
+ int actual_size = 0;
+
+ char **resp = malloc(size);
+ char **resp_ptr = resp;
+LOGE("Listed %d PLMNs\n", entries_info->num);
+ for(i = 0; i < entries_info->num; i++) {
+ /* Assumed type for 'emergency only' PLMNs */
+ if(entries[i].type == 0x01)
+ continue;
+
+ char *plmn = plmn_string(entries[i].plmn);
+
+ LOGD("PLMN #%d: %s (%s)\n", i, plmn_lookup(plmn), plmn);
+
+ /* Long (E)ONS */
+ asprintf(&resp_ptr[0], "%s", plmn_lookup(plmn));
+
+ /* Short (E)ONS - FIXME: real short EONS */
+ asprintf(&resp_ptr[1], "%s", plmn_lookup(plmn));
+
+ /* PLMN */
+ asprintf(&resp_ptr[2], "%s", plmn);
+
+ free(plmn);
+
+ /* PLMN status */
+ switch(entries[i].status) {
+ case IPC_NET_PLMN_STATUS_AVAILABLE:
+ asprintf(&resp_ptr[3], "available");
+ break;
+ case IPC_NET_PLMN_STATUS_CURRENT:
+ asprintf(&resp_ptr[3], "current");
+ break;
+ case IPC_NET_PLMN_STATUS_FORBIDDEN:
+ asprintf(&resp_ptr[3], "forbidden");
+ break;
+ default:
+ asprintf(&resp_ptr[3], "unknown");
+ break;
+ }
+
+ actual_size++;
+ resp_ptr += 4;
+ }
+
+ RIL_onRequestComplete(t, RIL_E_SUCCESS, resp, (4 * sizeof(char*) * actual_size));
+
+ /* FIXME: free individual strings */
+ free(resp);
+}
diff --git a/pwr.c b/pwr.c
new file mode 100644
index 0000000..009e67a
--- /dev/null
+++ b/pwr.c
@@ -0,0 +1,98 @@
+#define LOG_TAG "RIL-PWR"
+#include <utils/Log.h>
+
+#include "samsung-ril.h"
+#include "util.h"
+
+extern const struct RIL_Env *rilenv;
+extern struct radio_state radio;
+extern struct ipc_client *ipc_client;
+
+/**
+ * Out: RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED
+ * Modem lets us know it's powered on. Though, it's still in LPM and should
+ * be considered as OFF. Send this to update RILJ radio state (OFF)
+ */
+void respondPowerUp(void)
+{
+ /* H1 baseband firmware bug workaround: sleep for 25ms to allow for nvram to initialize */
+ usleep(25000);
+
+ radio.radio_state = RADIO_STATE_OFF;
+ radio.power_mode = POWER_MODE_LPM;
+ RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
+}
+
+/**
+ * In: IPC_PWR_PHONE_STATE
+ * Noti from the modem giving current power mode (LPM or NORMAL)
+ * LPM = Low Power Mode (airplane mode for instance)
+ *
+ * Out: RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED
+ * Update radio state according to modem power state
+ */
+void respondPowerPhoneState(struct ipc_message_info *info)
+{
+ uint8_t state = *((uint8_t *)info->data);
+
+ switch(state)
+ {
+ /* This shouldn't append for LPM (no respond message) */
+ case IPC_PWR_R(IPC_PWR_PHONE_STATE_LPM):
+ radio.power_mode = POWER_MODE_LPM;
+ radio.radio_state = RADIO_STATE_OFF;
+ LOGD("Got power to LPM");
+ RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
+ break;
+ case IPC_PWR_R(IPC_PWR_PHONE_STATE_NORMAL):
+ usleep(3000);
+
+ radio.power_mode = POWER_MODE_NORMAL;
+ radio.radio_state = RADIO_STATE_SIM_NOT_READY;
+ LOGD("Got power to NORMAL");
+
+ /*
+ * return RIL_E_SUCCESS is done at IPC_SEC_PIN_STATUS:
+ * breaks return-from-airplane-mode if done here
+ */
+ RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
+ break;
+ }
+
+ RadioTokensCheck();
+}
+
+/**
+ * In: RIL_REQUEST_RADIO_POWER
+ * Request ON or OFF radio power mode
+ *
+ * Out: IPC_PWR_PHONE_STATE
+ * Order the modem to get in required power mode
+ */
+void requestPower(RIL_Token t, void *data, size_t datalen)
+{
+ int power_state = *((int *)data);
+ unsigned short power_data;
+
+ LOGD("requested power_state is %d", power_state);
+
+ if(power_state > 0) {
+ LOGD("Request power to NORMAL");
+ power_data = IPC_PWR_PHONE_STATE_NORMAL;
+ ipc_client_send(ipc_client, IPC_PWR_PHONE_STATE, IPC_TYPE_EXEC, (void *) &power_data, sizeof(power_data), getRequestId(t));
+
+ radio.tokens.radio_power = t;
+
+ /* Don't tell the RIL we're not off anymore: wait for the message */
+ } else {
+ LOGD("Request power to LPM");
+ power_data = IPC_PWR_PHONE_STATE_LPM;
+ ipc_client_send(ipc_client, IPC_PWR_PHONE_STATE, IPC_TYPE_EXEC, (void *) &power_data, sizeof(power_data), getRequestId(t));
+
+ RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+
+ /* We're not going to get any message to make sure we're in LPM so tell RILJ we're off anyway */
+ radio_init_lpm();
+ RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
+ }
+}
diff --git a/samsung-ril.c b/samsung-ril.c
index bd9bc7f..0f91378 100644
--- a/samsung-ril.c
+++ b/samsung-ril.c
@@ -1,3 +1,5 @@
+#include <time.h>
+
#include <telephony/ril.h>
#include <radio.h>
@@ -9,17 +11,23 @@
#include "samsung-ril.h"
#include "util.h"
-#define RIL_VERSION_STRING "Samsung H1 RIL"
+#define RIL_VERSION_STRING "Samsung RIL"
-struct radio_state radio;
const struct RIL_Env *rilenv;
+struct radio_state radio;
+
struct ipc_client *ipc_client;
+int client_fmt_fd = -1;
+
+/*
+ * Token-related function
+ */
/* Tokens associated with requests */
RIL_Token request_ids[256];
int rid = 0;
-void start_thread();
+void read_loop_thread();
int getRequestId(RIL_Token token)
{
@@ -42,204 +50,36 @@ RIL_Token getToken(int id)
return request_ids[id];
}
-void respondNitz(void *data, int length)
-{
- struct ipc_misc_time_info *nitz = (struct ipc_misc_time_info*)data;
- char str[128];
-
- sprintf(str, "%02u/%02u/%02u,%02u:%02u:%02u+%02d,%02d",
- nitz->year, nitz->mon, nitz->day, nitz->hour, nitz->min, nitz->sec, nitz->tz, 0);
-
- RIL_onUnsolicitedResponse(RIL_UNSOL_NITZ_TIME_RECEIVED, str, strlen(str) + 1);
-}
-
-void requestIMEI(RIL_Token t)
+void RadioTokensCheck(void)
{
- if(radio.radio_state != RADIO_STATE_OFF) {
- ipc_client_send_get(IPC_MISC_ME_SN, getRequestId(t));
- } else {
- radio.token_imei = t;
+ if(radio.tokens.baseband_version != 0) {
+ if(radio.radio_state != RADIO_STATE_OFF) {
+ requestBasebandVersion(radio.tokens.baseband_version);
+ radio.tokens.baseband_version = 0;
+ }
}
-}
-
-void respondIMEI(RIL_Token t, void *data, int length)
-{
- struct ipc_misc_me_sn *imei_info;
- char imei[33];
- char imeisv[3];
-
- imei_info = (struct ipc_misc_me_sn*)data;
-
- if(imei_info->length > 32)
- return;
-
- memset(imei, 0, sizeof(imei));
- memset(imeisv, 0, sizeof(imeisv));
-
- memcpy(imei, imei_info->imei, imei_info->length);
-
- /* Last two bytes of IMEI in imei_info are the SV bytes */
- memcpy(imeisv, (imei_info->imei + imei_info->length - 2), 2);
-
- /* IMEI */
- RIL_onRequestComplete(t, RIL_E_SUCCESS, imei, sizeof(char*));
-
- /* IMEI SV */
- RIL_onRequestComplete(radio.token_imeisv, RIL_E_SUCCESS, imeisv, sizeof(char*));
-}
-
-void requestIMEISV(RIL_Token t)
-{
- radio.token_imeisv = t;
-}
-
-void requestOperator(RIL_Token t)
-{
- ipc_client_send_get(IPC_NET_CURRENT_PLMN, getRequestId(t));
-}
-
-void respondOperator(RIL_Token t, void *data, int length)
-{
- struct ipc_net_current_plmn *plmndata = (struct ipc_net_current_plmn*)data;
-
- char plmn[7];
- memset(plmn, 0, sizeof(plmn));
- memcpy(plmn, plmndata->plmn, 6);
-
- if(plmn[5] == '#')
- plmn[5] = '\0'; //FIXME: remove #?
-
- char *response[3];
- asprintf(&response[0], "%s", plmn_lookup(plmn));
- //asprintf(&response[1], "%s", "Voda NL");
- response[1] = NULL;
- response[2] = plmn;
-
- RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
-
- free(response[0]);
- free(response[1]);
-}
-
-void requestRegistrationState(RIL_Token t)
-{
- char *response[15];
- memset(response, 0, sizeof(response));
-
- asprintf(&response[0], "%d", 1); //FIXME: registration state
- asprintf(&response[1], "%x", radio.netinfo.lac);
- asprintf(&response[2], "%x", radio.netinfo.cid);
- asprintf(&response[3], "%d", 1); //FIXME: network technology
-
- RIL_onRequestComplete(t, RIL_E_SUCCESS, response, sizeof(response));
-
- free(response[0]);
- free(response[1]);
- free(response[2]);
-}
-
-void requestNwSelectionMode(RIL_Token t)
-{
- unsigned int mode = 0;
- RIL_onRequestComplete(t, RIL_E_SUCCESS, &mode, sizeof(mode));
-}
-
-void requestAvailNetworks(RIL_Token t)
-{
- ipc_client_send_get(IPC_NET_PLMN_LIST, getRequestId(t));
-}
-
-/* FIXME: cleanup struct names & resp[] addressing */
-void respondAvailNetworks(RIL_Token t, void *data, int length)
-{
- struct ipc_net_plmn_entries *entries_info = (struct ipc_net_plmn_entries*)data;
- struct ipc_net_plmn_entry *entries = entries_info->data;
-
- int i ;
- int size = (4 * entries_info->num * sizeof(char*));
- int actual_size = 0;
-
- char **resp = malloc(size);
- char **resp_ptr = resp;
-
- for(i = 0; i < entries_info->num; i++) {
- /* Assumed type for 'emergency only' PLMNs */
- if(entries[i].type == 0x01)
- continue;
-
- char *plmn = plmn_string(entries[i].plmn);
- /* Long (E)ONS */
- asprintf(&resp_ptr[0], "%s", plmn_lookup(plmn));
-
- /* Short (E)ONS - FIXME: real short EONS */
- asprintf(&resp_ptr[1], "%s", plmn_lookup(plmn));
-
- /* PLMN */
- asprintf(&resp_ptr[2], "%s", plmn);
-
- free(plmn);
-
- /* PLMN status */
- switch(entries[i].status) {
- case IPC_NET_PLMN_STATUS_AVAILABLE:
- asprintf(&resp_ptr[3], "available");
- break;
- case IPC_NET_PLMN_STATUS_CURRENT:
- asprintf(&resp_ptr[3], "current");
- break;
- case IPC_NET_PLMN_STATUS_FORBIDDEN:
- asprintf(&resp_ptr[3], "forbidden");
- break;
- default:
- asprintf(&resp_ptr[3], "unknown");
- break;
+ if(radio.tokens.get_imei != 0) {
+ if(radio.radio_state != RADIO_STATE_OFF) {
+ requestIMEI(radio.tokens.get_imei);
+ radio.tokens.get_imei = 0;
}
-
- actual_size++;
- resp_ptr += 4;
}
-
- RIL_onRequestComplete(t, RIL_E_SUCCESS, resp, (4 * sizeof(char*) * actual_size));
-
- /* FIXME: free individual strings */
- free(resp);
}
-void respondSignalStrength(RIL_Token t, void *data, int length)
-{
- struct ipc_disp_icon_info *signal_info = (struct ipc_disp_icon_info*)data;
- int rssi;
-
- RIL_SignalStrength ss;
- memset(&ss, 0, sizeof(ss));
-
- /* Multiplying the number of bars by 3 yields
- * an asu with an equal number of bars in Android
- */
- ss.GW_SignalStrength.signalStrength = (3 * signal_info->rssi);
- ss.GW_SignalStrength.bitErrorRate = 99;
-
- RIL_onUnsolicitedResponse(RIL_UNSOL_SIGNAL_STRENGTH, &ss, sizeof(ss));
-}
-
-void requestPower(RIL_Token t, void *data, size_t datalen)
-{
- int *power_state = (int*)data;
-
- if(*power_state) {
- start_thread();
- RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
- } else {
- LOGE("%s: power off not implemented", __FUNCTION__);
- RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
- }
-}
+/*
+ * RILJ (RIL to modem) related functions
+ */
void onRequest(int request, void *data, size_t datalen, RIL_Token t)
{
//LOGD("%s: start %d %08X", __FUNCTION__, request, t);
-
+/*
+ if(radio.tokens.radio_power != 0) {
+ RIL_onRequestComplete(t, RIL_E_RADIO_NOT_AVAILABLE, NULL, 0);
+ return;
+ }
+*/
switch(request) {
case RIL_REQUEST_RADIO_POWER:
requestPower(t, data, datalen);
@@ -295,10 +135,10 @@ void onRequest(int request, void *data, size_t datalen, RIL_Token t)
requestSendSms(t, data, datalen);
break;
case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
- requestSendSms(t, data, datalen);
+ requestSendSmsExpectMore(t, data, datalen);
break;
case RIL_REQUEST_SMS_ACKNOWLEDGE:
- requestSmsAcknowledge(t);
+ requestSmsAcknowledge(t, data, datalen);
break;
case RIL_REQUEST_GET_SIM_STATUS:
requestSimStatus(t);
@@ -324,6 +164,11 @@ void onRequest(int request, void *data, size_t datalen, RIL_Token t)
case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM:
RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
break;
+ case RIL_REQUEST_SCREEN_STATE:
+ /* This doesn't affect anything */
+ RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+ break;
+
default:
LOGE("Request not implemented: %d\n", request);
RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
@@ -354,23 +199,6 @@ const char *getVersion(void)
return RIL_VERSION_STRING;
}
-void respondPowerup()
-{
- /* Update radio state */
- radio.radio_state = RADIO_STATE_SIM_NOT_READY;
- RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
-
- /* Send pending IMEI and baseband version requests */
- if(radio.token_imei) {
- ipc_client_send_get(IPC_MISC_ME_SN, getRequestId(radio.token_imei));
- radio.token_imei = 0;
- }
-
- if(radio.token_baseband_ver) {
- ipc_client_send_get(IPC_MISC_ME_VERSION, getRequestId(radio.token_baseband_ver));
- }
-}
-
void respondGenPhonRes(struct ipc_message_info *info)
{
struct ipc_gen_phone_res *gen_res = (struct ipc_gen_phone_res*)info->data;
@@ -383,16 +211,23 @@ void respondGenPhonRes(struct ipc_message_info *info)
}
}
+/**
+ * libsamsung-ipc (modem to RIL) related functions
+ */
+
void onReceive(struct ipc_message_info *info)
{
/* FIXME: This _needs_ to be moved to each individual function. Unsollicited calls do not have a token! */
RIL_Token t = getToken(info->aseq);
+ // TODO: add IPC_NET_SERVING_NETWORK
+
switch(IPC_COMMAND(info)) {
case IPC_PWR_PHONE_PWR_UP:
- /* H1 baseband firmware bug workaround: sleep for 25ms to allow for nvram to initialize */
- usleep(25000);
- respondPowerup();
+ respondPowerUp();
+ break;
+ case IPC_PWR_PHONE_STATE:
+ respondPowerPhoneState(info);
break;
case IPC_MISC_ME_VERSION:
respondBasebandVersion(info);
@@ -401,13 +236,13 @@ void onReceive(struct ipc_message_info *info)
respondIMSI(info);
break;
case IPC_MISC_ME_SN:
- respondIMEI(t, info->data, info->length);
+ respondMeSn(t, info->data, info->length);
break;
case IPC_MISC_TIME_INFO:
respondNitz(info->data, info->length);
break;
case IPC_NET_CURRENT_PLMN:
- respondOperator(t, info->data, info->length);
+ respondOperator(info);
break;
case IPC_NET_PLMN_LIST:
respondAvailNetworks(t, info->data, info->length);
@@ -419,6 +254,9 @@ void onReceive(struct ipc_message_info *info)
respondModeSel(info);
break;
case IPC_DISP_ICON_INFO:
+ respondIconSignalStrength(t, info->data, info->length);
+ break;
+ case IPC_DISP_RSSI_INFO:
respondSignalStrength(t, info->data, info->length);
break;
case IPC_CALL_INCOMING:
@@ -433,6 +271,15 @@ void onReceive(struct ipc_message_info *info)
case IPC_SMS_INCOMING_MSG:
respondSmsIncoming(t, info->data, info->length);
break;
+ case IPC_SMS_DELIVER_REPORT:
+ respondSmsDeliverReport(t, info->data, info->length);
+ break;
+ case IPC_SMS_SVC_CENTER_ADDR:
+ respondSmsSvcCenterAddr(t, info->data, info->length);
+ break;
+ case IPC_SMS_SEND_MSG:
+ respondSmsSendMsg(t, info->data, info->length);
+ break;
case IPC_SEC_PIN_STATUS:
respondSimStatusChanged(t, info->data, info->length);
break;
@@ -454,6 +301,9 @@ void onReceive(struct ipc_message_info *info)
case IPC_GEN_PHONE_RES:
respondGenPhonRes(info);
break;
+ case IPC_SMS_DEVICE_READY:
+ respondSmsDeviceReady(t, info);
+ break;
default:
//LOGD("Unknown msgtype: %04x", info->type);
break;
@@ -465,52 +315,69 @@ void ipc_log_handler(const char *message, void *user_data)
LOGD("ipc: %s", message);
}
-void *init_loop()
+/**
+ * read_loop():
+ * This function is the main IPC read loop
+ */
+void *read_loop()
{
struct ipc_message_info resp;
+ fd_set fds;
- ipc_client = ipc_client_new(IPC_CLIENT_TYPE_FMT);
-
- ipc_client_set_log_handler(ipc_client, ipc_log_handler, NULL);
-
- ipc_client_bootstrap_modem(ipc_client);
+ FD_ZERO(&fds);
+ FD_SET(client_fmt_fd, &fds);
- if(ipc_client_open(ipc_client)) {
- LOGE("%s: failed to open ipc client", __FUNCTION__);
- return 0;
- }
+ while(1) {
+ usleep(3000);
- if(ipc_client_power_on(ipc_client)) {
- LOGE("%s: failed to power on ipc client", __FUNCTION__);
- return 0;
- }
+ select(client_fmt_fd + 1, &fds, NULL, NULL, NULL);
- while(1) {
- ipc_client_recv(ipc_client, &resp);
+ if(FD_ISSET(client_fmt_fd, &fds)) {
+ if(ipc_client_recv(ipc_client, &resp)) {
+ LOGE("IPC RECV failure!!!");
+ break;
+ }
+ LOGD("RECV aseq=0x%x mseq=0x%x data_length=%d\n", resp.aseq, resp.mseq, resp.length);
- onReceive(&resp);
+ onReceive(&resp);
- if(resp.data != NULL)
- free(resp.data);
+ if(resp.data != NULL)
+ free(resp.data);
+ }
}
ipc_client_power_off(ipc_client);
ipc_client_close(ipc_client);
-
ipc_client_free(ipc_client);
return 0;
}
-void start_thread()
+void radio_init_tokens(void)
+{
+ memset(&(radio.tokens), 0, sizeof(struct ril_tokens));
+}
+
+void radio_init_lpm(void)
+{
+ memset(&radio, 0, sizeof(radio));
+ radio.radio_state = RADIO_STATE_OFF;
+ radio.power_mode = POWER_MODE_LPM;
+}
+
+void read_loop_thread()
{
pthread_t thread;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
- pthread_create(&thread, &attr, init_loop, NULL);
+ pthread_create(&thread, &attr, read_loop, NULL);
}
+/**
+ * RIL_Init function
+ */
+
static const RIL_RadioFunctions radio_ops = {
RIL_VERSION,
onRequest,
@@ -522,13 +389,40 @@ static const RIL_RadioFunctions radio_ops = {
const RIL_RadioFunctions *RIL_Init(const struct RIL_Env *env, int argc, char **argv)
{
- memset(&radio, 0, sizeof(radio));
- radio.radio_state = RADIO_STATE_OFF;
- radio.token_ps = 0;
- radio.token_cs = 0;
+ radio_init_lpm();
+ radio_init_tokens();
rilenv = env;
+ LOGD("Creating new FMT client");
+ ipc_client = ipc_client_new(IPC_CLIENT_TYPE_FMT);
+
+ ipc_client_set_log_handler(ipc_client, ipc_log_handler, NULL);
+
+ ipc_client_bootstrap_modem(ipc_client);
+
+ LOGD("All handlers data is %p", &client_fmt_fd);
+ ipc_client_set_all_handlers_data(ipc_client, &client_fmt_fd);
+
+ LOGD("Client open...");
+ if(ipc_client_open(ipc_client)) {
+ LOGE("%s: failed to open ipc client", __FUNCTION__);
+ return 0;
+ }
+
+ if(client_fmt_fd < 0) {
+ LOGE("%s: client_fmt_fd is negative, aborting", __FUNCTION__);
+ return 0;
+ }
+
+ LOGD("Client power on...");
+ if(ipc_client_power_on(ipc_client)) {
+ LOGE("%s: failed to power on ipc client", __FUNCTION__);
+ return 0;
+ }
+
+ read_loop_thread();
+
return &radio_ops;
}
diff --git a/samsung-ril.h b/samsung-ril.h
index cf91cb4..c13686f 100644
--- a/samsung-ril.h
+++ b/samsung-ril.h
@@ -27,27 +27,49 @@ typedef enum {
SIM_SERVICE_PROVIDER_PERSO = 9,
} SIM_Status;
+typedef enum {
+ POWER_MODE_LPM = 0,
+ POWER_MODE_NORMAL = 2,
+ POWER_MODE_SIM_INIT_COMPLETE = 4,
+} Modem_PowerMode;
+
+// Move RIL_Token token_ps, token_cs; here
+struct ril_tokens {
+ RIL_Token radio_power;
+ RIL_Token get_imei;
+ RIL_Token get_imeisv;
+ RIL_Token baseband_version;
+
+ RIL_Token registration_state;
+ RIL_Token gprs_registration_state;
+ RIL_Token operator;
+
+ RIL_Token send_sms;
+};
+
+
struct radio_state {
RIL_RadioState radio_state;
RIL_CardState card_state;
+ SIM_Status sim_status;
+ Modem_PowerMode power_mode;
- RIL_Token token_imei;
- RIL_Token token_imeisv;
-
- RIL_Token token_baseband_ver;
+ struct ril_tokens tokens;
struct ipc_net_regist netinfo;
+ struct ipc_net_regist gprs_netinfo;
+ struct ipc_net_current_plmn plmndata;
- /* SIM status - RIL_REQUEST_GET_SIM_STATUS */
- SIM_Status sim_status;
-
- /* Samsung H1 baseband returns bogus request id for NET_REGIST GETs */
- RIL_Token token_ps, token_cs;
+ unsigned char msg_tpid_lock;
+ char *msg_pdu;
};
+void RadioTokensCheck(void);
int getRequestId(RIL_Token token);
RIL_Token getToken(int id);
+void radio_init_lpm(void);
+
/* Call */
void requestCallList(RIL_Token t);
void requestGetCurrentCalls(RIL_Token t);
@@ -92,8 +114,17 @@ void respondSmsIncoming(RIL_Token t, void *data, int length);
void requestSendSmsEx(RIL_Token t, void *data, size_t datalen, unsigned char hint);
void requestSendSms(RIL_Token t, void *data, size_t datalen);
void requestSendSmsExpectMore(RIL_Token t, void *data, size_t datalen);
-void requestSmsAcknowledge(RIL_Token t);
+void requestSmsAcknowledge(RIL_Token t, void *data, size_t datalen);
+void respondSmsDeviceReady(RIL_Token t, struct ipc_message_info *info);
void requestIMSI(RIL_Token t);
void respondIMSI(struct ipc_message_info *request);
+/* PWR */
+void respondPowerUp(void);
+void respondPowerPhoneState(struct ipc_message_info *info);
+void requestPower(RIL_Token t, void *data, size_t datalen);
+
+/* DISP */
+void respondIconSignalStrength(RIL_Token t, void *data, int length);
+void respondSignalStrength(RIL_Token t, void *data, int length);
diff --git a/sim.c b/sim.c
index 4baa379..4bed491 100644
--- a/sim.c
+++ b/sim.c
@@ -17,6 +17,10 @@ extern struct ipc_client *ipc_client;
*/
void updateRadioState(SIM_Status status)
{
+ /* If power mode isn't at least normal, don't update RIL state */
+ if(radio.power_mode < POWER_MODE_NORMAL)
+ return;
+
switch(status) {
case SIM_READY:
radio.radio_state = RADIO_STATE_SIM_READY;
@@ -39,6 +43,7 @@ void updateRadioState(SIM_Status status)
break;
}
+ RadioTokensCheck();
RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, NULL, 0);
}
@@ -58,6 +63,15 @@ void respondSimStatusChanged(RIL_Token t, void *data, int length)
{
struct ipc_sec_pin_status_noti *pin_status = (struct ipc_sec_pin_status_noti*)data;
+ /* Don't consider this if modem isn't in normal power mode. */
+ if(radio.power_mode < POWER_MODE_NORMAL)
+ return;
+
+ if(radio.power_mode == POWER_MODE_NORMAL && radio.tokens.radio_power != 0) {
+ RIL_onRequestComplete(radio.tokens.radio_power, RIL_E_SUCCESS, NULL, 0);
+ radio.tokens.radio_power = 0;
+ }
+
/* Determine SIM status */
switch(pin_status->type) {
case IPC_SEC_PIN_SIM_INITIALIZING:
@@ -340,11 +354,7 @@ void requestEnterSimPin(RIL_Token t, void *data, size_t datalen)
RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
}
- memset(&pin_status, 0, sizeof(pin_status));
-
- pin_status.type = IPC_SEC_PIN_TYPE_PIN1;
- pin_status.length1 = strlen(pin);
- memcpy(pin_status.pin1, pin, strlen(pin));
+ ipc_sec_pin_status_set_setup(&pin_status, IPC_SEC_PIN_TYPE_PIN1, pin, NULL);
ipc_client_send_set(IPC_SEC_PIN_STATUS, getRequestId(t), (unsigned char*)&pin_status, sizeof(pin_status));
diff --git a/sms.c b/sms.c
index 0405649..cf8a4d0 100644
--- a/sms.c
+++ b/sms.c
@@ -11,18 +11,21 @@ extern struct ipc_client *ipc_client;
void respondSmsIncoming(RIL_Token t, void *data, int length)
{
struct ipc_sms_incoming_msg *info = (struct ipc_sms_incoming_msg*)data;
- unsigned char *pdu = ((unsigned char*)data+sizeof(struct ipc_sms_incoming_msg));
+ unsigned char *pdu = ((unsigned char*)data + sizeof(struct ipc_sms_incoming_msg));
- /**
- * H1 libtelplugin seems to provide the SMSC address length
- * instead of the number of octects used for the SMSC info struct
- */
- pdu[0] = (pdu[0] >> 1) + (pdu[0] & 0x01) + 1;
-
- int resp_length = length * 2 + 1;
+ int resp_length = info->length * 2 + 1;
char *resp = (char*)malloc(resp_length);
- bin2hex(pdu, length, resp);
+ bin2hex(pdu, info->length, resp);
+ LOGD("PDU string is '%s'\n", resp);
+
+ if(radio.msg_tpid_lock != 0) {
+ LOGE("Another message is already waiting for ACK, aborting");
+ //FIXME: it would be cleaner to enqueue it
+ goto exit;
+ }
+
+ radio.msg_tpid_lock = info->msg_tpid;
if(info->type == IPC_SMS_TYPE_POINT_TO_POINT) {
RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NEW_SMS, resp, resp_length);
@@ -32,70 +35,89 @@ void respondSmsIncoming(RIL_Token t, void *data, int length)
LOGE("%s: Unknown message type", __FUNCTION__);
}
+exit:
free(resp);
}
-/**
- * Helper function to send a single SMS
- * Optionally notifying the network that
- * additional messages are to be expected
- */
-void requestSendSmsEx(RIL_Token t, void *data, size_t datalen, unsigned char hint)
+void requestSendSms(RIL_Token t, void *data, size_t datalen)
{
- int sc_length, data_length, length;
- struct ipc_sms_send_msg *msg;
- unsigned char *p, *buf;
- const char **request = (const char**)data;
-
- /**
- * If the SC is not provided we need to specify length 0 -> 1 zero byte
- */
- sc_length = (request[0] != NULL) ? (strlen(request[0]) / 2) : 1;
- data_length = (strlen(request[1]) / 2);
+ const char **request;
+ request = (char **) data;
+ int pdu_len = strlen(request[1]);
- length = sizeof(struct ipc_sms_send_msg) + sc_length + data_length;
+ /* We first need to get SMS SVC before sending the message */
- buf = (unsigned char*)malloc(length);
- memset(buf, 0, length);
- p = buf;
+ if(request[0] == NULL) {
+ LOGD("We have no SMSC, asking one before anything");
- /* First, setup the header required by IPC */
- msg = (struct ipc_sms_send_msg*)p;
- msg->hint = hint;
- msg->length = sc_length + data_length;
+ if(radio.tokens.send_sms != 0 && radio.msg_pdu != NULL) {
+ LOGE("Another message is being sent, aborting");
+ //FIXME: it would be cleaner to enqueue it
+ }
- p += sizeof(struct ipc_sms_send_msg);
+ radio.tokens.send_sms = t;
+ radio.msg_pdu = malloc(pdu_len);
+ memcpy(radio.msg_pdu, request[1], pdu_len);
- /* Add SC data */
- if(sc_length > 1) {
- hex2bin(request[0], strlen(request[0]), p);
+ ipc_client_send_get(IPC_SMS_SVC_CENTER_ADDR, getRequestId(t));
+
} else {
- *p = 0x00;
+ sms_send_msg(t, request[1], request[0]);
}
+}
+
+void sms_send_msg(RIL_Token t, char *pdu, char *smsc_string)
+{
+ char *data;
+ char *p;
+ struct ipc_sms_send_msg send_msg;
+ char *decoded_pdu;
- p += sc_length;
+ int pdu_str_len = strlen(pdu);
+ int pdu_len = pdu_str_len / 2;
+ int smsc_len = smsc_string[0];
+ int send_msg_len = sizeof(struct ipc_sms_send_msg);
+ int length = pdu_len + smsc_len + send_msg_len;
- /* Add SMS PDU data */
- hex2bin(request[1], strlen(request[1]), p);
+ LOGD("Sending SMS message!");
- /* FIXME: ipc_sms_send_msg(buf, length, getRequestId(t)); */
- LOGE("%s: missing impl", __FUNCTION__);
+ LOGD("length is %x + %x + %x = 0x%x\n", pdu_len, smsc_len, send_msg_len, length);
- /* FIXME: Move to baseband response handler */
- RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
+ decoded_pdu = malloc(pdu_len);
+ hex2bin(pdu, pdu_str_len, decoded_pdu);
+
+ data = malloc(length);
+ memset(&send_msg, 0, sizeof(struct ipc_sms_send_msg));
+
+ send_msg.type = IPC_SMS_TYPE_OUTGOING;
+ send_msg.msg_type = IPC_SMS_MSG_SINGLE; //fixme: define based on PDU
+ send_msg.length = (unsigned char) length;
+ send_msg.smsc_len = (unsigned char) smsc_len;
+
+ p = data;
- free(buf);
+ memcpy(p, &send_msg, send_msg_len);
+ p += send_msg_len;
+ memcpy(p, (char *) (smsc_string + 1), smsc_len);
+ p += smsc_len;
+ memcpy(p, decoded_pdu, pdu_len);
+
+ ipc_client_send(ipc_client, IPC_SMS_SEND_MSG, IPC_TYPE_EXEC, data, length, getRequestId(t));
+
+ /* Wait for ACK to return to RILJ */
+ radio.tokens.send_sms = t;
+
+ free(decoded_pdu);
+ free(data);
}
-/**
- * In: RIL_REQUEST_SEND_SMS
- * Send an SMS message
- *
- * Out: IPC_SMS_SEND_MSG
- */
-void requestSendSms(RIL_Token t, void *data, size_t datalen)
+void respondSmsSvcCenterAddr(RIL_Token t, void *data, size_t datalen)
{
- requestSendSmsEx(t, data, datalen, IPC_SMS_MSG_SINGLE);
+ if(radio.tokens.send_sms == t && radio.msg_pdu != NULL) {
+ sms_send_msg(t, radio.msg_pdu, data);
+
+ free(radio.msg_pdu);
+ }
}
/**
@@ -108,7 +130,51 @@ void requestSendSms(RIL_Token t, void *data, size_t datalen)
*/
void requestSendSmsExpectMore(RIL_Token t, void *data, size_t datalen)
{
- requestSendSmsEx(t, data, datalen, IPC_SMS_MSG_MULTIPLE);
+ /* FIXME: We seriously need a decent queue here */
+
+}
+
+unsigned short sms_ack_error_ril2ipc(int success, int failcause)
+{
+ if(success) {
+ return IPC_SMS_ACK_NO_ERROR;
+ } else {
+ switch(failcause) {
+ case 0xD3:
+ return IPC_SMS_ACK_PDA_FULL_ERROR;
+ default:
+ return IPC_SMS_ACK_UNSPEC_ERROR;
+ }
+ }
+}
+
+RIL_Errno sms_ack_error_ipc2ril(unsigned short error)
+{
+ switch(error) {
+ case IPC_SMS_ACK_NO_ERROR:
+ return RIL_E_SUCCESS;
+ default:
+ return RIL_E_GENERIC_FAILURE;
+ }
+}
+
+void respondSmsSendMsg(RIL_Token t, void *data, size_t datalen)
+{
+ struct ipc_sms_deliv_report_msg *report_msg = data;
+ RIL_Errno ril_ack_err;
+
+ if(radio.tokens.send_sms != t) {
+ LOGE("Wrong token to ACK");
+ }
+
+ LOGD("RECV ack for msg_tpid %d\n", report_msg->msg_tpid);
+
+ ril_ack_err = sms_ack_error_ipc2ril(report_msg->error);
+
+ radio.tokens.send_sms = 0;
+
+ RIL_onRequestComplete(t, ril_ack_err, NULL, 0);
+
}
/**
@@ -119,12 +185,39 @@ void requestSendSmsExpectMore(RIL_Token t, void *data, size_t datalen)
* Out: IPC_SMS_DELIVER_REPORT
* Sends a SMS delivery report
*/
-void requestSmsAcknowledge(RIL_Token t)
+void requestSmsAcknowledge(RIL_Token t, void *data, size_t datalen)
+{
+ struct ipc_sms_deliv_report_msg report_msg;
+ int success = ((int *)data)[0];
+ int failcause = ((int *)data)[1];
+
+ if(radio.msg_tpid_lock == 0) {
+ LOGE("No stored msg_tpid, aborting\n");
+ return;
+ }
+
+ report_msg.type = IPC_SMS_TYPE_STATUS_REPORT;
+ report_msg.error = sms_ack_error_ril2ipc(success, failcause);
+ report_msg.msg_tpid = radio.msg_tpid_lock;
+ report_msg.unk = 0;
+
+ radio.msg_tpid_lock = 0;
+
+ ipc_client_send(ipc_client, IPC_SMS_DELIVER_REPORT, IPC_TYPE_EXEC, (void *) &report_msg, sizeof(struct ipc_sms_deliv_report_msg), getRequestId(t));
+}
+
+void respondSmsDeliverReport(RIL_Token t, void *data, size_t datalen)
{
- /* FIXME ipc_sms_deliver_report(getRequestId(t)); */
- LOGE("%s: missing impl", __FUNCTION__);
+ //FIXME: check it's alright from data (or not, no need to check the ACK of our ACK)
- /* FIXME: Move to baseband response handler */
RIL_onRequestComplete(t, RIL_E_SUCCESS, NULL, 0);
}
+void respondSmsDeviceReady(RIL_Token t, struct ipc_message_info *info)
+{
+ if(radio.radio_state == RADIO_STATE_SIM_READY) {
+ ipc_client_send(ipc_client, IPC_SMS_DEVICE_READY, IPC_TYPE_SET, NULL, 0, getRequestId(t));
+ }
+
+ RadioTokensCheck();
+}
diff --git a/util.c b/util.c
index 3e33e0f..dc13866 100644
--- a/util.c
+++ b/util.c
@@ -57,80 +57,3 @@ void bin2hex(const unsigned char *data, int length, char *buf)
*p = '\0';
}
-
-/**
- * Converts IPC network registration status to Android RIL format
- */
-unsigned char registatus_ipc2ril(unsigned char status)
-{
- switch(status) {
- case 1:
- return 0;
- case 2:
- return 1;
- case 3:
- return 2;
- case 4:
- return 13;
- case 5:
- return 14;
- case 6:
- return 5;
- default:
- LOGE("%s: invalid status %d", __FUNCTION__, status);
- return 255;
- }
-}
-
-/**
- * Converts IPC network access technology to Android RIL format
- */
-unsigned char act_ipc2ril(unsigned char act)
-{
- switch(act) {
- case 1:
- case 2:
- return 1;
- case 3:
- return 2;
- case 4:
- return 3;
- default:
- return 0;
- }
-}
-
-/**
- * Converts IPC preferred network type to Android RIL format
- */
-unsigned char modesel_ipc2ril(unsigned char mode)
-{
- switch(mode) {
- case 0:
- return 7;
- case 1:
- case 3:
- return 1;
- case 2:
- case 4:
- return 2;
- default:
- return 255;
- }
-}
-
-/**
- * Converts Android RIL preferred network type to IPC format
- */
-unsigned char modesel_ril2ipc(unsigned char mode)
-{
- switch(mode) {
- case 1:
- return 2;
- case 2:
- return 3;
- default:
- return 1;
- }
-}
-
diff --git a/util.h b/util.h
index 820c1f5..b72e35a 100644
--- a/util.h
+++ b/util.h
@@ -1,8 +1,2 @@
void bin2hex(const unsigned char *data, int length, char *buf);
void hex2bin(const char *data, int length, unsigned char *buf);
-
-unsigned char registatus_ipc2ril(unsigned char status);
-unsigned char act_ipc2ril(unsigned char act);
-unsigned char modesel_ipc2ril(unsigned char mode);
-unsigned char modesel_ril2ipc(unsigned char mode);
-