dom/voicemail/test/marionette/pdu_builder.js

changeset 0
6474c204b198
equal deleted inserted replaced
-1:000000000000 0:02cfce5c8765
1 /* Any copyright is dedicated to the Public Domain.
2 * http://creativecommons.org/publicdomain/zero/1.0/ */
3 "use strict";
4
5 let RIL = {};
6 SpecialPowers.Cu.import("resource://gre/modules/ril_consts.js", RIL);
7
8 // Only bring in what we need from ril_worker/RadioInterfaceLayer here. Reusing
9 // that code turns out to be a nightmare, so there is some code duplication.
10 let PDUBuilder = {
11 toHexString: function(n, length) {
12 let str = n.toString(16);
13 if (str.length < length) {
14 for (let i = 0; i < length - str.length; i++) {
15 str = "0" + str;
16 }
17 }
18 return str.toUpperCase();
19 },
20
21 writeUint16: function(value) {
22 this.buf += (value & 0xff).toString(16).toUpperCase();
23 this.buf += ((value >> 8) & 0xff).toString(16).toUpperCase();
24 },
25
26 writeHexOctet: function(octet) {
27 this.buf += this.toHexString(octet, 2);
28 },
29
30 writeSwappedNibbleBCD: function(data) {
31 data = data.toString();
32 let zeroCharCode = '0'.charCodeAt(0);
33
34 for (let i = 0; i < data.length; i += 2) {
35 let low = data.charCodeAt(i) - zeroCharCode;
36 let high;
37 if (i + 1 < data.length) {
38 high = data.charCodeAt(i + 1) - zeroCharCode;
39 } else {
40 high = 0xF;
41 }
42
43 this.writeHexOctet((high << 4) | low);
44 }
45 },
46
47 writeStringAsSeptets: function(message, paddingBits, langIndex,
48 langShiftIndex) {
49 const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[langIndex];
50 const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex];
51
52 let dataBits = paddingBits;
53 let data = 0;
54 for (let i = 0; i < message.length; i++) {
55 let septet = langTable.indexOf(message[i]);
56 if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) {
57 continue;
58 }
59
60 if (septet >= 0) {
61 data |= septet << dataBits;
62 dataBits += 7;
63 } else {
64 septet = langShiftTable.indexOf(message[i]);
65 if (septet == -1) {
66 throw new Error(message[i] + " not in 7 bit alphabet "
67 + langIndex + ":" + langShiftIndex + "!");
68 }
69
70 if (septet == RIL.PDU_NL_RESERVED_CONTROL) {
71 continue;
72 }
73
74 data |= RIL.PDU_NL_EXTENDED_ESCAPE << dataBits;
75 dataBits += 7;
76 data |= septet << dataBits;
77 dataBits += 7;
78 }
79
80 for (; dataBits >= 8; dataBits -= 8) {
81 this.writeHexOctet(data & 0xFF);
82 data >>>= 8;
83 }
84 }
85
86 if (dataBits != 0) {
87 this.writeHexOctet(data & 0xFF);
88 }
89 },
90
91 buildAddress: function(address) {
92 let addressFormat = RIL.PDU_TOA_ISDN; // 81
93 if (address[0] == '+') {
94 addressFormat = RIL.PDU_TOA_INTERNATIONAL | RIL.PDU_TOA_ISDN; // 91
95 address = address.substring(1);
96 }
97
98 this.buf = "";
99 this.writeHexOctet(address.length);
100 this.writeHexOctet(addressFormat);
101 this.writeSwappedNibbleBCD(address);
102
103 return this.buf;
104 },
105
106 // assumes 7 bit encoding
107 buildUserData: function(options) {
108 let headerLength = 0;
109 this.buf = "";
110 if (options.headers) {
111 for each (let header in options.headers) {
112 headerLength += 2; // id + length octets
113 if (header.octets) {
114 headerLength += header.octets.length;
115 }
116 };
117 }
118
119 let encodedBodyLength = options.body.length;
120 let headerOctets = (headerLength ? headerLength + 1 : 0);
121
122 let paddingBits;
123 let userDataLengthInSeptets;
124 let headerSeptets = Math.ceil(headerOctets * 8 / 7);
125 userDataLengthInSeptets = headerSeptets + encodedBodyLength;
126 paddingBits = headerSeptets * 7 - headerOctets * 8;
127
128 this.writeHexOctet(userDataLengthInSeptets);
129 if (options.headers) {
130 this.writeHexOctet(headerLength);
131
132 for each (let header in options.headers) {
133 this.writeHexOctet(header.id);
134 this.writeHexOctet(header.length);
135
136 if (header.octets) {
137 for each (let octet in header.octets) {
138 this.writeHexOctet(octet);
139 }
140 }
141 }
142 }
143
144 this.writeStringAsSeptets(options.body, paddingBits,
145 RIL.PDU_NL_IDENTIFIER_DEFAULT,
146 RIL.PDU_NL_IDENTIFIER_DEFAULT);
147 return this.buf;
148 }
149 };

mercurial