Add support for UNSOL PCO Data.

bug:28961371
bug:28567303
Change-Id: Ibbb415c9f5799d666b1599ed0abf97ec24642a3a
diff --git a/include/telephony/ril.h b/include/telephony/ril.h
index 47b4f47..d88e168 100644
--- a/include/telephony/ril.h
+++ b/include/telephony/ril.h
@@ -65,10 +65,12 @@
  *                    RIL_CellInfoWcdma_v12, RIL_CellInfoLte_v12, RIL_CellInfo_v12.
  *
  * RIL_VERSION = 13 : This version includes new wakelock semantics and as the first
- *                    strongly versioned version it enforces structure use. New
- *                    data structures are added, namely RIL_CarrierMatchType,
- *                    RIL_Carrier, RIL_CarrierRestrictions. New commands added:
- *                    RIL_REQUEST_SET_CARRIER_RESTRICTIONS, RIL_REQUEST_SET_CARRIER_RESTRICTIONS
+ *                    strongly versioned version it enforces structure use.
+ * RIL_VERSION = 14 : New data structures are added, namely RIL_CarrierMatchType,
+ *                    RIL_Carrier, RIL_CarrierRestrictions and RIL_PCO_Data.
+ *                    New commands added: RIL_REQUEST_SET_CARRIER_RESTRICTIONS,
+ *                    RIL_REQUEST_SET_CARRIER_RESTRICTIONS and
+ *                    RIL_UNSOL_PCO_DATA
  */
 #define RIL_VERSION 12
 #define LAST_IMPRECISE_RIL_VERSION 12 // Better self-documented name
@@ -5765,6 +5767,19 @@
  */
 #define RIL_UNSOL_LCEDATA_RECV 1045
 
+ /**
+  * RIL_UNSOL_PCO_DATA
+  *
+  * Called when there is new Carrier PCO data received for a data call.  Ideally
+  * only new data will be forwarded, though this is not required.  Multiple
+  * boxes of carrier PCO data for a given call should result in a series of
+  * RIL_UNSOL_PCO_DATA calls.
+  *
+  * "data" is the RIL_PCO_Data structure.
+  *
+  */
+#define RIL_UNSOL_PCO_DATA 1046
+
 /***********************************************************************/
 
 
@@ -6030,6 +6045,18 @@
 void RIL_requestTimedCallback (RIL_TimedCallback callback,
                                void *param, const struct timeval *relativeTime);
 
+typedef struct {
+  int cid;             /* Context ID, uniquely identifies this call */
+  char *bearer_proto;  /* One of the PDP_type values in TS 27.007 section 10.1.1.
+                          For example, "IP", "IPV6", "IPV4V6" */
+  int pco_id;          /* The protocol ID for this box.  Note that only IDs from
+                          FF00H - FFFFH are accepted.  If more than one is included
+                          from the network, multiple calls should be made to send all
+                          of them. */
+  int contents_length; /* The number of octets in the contents. */
+  char *contents;      /* Carrier-defined content.  It is binary, opaque and
+                          loosely defined in LTE Layer 3 spec 24.008 */
+} RIL_PCO_Data;
 
 #endif /* RIL_SHLIB */
 
diff --git a/libril/ril.cpp b/libril/ril.cpp
index b9e0f79..1bb5643 100755
--- a/libril/ril.cpp
+++ b/libril/ril.cpp
@@ -316,6 +316,7 @@
 static int responseLceData(Parcel &p, void *response, size_t responselen);
 static int responseActivityData(Parcel &p, void *response, size_t responselen);
 static int responseCarrierRestrictions(Parcel &p, void *response, size_t responselen);
+static int responsePcoData(Parcel &p, void *response, size_t responselen);
 
 static int decodeVoiceRadioTechnology (RIL_RadioState radioState);
 static int decodeCdmaSubscriptionSource (RIL_RadioState radioState);
@@ -2149,9 +2150,9 @@
 
     memset(&cr, 0, sizeof(RIL_CarrierRestrictions));
 
-    if (s_callbacks.version < 13) {
+    if (s_callbacks.version < 14) {
         RLOGE("Unsuppoted RIL version %d, min version expected %d",
-              s_callbacks.version, 13);
+              s_callbacks.version, 14);
         RIL_onRequestComplete(pRI, RIL_E_REQUEST_NOT_SUPPORTED, NULL, 0);
         return;
     }
@@ -4063,7 +4064,7 @@
   }
   if (responselen != sizeof(RIL_CarrierRestrictions)) {
     RLOGE("responseCarrierRestrictions: invalid response length %d expecting len: %d",
-          sizeof(RIL_CarrierRestrictions), responselen);
+          responselen, sizeof(RIL_CarrierRestrictions));
     return RIL_ERRNO_INVALID_RESPONSE;
   }
 
@@ -4093,6 +4094,32 @@
   return 0;
 }
 
+static int responsePcoData(Parcel &p, void *response, size_t responselen) {
+  if (response == NULL) {
+    RLOGE("responsePcoData: invalid NULL response");
+    return RIL_ERRNO_INVALID_RESPONSE;
+  }
+  if (responselen != sizeof(RIL_PCO_Data)) {
+    RLOGE("responsePcoData: invalid response length %d, expecting %d",
+          responselen, sizeof(RIL_PCO_Data));
+    return RIL_ERRNO_INVALID_RESPONSE;
+  }
+
+  RIL_PCO_Data *p_cur = (RIL_PCO_Data *)response;
+  p.writeInt32(p_cur->cid);
+  writeStringToParcel(p, p_cur->bearer_proto);
+  p.writeInt32(p_cur->pco_id);
+  p.writeInt32(p_cur->contents_length);
+  p.write(p_cur->contents, p_cur->contents_length);
+
+  startResponse;
+      appendPrintBuf("PCO data received: cid %d, id %d, length %d",
+                     p_cur->cid, p_cur->pco_id, p_cur->contents_length);
+  closeResponse;
+
+  return 0;
+}
+
 /**
  * A write on the wakeup fd is done just to pop us out of select()
  * We empty the buffer here and then ril_event will reset the timers on the
@@ -5768,6 +5795,7 @@
         case RIL_REQUEST_SHUTDOWN: return "SHUTDOWN";
         case RIL_UNSOL_RADIO_CAPABILITY: return "RIL_UNSOL_RADIO_CAPABILITY";
         case RIL_RESPONSE_ACKNOWLEDGEMENT: return "RIL_RESPONSE_ACKNOWLEDGEMENT";
+        case RIL_UNSOL_PCO_DATA: return "RIL_UNSOL_PCO_DATA";
         default: return "<unknown request>";
     }
 }
diff --git a/libril/ril_unsol_commands.h b/libril/ril_unsol_commands.h
index eb9e12d..11ae050 100755
--- a/libril/ril_unsol_commands.h
+++ b/libril/ril_unsol_commands.h
@@ -60,3 +60,4 @@
     {RIL_UNSOL_ON_SS, responseSSData, WAKE_PARTIAL},
     {RIL_UNSOL_STK_CC_ALPHA_NOTIFY, responseString, WAKE_PARTIAL},
     {RIL_UNSOL_LCEDATA_RECV, responseLceData, WAKE_PARTIAL},
+    {RIL_UNSOL_PCO_DATA, responsePcoData, WAKE_PARTIAL},