Bug 924740 - Part 1: RIL patch - [fugu] It throws exception when run ICCIOHelper.processICCIOGetResponse for USIM card. r=yoshi, a=1.3+
authorShawn Ku <sku@mozilla.com>
Thu, 02 Jan 2014 11:14:40 +0800
changeset 175628 1edbd949c5a7ce8df345d3ef91995781b51075ed
parent 175627 2f877b02b2f9072a2756a41b39d0b671139d74ed
child 175629 cdbb6973f650240986b36fdc1d97ccdafd27b22b
push id445
push userffxbld
push dateMon, 10 Mar 2014 22:05:19 +0000
treeherdermozilla-release@dc38b741b04e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersyoshi, 1
bugs924740
milestone28.0a2
Bug 924740 - Part 1: RIL patch - [fugu] It throws exception when run ICCIOHelper.processICCIOGetResponse for USIM card. r=yoshi, a=1.3+
dom/system/gonk/ril_worker.js
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -10939,16 +10939,25 @@ let BerTlvHelper = {
    * | Byte    | Description      | Length |
    * |  1      | Tag              |   1    |
    * |  2      | Length           |   1    |
    * |  3 ~ 4  | File identifier  |   2    |
    */
   retrieveFileIdentifier: function retrieveFileIdentifier(length) {
     return {fileId : (GsmPDUHelper.readHexOctet() << 8) +
                       GsmPDUHelper.readHexOctet()};
+  },
+
+  searchForNextTag: function searchForNextTag(tag, iter) {
+    for (let [index, tlv] in iter) {
+      if (tlv.tag === tag) {
+        return tlv;
+      }
+    }
+    return null;
   }
 };
 BerTlvHelper[BER_FCP_TEMPLATE_TAG] = function BER_FCP_TEMPLATE_TAG(length) {
   return this.processFcpTemplate(length);
 };
 BerTlvHelper[BER_PROACTIVE_COMMAND_TAG] = function BER_PROACTIVE_COMMAND_TAG(length) {
   return this.processProactiveCommand(length);
 };
@@ -11218,19 +11227,70 @@ let ICCIOHelper = {
   },
 
   /**
    * Process a ICC_COMMAND_GET_RESPONSE type command for REQUEST_SIM_IO.
    */
   processICCIOGetResponse: function processICCIOGetResponse(options) {
     let strLen = Buf.readInt32();
 
+    let peek = GsmPDUHelper.readHexOctet();
+    Buf.seekIncoming(-1 * Buf.PDU_HEX_OCTET_SIZE);
+    if (peek === BER_FCP_TEMPLATE_TAG) {
+      this.processUSimGetResponse(options, strLen / 2);
+    } else {
+      this.processSimGetResponse(options);
+    }
+    Buf.readStringDelimiter(strLen);
+
+    if (options.callback) {
+      options.callback(options);
+    }
+  },
+
+  /**
+   * Helper function for processing USIM get response.
+   */
+  processUSimGetResponse: function processUSimGetResponse(options, octetLen) {
+    let berTlv = BerTlvHelper.decode(octetLen);
+    // See TS 102 221 Table 11.4 for the content order of getResponse.
+    let iter = Iterator(berTlv.value);
+    let tlv = BerTlvHelper.searchForNextTag(BER_FCP_FILE_DESCRIPTOR_TAG,
+                                            iter);
+    if (!tlv || (tlv.value.fileStructure !== UICC_EF_STRUCTURE[options.type])) {
+      throw new Error("Expected EF type " + UICC_EF_STRUCTURE[options.type] +
+                      " but read " + tlv.value.fileStructure);
+    }
+
+    if (tlv.value.fileStructure === UICC_EF_STRUCTURE[EF_TYPE_LINEAR_FIXED] ||
+        tlv.value.fileStructure === UICC_EF_STRUCTURE[EF_TYPE_CYCLIC]) {
+      options.recordSize = tlv.value.recordLength;
+      options.totalRecords = tlv.value.numOfRecords;
+    }
+
+    tlv = BerTlvHelper.searchForNextTag(BER_FCP_FILE_IDENTIFIER_TAG, iter);
+    if (!tlv || (tlv.value.fileId !== options.fileId)) {
+      throw new Error("Expected file ID " + options.fileId.toString(16) +
+                      " but read " + fileId.toString(16));
+    }
+
+    tlv = BerTlvHelper.searchForNextTag(BER_FCP_FILE_SIZE_DATA_TAG, iter);
+    if (!tlv) {
+      throw new Error("Unexpected file size data");
+    }
+    options.fileSize = tlv.value.fileSizeData;
+  },
+
+  /**
+   * Helper function for processing SIM get response.
+   */
+  processSimGetResponse: function processSimGetResponse(options) {
     // The format is from TS 51.011, clause 9.2.1
 
-    // Skip RFU, data[0] data[1]
+    // Skip RFU, data[0] data[1].
     Buf.seekIncoming(2 * Buf.PDU_HEX_OCTET_SIZE);
 
     // File size, data[2], data[3]
     options.fileSize = (GsmPDUHelper.readHexOctet() << 8) |
                         GsmPDUHelper.readHexOctet();
 
     // 2 bytes File id. data[4], data[5]
     let fileId = (GsmPDUHelper.readHexOctet() << 8) |
@@ -11254,30 +11314,25 @@ let ICCIOHelper = {
         Buf.PDU_HEX_OCTET_SIZE));
 
     // Read Structure of EF, data[13]
     let efType = GsmPDUHelper.readHexOctet();
     if (efType != options.type) {
       throw new Error("Expected EF type " + options.type + " but read " + efType);
     }
 
+    // TODO: Bug 952025.
     // Length of a record, data[14].
     // Only available for LINEAR_FIXED and CYCLIC.
     if (efType == EF_TYPE_LINEAR_FIXED || efType == EF_TYPE_CYCLIC) {
       options.recordSize = GsmPDUHelper.readHexOctet();
       options.totalRecords = options.fileSize / options.recordSize;
     } else {
       Buf.seekIncoming(1 * Buf.PDU_HEX_OCTET_SIZE);
     }
-
-    Buf.readStringDelimiter(strLen);
-
-    if (options.callback) {
-      options.callback(options);
-    }
   },
 
   /**
    * Process a ICC_COMMAND_READ_RECORD type command for REQUEST_SIM_IO.
    */
   processICCIOReadRecord: function processICCIOReadRecord(options) {
     if (options.callback) {
       options.callback(options);