summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRicardo Cerqueira <cyanogenmod@cerqueira.org>2013-11-01 19:20:03 +0000
committerRicardo Cerqueira <cyanogenmod@cerqueira.org>2013-11-01 19:20:03 +0000
commit40e57d7ce7118f18c577ed25a1aa8e44f50ab210 (patch)
tree5aa851663c0abb481235a228bd8538ce9d0716ff
parentcb688f23ea70780abe6a428bf7cba0060d99ebf9 (diff)
parenta18b9d1e1a014290691d63a7f335085dadc83e46 (diff)
downloadandroid_hardware_ril-40e57d7ce7118f18c577ed25a1aa8e44f50ab210.tar.gz
android_hardware_ril-40e57d7ce7118f18c577ed25a1aa8e44f50ab210.tar.bz2
android_hardware_ril-40e57d7ce7118f18c577ed25a1aa8e44f50ab210.zip
Merge tag 'android-4.4_r1' into cm-11.0
Android 4.4 Release 1.0 Conflicts: include/telephony/ril.h libril/ril.cpp libril/ril_commands.h libril/ril_unsol_commands.h
-rw-r--r--include/telephony/record_stream.h43
-rw-r--r--include/telephony/ril.h115
-rw-r--r--libril/Android.mk6
-rw-r--r--libril/ril.cpp222
-rw-r--r--libril/ril_commands.h3
-rw-r--r--libril/ril_unsol_commands.h1
-rw-r--r--librilutils/Android.mk6
-rw-r--r--librilutils/record_stream.c186
-rw-r--r--reference-ril/reference-ril.c113
-rw-r--r--rild/Android.mk4
10 files changed, 682 insertions, 17 deletions
diff --git a/include/telephony/record_stream.h b/include/telephony/record_stream.h
new file mode 100644
index 0000000..7a89ae4
--- /dev/null
+++ b/include/telephony/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/include/telephony/ril.h b/include/telephony/ril.h
index 5b54efe..c9f9ff6 100644
--- a/include/telephony/ril.h
+++ b/include/telephony/ril.h
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <stdint.h>
+#include <telephony/ril_cdma_sms.h>
#ifndef FEATURE_UNIT_TEST
#include <sys/time.h>
#endif /* !FEATURE_UNIT_TEST */
@@ -27,7 +28,7 @@
extern "C" {
#endif
-#define RIL_VERSION 8 /* Current version */
+#define RIL_VERSION 9 /* Current version */
#ifdef LEGACY_RIL
#define RIL_VERSION_MIN 2 /* Minimum RIL_VERSION supported */
#else
@@ -125,7 +126,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 */
@@ -239,6 +241,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
@@ -405,7 +429,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,
@@ -3490,6 +3514,64 @@ 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
+
+/**
+ * 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
+
/***********************************************************************/
@@ -3980,6 +4062,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
+
/***********************************************************************/
@@ -4048,6 +4149,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/Android.mk b/libril/Android.mk
index 7c568c3..0e8dfb5 100644
--- a/libril/Android.mk
+++ b/libril/Android.mk
@@ -14,7 +14,8 @@ LOCAL_SHARED_LIBRARIES := \
libutils \
libbinder \
libcutils \
- libhardware_legacy
+ libhardware_legacy \
+ librilutils
LOCAL_CFLAGS :=
ifdef BOARD_USE_NEW_LIBRIL_HTC
@@ -51,7 +52,8 @@ LOCAL_SRC_FILES:= \
LOCAL_STATIC_LIBRARIES := \
libutils_static \
- libcutils
+ libcutils \
+ librilutils_static
LOCAL_CFLAGS :=
diff --git a/libril/ril.cpp b/libril/ril.cpp
index e398cf6..2b4292e 100644
--- a/libril/ril.cpp
+++ b/libril/ril.cpp
@@ -23,7 +23,7 @@
#include <telephony/ril_cdma_sms.h>
#include <cutils/sockets.h>
#include <cutils/jstring.h>
-#include <cutils/record_stream.h>
+#include <telephony/record_stream.h>
#include <utils/Log.h>
#include <utils/SystemClock.h>
#include <pthread.h>
@@ -204,9 +204,13 @@ 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);
+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);
@@ -880,9 +884,8 @@ invalid:
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;
@@ -946,7 +949,7 @@ dispatchCdmaSms(Parcel &p, RequestInfo *pRI) {
}
if (status != NO_ERROR) {
- goto invalid;
+ return status;
}
startRequest;
@@ -958,6 +961,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
@@ -972,6 +987,149 @@ invalid:
}
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;
int32_t t;
@@ -1307,6 +1465,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;
@@ -3635,6 +3843,9 @@ 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";
#endif
+ 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";
@@ -3673,6 +3884,7 @@ requestToString(int request) {
#ifndef RIL_NO_CELL_INFO_LIST
case RIL_UNSOL_CELL_INFO_LIST: return "UNSOL_CELL_INFO_LIST";
#endif
+ case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED: return "RESPONSE_IMS_NETWORK_STATE_CHANGED";
default: return "<unknown request>";
}
}
diff --git a/libril/ril_commands.h b/libril/ril_commands.h
index ccf3efb..4d026c3 100644
--- a/libril/ril_commands.h
+++ b/libril/ril_commands.h
@@ -127,3 +127,6 @@
{RIL_REQUEST_GET_CELL_INFO_LIST, dispatchVoid, responseCellInfoList},
{RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, dispatchInts, responseVoid},
#endif
+ {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 55dac19..ad6411e 100644
--- a/libril/ril_unsol_commands.h
+++ b/libril/ril_unsol_commands.h
@@ -53,3 +53,4 @@
#ifndef RIL_NO_CELL_INFO_LIST
{RIL_UNSOL_CELL_INFO_LIST, responseCellInfoList, WAKE_PARTIAL},
#endif
+ {RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
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/librilutils/record_stream.c b/librilutils/record_stream.c
new file mode 100644
index 0000000..558d179
--- /dev/null
+++ b/librilutils/record_stream.c
@@ -0,0 +1,186 @@
+/*
+**
+** 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 <stdlib.h>
+#include <unistd.h>
+#include <assert.h>
+#include <errno.h>
+#include <telephony/record_stream.h>
+#include <string.h>
+#include <stdint.h>
+#ifdef HAVE_WINSOCK
+#include <winsock2.h> /* for ntohl */
+#else
+#include <netinet/in.h>
+#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/reference-ril/reference-ril.c b/reference-ril/reference-ril.c
index e8529cb..097ca92 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
@@ -1501,12 +1509,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)
@@ -1519,6 +1529,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];
@@ -1536,17 +1552,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)
@@ -2053,6 +2120,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;
@@ -2170,6 +2240,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));
@@ -2929,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
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