|
1 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, |
|
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
4 |
|
5 "use strict"; |
|
6 |
|
7 const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; |
|
8 |
|
9 let WSP = {}; |
|
10 Cu.import("resource://gre/modules/WspPduHelper.jsm", WSP); |
|
11 let WBXML = {}; |
|
12 Cu.import("resource://gre/modules/WbxmlPduHelper.jsm", WBXML); |
|
13 |
|
14 // set to true to see debug messages |
|
15 let DEBUG = WBXML.DEBUG_ALL | false; |
|
16 |
|
17 /** |
|
18 * Public identifier for SI |
|
19 * |
|
20 * @see http://technical.openmobilealliance.org/tech/omna/omna-wbxml-public-docid.aspx |
|
21 */ |
|
22 const PUBLIC_IDENTIFIER_SI = "-//WAPFORUM//DTD SI 1.0//EN"; |
|
23 |
|
24 /** |
|
25 * Parse inline date encoded in OPAQUE format. |
|
26 * |
|
27 * @param data |
|
28 * A wrapped object containing raw PDU data. |
|
29 * @param msg |
|
30 * Target object for decoding. |
|
31 * |
|
32 * @see WAP-167-SERVICEIND-20010731-A, clause 8.2.2 |
|
33 * |
|
34 */ |
|
35 this.OpaqueAsDate = { |
|
36 decode: function decode_opaque_as_date(data) { |
|
37 let size = WSP.UintVar.decode(data); |
|
38 let dateBuf = [0, 0, 0, 0, 0, 0, 0]; |
|
39 |
|
40 // Maximum length for date is 7 bytes. |
|
41 if (size > dateBuf.length) |
|
42 size = dateBuf.length |
|
43 |
|
44 // Read date date, non-specified parts remain 0. |
|
45 for (let i = 0; i < size; i++) { |
|
46 dateBuf[i] = WSP.Octet.decode(data); |
|
47 } |
|
48 |
|
49 // Decode and return result in "YYYY-MM-DDThh:mm:ssZ" form |
|
50 let year = ((dateBuf[0] >> 4) & 0x0F) * 1000 + (dateBuf[0] & 0x0F) * 100 + |
|
51 ((dateBuf[1] >> 4) & 0x0F) * 10 + (dateBuf[1] & 0x0F); |
|
52 let month = ((dateBuf[2] >> 4) & 0x0F) * 10 + (dateBuf[2] & 0x0F); |
|
53 let date = ((dateBuf[3] >> 4) & 0x0F) * 10 + (dateBuf[3] & 0x0F); |
|
54 let hour = ((dateBuf[4] >> 4) & 0x0F) * 10 + (dateBuf[4] & 0x0F); |
|
55 let minute = ((dateBuf[5] >> 4) & 0x0F) * 10 + (dateBuf[5] & 0x0F); |
|
56 let second = ((dateBuf[6] >> 4) & 0x0F) * 10 + (dateBuf[6] & 0x0F); |
|
57 let dateValue = new Date(Date.UTC(year, month - 1, date, hour, minute, second)); |
|
58 |
|
59 return dateValue.toISOString().replace(".000", ""); |
|
60 }, |
|
61 }; |
|
62 |
|
63 this.PduHelper = { |
|
64 |
|
65 /** |
|
66 * @param data |
|
67 * A wrapped object containing raw PDU data. |
|
68 * @param contentType |
|
69 * Content type of incoming SI message, should be "text/vnd.wap.si" or |
|
70 * "application/vnd.wap.sic". |
|
71 * |
|
72 * @return A message object containing attribute content and contentType. |
|
73 * |content| will contain string of decoded SI message if successfully |
|
74 * decoded, or raw data if failed. |
|
75 * |contentType| will be string representing corresponding type of |
|
76 * content. |
|
77 */ |
|
78 parse: function parse_si(data, contentType) { |
|
79 // We only need content and contentType |
|
80 let msg = { |
|
81 contentType: contentType |
|
82 }; |
|
83 |
|
84 /** |
|
85 * Message is compressed by WBXML, decode into string. |
|
86 * |
|
87 * @see WAP-192-WBXML-20010725-A |
|
88 */ |
|
89 if (contentType === "application/vnd.wap.sic") { |
|
90 let globalTokenOverride = {}; |
|
91 globalTokenOverride[0xC3] = { |
|
92 number: 0xC3, |
|
93 coder: OpaqueAsDate |
|
94 }; |
|
95 |
|
96 let appToken = { |
|
97 publicId: PUBLIC_IDENTIFIER_SI, |
|
98 tagTokenList: SI_TAG_FIELDS, |
|
99 attrTokenList: SI_ATTRIBUTE_FIELDS, |
|
100 valueTokenList: SI_VALUE_FIELDS, |
|
101 globalTokenOverride: globalTokenOverride |
|
102 } |
|
103 |
|
104 try { |
|
105 let parseResult = WBXML.PduHelper.parse(data, appToken); |
|
106 msg.content = parseResult.content; |
|
107 msg.contentType = "text/vnd.wap.si"; |
|
108 } catch (e) { |
|
109 // Provide raw data if we failed to parse. |
|
110 msg.content = data.array; |
|
111 } |
|
112 return msg; |
|
113 } |
|
114 |
|
115 /** |
|
116 * Message is plain text, transform raw to string. |
|
117 */ |
|
118 try { |
|
119 let stringData = WSP.Octet.decodeMultiple(data, data.array.length); |
|
120 msg.content = WSP.PduHelper.decodeStringContent(stringData, "UTF-8"); |
|
121 } catch (e) { |
|
122 // Provide raw data if we failed to parse. |
|
123 msg.content = data.array; |
|
124 } |
|
125 return msg; |
|
126 |
|
127 } |
|
128 }; |
|
129 |
|
130 /** |
|
131 * Tag tokens |
|
132 * |
|
133 * @see WAP-167-SERVICEIND-20010731-A, clause 8.3.1 |
|
134 */ |
|
135 const SI_TAG_FIELDS = (function () { |
|
136 let names = {}; |
|
137 function add(name, codepage, number) { |
|
138 let entry = { |
|
139 name: name, |
|
140 number: number, |
|
141 }; |
|
142 if (!names[codepage]) { |
|
143 names[codepage] = {}; |
|
144 } |
|
145 names[codepage][number] = entry; |
|
146 } |
|
147 |
|
148 add("si", 0, 0x05); |
|
149 add("indication", 0, 0x06); |
|
150 add("info", 0, 0x07); |
|
151 add("item", 0, 0x08); |
|
152 |
|
153 return names; |
|
154 })(); |
|
155 |
|
156 /** |
|
157 * Attribute Tokens |
|
158 * |
|
159 * @see WAP-167-SERVICEIND-20010731-A, clause 8.3.2 |
|
160 */ |
|
161 const SI_ATTRIBUTE_FIELDS = (function () { |
|
162 let names = {}; |
|
163 function add(name, value, codepage, number) { |
|
164 let entry = { |
|
165 name: name, |
|
166 value: value, |
|
167 number: number, |
|
168 }; |
|
169 if (!names[codepage]) { |
|
170 names[codepage] = {}; |
|
171 } |
|
172 names[codepage][number] = entry; |
|
173 } |
|
174 |
|
175 add("action", "signal-none", 0, 0x05); |
|
176 add("action", "signal-low", 0, 0x06); |
|
177 add("action", "signal-medium", 0, 0x07); |
|
178 add("action", "signal-high", 0, 0x08); |
|
179 add("action", "delete", 0, 0x09); |
|
180 add("created", "", 0, 0x0A); |
|
181 add("href", "", 0, 0x0B); |
|
182 add("href", "http://", 0, 0x0C); |
|
183 add("href", "http://www.", 0, 0x0D); |
|
184 add("href", "https://", 0, 0x0E); |
|
185 add("href", "https://www.", 0, 0x0F); |
|
186 add("si-expires", "", 0, 0x10); |
|
187 add("si-id", "", 0, 0x11); |
|
188 add("class", "", 0, 0x12); |
|
189 |
|
190 return names; |
|
191 })(); |
|
192 |
|
193 const SI_VALUE_FIELDS = (function () { |
|
194 let names = {}; |
|
195 function add(value, codepage, number) { |
|
196 let entry = { |
|
197 value: value, |
|
198 number: number, |
|
199 }; |
|
200 if (!names[codepage]) { |
|
201 names[codepage] = {}; |
|
202 } |
|
203 names[codepage][number] = entry; |
|
204 } |
|
205 |
|
206 add(".com/", 0, 0x85); |
|
207 add(".edu/", 0, 0x86); |
|
208 add(".net/", 0, 0x87); |
|
209 add(".org/", 0, 0x88); |
|
210 |
|
211 return names; |
|
212 })(); |
|
213 |
|
214 this.EXPORTED_SYMBOLS = [ |
|
215 // Parser |
|
216 "PduHelper", |
|
217 ]; |