From 2126ab2f05c1033fdca7542f38372dffd1468e1c Mon Sep 17 00:00:00 2001 From: Robert Greenwalt Date: Tue, 9 Apr 2013 12:20:45 -0700 Subject: [PATCH 01/11] Fixes typo in logging string. Pointed out by bodhisatwa in https://code.google.com/p/android/issues/detail?id=54098 Change-Id: I4cb42627bb0858360d6f88dedf9412720e4b5cca --- libril/ril.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libril/ril.cpp b/libril/ril.cpp index 0f37cc1..41e2fd2 100644 --- a/libril/ril.cpp +++ b/libril/ril.cpp @@ -3276,7 +3276,7 @@ const char * failCauseToString(RIL_Errno e) { switch(e) { case RIL_E_SUCCESS: return "E_SUCCESS"; - case RIL_E_RADIO_NOT_AVAILABLE: return "E_RAIDO_NOT_AVAILABLE"; + case RIL_E_RADIO_NOT_AVAILABLE: return "E_RADIO_NOT_AVAILABLE"; case RIL_E_GENERIC_FAILURE: return "E_GENERIC_FAILURE"; case RIL_E_PASSWORD_INCORRECT: return "E_PASSWORD_INCORRECT"; case RIL_E_SIM_PIN2: return "E_SIM_PIN2"; From f467af616bbbc479771184731132d68e213a4419 Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Mon, 6 May 2013 23:59:40 -0700 Subject: [PATCH 02/11] libril: move record_stream here as it is the sole client Change-Id: I85b94c4c6d61dfaa964367a58c773b5550a47995 Signed-off-by: Dima Zavin --- libril/Android.mk | 6 +- libril/record_stream.c | 186 +++++++++++++++++++++++++++++++++++++++++ libril/record_stream.h | 43 ++++++++++ libril/ril.cpp | 2 +- 4 files changed, 234 insertions(+), 3 deletions(-) create mode 100644 libril/record_stream.c create mode 100644 libril/record_stream.h diff --git a/libril/Android.mk b/libril/Android.mk index b099d4b..7ccd37a 100644 --- a/libril/Android.mk +++ b/libril/Android.mk @@ -5,7 +5,8 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ ril.cpp \ - ril_event.cpp + ril_event.cpp \ + record_stream.c LOCAL_SHARED_LIBRARIES := \ liblog \ @@ -29,7 +30,8 @@ ifneq ($(ANDROID_BIONIC_TRANSITION),) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ - ril.cpp + ril.cpp \ + record_stream.c LOCAL_STATIC_LIBRARIES := \ libutils_static \ diff --git a/libril/record_stream.c b/libril/record_stream.c new file mode 100644 index 0000000..2add14d --- /dev/null +++ b/libril/record_stream.c @@ -0,0 +1,186 @@ +/* libs/cutils/record_stream.c +** +** Copyright 2006, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +#include +#include +#include +#include +#include "record_stream.h" +#include +#include +#ifdef HAVE_WINSOCK +#include /* for ntohl */ +#else +#include +#endif + +#define HEADER_SIZE 4 + +struct RecordStream { + int fd; + size_t maxRecordLen; + + unsigned char *buffer; + + unsigned char *unconsumed; + unsigned char *read_end; + unsigned char *buffer_end; +}; + + +extern RecordStream *record_stream_new(int fd, size_t maxRecordLen) +{ + RecordStream *ret; + + assert (maxRecordLen <= 0xffff); + + ret = (RecordStream *)calloc(1, sizeof(RecordStream)); + + ret->fd = fd; + ret->maxRecordLen = maxRecordLen; + ret->buffer = (unsigned char *)malloc (maxRecordLen + HEADER_SIZE); + + ret->unconsumed = ret->buffer; + ret->read_end = ret->buffer; + ret->buffer_end = ret->buffer + maxRecordLen + HEADER_SIZE; + + return ret; +} + + +extern void record_stream_free(RecordStream *rs) +{ + free(rs->buffer); + free(rs); +} + + +/* returns NULL; if there isn't a full record in the buffer */ +static unsigned char * getEndOfRecord (unsigned char *p_begin, + unsigned char *p_end) +{ + size_t len; + unsigned char * p_ret; + + if (p_end < p_begin + HEADER_SIZE) { + return NULL; + } + + //First four bytes are length + len = ntohl(*((uint32_t *)p_begin)); + + p_ret = p_begin + HEADER_SIZE + len; + + if (p_end < p_ret) { + return NULL; + } + + return p_ret; +} + +static void *getNextRecord (RecordStream *p_rs, size_t *p_outRecordLen) +{ + unsigned char *record_start, *record_end; + + record_end = getEndOfRecord (p_rs->unconsumed, p_rs->read_end); + + if (record_end != NULL) { + /* one full line in the buffer */ + record_start = p_rs->unconsumed + HEADER_SIZE; + p_rs->unconsumed = record_end; + + *p_outRecordLen = record_end - record_start; + + return record_start; + } + + return NULL; +} + +/** + * Reads the next record from stream fd + * Records are prefixed by a 16-bit big endian length value + * Records may not be larger than maxRecordLen + * + * Doesn't guard against EINTR + * + * p_outRecord and p_outRecordLen may not be NULL + * + * Return 0 on success, -1 on fail + * Returns 0 with *p_outRecord set to NULL on end of stream + * Returns -1 / errno = EAGAIN if it needs to read again + */ +int record_stream_get_next (RecordStream *p_rs, void ** p_outRecord, + size_t *p_outRecordLen) +{ + void *ret; + + ssize_t countRead; + + /* is there one record already in the buffer? */ + ret = getNextRecord (p_rs, p_outRecordLen); + + if (ret != NULL) { + *p_outRecord = ret; + return 0; + } + + // if the buffer is full and we don't have a full record + if (p_rs->unconsumed == p_rs->buffer + && p_rs->read_end == p_rs->buffer_end + ) { + // this should never happen + //ALOGE("max record length exceeded\n"); + assert (0); + errno = EFBIG; + return -1; + } + + if (p_rs->unconsumed != p_rs->buffer) { + // move remainder to the beginning of the buffer + size_t toMove; + + toMove = p_rs->read_end - p_rs->unconsumed; + if (toMove) { + memmove(p_rs->buffer, p_rs->unconsumed, toMove); + } + + p_rs->read_end = p_rs->buffer + toMove; + p_rs->unconsumed = p_rs->buffer; + } + + countRead = read (p_rs->fd, p_rs->read_end, p_rs->buffer_end - p_rs->read_end); + + if (countRead <= 0) { + /* note: end-of-stream drops through here too */ + *p_outRecord = NULL; + return countRead; + } + + p_rs->read_end += countRead; + + ret = getNextRecord (p_rs, p_outRecordLen); + + if (ret == NULL) { + /* not enough of a buffer to for a whole command */ + errno = EAGAIN; + return -1; + } + + *p_outRecord = ret; + return 0; +} diff --git a/libril/record_stream.h b/libril/record_stream.h new file mode 100644 index 0000000..7a89ae4 --- /dev/null +++ b/libril/record_stream.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2006 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * A simple utility for reading fixed records out of a stream fd + */ + +#ifndef _LIBRIL_RECORD_STREAM_H +#define _LIBRIL_RECORD_STREAM_H + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef struct RecordStream RecordStream; + +extern RecordStream *record_stream_new(int fd, size_t maxRecordLen); +extern void record_stream_free(RecordStream *p_rs); + +extern int record_stream_get_next (RecordStream *p_rs, void ** p_outRecord, + size_t *p_outRecordLen); + +#ifdef __cplusplus +} +#endif + + +#endif /*_LIBRIL_RECORD_STREAM_H*/ + diff --git a/libril/ril.cpp b/libril/ril.cpp index bd83654..5c7b243 100644 --- a/libril/ril.cpp +++ b/libril/ril.cpp @@ -23,7 +23,7 @@ #include #include #include -#include +#include "record_stream.h" #include #include #include From 75697538e485ea2981960dcd4878bfdd032731ac Mon Sep 17 00:00:00 2001 From: Sungmin Choi Date: Fri, 26 Apr 2013 15:04:45 -0700 Subject: [PATCH 03/11] Set initial attach apn for LTE network When mobile register LTE network, APN provided by operators is needed. If mobile does not have apn information, it could not register LTE network. To deliver APN information which is used during LTE attach to modem chipset, setLteAttachProfile() and RIL_REQUEST_SET_LTE_ATTACH_PROFILE command is added. When Telephony DB is loaded or Telephony DB is changed, follow steps. 1. If preferred default ApnContext exists, this is delivered to modem chipset. 2. If preferred default ApnContext is null, find other ApnContext which can handle default type. 3. If other ApnContext which can handle default type does not exist, any other ApnContext delivered to modem chipset. Then modem register LTE network with APN information delivered from AP. Bug: 8733613 Change-Id: If84c62cddccf96a531dae0527ed1a6592ae76201 Signed-off-by: Seonju Oh Signed-off-by: Hyejin Kim Signed-off-by: Sungmin Choi --- include/telephony/ril.h | 22 +++++++++++++++++ libril/ril.cpp | 52 +++++++++++++++++++++++++++++++++++++++++ libril/ril_commands.h | 1 + 3 files changed, 75 insertions(+) diff --git a/include/telephony/ril.h b/include/telephony/ril.h index 68656fa..1da4d10 100644 --- a/include/telephony/ril.h +++ b/include/telephony/ril.h @@ -3482,6 +3482,20 @@ typedef struct { */ #define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110 +/** + * RIL_REQUEST_SET_INITIAL_ATTACH_APN + * + * Set an apn to initial attach network + * "response" is NULL + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE (radio resetting) + * GENERIC_FAILURE + * SUBSCRIPTION_NOT_AVAILABLE + */ +#define RIL_REQUEST_SET_INITIAL_ATTACH_APN 111 + /***********************************************************************/ @@ -4040,6 +4054,14 @@ typedef struct { RIL_GetVersion getVersion; } RIL_RadioFunctions; +typedef struct { + char *apn; + char *protocol; + int authtype; + char *username; + char *password; +} RIL_InitialAttachApn; + #ifdef RIL_SHLIB struct RIL_Env { /** diff --git a/libril/ril.cpp b/libril/ril.cpp index 5c7b243..f9dbced 100644 --- a/libril/ril.cpp +++ b/libril/ril.cpp @@ -204,6 +204,7 @@ static void dispatchRaw(Parcel& p, RequestInfo *pRI); static void dispatchSmsWrite (Parcel &p, RequestInfo *pRI); static void dispatchDataCall (Parcel& p, RequestInfo *pRI); static void dispatchVoiceRadioTech (Parcel& p, RequestInfo *pRI); +static void dispatchSetInitialAttachApn (Parcel& p, RequestInfo *pRI); static void dispatchCdmaSubscriptionSource (Parcel& p, RequestInfo *pRI); static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI); @@ -1305,6 +1306,56 @@ static void dispatchCdmaSubscriptionSource(Parcel& p, RequestInfo *pRI) { RIL_onRequestComplete(pRI, RIL_E_SUCCESS, &cdmaSubscriptionSource, sizeof(int)); } +static void dispatchSetInitialAttachApn(Parcel &p, RequestInfo *pRI) +{ + RIL_InitialAttachApn pf; + int32_t t; + status_t status; + + memset(&pf, 0, sizeof(pf)); + + pf.apn = strdupReadString(p); + pf.protocol = strdupReadString(p); + + status = p.readInt32(&t); + pf.authtype = (int) t; + + pf.username = strdupReadString(p); + pf.password = strdupReadString(p); + + startRequest; + appendPrintBuf("%sapn=%s, protocol=%s, auth_type=%d, username=%s, password=%s", + printBuf, pf.apn, pf.protocol, pf.auth_type, pf.username, pf.password); + closeRequest; + printRequest(pRI->token, pRI->pCI->requestNumber); + + if (status != NO_ERROR) { + goto invalid; + } + s_callbacks.onRequest(pRI->pCI->requestNumber, &pf, sizeof(pf), pRI); + +#ifdef MEMSET_FREED + memsetString(pf.apn); + memsetString(pf.protocol); + memsetString(pf.username); + memsetString(pf.password); +#endif + + free(pf.apn); + free(pf.protocol); + free(pf.username); + free(pf.password); + +#ifdef MEMSET_FREED + memset(&pf, 0, sizeof(pf)); +#endif + + return; +invalid: + invalidCommandBlock(pRI); + return; +} + static int blockingWrite(int fd, const void *buffer, size_t len) { size_t writeOffset = 0; @@ -3601,6 +3652,7 @@ requestToString(int request) { case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH"; case RIL_REQUEST_GET_CELL_INFO_LIST: return"GET_CELL_INFO_LIST"; case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"SET_UNSOL_CELL_INFO_LIST_RATE"; + case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "RIL_REQUEST_SET_INITIAL_ATTACH_APN"; case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED"; case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED"; case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED"; diff --git a/libril/ril_commands.h b/libril/ril_commands.h index 0519a2a..3e5a619 100644 --- a/libril/ril_commands.h +++ b/libril/ril_commands.h @@ -125,3 +125,4 @@ {RIL_REQUEST_VOICE_RADIO_TECH, dispatchVoiceRadioTech, responseInts}, {RIL_REQUEST_GET_CELL_INFO_LIST, dispatchVoid, responseCellInfoList}, {RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, dispatchInts, responseVoid}, + {RIL_REQUEST_SET_INITIAL_ATTACH_APN, dispatchSetInitialAttachApn, responseVoid}, From 622bf2bf79849127cbedd1f56631615bf58aaf78 Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Wed, 22 May 2013 11:29:34 -0700 Subject: [PATCH 04/11] ril: move record_stream_xxx to librilutils and export header Change-Id: I9986c8c5fb1777bbd2b686769ecc726319a73100 Signed-off-by: Dima Zavin --- {libril => include/telephony}/record_stream.h | 0 libril/Android.mk | 12 ++++++------ libril/ril.cpp | 2 +- librilutils/Android.mk | 6 ++++-- {libril => librilutils}/record_stream.c | 4 ++-- 5 files changed, 13 insertions(+), 11 deletions(-) rename {libril => include/telephony}/record_stream.h (100%) rename {libril => librilutils}/record_stream.c (98%) diff --git a/libril/record_stream.h b/include/telephony/record_stream.h similarity index 100% rename from libril/record_stream.h rename to include/telephony/record_stream.h diff --git a/libril/Android.mk b/libril/Android.mk index 7ccd37a..62aeb05 100644 --- a/libril/Android.mk +++ b/libril/Android.mk @@ -5,15 +5,15 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ ril.cpp \ - ril_event.cpp \ - record_stream.c + ril_event.cpp LOCAL_SHARED_LIBRARIES := \ liblog \ libutils \ libbinder \ libcutils \ - libhardware_legacy + libhardware_legacy \ + librilutils LOCAL_CFLAGS := @@ -30,12 +30,12 @@ ifneq ($(ANDROID_BIONIC_TRANSITION),) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ - ril.cpp \ - record_stream.c + ril.cpp LOCAL_STATIC_LIBRARIES := \ libutils_static \ - libcutils + libcutils \ + librilutils_static LOCAL_CFLAGS := diff --git a/libril/ril.cpp b/libril/ril.cpp index 5c7b243..7275903 100644 --- a/libril/ril.cpp +++ b/libril/ril.cpp @@ -23,7 +23,7 @@ #include #include #include -#include "record_stream.h" +#include #include #include #include diff --git a/librilutils/Android.mk b/librilutils/Android.mk index a959202..a50e374 100644 --- a/librilutils/Android.mk +++ b/librilutils/Android.mk @@ -4,7 +4,8 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ - librilutils.c + librilutils.c \ + record_stream.c LOCAL_CFLAGS := @@ -20,7 +21,8 @@ include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ - librilutils.c + librilutils.c \ + record_stream.c LOCAL_STATIC_LIBRARIES := diff --git a/libril/record_stream.c b/librilutils/record_stream.c similarity index 98% rename from libril/record_stream.c rename to librilutils/record_stream.c index 2add14d..558d179 100644 --- a/libril/record_stream.c +++ b/librilutils/record_stream.c @@ -1,4 +1,4 @@ -/* libs/cutils/record_stream.c +/* ** ** Copyright 2006, The Android Open Source Project ** @@ -19,7 +19,7 @@ #include #include #include -#include "record_stream.h" +#include #include #include #ifdef HAVE_WINSOCK From 8cc4c1d4bda512472143835813fd6f79c5474e43 Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Wed, 22 May 2013 11:30:17 -0700 Subject: [PATCH 05/11] HACK: rild: include librilutils as whole static lib To work around broken RILs that didn't link against librilutils, include it as a whole static library here. Change-Id: I7234c5b87b3e99814d67ef3c6900e9ccc679bf5c Signed-off-by: Dima Zavin --- rild/Android.mk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rild/Android.mk b/rild/Android.mk index f01b320..1f616b1 100644 --- a/rild/Android.mk +++ b/rild/Android.mk @@ -13,6 +13,10 @@ LOCAL_SHARED_LIBRARIES := \ libril \ libdl +# temporary hack for broken vendor rils +LOCAL_WHOLE_STATIC_LIBRARIES := \ + librilutils_static + LOCAL_CFLAGS := -DRIL_SHLIB LOCAL_MODULE:= rild From 0e09487471b09e45b5fc1b1588a600f35157079a Mon Sep 17 00:00:00 2001 From: Uma Maheswari Ramalingam Date: Wed, 28 Sep 2011 13:25:48 -0700 Subject: [PATCH 06/11] Support for LTE/WCDMA mode Add network mode LTE/WCDMA to preferred network type Operator mandated requirement Change-Id: I26454b69ce670a5fa2129c4cd75b68af80d210e1 --- include/telephony/ril.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/telephony/ril.h b/include/telephony/ril.h index 76db7ba..d26b8ed 100644 --- a/include/telephony/ril.h +++ b/include/telephony/ril.h @@ -119,7 +119,8 @@ typedef enum { PREF_NET_TYPE_LTE_CDMA_EVDO = 8, /* LTE, CDMA and EvDo */ PREF_NET_TYPE_LTE_GSM_WCDMA = 9, /* LTE, GSM/WCDMA */ PREF_NET_TYPE_LTE_CMDA_EVDO_GSM_WCDMA = 10, /* LTE, CDMA, EvDo, GSM/WCDMA */ - PREF_NET_TYPE_LTE_ONLY = 11 /* LTE only */ + PREF_NET_TYPE_LTE_ONLY = 11, /* LTE only */ + PREF_NET_TYPE_LTE_WCDMA = 12 /* LTE/WCDMA */ } RIL_PreferredNetworkType; /* Source for cdma subscription */ From 5802701949894c743dc95731091af94307c54bd0 Mon Sep 17 00:00:00 2001 From: Jun Tian Date: Tue, 30 Jul 2013 11:07:22 +0800 Subject: [PATCH 07/11] Fix libril.so crash issue caused by wrong switch logic of onRequest in reference-ril.c If the tech is not CDMA, it will fall-through to the default case. But the new added RIL_REQUEST_GET_CELL_INFO_LIST and RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE cases will intercept it and cause the request call into wrong request functions. Move these two new requests before the CDMA cases to fix the logic issue. Bug: 9193696 Change-Id: I2cb03cbdb6be8eb1afd92c01c764e87b6aa62796 Signed-off-by: Jun Tian Signed-off-by: Panfeng Chang Signed-off-by: Yanglin Zhu Signed-off-by: Jackie Wu --- reference-ril/reference-ril.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/reference-ril/reference-ril.c b/reference-ril/reference-ril.c index facd223..77c6f31 100644 --- a/reference-ril/reference-ril.c +++ b/reference-ril/reference-ril.c @@ -2185,6 +2185,14 @@ onRequest (int request, void *data, size_t datalen, RIL_Token t) requestGetPreferredNetworkType(request, data, datalen, t); break; + case RIL_REQUEST_GET_CELL_INFO_LIST: + requestGetCellInfoList(data, datalen, t); + break; + + case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: + requestSetCellInfoListRate(data, datalen, t); + break; + /* CDMA Specific Requests */ case RIL_REQUEST_BASEBAND_VERSION: if (TECH_BIT(sMdmInfo) == MDM_CDMA) { @@ -2234,14 +2242,6 @@ onRequest (int request, void *data, size_t datalen, RIL_Token t) break; } // Fall-through if tech is not cdma - case RIL_REQUEST_GET_CELL_INFO_LIST: - requestGetCellInfoList(data, datalen, t); - break; - - case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: - requestSetCellInfoListRate(data, datalen, t); - break; - default: RLOGD("Request not supported. Tech: %d",TECH(sMdmInfo)); RIL_onRequestComplete(t, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0); From 3d14a71de78f2b0d02c7943e554c8726b1703935 Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Mon, 5 Aug 2013 14:44:01 -0700 Subject: [PATCH 08/11] Restart, cleanup or retry inactve connections. Instead of retrying all inactive connections, restart radio on very bad errors, clean up those that are permanent failures and retry the others. Bug: 10131736 Change-Id: I2527b18d6cda52c55fb94be58fbb1a7a86818ef9 Signed-off-by: Wink Saville --- include/telephony/ril.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/telephony/ril.h b/include/telephony/ril.h index 68656fa..ac69b18 100644 --- a/include/telephony/ril.h +++ b/include/telephony/ril.h @@ -387,6 +387,7 @@ typedef enum { PDP_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED = 0x21, /* no retry */ PDP_FAIL_SERVICE_OPTION_OUT_OF_ORDER = 0x22, PDP_FAIL_NSAPI_IN_USE = 0x23, /* no retry */ + PDP_FAIL_REGULAR_DEACTIVATION = 0x24, /* restart radio */ PDP_FAIL_ONLY_IPV4_ALLOWED = 0x32, /* no retry */ PDP_FAIL_ONLY_IPV6_ALLOWED = 0x33, /* no retry */ PDP_FAIL_ONLY_SINGLE_BEARER_ALLOWED = 0x34, From 6c09776c813e63715195bfc529b4d1886a8b675f Mon Sep 17 00:00:00 2001 From: Rika Brooks Date: Tue, 15 Nov 2011 11:19:30 -0800 Subject: [PATCH 09/11] RIL: Support SMS on IMS, DO NOT MERGE RIL_REQUEST_IMS_REGISTRATION_STATE is used to aquire IMS registration state. RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED is called when IMS registration state has changed. RIL_REQUEST_IMS_SEND_SMS is used to send MO SMS over IMS. However, if retry field is set in case of failure, RIL_REQUEST_IMS_SEND_SMS sets messageRef from RIL_SMS_RESPONSE of corresponding failed MO SMS, and sets retry field to non-zero. If voice is available, sends RIL_REQUEST_IMS_SEND_SMS retries with data encoded based on voice tech available. Bug: 9626411 Change-Id: I87ca9841b4ace931c55e2d379fe6d7589b2dc8a5 --- include/telephony/ril.h | 85 +++++++++++++++++ libril/ril.cpp | 169 +++++++++++++++++++++++++++++++++- libril/ril_commands.h | 3 + libril/ril_unsol_commands.h | 2 + reference-ril/reference-ril.c | 115 ++++++++++++++++++++++- 5 files changed, 365 insertions(+), 9 deletions(-) diff --git a/include/telephony/ril.h b/include/telephony/ril.h index 68656fa..9586254 100644 --- a/include/telephony/ril.h +++ b/include/telephony/ril.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2006 The Android Open Source Project + * Copyright (c) 2012, The Linux Foundation. All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +20,7 @@ #include #include +#include #ifndef FEATURE_UNIT_TEST #include #endif /* !FEATURE_UNIT_TEST */ @@ -232,6 +234,28 @@ typedef struct { to point connections. */ } RIL_Data_Call_Response_v6; +typedef enum { + RADIO_TECH_3GPP = 1, /* 3GPP Technologies - GSM, WCDMA */ + RADIO_TECH_3GPP2 = 2 /* 3GPP2 Technologies - CDMA */ +} RIL_RadioTechnologyFamily; + +typedef struct { + RIL_RadioTechnologyFamily tech; + unsigned char retry; /* 0 == not retry, nonzero == retry */ + int messageRef; /* Valid field if retry is set to nonzero. + Contains messageRef from RIL_SMS_Response + corresponding to failed MO SMS. + */ + + union { + /* Valid field if format is FORMAT_3GPP2. See RIL_REQUEST_CDMA_SEND_SMS */ + RIL_CDMA_SMS_Message* cdmaMessage; + + /* Valid field if format is FORMAT_3GPP. See RIL_REQUEST_SEND_SMS */ + char** gsmMessage; + } message; +} RIL_IMS_SMS_Message; + typedef struct { int messageRef; /* TP-Message-Reference for GSM, and BearerData MessageId for CDMA @@ -3482,6 +3506,53 @@ typedef struct { */ #define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110 +/** + * RIL_REQUEST_IMS_REGISTRATION_STATE + * + * Request current IMS registration state + * + * "data" is NULL + * + * "response" is int * + * ((int *)response)[0] is registration state: + * 0 - Not registered + * 1 - Registered + * + * If ((int*)response)[0] is = 1, then ((int *) response)[1] + * must follow with IMS SMS format: + * + * ((int *) response)[1] is of type const RIL_IMS_SMS_Format + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * GENERIC_FAILURE + */ +#define RIL_REQUEST_IMS_REGISTRATION_STATE 111 + +/** + * RIL_REQUEST_IMS_SEND_SMS + * + * Send a SMS message over IMS + * + * "data" is const RIL_IMS_SMS_Message * + * + * "response" is a const RIL_SMS_Response * + * + * Based on the return error, caller decides to resend if sending sms + * fails. SMS_SEND_FAIL_RETRY means retry, and other errors means no retry. + * In case of retry, data is encoded based on Voice Technology available. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SMS_SEND_FAIL_RETRY + * FDN_CHECK_FAILURE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_IMS_SEND_SMS 112 + /***********************************************************************/ @@ -3972,6 +4043,20 @@ typedef struct { */ #define RIL_UNSOL_CELL_INFO_LIST 1036 +/** + * RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED + * + * Called when IMS registration state has changed + * + * Callee will invoke the following requests on main thread: + * + * RIL_REQUEST_IMS_REGISTRATION_STATE + * + * "data" is NULL + * + */ +#define RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED 1037 + /***********************************************************************/ diff --git a/libril/ril.cpp b/libril/ril.cpp index e1877a1..04ca858 100644 --- a/libril/ril.cpp +++ b/libril/ril.cpp @@ -1,6 +1,7 @@ /* //device/libs/telephony/ril.cpp ** ** Copyright 2006, The Android Open Source Project +** Copyright (c) 2012, The Linux Foundation. All rights reserved. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -207,6 +208,9 @@ static void dispatchVoiceRadioTech (Parcel& p, RequestInfo *pRI); static void dispatchCdmaSubscriptionSource (Parcel& p, RequestInfo *pRI); static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI); +static void dispatchImsSms(Parcel &p, RequestInfo *pRI); +static void dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef); +static void dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef); static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI); static void dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI); static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI); @@ -878,9 +882,8 @@ dispatchRaw(Parcel &p, RequestInfo *pRI) { return; } -static void -dispatchCdmaSms(Parcel &p, RequestInfo *pRI) { - RIL_CDMA_SMS_Message rcsm; +static status_t +constructCdmaSms(Parcel &p, RequestInfo *pRI, RIL_CDMA_SMS_Message& rcsm) { int32_t t; uint8_t ut; status_t status; @@ -944,7 +947,7 @@ dispatchCdmaSms(Parcel &p, RequestInfo *pRI) { } if (status != NO_ERROR) { - goto invalid; + return status; } startRequest; @@ -956,6 +959,18 @@ dispatchCdmaSms(Parcel &p, RequestInfo *pRI) { printRequest(pRI->token, pRI->pCI->requestNumber); + return status; +} + +static void +dispatchCdmaSms(Parcel &p, RequestInfo *pRI) { + RIL_CDMA_SMS_Message rcsm; + + ALOGD("dispatchCdmaSms"); + if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) { + goto invalid; + } + s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI); #ifdef MEMSET_FREED @@ -969,6 +984,149 @@ dispatchCdmaSms(Parcel &p, RequestInfo *pRI) { return; } +static void +dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) { + RIL_IMS_SMS_Message rism; + RIL_CDMA_SMS_Message rcsm; + + ALOGD("dispatchImsCdmaSms: retry=%d, messageRef=%d", retry, messageRef); + + if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) { + goto invalid; + } + memset(&rism, 0, sizeof(rism)); + rism.tech = RADIO_TECH_3GPP2; + rism.retry = retry; + rism.messageRef = messageRef; + rism.message.cdmaMessage = &rcsm; + + s_callbacks.onRequest(pRI->pCI->requestNumber, &rism, + sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t) + +sizeof(rcsm),pRI); + +#ifdef MEMSET_FREED + memset(&rcsm, 0, sizeof(rcsm)); + memset(&rism, 0, sizeof(rism)); +#endif + + return; + +invalid: + invalidCommandBlock(pRI); + return; +} + +static void +dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) { + RIL_IMS_SMS_Message rism; + int32_t countStrings; + status_t status; + size_t datalen; + char **pStrings; + ALOGD("dispatchImsGsmSms: retry=%d, messageRef=%d", retry, messageRef); + + status = p.readInt32 (&countStrings); + + if (status != NO_ERROR) { + goto invalid; + } + + memset(&rism, 0, sizeof(rism)); + rism.tech = RADIO_TECH_3GPP; + rism.retry = retry; + rism.messageRef = messageRef; + + startRequest; + appendPrintBuf("%sformat=%d,", printBuf, rism.tech); + if (countStrings == 0) { + // just some non-null pointer + pStrings = (char **)alloca(sizeof(char *)); + datalen = 0; + } else if (((int)countStrings) == -1) { + pStrings = NULL; + datalen = 0; + } else { + datalen = sizeof(char *) * countStrings; + + pStrings = (char **)alloca(datalen); + + for (int i = 0 ; i < countStrings ; i++) { + pStrings[i] = strdupReadString(p); + appendPrintBuf("%s%s,", printBuf, pStrings[i]); + } + } + removeLastChar; + closeRequest; + printRequest(pRI->token, pRI->pCI->requestNumber); + + rism.message.gsmMessage = pStrings; + s_callbacks.onRequest(pRI->pCI->requestNumber, &rism, + sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t) + +datalen, pRI); + + if (pStrings != NULL) { + for (int i = 0 ; i < countStrings ; i++) { +#ifdef MEMSET_FREED + memsetString (pStrings[i]); +#endif + free(pStrings[i]); + } + +#ifdef MEMSET_FREED + memset(pStrings, 0, datalen); +#endif + } + +#ifdef MEMSET_FREED + memset(&rism, 0, sizeof(rism)); +#endif + return; +invalid: + ALOGE("dispatchImsGsmSms invalid block"); + invalidCommandBlock(pRI); + return; +} + +static void +dispatchImsSms(Parcel &p, RequestInfo *pRI) { + int32_t t; + status_t status = p.readInt32(&t); + RIL_RadioTechnologyFamily format; + uint8_t retry; + int32_t messageRef; + + ALOGD("dispatchImsSms"); + if (status != NO_ERROR) { + goto invalid; + } + format = (RIL_RadioTechnologyFamily) t; + + // read retry field + status = p.read(&retry,sizeof(retry)); + if (status != NO_ERROR) { + goto invalid; + } + // read messageRef field + status = p.read(&messageRef,sizeof(messageRef)); + if (status != NO_ERROR) { + goto invalid; + } + + if (RADIO_TECH_3GPP == format) { + dispatchImsGsmSms(p, pRI, retry, messageRef); + } else if (RADIO_TECH_3GPP2 == format) { + dispatchImsCdmaSms(p, pRI, retry, messageRef); + } else { + ALOGE("requestImsSendSMS invalid format value =%d", format); + } + + return; + +invalid: + invalidCommandBlock(pRI); + return; +} + static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) { RIL_CDMA_SMS_Ack rcsa; @@ -3601,6 +3759,8 @@ requestToString(int request) { case RIL_REQUEST_VOICE_RADIO_TECH: return "VOICE_RADIO_TECH"; case RIL_REQUEST_GET_CELL_INFO_LIST: return"GET_CELL_INFO_LIST"; case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"SET_UNSOL_CELL_INFO_LIST_RATE"; + case RIL_REQUEST_IMS_REGISTRATION_STATE: return "IMS_REGISTRATION_STATE"; + case RIL_REQUEST_IMS_SEND_SMS: return "IMS_SEND_SMS"; case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED"; case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED"; case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED"; @@ -3637,6 +3797,7 @@ requestToString(int request) { case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED"; case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED"; case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST"; + case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "RESPONSE_IMS_NETWORK_STATE_CHANGED"; default: return ""; } } diff --git a/libril/ril_commands.h b/libril/ril_commands.h index 0519a2a..bc1c7f3 100644 --- a/libril/ril_commands.h +++ b/libril/ril_commands.h @@ -1,6 +1,7 @@ /* //device/libs/telephony/ril_commands.h ** ** Copyright 2006, The Android Open Source Project +** Copyright (c) 2012, The Linux Foundation. All rights reserved. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -125,3 +126,5 @@ {RIL_REQUEST_VOICE_RADIO_TECH, dispatchVoiceRadioTech, responseInts}, {RIL_REQUEST_GET_CELL_INFO_LIST, dispatchVoid, responseCellInfoList}, {RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, dispatchInts, responseVoid}, + {RIL_REQUEST_IMS_REGISTRATION_STATE, dispatchVoid, responseInts}, + {RIL_REQUEST_IMS_SEND_SMS, dispatchImsSms, responseSMS}, diff --git a/libril/ril_unsol_commands.h b/libril/ril_unsol_commands.h index 0711225..b491cf2 100644 --- a/libril/ril_unsol_commands.h +++ b/libril/ril_unsol_commands.h @@ -1,6 +1,7 @@ /* //device/libs/telephony/ril_unsol_commands.h ** ** Copyright 2006, The Android Open Source Project +** Copyright (c) 2012, The Linux Foundation. All rights reserved. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -51,3 +52,4 @@ {RIL_UNSOL_RIL_CONNECTED, responseInts, WAKE_PARTIAL}, {RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, responseInts, WAKE_PARTIAL}, {RIL_UNSOL_CELL_INFO_LIST, responseCellInfoList, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED, responseVoid, WAKE_PARTIAL}, diff --git a/reference-ril/reference-ril.c b/reference-ril/reference-ril.c index 77c6f31..7253eb0 100644 --- a/reference-ril/reference-ril.c +++ b/reference-ril/reference-ril.c @@ -1,6 +1,7 @@ /* //device/system/reference-ril/reference-ril.c ** ** Copyright 2006, The Android Open Source Project +** Copyright (c) 2012, The Linux Foundation. All rights reserved. ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. @@ -211,6 +212,14 @@ static const struct timeval TIMEVAL_SIMPOLL = {1,0}; static const struct timeval TIMEVAL_CALLSTATEPOLL = {0,500000}; static const struct timeval TIMEVAL_0 = {0,0}; +static int s_ims_registered = 0; // 0==unregistered +static int s_ims_services = 1; // & 0x1 == sms over ims supported +static int s_ims_format = 1; // FORMAT_3GPP(1) vs FORMAT_3GPP2(2); +static int s_ims_cause_retry = 0; // 1==causes sms over ims to temp fail +static int s_ims_cause_perm_failure = 0; // 1==causes sms over ims to permanent fail +static int s_ims_gsm_retry = 0; // 1==causes sms over gsm to temp fail +static int s_ims_gsm_fail = 0; // 1==causes sms over gsm to permanent fail + #ifdef WORKAROUND_ERRONEOUS_ANSWER // Max number of times we'll try to repoll when we think // we have a AT+CLCC race condition @@ -1499,12 +1508,14 @@ static void requestCdmaSendSMS(void *data, size_t datalen, RIL_Token t) // But it is not implemented yet. memset(&response, 0, sizeof(response)); + response.messageRef = 1; RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); return; error: // Cdma Send SMS will always cause send retry error. - RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, NULL, 0); + response.messageRef = -1; + RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response)); } static void requestSendSMS(void *data, size_t datalen, RIL_Token t) @@ -1517,6 +1528,12 @@ static void requestSendSMS(void *data, size_t datalen, RIL_Token t) RIL_SMS_Response response; ATResponse *p_response = NULL; + memset(&response, 0, sizeof(response)); + ALOGD("requestSendSMS datalen =%d", datalen); + + if (s_ims_gsm_fail != 0) goto error; + if (s_ims_gsm_retry != 0) goto error2; + smsc = ((const char **)data)[0]; pdu = ((const char **)data)[1]; @@ -1534,17 +1551,68 @@ static void requestSendSMS(void *data, size_t datalen, RIL_Token t) if (err != 0 || p_response->success == 0) goto error; - memset(&response, 0, sizeof(response)); - /* FIXME fill in messageRef and ackPDU */ - + response.messageRef = 1; RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); at_response_free(p_response); return; error: - RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); + response.messageRef = -2; + RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response)); + at_response_free(p_response); + return; +error2: + // send retry error. + response.messageRef = -1; + RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response)); at_response_free(p_response); + return; +} + +static void requestImsSendSMS(void *data, size_t datalen, RIL_Token t) +{ + RIL_IMS_SMS_Message *p_args; + RIL_SMS_Response response; + + memset(&response, 0, sizeof(response)); + + ALOGD("requestImsSendSMS: datalen=%d, " + "registered=%d, service=%d, format=%d, ims_perm_fail=%d, " + "ims_retry=%d, gsm_fail=%d, gsm_retry=%d", + datalen, s_ims_registered, s_ims_services, s_ims_format, + s_ims_cause_perm_failure, s_ims_cause_retry, s_ims_gsm_fail, + s_ims_gsm_retry); + + // figure out if this is gsm/cdma format + // then route it to requestSendSMS vs requestCdmaSendSMS respectively + p_args = (RIL_IMS_SMS_Message *)data; + + if (0 != s_ims_cause_perm_failure ) goto error; + + // want to fail over ims and this is first request over ims + if (0 != s_ims_cause_retry && 0 == p_args->retry) goto error2; + + if (RADIO_TECH_3GPP == p_args->tech) { + return requestSendSMS(p_args->message.gsmMessage, + datalen - sizeof(RIL_RadioTechnologyFamily), + t); + } else if (RADIO_TECH_3GPP2 == p_args->tech) { + return requestCdmaSendSMS(p_args->message.cdmaMessage, + datalen - sizeof(RIL_RadioTechnologyFamily), + t); + } else { + ALOGE("requestImsSendSMS invalid format value =%d", p_args->tech); + } + +error: + response.messageRef = -2; + RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response)); + return; + +error2: + response.messageRef = -1; + RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response)); } static void requestSetupDataCall(void *data, size_t datalen, RIL_Token t) @@ -2051,6 +2119,9 @@ onRequest (int request, void *data, size_t datalen, RIL_Token t) case RIL_REQUEST_CDMA_SEND_SMS: requestCdmaSendSMS(data, datalen, t); break; + case RIL_REQUEST_IMS_SEND_SMS: + requestImsSendSMS(data, datalen, t); + break; case RIL_REQUEST_SETUP_DATA_CALL: requestSetupDataCall(data, datalen, t); break; @@ -2168,6 +2239,28 @@ onRequest (int request, void *data, size_t datalen, RIL_Token t) requestEnterSimPin(data, datalen, t); break; + case RIL_REQUEST_IMS_REGISTRATION_STATE: + { + int reply[2]; + //0==unregistered, 1==registered + reply[0] = s_ims_registered; + + //to be used when changed to include service supporated info + //reply[1] = s_ims_services; + + // FORMAT_3GPP(1) vs FORMAT_3GPP2(2); + reply[1] = s_ims_format; + + ALOGD("IMS_REGISTRATION=%d, format=%d ", + reply[0], reply[1]); + if (reply[1] != -1) { + RIL_onRequestComplete(t, RIL_E_SUCCESS, reply, sizeof(reply)); + } else { + RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); + } + break; + } + case RIL_REQUEST_VOICE_RADIO_TECH: { int tech = techFromModemType(TECH(sMdmInfo)); @@ -2927,6 +3020,18 @@ static void waitForClose() pthread_mutex_unlock(&s_state_mutex); } +static void sendUnsolImsNetworkStateChanged() +{ +#if 0 // to be used when unsol is changed to return data. + int reply[2]; + reply[0] = s_ims_registered; + reply[1] = s_ims_services; + reply[1] = s_ims_format; +#endif + RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED, + NULL, 0); +} + /** * Called by atchannel when an unsolicited line appears * This is called on atchannel's reader thread. AT commands may From 3492c6e5917828645feb3dba4618629929a43ab1 Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Thu, 3 Oct 2013 13:53:27 -0700 Subject: [PATCH 10/11] Change PDP_FAIL_SIGNAL_LOST to be retryable. We've changed this in the framework: https://googleplex-android-review.git.corp.google.com/#/c/366996/ So this updates ril.h to match. Bug: 10954174, 10804691 Change-Id: I820d44e74251fd4fc375551474341572e9020aee --- include/telephony/ril.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/telephony/ril.h b/include/telephony/ril.h index 2957441..766d5da 100644 --- a/include/telephony/ril.h +++ b/include/telephony/ril.h @@ -399,7 +399,7 @@ typedef enum { PDP_FAIL_DATA_REGISTRATION_FAIL = -2, /* reasons for data call drop - network/modem disconnect */ - PDP_FAIL_SIGNAL_LOST = -3, /* no retry */ + PDP_FAIL_SIGNAL_LOST = -3, PDP_FAIL_PREF_RADIO_TECH_CHANGED = -4,/* preferred technology has changed, should retry with parameters appropriate for new technology */ PDP_FAIL_RADIO_POWER_OFF = -5, /* data call was disconnected because radio was resetting, From a18b9d1e1a014290691d63a7f335085dadc83e46 Mon Sep 17 00:00:00 2001 From: Sukanya Rajkhowa Date: Tue, 10 Sep 2013 12:30:13 -0700 Subject: [PATCH 11/11] RIL: Support SMS over IMS RIL_REQUEST_IMS_REGISTRATION_STATE is used to aquire IMS registration state. RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED is called when IMS registration state has changed. RIL_REQUEST_IMS_SEND_SMS is used to send MO SMS over IMS. However, if retry field is set in case of failure, RIL_REQUEST_IMS_SEND_SMS sets messageRef from RIL_SMS_RESPONSE of corresponding failed MO SMS, and sets retry field to non-zero. If voice is available, sends RIL_REQUEST_IMS_SEND_SMS retries with data encoded based on voice tech available. Bug: 9626411 Change-Id: If0ecc9fa47661f6560171e472f3c464713e97968 --- include/telephony/ril.h | 88 +++++++++++++++++- libril/ril.cpp | 168 +++++++++++++++++++++++++++++++++- libril/ril_commands.h | 2 + libril/ril_unsol_commands.h | 1 + reference-ril/reference-ril.c | 113 ++++++++++++++++++++++- 5 files changed, 362 insertions(+), 10 deletions(-) diff --git a/include/telephony/ril.h b/include/telephony/ril.h index 766d5da..803d965 100644 --- a/include/telephony/ril.h +++ b/include/telephony/ril.h @@ -19,6 +19,7 @@ #include #include +#include #ifndef FEATURE_UNIT_TEST #include #endif /* !FEATURE_UNIT_TEST */ @@ -27,7 +28,7 @@ extern "C" { #endif -#define RIL_VERSION 8 /* Current version */ +#define RIL_VERSION 9 /* Current version */ #define RIL_VERSION_MIN 6 /* Minimum RIL_VERSION supported */ #define CDMA_ALPHA_INFO_BUFFER_LENGTH 64 @@ -233,6 +234,28 @@ typedef struct { to point connections. */ } RIL_Data_Call_Response_v6; +typedef enum { + RADIO_TECH_3GPP = 1, /* 3GPP Technologies - GSM, WCDMA */ + RADIO_TECH_3GPP2 = 2 /* 3GPP2 Technologies - CDMA */ +} RIL_RadioTechnologyFamily; + +typedef struct { + RIL_RadioTechnologyFamily tech; + unsigned char retry; /* 0 == not retry, nonzero == retry */ + int messageRef; /* Valid field if retry is set to nonzero. + Contains messageRef from RIL_SMS_Response + corresponding to failed MO SMS. + */ + + union { + /* Valid field if tech is RADIO_TECH_3GPP2. See RIL_REQUEST_CDMA_SEND_SMS */ + RIL_CDMA_SMS_Message* cdmaMessage; + + /* Valid field if tech is RADIO_TECH_3GPP. See RIL_REQUEST_SEND_SMS */ + char** gsmMessage; + } message; +} RIL_IMS_SMS_Message; + typedef struct { int messageRef; /* TP-Message-Reference for GSM, and BearerData MessageId for CDMA @@ -3498,6 +3521,50 @@ typedef struct { */ #define RIL_REQUEST_SET_INITIAL_ATTACH_APN 111 +/** + * RIL_REQUEST_IMS_REGISTRATION_STATE + * + * Request current IMS registration state + * + * "data" is NULL + * + * "response" is int * + * ((int *)response)[0] is registration state: + * 0 - Not registered + * 1 - Registered + * ((int *)response)[1] is bitmap of the supported services: + * & 0x1 - SMS supported + * + * If IMS is registered and supports SMS, then ((int *) response)[2] + * must follow with IMS SMS format: + * + * ((int *) response)[2] is of type const RIL_IMS_SMS_Format + */ +#define RIL_REQUEST_IMS_REGISTRATION_STATE 112 + +/** + * RIL_REQUEST_IMS_SEND_SMS + * + * Send a SMS message over IMS + * + * "data" is const RIL_IMS_SMS_Message * + * + * "response" is a const RIL_SMS_Response * + * + * Based on the return error, caller decides to resend if sending sms + * fails. SMS_SEND_FAIL_RETRY means retry, and other errors means no retry. + * In case of retry, data is encoded based on Voice Technology available. + * + * Valid errors: + * SUCCESS + * RADIO_NOT_AVAILABLE + * SMS_SEND_FAIL_RETRY + * FDN_CHECK_FAILURE + * GENERIC_FAILURE + * + */ +#define RIL_REQUEST_IMS_SEND_SMS 113 + /***********************************************************************/ @@ -3988,6 +4055,25 @@ typedef struct { */ #define RIL_UNSOL_CELL_INFO_LIST 1036 +/* + * RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED + * + * Called when IMS registration state has changed + * + * "data" is int * + * ((int *)response)[0] is registration state: + * 0 - Not registered + * 1 - Registered + * ((int *)response)[1] is bitmap of the services supported: + * & 0x1 - SMS supported + * + * If IMS is registered and supports SMS, then ((int *) response)[2] + * must follow with IMS SMS format: + * + * ((int *) response)[2] is of type const RIL_IMS_SMS_Format + */ +#define RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED 1037 + /***********************************************************************/ diff --git a/libril/ril.cpp b/libril/ril.cpp index 46a150f..1957939 100644 --- a/libril/ril.cpp +++ b/libril/ril.cpp @@ -208,6 +208,9 @@ static void dispatchSetInitialAttachApn (Parcel& p, RequestInfo *pRI); static void dispatchCdmaSubscriptionSource (Parcel& p, RequestInfo *pRI); static void dispatchCdmaSms(Parcel &p, RequestInfo *pRI); +static void dispatchImsSms(Parcel &p, RequestInfo *pRI); +static void dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef); +static void dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef); static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI); static void dispatchGsmBrSmsCnf(Parcel &p, RequestInfo *pRI); static void dispatchCdmaBrSmsCnf(Parcel &p, RequestInfo *pRI); @@ -879,9 +882,8 @@ dispatchRaw(Parcel &p, RequestInfo *pRI) { return; } -static void -dispatchCdmaSms(Parcel &p, RequestInfo *pRI) { - RIL_CDMA_SMS_Message rcsm; +static status_t +constructCdmaSms(Parcel &p, RequestInfo *pRI, RIL_CDMA_SMS_Message& rcsm) { int32_t t; uint8_t ut; status_t status; @@ -945,7 +947,7 @@ dispatchCdmaSms(Parcel &p, RequestInfo *pRI) { } if (status != NO_ERROR) { - goto invalid; + return status; } startRequest; @@ -957,6 +959,18 @@ dispatchCdmaSms(Parcel &p, RequestInfo *pRI) { printRequest(pRI->token, pRI->pCI->requestNumber); + return status; +} + +static void +dispatchCdmaSms(Parcel &p, RequestInfo *pRI) { + RIL_CDMA_SMS_Message rcsm; + + ALOGD("dispatchCdmaSms"); + if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) { + goto invalid; + } + s_callbacks.onRequest(pRI->pCI->requestNumber, &rcsm, sizeof(rcsm),pRI); #ifdef MEMSET_FREED @@ -970,6 +984,149 @@ dispatchCdmaSms(Parcel &p, RequestInfo *pRI) { return; } +static void +dispatchImsCdmaSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) { + RIL_IMS_SMS_Message rism; + RIL_CDMA_SMS_Message rcsm; + + ALOGD("dispatchImsCdmaSms: retry=%d, messageRef=%d", retry, messageRef); + + if (NO_ERROR != constructCdmaSms(p, pRI, rcsm)) { + goto invalid; + } + memset(&rism, 0, sizeof(rism)); + rism.tech = RADIO_TECH_3GPP2; + rism.retry = retry; + rism.messageRef = messageRef; + rism.message.cdmaMessage = &rcsm; + + s_callbacks.onRequest(pRI->pCI->requestNumber, &rism, + sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t) + +sizeof(rcsm),pRI); + +#ifdef MEMSET_FREED + memset(&rcsm, 0, sizeof(rcsm)); + memset(&rism, 0, sizeof(rism)); +#endif + + return; + +invalid: + invalidCommandBlock(pRI); + return; +} + +static void +dispatchImsGsmSms(Parcel &p, RequestInfo *pRI, uint8_t retry, int32_t messageRef) { + RIL_IMS_SMS_Message rism; + int32_t countStrings; + status_t status; + size_t datalen; + char **pStrings; + ALOGD("dispatchImsGsmSms: retry=%d, messageRef=%d", retry, messageRef); + + status = p.readInt32 (&countStrings); + + if (status != NO_ERROR) { + goto invalid; + } + + memset(&rism, 0, sizeof(rism)); + rism.tech = RADIO_TECH_3GPP; + rism.retry = retry; + rism.messageRef = messageRef; + + startRequest; + appendPrintBuf("%sformat=%d,", printBuf, rism.format); + if (countStrings == 0) { + // just some non-null pointer + pStrings = (char **)alloca(sizeof(char *)); + datalen = 0; + } else if (((int)countStrings) == -1) { + pStrings = NULL; + datalen = 0; + } else { + datalen = sizeof(char *) * countStrings; + + pStrings = (char **)alloca(datalen); + + for (int i = 0 ; i < countStrings ; i++) { + pStrings[i] = strdupReadString(p); + appendPrintBuf("%s%s,", printBuf, pStrings[i]); + } + } + removeLastChar; + closeRequest; + printRequest(pRI->token, pRI->pCI->requestNumber); + + rism.message.gsmMessage = pStrings; + s_callbacks.onRequest(pRI->pCI->requestNumber, &rism, + sizeof(RIL_RadioTechnologyFamily)+sizeof(uint8_t)+sizeof(int32_t) + +datalen, pRI); + + if (pStrings != NULL) { + for (int i = 0 ; i < countStrings ; i++) { +#ifdef MEMSET_FREED + memsetString (pStrings[i]); +#endif + free(pStrings[i]); + } + +#ifdef MEMSET_FREED + memset(pStrings, 0, datalen); +#endif + } + +#ifdef MEMSET_FREED + memset(&rism, 0, sizeof(rism)); +#endif + return; +invalid: + ALOGE("dispatchImsGsmSms invalid block"); + invalidCommandBlock(pRI); + return; +} + +static void +dispatchImsSms(Parcel &p, RequestInfo *pRI) { + int32_t t; + status_t status = p.readInt32(&t); + RIL_RadioTechnologyFamily format; + uint8_t retry; + int32_t messageRef; + + ALOGD("dispatchImsSms"); + if (status != NO_ERROR) { + goto invalid; + } + format = (RIL_RadioTechnologyFamily) t; + + // read retry field + status = p.read(&retry,sizeof(retry)); + if (status != NO_ERROR) { + goto invalid; + } + // read messageRef field + status = p.read(&messageRef,sizeof(messageRef)); + if (status != NO_ERROR) { + goto invalid; + } + + if (RADIO_TECH_3GPP == format) { + dispatchImsGsmSms(p, pRI, retry, messageRef); + } else if (RADIO_TECH_3GPP2 == format) { + dispatchImsCdmaSms(p, pRI, retry, messageRef); + } else { + ALOGE("requestImsSendSMS invalid format value =%d", format); + } + + return; + +invalid: + invalidCommandBlock(pRI); + return; +} + static void dispatchCdmaSmsAck(Parcel &p, RequestInfo *pRI) { RIL_CDMA_SMS_Ack rcsa; @@ -3653,6 +3810,8 @@ requestToString(int request) { case RIL_REQUEST_GET_CELL_INFO_LIST: return"GET_CELL_INFO_LIST"; case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE: return"SET_UNSOL_CELL_INFO_LIST_RATE"; case RIL_REQUEST_SET_INITIAL_ATTACH_APN: return "RIL_REQUEST_SET_INITIAL_ATTACH_APN"; + case RIL_REQUEST_IMS_REGISTRATION_STATE: return "IMS_REGISTRATION_STATE"; + case RIL_REQUEST_IMS_SEND_SMS: return "IMS_SEND_SMS"; case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED: return "UNSOL_RESPONSE_RADIO_STATE_CHANGED"; case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED: return "UNSOL_RESPONSE_CALL_STATE_CHANGED"; case RIL_UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED: return "UNSOL_RESPONSE_VOICE_NETWORK_STATE_CHANGED"; @@ -3689,6 +3848,7 @@ requestToString(int request) { case RIL_UNSOL_RIL_CONNECTED: return "UNSOL_RIL_CONNECTED"; case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED: return "UNSOL_VOICE_RADIO_TECH_CHANGED"; case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST"; + case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "RESPONSE_IMS_NETWORK_STATE_CHANGED"; default: return ""; } } diff --git a/libril/ril_commands.h b/libril/ril_commands.h index 3e5a619..16daa72 100644 --- a/libril/ril_commands.h +++ b/libril/ril_commands.h @@ -126,3 +126,5 @@ {RIL_REQUEST_GET_CELL_INFO_LIST, dispatchVoid, responseCellInfoList}, {RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, dispatchInts, responseVoid}, {RIL_REQUEST_SET_INITIAL_ATTACH_APN, dispatchSetInitialAttachApn, responseVoid}, + {RIL_REQUEST_IMS_REGISTRATION_STATE, dispatchVoid, responseInts}, + {RIL_REQUEST_IMS_SEND_SMS, dispatchImsSms, responseSMS}, diff --git a/libril/ril_unsol_commands.h b/libril/ril_unsol_commands.h index 0711225..b6d532f 100644 --- a/libril/ril_unsol_commands.h +++ b/libril/ril_unsol_commands.h @@ -51,3 +51,4 @@ {RIL_UNSOL_RIL_CONNECTED, responseInts, WAKE_PARTIAL}, {RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, responseInts, WAKE_PARTIAL}, {RIL_UNSOL_CELL_INFO_LIST, responseCellInfoList, WAKE_PARTIAL}, + {RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED, responseVoid, WAKE_PARTIAL}, diff --git a/reference-ril/reference-ril.c b/reference-ril/reference-ril.c index 77c6f31..1b7a7bc 100644 --- a/reference-ril/reference-ril.c +++ b/reference-ril/reference-ril.c @@ -211,6 +211,14 @@ static const struct timeval TIMEVAL_SIMPOLL = {1,0}; static const struct timeval TIMEVAL_CALLSTATEPOLL = {0,500000}; static const struct timeval TIMEVAL_0 = {0,0}; +static int s_ims_registered = 0; // 0==unregistered +static int s_ims_services = 1; // & 0x1 == sms over ims supported +static int s_ims_format = 1; // FORMAT_3GPP(1) vs FORMAT_3GPP2(2); +static int s_ims_cause_retry = 0; // 1==causes sms over ims to temp fail +static int s_ims_cause_perm_failure = 0; // 1==causes sms over ims to permanent fail +static int s_ims_gsm_retry = 0; // 1==causes sms over gsm to temp fail +static int s_ims_gsm_fail = 0; // 1==causes sms over gsm to permanent fail + #ifdef WORKAROUND_ERRONEOUS_ANSWER // Max number of times we'll try to repoll when we think // we have a AT+CLCC race condition @@ -1499,12 +1507,14 @@ static void requestCdmaSendSMS(void *data, size_t datalen, RIL_Token t) // But it is not implemented yet. memset(&response, 0, sizeof(response)); + response.messageRef = 1; RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); return; error: // Cdma Send SMS will always cause send retry error. - RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, NULL, 0); + response.messageRef = -1; + RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response)); } static void requestSendSMS(void *data, size_t datalen, RIL_Token t) @@ -1517,6 +1527,12 @@ static void requestSendSMS(void *data, size_t datalen, RIL_Token t) RIL_SMS_Response response; ATResponse *p_response = NULL; + memset(&response, 0, sizeof(response)); + RLOGD("requestSendSMS datalen =%d", datalen); + + if (s_ims_gsm_fail != 0) goto error; + if (s_ims_gsm_retry != 0) goto error2; + smsc = ((const char **)data)[0]; pdu = ((const char **)data)[1]; @@ -1534,17 +1550,68 @@ static void requestSendSMS(void *data, size_t datalen, RIL_Token t) if (err != 0 || p_response->success == 0) goto error; - memset(&response, 0, sizeof(response)); - /* FIXME fill in messageRef and ackPDU */ - + response.messageRef = 1; RIL_onRequestComplete(t, RIL_E_SUCCESS, &response, sizeof(response)); at_response_free(p_response); return; error: - RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); + response.messageRef = -2; + RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response)); + at_response_free(p_response); + return; +error2: + // send retry error. + response.messageRef = -1; + RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response)); at_response_free(p_response); + return; + } + +static void requestImsSendSMS(void *data, size_t datalen, RIL_Token t) +{ + RIL_IMS_SMS_Message *p_args; + RIL_SMS_Response response; + + memset(&response, 0, sizeof(response)); + + RLOGD("requestImsSendSMS: datalen=%d, " + "registered=%d, service=%d, format=%d, ims_perm_fail=%d, " + "ims_retry=%d, gsm_fail=%d, gsm_retry=%d", + datalen, s_ims_registered, s_ims_services, s_ims_format, + s_ims_cause_perm_failure, s_ims_cause_retry, s_ims_gsm_fail, + s_ims_gsm_retry); + + // figure out if this is gsm/cdma format + // then route it to requestSendSMS vs requestCdmaSendSMS respectively + p_args = (RIL_IMS_SMS_Message *)data; + + if (0 != s_ims_cause_perm_failure ) goto error; + + // want to fail over ims and this is first request over ims + if (0 != s_ims_cause_retry && 0 == p_args->retry) goto error2; + + if (RADIO_TECH_3GPP == p_args->tech) { + return requestSendSMS(p_args->message.gsmMessage, + datalen - sizeof(RIL_RadioTechnologyFamily), + t); + } else if (RADIO_TECH_3GPP2 == p_args->tech) { + return requestCdmaSendSMS(p_args->message.cdmaMessage, + datalen - sizeof(RIL_RadioTechnologyFamily), + t); + } else { + RLOGE("requestImsSendSMS invalid format value =%d", p_args->tech); + } + +error: + response.messageRef = -2; + RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response)); + return; + +error2: + response.messageRef = -1; + RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response)); } static void requestSetupDataCall(void *data, size_t datalen, RIL_Token t) @@ -2051,6 +2118,9 @@ onRequest (int request, void *data, size_t datalen, RIL_Token t) case RIL_REQUEST_CDMA_SEND_SMS: requestCdmaSendSMS(data, datalen, t); break; + case RIL_REQUEST_IMS_SEND_SMS: + requestImsSendSMS(data, datalen, t); + break; case RIL_REQUEST_SETUP_DATA_CALL: requestSetupDataCall(data, datalen, t); break; @@ -2168,6 +2238,27 @@ onRequest (int request, void *data, size_t datalen, RIL_Token t) requestEnterSimPin(data, datalen, t); break; + case RIL_REQUEST_IMS_REGISTRATION_STATE: { + int reply[2]; + //0==unregistered, 1==registered + reply[0] = s_ims_registered; + + //to be used when changed to include service supporated info + //reply[1] = s_ims_services; + + // FORMAT_3GPP(1) vs FORMAT_3GPP2(2); + reply[1] = s_ims_format; + + RLOGD("IMS_REGISTRATION=%d, format=%d ", + reply[0], reply[1]); + if (reply[1] != -1) { + RIL_onRequestComplete(t, RIL_E_SUCCESS, reply, sizeof(reply)); + } else { + RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0); + } + break; + } + case RIL_REQUEST_VOICE_RADIO_TECH: { int tech = techFromModemType(TECH(sMdmInfo)); @@ -2927,6 +3018,18 @@ static void waitForClose() pthread_mutex_unlock(&s_state_mutex); } +static void sendUnsolImsNetworkStateChanged() +{ +#if 0 // to be used when unsol is changed to return data. + int reply[2]; + reply[0] = s_ims_registered; + reply[1] = s_ims_services; + reply[1] = s_ims_format; +#endif + RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED, + NULL, 0); +} + /** * Called by atchannel when an unsolicited line appears * This is called on atchannel's reader thread. AT commands may