From 233ef2c6769c1c833e89651ae5846e66a5097cfb Mon Sep 17 00:00:00 2001 From: Paul Kocialkowski Date: Sun, 1 Sep 2013 14:48:42 +0200 Subject: sms: Write/delete SMS on SIM support Signed-off-by: Paul Kocialkowski --- samsung-ril.c | 12 +++++ samsung-ril.h | 5 +++ sms.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+) diff --git a/samsung-ril.c b/samsung-ril.c index e1bf2cc..9187f48 100644 --- a/samsung-ril.c +++ b/samsung-ril.c @@ -366,6 +366,12 @@ void ipc_fmt_dispatch(struct ipc_message_info *info) case IPC_SMS_DEVICE_READY: ipc_sms_device_ready(info); break; + case IPC_SMS_SAVE_MSG: + ipc_sms_save_msg(info); + break; + case IPC_SMS_DEL_MSG: + ipc_sms_del_msg(info); + break; /* SVC */ case IPC_SVC_DISPLAY_SCREEN: ipc_svc_display_screen(info); @@ -576,6 +582,12 @@ void ril_on_request(int request, void *data, size_t length, RIL_Token t) case RIL_REQUEST_SMS_ACKNOWLEDGE: ril_request_sms_acknowledge(t, data, length); break; + case RIL_REQUEST_WRITE_SMS_TO_SIM: + ril_request_write_sms_to_sim(t, data, length); + break; + case RIL_REQUEST_DELETE_SMS_ON_SIM: + ril_request_delete_sms_on_sim(t, data, length); + break; /* CALL */ case RIL_REQUEST_DIAL: ril_request_dial(t, data, length); diff --git a/samsung-ril.h b/samsung-ril.h index 49e1d0b..ff63d27 100644 --- a/samsung-ril.h +++ b/samsung-ril.h @@ -420,6 +420,11 @@ void ipc_sms_incoming_msg(struct ipc_message_info *info); void ril_request_sms_acknowledge(RIL_Token t, void *data, size_t length); void ipc_sms_deliver_report(struct ipc_message_info *info); +void ril_request_write_sms_to_sim(RIL_Token token, void *data, size_t size); +void ipc_sms_save_msg(struct ipc_message_info *info); +void ril_request_delete_sms_on_sim(RIL_Token token, void *data, size_t size); +void ipc_sms_del_msg(struct ipc_message_info *info); + void ipc_sms_device_ready(struct ipc_message_info *info); /* Call */ diff --git a/sms.c b/sms.c index b3e13b2..3b9a713 100644 --- a/sms.c +++ b/sms.c @@ -56,6 +56,22 @@ RIL_Errno ipc2ril_sms_ack_error(unsigned short error, int *error_code) } } +unsigned char ril2ipc_sms_save_msg_status(int status) +{ + switch (status) { + case 0: + return IPC_SMS_STATUS_REC_UNREAD; + case 1: + return IPC_SMS_STATUS_REC_READ; + case 2: + return IPC_SMS_STATUS_STO_UNSENT; + case 3: + return IPC_SMS_STATUS_STO_SENT; + default: + return IPC_SMS_STATUS_REC_READ; + } +} + /* * Outgoing SMS functions */ @@ -700,6 +716,132 @@ error: ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); } +void ril_request_write_sms_to_sim(RIL_Token token, void *data, size_t size) +{ + struct ipc_sms_save_msg_request_data *sms_save_msg_request_data; + RIL_SMS_WriteArgs *args; + void *buffer = NULL; + size_t length; + size_t data_length; + size_t pdu_length = 0; + size_t pdu_hex_length = 0; + size_t smsc_length = 0; + size_t smsc_hex_length = 0; + unsigned char *p; + + if (data == NULL || size < sizeof(RIL_SMS_WriteArgs)) + goto error; + + args = (RIL_SMS_WriteArgs *) data; + + if (args->pdu != NULL) { + pdu_length = strlen(args->pdu); + pdu_hex_length = pdu_length % 2 == 0 ? pdu_length / 2 : (pdu_length ^ 1) / 2; + } + + if (args->smsc != NULL) { + smsc_length = strlen(args->smsc); + smsc_hex_length = smsc_length % 2 == 0 ? smsc_length / 2 : (smsc_length ^ 1) / 2; + } + + data_length = pdu_hex_length + smsc_hex_length; + if (data_length == 0 || data_length > 0xff) + goto error; + + length = sizeof(struct ipc_sms_save_msg_request_data) + data_length; + buffer = malloc(length); + + sms_save_msg_request_data = (struct ipc_sms_save_msg_request_data *) buffer; + + memset(sms_save_msg_request_data, 0, sizeof(struct ipc_sms_save_msg_request_data)); + sms_save_msg_request_data->unknown = 0x02; + sms_save_msg_request_data->index = 12 - 1; + sms_save_msg_request_data->status = ril2ipc_sms_save_msg_status(args->status); + sms_save_msg_request_data->length = (unsigned char) (data_length & 0xff); + + p = (unsigned char *) buffer + sizeof(struct ipc_sms_save_msg_request_data); + + if (args->smsc != NULL && smsc_length > 0) { + hex2bin(args->smsc, smsc_length, p); + p += smsc_hex_length; + } + + if (args->pdu != NULL && pdu_length > 0) { + hex2bin(args->pdu, pdu_length, p); + p += pdu_hex_length; + } + + ipc_gen_phone_res_expect_to_abort(ril_request_get_id(token), IPC_SMS_SAVE_MSG); + + ipc_fmt_send(IPC_SMS_SAVE_MSG, IPC_TYPE_EXEC, buffer, length, ril_request_get_id(token)); + + goto complete; + +error: + ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); + +complete: + if (buffer != NULL) + free(buffer); +} + +void ipc_sms_save_msg(struct ipc_message_info *info) +{ + struct ipc_sms_save_msg_response_data *sms_save_msg_response_data; + + if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sms_save_msg_response_data)) + return; + + sms_save_msg_response_data = (struct ipc_sms_save_msg_response_data *) info->data; + + if (sms_save_msg_response_data->error) + ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); + else + ril_request_complete(ril_request_get_token(info->aseq), RIL_E_SUCCESS, NULL, 0); +} + +void ril_request_delete_sms_on_sim(RIL_Token token, void *data, size_t size) +{ + struct ipc_sms_del_msg_request_data sms_del_msg_request_data; + int index = 0; + + if (data == NULL || size < sizeof(index)) + goto error; + + index = *((int *) data); + + if (index <= 0 || index > 0xffff) + goto error; + + memset(&sms_del_msg_request_data, 0, sizeof(sms_del_msg_request_data)); + sms_del_msg_request_data.unknown = 0x02; + sms_del_msg_request_data.index = (short) index - 1; + + ipc_gen_phone_res_expect_to_abort(ril_request_get_id(token), IPC_SMS_DEL_MSG); + + ipc_fmt_send(IPC_SMS_DEL_MSG, IPC_TYPE_EXEC, (unsigned char *) &sms_del_msg_request_data, sizeof(sms_del_msg_request_data), ril_request_get_id(token)); + + return; + +error: + ril_request_complete(token, RIL_E_GENERIC_FAILURE, NULL, 0); +} + +void ipc_sms_del_msg(struct ipc_message_info *info) +{ + struct ipc_sms_del_msg_response_data *sms_del_msg_response_data; + + if (info == NULL || info->data == NULL || info->length < sizeof(struct ipc_sms_del_msg_response_data)) + return; + + sms_del_msg_response_data = (struct ipc_sms_del_msg_response_data *) info->data; + + if (sms_del_msg_response_data->error) + ril_request_complete(ril_request_get_token(info->aseq), RIL_E_GENERIC_FAILURE, NULL, 0); + else + ril_request_complete(ril_request_get_token(info->aseq), RIL_E_SUCCESS, NULL, 0); +} + /* * Apparently non-SMS-messages-related function */ -- cgit v1.1