summaryrefslogtreecommitdiffstats
path: root/sms.c
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 /sms.c
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
Diffstat (limited to 'sms.c')
-rw-r--r--sms.c211
1 files changed, 152 insertions, 59 deletions
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();
+}