Bug 1032858 - Part 2: implementation of cell info list. r=hsinyi
authorJessica Jong <jjong@mozilla.com>
Mon, 21 Jul 2014 18:21:44 +0800
changeset 216081 e69bc093068c95f01ea36843dc1d636391464275
parent 216080 6474f3075112c5ea240a86b1916074db4db07530
child 216082 a594cb120c54be8be99dde28265bc9680fb7b026
push id3857
push userraliiev@mozilla.com
push dateTue, 02 Sep 2014 16:39:23 +0000
treeherdermozilla-beta@5638b907b505 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershsinyi
bugs1032858
milestone33.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1032858 - Part 2: implementation of cell info list. r=hsinyi
dom/system/gonk/RadioInterfaceLayer.js
dom/system/gonk/ril_consts.js
dom/system/gonk/ril_worker.js
dom/system/gonk/worker_buf.js
--- a/dom/system/gonk/RadioInterfaceLayer.js
+++ b/dom/system/gonk/RadioInterfaceLayer.js
@@ -54,16 +54,24 @@ const RADIOINTERFACE_CID =
 const RILNETWORKINTERFACE_CID =
   Components.ID("{3bdd52a9-3965-4130-b569-0ac5afed045e}");
 const GSMICCINFO_CID =
   Components.ID("{d90c4261-a99d-47bc-8b05-b057bb7e8f8a}");
 const CDMAICCINFO_CID =
   Components.ID("{39ba3c08-aacc-46d0-8c04-9b619c387061}");
 const NEIGHBORINGCELLINFO_CID =
   Components.ID("{f9dfe26a-851e-4a8b-a769-cbb1baae7ded}");
+const GSMCELLINFO_CID =
+    Components.ID("{41f6201e-7263-42e3-b31f-38a9dc8a280a}");
+const WCDMACELLINFO_CID =
+    Components.ID("{eeaaf307-df6e-4c98-b121-e3302b1fc468}");
+const CDMACELLINFO_CID =
+    Components.ID("{b497d6e4-4cb8-4d6e-b673-840c7d5ddf25}");
+const LTECELLINFO_CID =
+    Components.ID("{c7e0a78a-4e99-42f5-9251-e6172c5ed8d8}");
 
 const NS_XPCOM_SHUTDOWN_OBSERVER_ID      = "xpcom-shutdown";
 const kNetworkInterfaceStateChangedTopic = "network-interface-state-changed";
 const kNetworkConnStateChangedTopic      = "network-connection-state-changed";
 const kNetworkActiveChangedTopic         = "network-active-changed";
 const kSmsReceivedObserverTopic          = "sms-received";
 const kSilentSmsReceivedObserverTopic    = "silent-sms-received";
 const kSmsSendingObserverTopic           = "sms-sending";
@@ -92,16 +100,19 @@ const DOM_MOBILE_MESSAGE_DELIVERY_RECEIV
 const DOM_MOBILE_MESSAGE_DELIVERY_SENDING  = "sending";
 const DOM_MOBILE_MESSAGE_DELIVERY_SENT     = "sent";
 const DOM_MOBILE_MESSAGE_DELIVERY_ERROR    = "error";
 
 const RADIO_POWER_OFF_TIMEOUT = 30000;
 const SMS_HANDLED_WAKELOCK_TIMEOUT = 5000;
 const HW_DEFAULT_CLIENT_ID = 0;
 
+const INT32_MAX = 2147483647;
+const UNKNOWN_RSSI = 99;
+
 const RIL_IPC_MOBILECONNECTION_MSG_NAMES = [
   "RIL:GetRilContext",
   "RIL:GetAvailableNetworks",
   "RIL:SelectNetwork",
   "RIL:SelectNetworkAuto",
   "RIL:SetPreferredNetworkType",
   "RIL:GetPreferredNetworkType",
   "RIL:SendMMI",
@@ -1071,17 +1082,119 @@ NeighboringCellInfo.prototype = {
   }),
 
   // nsINeighboringCellInfo
 
   networkType: null,
   gsmLocationAreaCode: -1,
   gsmCellId: -1,
   wcdmaPsc: -1,
-  signalStrength: 99
+  signalStrength: UNKNOWN_RSSI
+};
+
+function CellInfo() {}
+CellInfo.prototype = {
+  type: null,
+  registered: false,
+  timestampType: Ci.nsICellInfo.TIMESTAMP_TYPE_UNKNOWN,
+  timestamp: 0
+};
+
+function GsmCellInfo() {}
+GsmCellInfo.prototype = {
+  __proto__: CellInfo.prototype,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIGsmCellInfo]),
+  classID: GSMCELLINFO_CID,
+  classInfo: XPCOMUtils.generateCI({
+    classID:          GSMCELLINFO_CID,
+    classDescription: "GsmCellInfo",
+    interfaces:       [Ci.nsIGsmCellInfo]
+  }),
+
+  // nsIGsmCellInfo
+
+  mcc: INT32_MAX,
+  mnc: INT32_MAX,
+  lac: INT32_MAX,
+  cid: INT32_MAX,
+  signalStrength: UNKNOWN_RSSI,
+  bitErrorRate: UNKNOWN_RSSI
+};
+
+function WcdmaCellInfo() {}
+WcdmaCellInfo.prototype = {
+  __proto__: CellInfo.prototype,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIWcdmaCellInfo]),
+  classID: WCDMACELLINFO_CID,
+  classInfo: XPCOMUtils.generateCI({
+    classID:          WCDMACELLINFO_CID,
+    classDescription: "WcdmaCellInfo",
+    interfaces:       [Ci.nsIWcdmaCellInfo]
+  }),
+
+  // nsIWcdmaCellInfo
+
+  mcc: INT32_MAX,
+  mnc: INT32_MAX,
+  lac: INT32_MAX,
+  cid: INT32_MAX,
+  psc: INT32_MAX,
+  signalStrength: UNKNOWN_RSSI,
+  bitErrorRate: UNKNOWN_RSSI
+};
+
+function LteCellInfo() {}
+LteCellInfo.prototype = {
+  __proto__: CellInfo.prototype,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsILteCellInfo]),
+  classID: LTECELLINFO_CID,
+  classInfo: XPCOMUtils.generateCI({
+    classID:          LTECELLINFO_CID,
+    classDescription: "LteCellInfo",
+    interfaces:       [Ci.nsILteCellInfo]
+  }),
+
+  // nsILteCellInfo
+
+  mcc: INT32_MAX,
+  mnc: INT32_MAX,
+  cid: INT32_MAX,
+  pcid: INT32_MAX,
+  tac: INT32_MAX,
+  signalStrength: UNKNOWN_RSSI,
+  rsrp: INT32_MAX,
+  rsrq: INT32_MAX,
+  rssnr: INT32_MAX,
+  cqi: INT32_MAX,
+  timingAdvance: INT32_MAX
+};
+
+function CdmaCellInfo() {}
+CdmaCellInfo.prototype = {
+  __proto__: CellInfo.prototype,
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsICdmaCellInfo]),
+  classID: CDMACELLINFO_CID,
+  classInfo: XPCOMUtils.generateCI({
+    classID:          CDMACELLINFO_CID,
+    classDescription: "CdmaCellInfo",
+    interfaces:       [Ci.nsICdmaCellInfo]
+  }),
+
+  // nsICdmaCellInfo
+
+  networkId: INT32_MAX,
+  systemId: INT32_MAX,
+  baseStationId: INT32_MAX,
+  longitude: INT32_MAX,
+  latitude: INT32_MAX,
+  cdmaDbm: INT32_MAX,
+  cdmaEcio: INT32_MAX,
+  evdoDbm: INT32_MAX,
+  evdoEcio: INT32_MAX,
+  evdoSnr: INT32_MAX
 };
 
 function DataConnectionHandler(clientId, radioInterface) {
   // Initial owning attributes.
   this.clientId = clientId;
   this.radioInterface = radioInterface;
   this.dataCallSettings = {
     oldEnabled: false,
@@ -4415,16 +4528,55 @@ RadioInterface.prototype = {
       this.workerMessenger.send(rilMessageType, message, function(response) {
         return callback.handleResponse(response);
       });
     } else {
       this.workerMessenger.send(rilMessageType, message);
     }
   },
 
+  getCellInfoList: function(callback) {
+    this.workerMessenger.send("getCellInfoList",
+                              null,
+                              function(response) {
+      if (response.errorMsg) {
+        callback.notifyGetCellInfoListFailed(response.errorMsg);
+        return;
+      }
+
+      let cellInfoList = [];
+      let count = response.result.length;
+      for (let i = 0; i < count; i++) {
+        let srcCellInfo = response.result[i];
+        let cellInfo;
+        switch (srcCellInfo.type) {
+          case RIL.CELL_INFO_TYPE_GSM:
+            cellInfo = new GsmCellInfo();
+            break;
+          case RIL.CELL_INFO_TYPE_WCDMA:
+            cellInfo = new WcdmaCellInfo();
+            break;
+          case RIL.CELL_INFO_TYPE_LTE:
+            cellInfo = new LteCellInfo();
+            break;
+          case RIL.CELL_INFO_TYPE_CDMA:
+            cellInfo = new CdmaCellInfo();
+            break;
+        }
+
+        if (!cellInfo) {
+          continue;
+        }
+        this.updateInfo(srcCellInfo, cellInfo);
+        cellInfoList.push(cellInfo);
+      }
+      callback.notifyGetCellInfoList(cellInfoList);
+    }.bind(this));
+  },
+
   getNeighboringCellIds: function(callback) {
     this.workerMessenger.send("getNeighboringCellIds",
                               null,
                               function(response) {
       if (response.errorMsg) {
         callback.notifyGetNeighboringCellIdsFailed(response.errorMsg);
         return;
       }
--- a/dom/system/gonk/ril_consts.js
+++ b/dom/system/gonk/ril_consts.js
@@ -124,16 +124,17 @@ this.REQUEST_GET_SMSC_ADDRESS = 100;
 this.REQUEST_SET_SMSC_ADDRESS = 101;
 this.REQUEST_REPORT_SMS_MEMORY_STATUS = 102;
 this.REQUEST_REPORT_STK_SERVICE_IS_RUNNING = 103;
 this.REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE = 104;
 this.REQUEST_ISIM_AUTHENTICATION = 105;
 this.REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU = 106;
 this.REQUEST_STK_SEND_ENVELOPE_WITH_STATUS = 107;
 this.REQUEST_VOICE_RADIO_TECH = 108;
+this.REQUEST_GET_CELL_INFO_LIST = 109;
 
 // Flame specific parcel types.
 this.REQUEST_SET_UICC_SUBSCRIPTION = 114;
 this.REQUEST_SET_DATA_SUBSCRIPTION = 115;
 this.REQUEST_GET_UICC_SUBSCRIPTION = 116;
 this.REQUEST_GET_DATA_SUBSCRIPTION = 117;
 
 // UICC Secure Access.
@@ -460,16 +461,21 @@ this.NETWORK_CREG_TECH_HSDPA = 9;
 this.NETWORK_CREG_TECH_HSUPA = 10;
 this.NETWORK_CREG_TECH_HSPA = 11;
 this.NETWORK_CREG_TECH_EVDOB = 12;
 this.NETWORK_CREG_TECH_EHRPD = 13;
 this.NETWORK_CREG_TECH_LTE = 14;
 this.NETWORK_CREG_TECH_HSPAP = 15;
 this.NETWORK_CREG_TECH_GSM = 16;
 
+this.CELL_INFO_TYPE_GSM = 1;
+this.CELL_INFO_TYPE_CDMA = 2;
+this.CELL_INFO_TYPE_LTE = 3;
+this.CELL_INFO_TYPE_WCDMA = 4;
+
 this.CALL_STATE_UNKNOWN = -1;
 this.CALL_STATE_ACTIVE = 0;
 this.CALL_STATE_HOLDING = 1;
 this.CALL_STATE_DIALING = 2;
 this.CALL_STATE_ALERTING = 3;
 this.CALL_STATE_INCOMING = 4;
 this.CALL_STATE_WAITING = 5;
 
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -1308,16 +1308,23 @@ RilObject.prototype = {
   /**
    * Request neighboring cell ids in GSM network.
    */
   getNeighboringCellIds: function(options) {
     this.context.Buf.simpleRequest(REQUEST_GET_NEIGHBORING_CELL_IDS, options);
   },
 
   /**
+   * Request all of the current cell information known to the radio.
+   */
+  getCellInfoList: function(options) {
+    this.context.Buf.simpleRequest(REQUEST_GET_CELL_INFO_LIST, options);
+  },
+
+  /**
    * Request various states about the network.
    */
   requestNetworkInfo: function() {
     if (this._processingNetworkInfo) {
       if (DEBUG) {
         this.context.debug("Network info requested, but we're already " +
                            "requesting network info.");
       }
@@ -6442,16 +6449,76 @@ RilObject.prototype[REQUEST_GET_NEIGHBOR
     }
 
     neighboringCellIds.push(cellId);
   }
 
   options.result = neighboringCellIds;
   this.sendChromeMessage(options);
 };
+RilObject.prototype[REQUEST_GET_CELL_INFO_LIST] = function REQUEST_GET_CELL_INFO_LIST(length, options) {
+  if (options.rilRequestError) {
+    options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
+    this.sendChromeMessage(options);
+    return;
+  }
+
+  let Buf = this.context.Buf;
+  let cellInfoList = [];
+  let num = Buf.readInt32();
+  for (let i = 0; i < num; i++) {
+    let cellInfo = {};
+    cellInfo.type = Buf.readInt32();
+    cellInfo.registered = Buf.readInt32() ? true : false;
+    cellInfo.timestampType = Buf.readInt32();
+    cellInfo.timestamp = Buf.readInt64();
+
+    switch(cellInfo.type) {
+      case CELL_INFO_TYPE_GSM:
+      case CELL_INFO_TYPE_WCDMA:
+        cellInfo.mcc = Buf.readInt32();
+        cellInfo.mnc = Buf.readInt32();
+        cellInfo.lac = Buf.readInt32();
+        cellInfo.cid = Buf.readInt32();
+        if (cellInfo.type == CELL_INFO_TYPE_WCDMA) {
+          cellInfo.psc = Buf.readInt32();
+        }
+        cellInfo.signalStrength = Buf.readInt32();
+        cellInfo.bitErrorRate = Buf.readInt32();
+        break;
+      case CELL_INFO_TYPE_CDMA:
+        cellInfo.networkId = Buf.readInt32();
+        cellInfo.systemId = Buf.readInt32();
+        cellInfo.basestationId = Buf.readInt32();
+        cellInfo.longitude = Buf.readInt32();
+        cellInfo.latitude = Buf.readInt32();
+        cellInfo.cdmaDbm = Buf.readInt32();
+        cellInfo.cdmaEcio = Buf.readInt32();
+        cellInfo.evdoDbm = Buf.readInt32();
+        cellInfo.evdoEcio = Buf.readInt32();
+        cellInfo.evdoSnr = Buf.readInt32();
+        break;
+      case CELL_INFO_TYPE_LTE:
+        cellInfo.mcc = Buf.readInt32();
+        cellInfo.mnc = Buf.readInt32();
+        cellInfo.cid = Buf.readInt32();
+        cellInfo.pcid = Buf.readInt32();
+        cellInfo.tac = Buf.readInt32();
+        cellInfo.signalStrength = Buf.readInt32();
+        cellInfo.rsrp = Buf.readInt32();
+        cellInfo.rsrq = Buf.readInt32();
+        cellInfo.rssnr = Buf.readInt32();
+        cellInfo.cqi = Buf.readInt32();
+        break;
+    }
+    cellInfoList.push(cellInfo);
+  }
+  options.result = cellInfoList;
+  this.sendChromeMessage(options);
+};
 RilObject.prototype[REQUEST_SET_LOCATION_UPDATES] = null;
 RilObject.prototype[REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE] = null;
 RilObject.prototype[REQUEST_CDMA_SET_ROAMING_PREFERENCE] = function REQUEST_CDMA_SET_ROAMING_PREFERENCE(length, options) {
   if (options.rilRequestError) {
     options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
   }
   this.sendChromeMessage(options);
 };
--- a/dom/system/gonk/worker_buf.js
+++ b/dom/system/gonk/worker_buf.js
@@ -262,16 +262,29 @@ let Buf = {
     return this.readUint8() | this.readUint8() << 8;
   },
 
   readInt32: function() {
     return this.readUint8()       | this.readUint8() <<  8 |
            this.readUint8() << 16 | this.readUint8() << 24;
   },
 
+  readInt64: function() {
+    // Avoid using bitwise operators as the operands of all bitwise operators
+    // are converted to signed 32-bit integers.
+    return this.readUint8()                   +
+           this.readUint8() * Math.pow(2, 8)  +
+           this.readUint8() * Math.pow(2, 16) +
+           this.readUint8() * Math.pow(2, 24) +
+           this.readUint8() * Math.pow(2, 32) +
+           this.readUint8() * Math.pow(2, 40) +
+           this.readUint8() * Math.pow(2, 48) +
+           this.readUint8() * Math.pow(2, 56);
+  },
+
   readInt32List: function() {
     let length = this.readInt32();
     let ints = [];
     for (let i = 0; i < length; i++) {
       ints.push(this.readInt32());
     }
     return ints;
   },