diff options
author | PaulK <contact@paulk.fr> | 2011-11-22 21:50:42 +0100 |
---|---|---|
committer | PaulK <contact@paulk.fr> | 2011-11-22 21:50:42 +0100 |
commit | 233f0f23c75971de36d77605572c9df6b344ca73 (patch) | |
tree | 06598ad50aa97a30041d05ab9c0e8d13c797ea51 /sms.c | |
parent | 791fd3e4a946c05d6598f5054075515df6327b7d (diff) | |
download | hardware_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.c | 211 |
1 files changed, 152 insertions, 59 deletions
@@ -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(); +} |