Snap for 5778854 from f09f011ad5fc2179f159490910e2755fb09e97f5 to qt-c2f2-release

Change-Id: I9ebc48ab9a2746b5898af41c63817e27d464d02d
diff --git a/android/2.0/AGnssRil.cpp b/android/2.0/AGnssRil.cpp
index 9de8b7d..a477fc2 100644
--- a/android/2.0/AGnssRil.cpp
+++ b/android/2.0/AGnssRil.cpp
@@ -57,29 +57,29 @@
 
     // for XTRA
     if (nullptr != mGnss && ( nullptr != mGnss->getGnssInterface() )) {
-        int8_t typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+        int8_t typeout = loc_core::TYPE_UNKNOWN;
         switch(type)
         {
             case IAGnssRil::NetworkType::MOBILE:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_MOBILE;
+                typeout = loc_core::TYPE_MOBILE;
                 break;
             case IAGnssRil::NetworkType::WIFI:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIFI;
+                typeout = loc_core::TYPE_WIFI;
                 break;
             case IAGnssRil::NetworkType::MMS:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_MMS;
+                typeout = loc_core::TYPE_MMS;
                 break;
             case IAGnssRil::NetworkType::SUPL:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_SUPL;
+                typeout = loc_core::TYPE_SUPL;
                 break;
             case IAGnssRil::NetworkType::DUN:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_DUN;
+                typeout = loc_core::TYPE_DUN;
                 break;
             case IAGnssRil::NetworkType::HIPRI:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_HIPRI;
+                typeout = loc_core::TYPE_HIPRI;
                 break;
             case IAGnssRil::NetworkType::WIMAX:
-                typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIMAX;
+                typeout = loc_core::TYPE_WIMAX;
                 break;
             default:
                 {
@@ -88,16 +88,16 @@
                     switch(networkType)
                     {
                         case NetworkType_BLUETOOTH:
-                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_BLUETOOTH;
+                            typeout = loc_core::TYPE_BLUETOOTH;
                             break;
                         case NetworkType_ETHERNET:
-                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_ETHERNET;
+                            typeout = loc_core::TYPE_ETHERNET;
                             break;
                         case NetworkType_PROXY:
-                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_PROXY;
+                            typeout = loc_core::TYPE_PROXY;
                             break;
                         default:
-                            typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+                            typeout = loc_core::TYPE_UNKNOWN;
                     }
                 }
                 break;
@@ -110,12 +110,12 @@
     ENTRY_LOG_CALLFLOW();
 
     if (nullptr != mGnss && (nullptr != mGnss->getGnssInterface())) {
-        int8_t typeout = loc_core::NetworkInfoDataItemBase::TYPE_UNKNOWN;
+        int8_t typeout = loc_core::TYPE_UNKNOWN;
         bool roaming = false;
         if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_METERED) {
-            typeout = loc_core::NetworkInfoDataItemBase::TYPE_WIFI;
+            typeout = loc_core::TYPE_WIFI;
         } else {
-            typeout = loc_core::NetworkInfoDataItemBase::TYPE_MOBILE;
+            typeout = loc_core::TYPE_MOBILE;
         }
         if (attributes.capabilities & IAGnssRil::NetworkCapability::NOT_ROAMING) {
             roaming = false;
diff --git a/core/SystemStatus.h b/core/SystemStatus.h
index f3467e2..35b4277 100644
--- a/core/SystemStatus.h
+++ b/core/SystemStatus.h
@@ -501,19 +501,67 @@
         mType = itemBase.getType();
     }
     inline bool equals(const SystemStatusNetworkInfo& peer) {
-        return (mAllTypes == peer.mAllTypes);
+        for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) {
+             if (!(mAllNetworkHandles[i] == peer.mAllNetworkHandles[i])) {
+                 return false;
+             }
+         }
+        return true;
     }
     inline virtual SystemStatusItemBase& collate(SystemStatusItemBase& curInfo) {
         uint64_t allTypes = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mAllTypes;
         uint64_t networkHandle =
                 (static_cast<SystemStatusNetworkInfo&>(curInfo)).mNetworkHandle;
         int32_t type = (static_cast<SystemStatusNetworkInfo&>(curInfo)).mType;
+        // Replace current with cached table for now and then update
+        memcpy(mAllNetworkHandles,
+               (static_cast<SystemStatusNetworkInfo&>(curInfo)).getNetworkHandle(),
+               sizeof(mAllNetworkHandles));
         if (mConnected) {
             mAllTypes |= allTypes;
-            mAllNetworkHandles[type] = networkHandle;
+            for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) {
+                if (mNetworkHandle == mAllNetworkHandles[i].networkHandle) {
+                    LOC_LOGD("collate duplicate detected, not updating");
+                    break;
+                }
+                if (NETWORK_HANDLE_UNKNOWN == mAllNetworkHandles[i].networkHandle) {
+                    mAllNetworkHandles[i].networkHandle = mNetworkHandle;
+                    mAllNetworkHandles[i].networkType = (loc_core::NetworkType) mType;
+                    break;
+                }
+            }
         } else if (0 != mAllTypes) {
-            mAllTypes = (allTypes & (~mAllTypes));
-            mAllNetworkHandles[type] = NETWORK_HANDLE_UNKNOWN;
+            uint8_t deletedIndex = MAX_NETWORK_HANDLES;
+            uint8_t lastValidIndex = 0;
+            uint8_t typeCount = 0;
+            for (; lastValidIndex < MAX_NETWORK_HANDLES &&
+                     NETWORK_HANDLE_UNKNOWN != mAllNetworkHandles[lastValidIndex].networkHandle;
+                 ++lastValidIndex) {
+                // Maintain count for number of network handles still
+                // connected for given type
+                if (mType == mAllNetworkHandles[lastValidIndex].networkType) {
+                    typeCount++;
+                }
+
+                if (mNetworkHandle == mAllNetworkHandles[lastValidIndex].networkHandle) {
+                    deletedIndex = lastValidIndex;
+                    typeCount--;
+                }
+            }
+
+            if (MAX_NETWORK_HANDLES != deletedIndex) {
+                LOC_LOGD("deletedIndex:%u, lastValidIndex:%u, typeCount:%u",
+                        deletedIndex, lastValidIndex, typeCount);
+                mAllNetworkHandles[deletedIndex] = mAllNetworkHandles[lastValidIndex];
+                mAllNetworkHandles[lastValidIndex].networkHandle = NETWORK_HANDLE_UNKNOWN;
+                mAllNetworkHandles[lastValidIndex].networkType = TYPE_UNKNOWN;
+            }
+
+            // If no more handles of given type, set bitmask
+            if (0 == typeCount) {
+                mAllTypes = (allTypes & (~mAllTypes));
+                LOC_LOGD("mAllTypes:%" PRIx64, mAllTypes);
+            }
         } // else (mConnected == false && mAllTypes == 0)
           // we keep mAllTypes as 0, which means no more connections.
 
diff --git a/core/data-items/DataItemConcreteTypesBase.h b/core/data-items/DataItemConcreteTypesBase.h
index a6e68f1..c32d65d 100644
--- a/core/data-items/DataItemConcreteTypesBase.h
+++ b/core/data-items/DataItemConcreteTypesBase.h
@@ -32,9 +32,11 @@
 
 #include <string>
 #include <cstring>
+#include <sstream>
 #include <DataItemId.h>
 #include <IDataItemCore.h>
 #include <gps_extended_c.h>
+#include <inttypes.h>
 
 #define MAC_ADDRESS_LENGTH    6
 // MAC address length in bytes
@@ -42,10 +44,68 @@
 #define SRN_MAC_ADDRESS_LENGTH    6
 #define WIFI_SUPPLICANT_DEFAULT_STATE    0
 
+static constexpr char sDelimit = ':';
+
 namespace loc_core
 {
 using namespace std;
 
+enum NetworkType {
+    TYPE_MOBILE = 0,
+    TYPE_WIFI,
+    TYPE_ETHERNET,
+    TYPE_BLUETOOTH,
+    TYPE_MMS,
+    TYPE_SUPL,
+    TYPE_DUN,
+    TYPE_HIPRI,
+    TYPE_WIMAX,
+    TYPE_PROXY,
+    TYPE_UNKNOWN,
+};
+
+typedef struct NetworkInfoType
+{
+    // Unique network handle ID
+    uint64_t networkHandle;
+    // Type of network for corresponding network handle
+    NetworkType networkType;
+    NetworkInfoType() : networkHandle(NETWORK_HANDLE_UNKNOWN), networkType(TYPE_UNKNOWN) {}
+    NetworkInfoType(string strObj) {
+        size_t posDelimit = strObj.find(sDelimit);
+
+        if ( posDelimit != string::npos) {
+            int32_t type = TYPE_UNKNOWN;
+            string handleStr = strObj.substr(0, posDelimit);
+            string typeStr = strObj.substr(posDelimit + 1, strObj.length() - posDelimit - 1);
+            stringstream(handleStr) >> networkHandle;
+            stringstream(typeStr) >> type;
+            networkType = (NetworkType) type;
+        } else {
+            networkHandle = NETWORK_HANDLE_UNKNOWN;
+            networkType = TYPE_UNKNOWN;
+        }
+    }
+    bool operator== (const NetworkInfoType& other) {
+        return ((networkHandle == other.networkHandle) && (networkType == other.networkType));
+    }
+    string toString() {
+        string valueStr;
+        valueStr.clear ();
+        char nethandle [32];
+        memset (nethandle, 0, 32);
+        snprintf(nethandle, sizeof(nethandle), "%" PRIu64, networkHandle);
+        valueStr += string(nethandle);
+        valueStr += sDelimit;
+        char type [12];
+        memset (type, 0, 12);
+        snprintf (type, 12, "%u", networkType);
+        valueStr += string (type);
+        return valueStr;
+    }
+} NetworkInfoType;
+
+
 class AirplaneModeDataItemBase : public IDataItemCore  {
 public:
     AirplaneModeDataItemBase(bool mode):
@@ -222,19 +282,6 @@
 
 class NetworkInfoDataItemBase : public IDataItemCore {
 public:
-    enum NetworkType {
-        TYPE_MOBILE = 0,
-        TYPE_WIFI,
-        TYPE_ETHERNET,
-        TYPE_BLUETOOTH,
-        TYPE_MMS,
-        TYPE_SUPL,
-        TYPE_DUN,
-        TYPE_HIPRI,
-        TYPE_WIMAX,
-        TYPE_PROXY,
-        TYPE_UNKNOWN,
-    };
     NetworkInfoDataItemBase(
     NetworkType initialType, int32_t type, string typeName, string subTypeName,
     bool available, bool connected, bool roaming, uint64_t networkHandle ):
@@ -247,9 +294,8 @@
             mRoaming(roaming),
             mNetworkHandle(networkHandle),
             mId(NETWORKINFO_DATA_ITEM_ID) {
-                memset (&mAllNetworkHandles, NETWORK_HANDLE_UNKNOWN,
-                        sizeof (mAllNetworkHandles));
-                mAllNetworkHandles[initialType] = networkHandle;
+                mAllNetworkHandles[0].networkHandle = networkHandle;
+                mAllNetworkHandles[0].networkType = initialType;
             }
     virtual ~NetworkInfoDataItemBase() {}
     inline virtual DataItemId getId() { return mId; }
@@ -259,8 +305,8 @@
         return (NetworkType)mType;
     }
     inline uint64_t getAllTypes() { return mAllTypes; }
-    inline uint64_t getNetworkHandle(NetworkType type) {
-        return mAllNetworkHandles[type];
+    inline NetworkInfoType* getNetworkHandle() {
+        return &mAllNetworkHandles[0];
     }
     // Data members
     uint64_t mAllTypes;
@@ -270,7 +316,7 @@
     bool mAvailable;
     bool mConnected;
     bool mRoaming;
-    uint64_t mAllNetworkHandles[TYPE_UNKNOWN + 1];
+    NetworkInfoType mAllNetworkHandles[MAX_NETWORK_HANDLES];
     uint64_t mNetworkHandle;
 protected:
     DataItemId mId;
diff --git a/gnss/XtraSystemStatusObserver.cpp b/gnss/XtraSystemStatusObserver.cpp
index 4cb6f5f..85c2ce5 100644
--- a/gnss/XtraSystemStatusObserver.cpp
+++ b/gnss/XtraSystemStatusObserver.cpp
@@ -129,19 +129,33 @@
 }
 
 bool XtraSystemStatusObserver::updateConnections(uint64_t allConnections,
-        uint64_t wifiNetworkHandle, uint64_t mobileNetworkHandle) {
+        NetworkInfoType* networkHandleInfo) {
     mIsConnectivityStatusKnown = true;
     mConnections = allConnections;
-    mWifiNetworkHandle = wifiNetworkHandle;
-    mMobileNetworkHandle = mobileNetworkHandle;
+
+    LOC_LOGd("updateConnections mConnections:%" PRIx64, mConnections);
+    for (uint8_t i = 0; i < MAX_NETWORK_HANDLES; ++i) {
+        mNetworkHandle[i] = networkHandleInfo[i];
+        LOC_LOGd("updateConnections [%d] networkHandle:%" PRIx64 " networkType:%u",
+            i, mNetworkHandle[i].networkHandle, mNetworkHandle[i].networkType);
+    }
 
     if (!mReqStatusReceived) {
         return true;
     }
 
     stringstream ss;
-    ss << "connection" << endl << mConnections << endl << wifiNetworkHandle
-            << endl << mobileNetworkHandle;
+    ss << "connection" << endl << mConnections << endl
+            << mNetworkHandle[0].toString() << endl
+            << mNetworkHandle[1].toString() << endl
+            << mNetworkHandle[2].toString() << endl
+            << mNetworkHandle[3].toString() << endl
+            << mNetworkHandle[4].toString() << endl
+            << mNetworkHandle[5].toString() << endl
+            << mNetworkHandle[6].toString() << endl
+            << mNetworkHandle[7].toString() << endl
+            << mNetworkHandle[8].toString() << endl
+            << mNetworkHandle[MAX_NETWORK_HANDLES-1].toString();
     string s = ss.str();
     return ( LocIpc::send(*mSender, (const uint8_t*)s.data(), s.size()) );
 }
@@ -200,7 +214,16 @@
     ss << "respondStatus" << endl;
     (mGpsLock == -1 ? ss : ss << mGpsLock) << endl;
     (mConnections == (uint64_t)~0 ? ss : ss << mConnections) << endl
-            << mWifiNetworkHandle << endl << mMobileNetworkHandle << endl
+            << mNetworkHandle[0].toString() << endl
+            << mNetworkHandle[1].toString() << endl
+            << mNetworkHandle[2].toString() << endl
+            << mNetworkHandle[3].toString() << endl
+            << mNetworkHandle[4].toString() << endl
+            << mNetworkHandle[5].toString() << endl
+            << mNetworkHandle[6].toString() << endl
+            << mNetworkHandle[7].toString() << endl
+            << mNetworkHandle[8].toString() << endl
+            << mNetworkHandle[MAX_NETWORK_HANDLES-1].toString() << endl
             << mTac << endl << mMccmnc << endl << mIsConnectivityStatusKnown;
 
     string s = ss.str();
@@ -272,11 +295,10 @@
                     {
                         NetworkInfoDataItemBase* networkInfo =
                                 static_cast<NetworkInfoDataItemBase*>(each);
+                        NetworkInfoType* networkHandleInfo =
+                                static_cast<NetworkInfoType*>(networkInfo->getNetworkHandle());
                         mXtraSysStatObj->updateConnections(networkInfo->getAllTypes(),
-                                (NetworkHandle) networkInfo->getNetworkHandle(
-                                        loc_core::NetworkInfoDataItemBase::TYPE_WIFI),
-                                (NetworkHandle) networkInfo->getNetworkHandle(
-                                        loc_core::NetworkInfoDataItemBase::TYPE_MOBILE));
+                                networkHandleInfo);
                     }
                     break;
 
diff --git a/gnss/XtraSystemStatusObserver.h b/gnss/XtraSystemStatusObserver.h
index 14f9393..3a5259d 100644
--- a/gnss/XtraSystemStatusObserver.h
+++ b/gnss/XtraSystemStatusObserver.h
@@ -55,7 +55,7 @@
 
     bool updateLockStatus(GnssConfigGpsLock lock);
     bool updateConnections(uint64_t allConnections,
-            uint64_t wifiNetworkHandle, uint64_t mobileNetworkHandle);
+            loc_core::NetworkInfoType* networkHandleInfo);
     bool updateTac(const string& tac);
     bool updateMccMnc(const string& mccmnc);
     bool updateXtraThrottle(const bool enabled);
@@ -69,8 +69,7 @@
     GnssConfigGpsLock mGpsLock;
     LocIpc mIpc;
     uint64_t mConnections;
-    uint64_t mWifiNetworkHandle;
-    uint64_t mMobileNetworkHandle;
+    loc_core::NetworkInfoType mNetworkHandle[MAX_NETWORK_HANDLES];
     string mTac;
     string mMccmnc;
     bool mXtraThrottle;
diff --git a/utils/gps_extended_c.h b/utils/gps_extended_c.h
index bfd289c..7edb3f9 100644
--- a/utils/gps_extended_c.h
+++ b/utils/gps_extended_c.h
@@ -2185,14 +2185,12 @@
 
 #define SOCKET_LOC_CLIENT_DIR          "/dev/socket/loc_client/"
 #define EAP_LOC_CLIENT_DIR             "/data/vendor/location/extap_locclient/"
-    
+
 #define LOC_CLIENT_NAME_PREFIX         "toclient"
 
 typedef uint64_t NetworkHandle;
 #define NETWORK_HANDLE_UNKNOWN  ~0
-
-typedef uint64_t NetworkHandle;
-#define NETWORK_HANDLE_UNKNOWN  ~0
+#define MAX_NETWORK_HANDLES 10
 
 #ifdef __cplusplus
 }