|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 subscriptLoader.loadSubScript("resource://gre/modules/ril_consts.js", this); |
|
5 |
|
6 function run_test() { |
|
7 run_next_test(); |
|
8 } |
|
9 |
|
10 function _getWorker() { |
|
11 let _postedMessage; |
|
12 let _worker = newWorker({ |
|
13 postRILMessage: function(data) { |
|
14 }, |
|
15 postMessage: function(message) { |
|
16 _postedMessage = message; |
|
17 } |
|
18 }); |
|
19 return { |
|
20 get postedMessage() { |
|
21 return _postedMessage; |
|
22 }, |
|
23 get worker() { |
|
24 return _worker; |
|
25 } |
|
26 }; |
|
27 } |
|
28 |
|
29 /* |
|
30 * Helper function to covert a HEX string to a byte array. |
|
31 * |
|
32 * @param hexString |
|
33 * A hexadecimal string of which the length is even. |
|
34 */ |
|
35 function hexStringToBytes(hexString) { |
|
36 let bytes = []; |
|
37 |
|
38 let length = hexString.length; |
|
39 |
|
40 for (let i = 0; i < length; i += 2) { |
|
41 bytes.push(Number.parseInt(hexString.substr(i, 2), 16)); |
|
42 } |
|
43 |
|
44 return bytes; |
|
45 } |
|
46 |
|
47 /* |
|
48 * Helper function to covert a byte array to a HEX string. |
|
49 * |
|
50 * @param bytes |
|
51 * Could be a regular byte array or Uint8Array. |
|
52 */ |
|
53 function bytesToHexString(bytes) { |
|
54 let hexString = ""; |
|
55 let hex; |
|
56 |
|
57 for (let i = 0; i < bytes.length; i++) { |
|
58 hex = bytes[i].toString(16).toUpperCase(); |
|
59 if (hex.length === 1) { |
|
60 hexString += "0"; |
|
61 } |
|
62 hexString += hex; |
|
63 } |
|
64 |
|
65 return hexString; |
|
66 } |
|
67 |
|
68 /* |
|
69 * Helper function to ecode Opaque UserData |
|
70 * |
|
71 * @param msg_type |
|
72 * PDU_CDMA_MSG_TYPE_SUBMIT or PDU_CDMA_MSG_TYPE_DELIVER |
|
73 * @param data |
|
74 * The byte array of opaque data to be encoded. |
|
75 */ |
|
76 function encodeOpaqueUserData(bitBufferHelper, options) { |
|
77 let bearerDataBuffer = []; |
|
78 bitBufferHelper.startWrite(bearerDataBuffer); |
|
79 |
|
80 // Msg-Id |
|
81 bitBufferHelper.writeBits(PDU_CDMA_MSG_USERDATA_MSG_ID, 8); |
|
82 bitBufferHelper.writeBits(3, 8); |
|
83 bitBufferHelper.writeBits(options.msg_type, 4); // MSG_TYPE |
|
84 bitBufferHelper.writeBits(1, 16); // MSG_ID |
|
85 bitBufferHelper.flushWithPadding(); // HEADER_IND (1) + RESERVED (3) |
|
86 |
|
87 // User Data |
|
88 bitBufferHelper.writeBits(PDU_CDMA_MSG_USERDATA_BODY, 8); |
|
89 let dataLength = options.data.length; |
|
90 bitBufferHelper.writeBits(2 + dataLength, 8); // 2 bytes for MSG_ENCODING, NUM_FIELDS |
|
91 bitBufferHelper.writeBits(PDU_CDMA_MSG_CODING_OCTET, 5); //MSG_ENCODING |
|
92 // MSG_TYPE is omitted if MSG_ENCODING is CODING_OCTET |
|
93 bitBufferHelper.writeBits(dataLength, 8); // NUM_FIELDS |
|
94 for (let i = 0; i < dataLength; i++) { // CHARi |
|
95 bitBufferHelper.writeBits(options.data[i], 8); |
|
96 } |
|
97 bitBufferHelper.flushWithPadding(); // RESERVED (3 filling bits) |
|
98 |
|
99 return bearerDataBuffer; |
|
100 } |
|
101 |
|
102 function newSmsParcel(cdmaPduHelper, pdu) { |
|
103 return newIncomingParcel(-1, |
|
104 RESPONSE_TYPE_UNSOLICITED, |
|
105 UNSOLICITED_RESPONSE_CDMA_NEW_SMS, |
|
106 pduToParcelData(cdmaPduHelper, pdu)); |
|
107 } |
|
108 |
|
109 /* |
|
110 * Helper function to encode PDU into Parcel. |
|
111 * See ril_cdma_sms.h for the structure definition of RIL_CDMA_SMS_Message |
|
112 * |
|
113 * @param teleservice |
|
114 * The Teleservice-Id of this PDU. |
|
115 * See PDU_CDMA_MSG_TELESERIVCIE_ID_XXX in ril_const.js. |
|
116 * @param address |
|
117 * The Orginating or Destinating address. |
|
118 * @param bearerData |
|
119 * The byte array of the encoded bearer data. |
|
120 */ |
|
121 function pduToParcelData(cdmaPduHelper, pdu) { |
|
122 |
|
123 let addrInfo = cdmaPduHelper.encodeAddr(pdu.address); |
|
124 // Teleservice, isServicePresent, ServiceCategory, |
|
125 // addrInfo {digitMode, numberMode, numberType, numberPlan, address.length, address} |
|
126 // Sub Address |
|
127 // bearerData length, bearerData. |
|
128 let dataLength = 4 + 4 + 4 |
|
129 + (5 + addrInfo.address.length) * 4 |
|
130 + 3 * 4 |
|
131 + 4 + pdu.bearerData.length * 4; |
|
132 |
|
133 let data = new Uint8Array(dataLength); |
|
134 let offset = 0; |
|
135 |
|
136 function writeInt(value) { |
|
137 data[offset++] = value & 0xFF; |
|
138 data[offset++] = (value >> 8) & 0xFF; |
|
139 data[offset++] = (value >> 16) & 0xFF; |
|
140 data[offset++] = (value >> 24) & 0xFF; |
|
141 } |
|
142 |
|
143 function writeByte(value) { |
|
144 data[offset++] = value & 0xFF; |
|
145 data[offset++] = 0; |
|
146 data[offset++] = 0; |
|
147 data[offset++] = 0; |
|
148 } |
|
149 |
|
150 // Teleservice |
|
151 writeInt(pdu.teleservice); |
|
152 |
|
153 // isServicePresent |
|
154 writeByte(0); |
|
155 |
|
156 // ServiceCategory |
|
157 writeInt(PDU_CDMA_MSG_CATEGORY_UNSPEC); |
|
158 |
|
159 // AddrInfo |
|
160 writeByte(addrInfo.digitMode); |
|
161 writeByte(addrInfo.numberMode); |
|
162 writeByte(addrInfo.numberType); |
|
163 writeByte(addrInfo.numberPlan); |
|
164 let addressLength = addrInfo.address.length; |
|
165 writeByte(addressLength); |
|
166 for (let i = 0; i < addressLength; i++) { |
|
167 writeByte(addrInfo.address[i]); |
|
168 } |
|
169 |
|
170 // Subaddress |
|
171 writeByte(0); |
|
172 writeByte(0); |
|
173 writeByte(0); |
|
174 |
|
175 // Bearer Data Length |
|
176 let dataLength = pdu.bearerData.length; |
|
177 writeByte(dataLength); |
|
178 |
|
179 // Bearer Data |
|
180 for (let i = 0; i < dataLength; i++) { |
|
181 writeByte(pdu.bearerData[i]); |
|
182 } |
|
183 |
|
184 return data; |
|
185 } |
|
186 |
|
187 /** |
|
188 * Verify CDMA SMS Delivery ACK Message. |
|
189 */ |
|
190 add_test(function test_processCdmaSmsStatusReport() { |
|
191 let workerHelper = _getWorker(); |
|
192 let worker = workerHelper.worker; |
|
193 let context = worker.ContextPool._contexts[0]; |
|
194 |
|
195 function test_StatusReport(errorClass, msgStatus) { |
|
196 let msgId = 0; |
|
197 let sentSmsMap = context.RIL._pendingSentSmsMap; |
|
198 |
|
199 sentSmsMap[msgId] = {}; |
|
200 |
|
201 let message = { |
|
202 SMSC: "", |
|
203 mti: 0, |
|
204 udhi: 0, |
|
205 sender: "0987654321", |
|
206 recipient: null, |
|
207 pid: PDU_PID_DEFAULT, |
|
208 epid: PDU_PID_DEFAULT, |
|
209 dcs: 0, |
|
210 mwi: null, |
|
211 replace: false, |
|
212 header: null, |
|
213 body: "Status: Sent, Dest: 0987654321", |
|
214 data: null, |
|
215 timestamp: new Date().valueOf(), |
|
216 language: null, |
|
217 status: null, |
|
218 scts: null, |
|
219 dt: null, |
|
220 encoding: PDU_CDMA_MSG_CODING_7BITS_ASCII, |
|
221 messageClass: GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], |
|
222 messageType: PDU_CDMA_MSG_TYPE_P2P, |
|
223 serviceCategory: 0, |
|
224 subMsgType: PDU_CDMA_MSG_TYPE_DELIVER_ACK, |
|
225 msgId: msgId, |
|
226 errorClass: errorClass, |
|
227 msgStatus: msgStatus |
|
228 }; |
|
229 |
|
230 context.RIL._processCdmaSmsStatusReport(message); |
|
231 |
|
232 let postedMessage = workerHelper.postedMessage; |
|
233 |
|
234 // Check if pending token is removed. |
|
235 do_check_true((errorClass === 2) ? !!sentSmsMap[msgId] : !sentSmsMap[msgId]); |
|
236 |
|
237 // Check the response message accordingly. |
|
238 if (errorClass === -1) { |
|
239 // Check if the report is treated as normal incoming SMS |
|
240 do_check_eq("sms-received", postedMessage.rilMessageType); |
|
241 } else if (errorClass === 2) { |
|
242 // Do nothing. |
|
243 } else { |
|
244 // Check Delivery Status |
|
245 if (errorClass === 0) { |
|
246 do_check_eq(postedMessage.deliveryStatus, GECKO_SMS_DELIVERY_STATUS_SUCCESS); |
|
247 } else { |
|
248 do_check_eq(postedMessage.deliveryStatus, GECKO_SMS_DELIVERY_STATUS_ERROR); |
|
249 } |
|
250 } |
|
251 } |
|
252 |
|
253 test_StatusReport(-1, -1); // Message Status Sub-parameter is absent. |
|
254 test_StatusReport(0, 0); // 00|000000: no error|Message accepted |
|
255 test_StatusReport(2, 4); // 10|000100: temporary condition|Network congestion |
|
256 test_StatusReport(3, 5); // 11|000101: permanent condition|Network error |
|
257 |
|
258 run_next_test(); |
|
259 }); |
|
260 |
|
261 /** |
|
262 * Verify WAP Push over CDMA SMS Message. |
|
263 */ |
|
264 add_test(function test_processCdmaSmsWapPush() { |
|
265 let workerHelper = _getWorker(), |
|
266 worker = workerHelper.worker, |
|
267 context = worker.ContextPool._contexts[0], |
|
268 bitBufferHelper = context.BitBufferHelper, |
|
269 cdmaPduHelper = context.CdmaPDUHelper; |
|
270 |
|
271 function test_CdmaSmsWapPdu(wdpData, reversed) { |
|
272 let orig_address = "0987654321", |
|
273 hexString, |
|
274 fullDataHexString = ""; |
|
275 |
|
276 for (let i = 0; i < wdpData.length; i++) { |
|
277 let dataIndex = (reversed) ? (wdpData.length - i - 1) : i; |
|
278 hexString = "00"; // MSG_TYPE |
|
279 hexString += bytesToHexString([wdpData.length]); // TOTAL_SEG |
|
280 hexString += bytesToHexString([dataIndex]); // SEG_NUM (zero-based) |
|
281 if ((dataIndex === 0)) { |
|
282 hexString += "23F00B84"; // SOURCE_PORT, DEST_PORT for 1st segment |
|
283 } |
|
284 hexString += wdpData[dataIndex]; // WDP DATA |
|
285 |
|
286 do_print("hexString: " + hexString); |
|
287 |
|
288 fullDataHexString += wdpData[i]; |
|
289 |
|
290 let pdu = { |
|
291 teleservice: PDU_CDMA_MSG_TELESERIVCIE_ID_WAP, |
|
292 address: orig_address, |
|
293 bearerData: encodeOpaqueUserData(bitBufferHelper, |
|
294 { msg_type: PDU_CDMA_MSG_TYPE_DELIVER, |
|
295 data: hexStringToBytes(hexString) }) |
|
296 }; |
|
297 |
|
298 worker.onRILMessage(0, newSmsParcel(cdmaPduHelper, pdu)); |
|
299 } |
|
300 |
|
301 let postedMessage = workerHelper.postedMessage; |
|
302 |
|
303 do_print("fullDataHexString: " + fullDataHexString); |
|
304 |
|
305 do_check_eq("sms-received", postedMessage.rilMessageType); |
|
306 do_check_eq(PDU_CDMA_MSG_TELESERIVCIE_ID_WAP, postedMessage.teleservice); |
|
307 do_check_eq(orig_address, postedMessage.sender); |
|
308 do_check_eq(0x23F0, postedMessage.header.originatorPort); |
|
309 do_check_eq(0x0B84, postedMessage.header.destinationPort); |
|
310 do_check_eq(fullDataHexString, bytesToHexString(postedMessage.data)); |
|
311 } |
|
312 |
|
313 // Verify Single WAP PDU |
|
314 test_CdmaSmsWapPdu(["000102030405060708090A0B0C0D0E0F"]); |
|
315 |
|
316 run_next_test(); |
|
317 }); |