am 38aaaa64: (-s ours) am 1b4c3db6: Merge "RIL: Support SMS on IMS, DO NOT MERGE" into jb-mr2-dev

* commit '38aaaa6494bd6deb42de8397fb421d1fb3b4e352':
  RIL: Support SMS on IMS, DO NOT MERGE
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 8252548..2957441 100644
--- a/include/telephony/ril.h
+++ b/include/telephony/ril.h
@@ -1,6 +1,5 @@
 /*
  * 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.
@@ -20,7 +19,6 @@
 
 #include <stdlib.h>
 #include <stdint.h>
-#include <telephony/ril_cdma_sms.h>
 #ifndef FEATURE_UNIT_TEST
 #include <sys/time.h>
 #endif /* !FEATURE_UNIT_TEST */
@@ -235,28 +233,6 @@
                                    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
@@ -3509,51 +3485,18 @@
 #define RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE 110
 
 /**
- * RIL_REQUEST_IMS_REGISTRATION_STATE
+ * RIL_REQUEST_SET_INITIAL_ATTACH_APN
  *
- * 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
+ * Set an apn to initial attach network
+ * "response" is NULL
  *
  * Valid errors:
  *  SUCCESS
- *  RADIO_NOT_AVAILABLE
+ *  RADIO_NOT_AVAILABLE (radio resetting)
  *  GENERIC_FAILURE
+ *  SUBSCRIPTION_NOT_AVAILABLE
  */
-#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
+#define RIL_REQUEST_SET_INITIAL_ATTACH_APN 111
 
 /***********************************************************************/
 
@@ -4045,20 +3988,6 @@
  */
 #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
-
 /***********************************************************************/
 
 
@@ -4127,6 +4056,14 @@
     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 b099d4b..62aeb05 100644
--- a/libril/Android.mk
+++ b/libril/Android.mk
@@ -12,7 +12,8 @@
     libutils \
     libbinder \
     libcutils \
-    libhardware_legacy
+    libhardware_legacy \
+    librilutils
 
 LOCAL_CFLAGS :=
 
@@ -33,7 +34,8 @@
 
 LOCAL_STATIC_LIBRARIES := \
     libutils_static \
-    libcutils
+    libcutils \
+    librilutils_static
 
 LOCAL_CFLAGS :=
 
diff --git a/libril/ril.cpp b/libril/ril.cpp
index 9826686..46a150f 100644
--- a/libril/ril.cpp
+++ b/libril/ril.cpp
@@ -1,7 +1,6 @@
 /* //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.
@@ -24,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>
@@ -205,12 +204,10 @@
 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);
@@ -882,8 +879,9 @@
     return;
 }
 
-static status_t
-constructCdmaSms(Parcel &p, RequestInfo *pRI, RIL_CDMA_SMS_Message& rcsm) {
+static void
+dispatchCdmaSms(Parcel &p, RequestInfo *pRI) {
+    RIL_CDMA_SMS_Message rcsm;
     int32_t  t;
     uint8_t ut;
     status_t status;
@@ -947,7 +945,7 @@
     }
 
     if (status != NO_ERROR) {
-        return status;
+        goto invalid;
     }
 
     startRequest;
@@ -959,18 +957,6 @@
 
     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
@@ -985,149 +971,6 @@
 }
 
 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;
     int32_t  t;
@@ -1463,6 +1306,56 @@
         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;
@@ -3759,8 +3652,7 @@
         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_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";
@@ -3797,7 +3689,6 @@
         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 "<unknown request>";
     }
 }
diff --git a/libril/ril_commands.h b/libril/ril_commands.h
index bc1c7f3..3e5a619 100644
--- a/libril/ril_commands.h
+++ b/libril/ril_commands.h
@@ -1,7 +1,6 @@
 /* //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.
@@ -126,5 +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_IMS_REGISTRATION_STATE, dispatchVoid, responseInts},
-    {RIL_REQUEST_IMS_SEND_SMS, dispatchImsSms, responseSMS},
+    {RIL_REQUEST_SET_INITIAL_ATTACH_APN, dispatchSetInitialAttachApn, responseVoid},
diff --git a/libril/ril_unsol_commands.h b/libril/ril_unsol_commands.h
index b491cf2..0711225 100644
--- a/libril/ril_unsol_commands.h
+++ b/libril/ril_unsol_commands.h
@@ -1,7 +1,6 @@
 /* //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.
@@ -52,4 +51,3 @@
     {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/librilutils/Android.mk b/librilutils/Android.mk
index a959202..a50e374 100644
--- a/librilutils/Android.mk
+++ b/librilutils/Android.mk
@@ -4,7 +4,8 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-    librilutils.c
+    librilutils.c \
+    record_stream.c
 
 LOCAL_CFLAGS :=
 
@@ -20,7 +21,8 @@
 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 7253eb0..77c6f31 100644
--- a/reference-ril/reference-ril.c
+++ b/reference-ril/reference-ril.c
@@ -1,7 +1,6 @@
 /* //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.
@@ -212,14 +211,6 @@
 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
@@ -1508,14 +1499,12 @@
     // 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.
-    response.messageRef = -1;
-    RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, &response, sizeof(response));
+    RIL_onRequestComplete(t, RIL_E_SMS_SEND_FAIL_RETRY, NULL, 0);
 }
 
 static void requestSendSMS(void *data, size_t datalen, RIL_Token t)
@@ -1528,12 +1517,6 @@
     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];
 
@@ -1551,68 +1534,17 @@
 
     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:
-    response.messageRef = -2;
-    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, &response, sizeof(response));
+    RIL_onRequestComplete(t, RIL_E_GENERIC_FAILURE, NULL, 0);
     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)
@@ -2119,9 +2051,6 @@
         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;
@@ -2239,28 +2168,6 @@
             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));
@@ -3020,18 +2927,6 @@
     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 @@
 	libril \
 	libdl
 
+# temporary hack for broken vendor rils
+LOCAL_WHOLE_STATIC_LIBRARIES := \
+	librilutils_static
+
 LOCAL_CFLAGS := -DRIL_SHLIB
 
 LOCAL_MODULE:= rild