summaryrefslogtreecommitdiffstats
path: root/dom/system/gonk/ril_worker_buf_object.js
blob: 70018c5b2a069e87d59b268955d5c27d591c21a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/* global require */
/* global DEBUG, DEBUG_WORKER */
/* global RESPONSE_TYPE_SOLICITED */
/* global RESPONSE_TYPE_UNSOLICITED */

"use strict";

/**
 * This is a specialized worker buffer for the Parcel protocol.
 *
 * NOTE: To prevent including/importing twice, this file should be included
 * in a file which already includes 'ril_consts.js' and 'require.js'.
 */
(function(exports) {

  // Set to true in ril_consts.js to see debug messages
  let DEBUG = DEBUG_WORKER;
  // Need to inherit it.
  let Buf = require("resource://gre/modules/workers/worker_buf.js").Buf;

  let BufObject = function(aContext) {
    this.context = aContext;
    // This gets incremented each time we send out a parcel.
    this.mToken = 1;
    // Maps tokens we send out with requests to the request type, so that
    // when we get a response parcel back, we know what request it was for.
    this.mTokenRequestMap = new Map();
    // This is because the underlying 'Buf' is still using the 'init' pattern, so
    // this derived one needs to invoke it.
    // Using 'apply' style to mark it's a parent method calling explicitly.
    Buf._init.apply(this);

    // Remapping the request type to different values based on RIL version.
    // We only have to do this for SUBSCRIPTION right now, so I just make it
    // simple. A generic logic or structure could be discussed if we have more
    // use cases, especially the cases from different partners.
    this._requestMap = {};
    // RIL version 8.
    // For the CAF's proprietary parcels. Please see
    // https://www.codeaurora.org/cgit/quic/la/platform/hardware/ril/tree/include/telephony/ril.h?h=b2g_jb_3.2
    let map = {};
    map[REQUEST_SET_UICC_SUBSCRIPTION] = 114;
    map[REQUEST_SET_DATA_SUBSCRIPTION] = 115;
    this._requestMap[8] = map;
    // RIL version 9.
    // For the CAF's proprietary parcels. Please see
    // https://www.codeaurora.org/cgit/quic/la/platform/hardware/ril/tree/include/telephony/ril.h?h=b2g_kk_3.5
    map = {};
    map[REQUEST_SET_UICC_SUBSCRIPTION] = 115;
    map[REQUEST_SET_DATA_SUBSCRIPTION] = 116;
    this._requestMap[9] = map;
  };

  /**
   * "inherit" the basic worker buffer.
   */
  BufObject.prototype = Object.create(Buf);

  /**
   * Process one parcel.
   */
  BufObject.prototype.processParcel = function() {
    let responseType = this.readInt32();

    let requestType, options;
    if (responseType == RESPONSE_TYPE_SOLICITED) {
      let token = this.readInt32();
      let error = this.readInt32();

      options = this.mTokenRequestMap.get(token);
      if (!options) {
        if (DEBUG) {
          this.context.debug("Suspicious uninvited request found: " +
                             token + ". Ignored!");
        }
        return;
      }

      this.mTokenRequestMap.delete(token);
      requestType = options.rilRequestType;

      if (error !== ERROR_SUCCESS) {
        options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[error] ||
                           GECKO_ERROR_UNSPECIFIED_ERROR;
      }
      if (DEBUG) {
        this.context.debug("Solicited response for request type " + requestType +
                           ", token " + token + ", error " + error);
      }
    } else if (responseType == RESPONSE_TYPE_UNSOLICITED) {
      requestType = this.readInt32();
      if (DEBUG) {
        this.context.debug("Unsolicited response for request type " + requestType);
      }
    } else {
      if (DEBUG) {
        this.context.debug("Unknown response type: " + responseType);
      }
      return;
    }

    this.context.RIL.handleParcel(requestType, this.readAvailable, options);
  };

  /**
   * Start a new outgoing parcel.
   *
   * @param type
   *        Integer specifying the request type.
   * @param options [optional]
   *        Object containing information about the request, e.g. the
   *        original main thread message object that led to the RIL request.
   */
  BufObject.prototype.newParcel = function(type, options) {
    if (DEBUG) {
      this.context.debug("New outgoing parcel of type " + type);
    }

    // We're going to leave room for the parcel size at the beginning.
    this.outgoingIndex = this.PARCEL_SIZE_SIZE;
    this.writeInt32(this._reMapRequestType(type));
    this.writeInt32(this.mToken);

    if (!options) {
      options = {};
    }
    options.rilRequestType = type;
    this.mTokenRequestMap.set(this.mToken, options);
    this.mToken++;
    return this.mToken;
  };

  BufObject.prototype.simpleRequest = function(type, options) {
    this.newParcel(type, options);
    this.sendParcel();
  };

  BufObject.prototype.onSendParcel = function(parcel) {
    self.postRILMessage(this.context.clientId, parcel);
  };

  /**
   * Remapping the request type to different values based on RIL version.
   * We only have to do this for SUBSCRIPTION right now, so I just make it
   * simple. A generic logic or structure could be discussed if we have more
   * use cases, especially the cases from different partners.
   */
  BufObject.prototype._reMapRequestType = function(type) {
    for (let version in this._requestMap) {
      if (this.context.RIL.version <= version) {
        let newType = this._requestMap[version][type];
        if (newType) {
          if (DEBUG) {
            this.context.debug("Remap request type to " + newType);
          }
          return newType;
        }
      }
    }
    return type;
  };

  // Before we make sure to form it as a module would not add extra
  // overhead of module loading, we need to define it in this way
  // rather than 'module.exports' it as a module component.
  exports.BufObject = BufObject;
})(self); // in worker self is the global