mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-01 06:35:42 +00:00
098e4596c2
--HG-- extra : rebase_source : fe3effc50ea11ee9a4292d127150b7bf92fb7634
155 lines
4.4 KiB
JavaScript
155 lines
4.4 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
"use strict";
|
|
|
|
let Cu = SpecialPowers.wrap(Components).utils;
|
|
let RIL = {};
|
|
|
|
Cu.import("resource://gre/modules/ril_consts.js", RIL);
|
|
|
|
// Only bring in what we need from ril_worker/RadioInterfaceLayer here. Reusing
|
|
// that code turns out to be a nightmare, so there is some code duplication.
|
|
let PDUBuilder = {
|
|
toHexString: function toHexString(n, length) {
|
|
let str = n.toString(16);
|
|
if (str.length < length) {
|
|
for (let i = 0; i < length - str.length; i++) {
|
|
str = "0" + str;
|
|
}
|
|
}
|
|
return str.toUpperCase();
|
|
},
|
|
|
|
writeUint16: function writeUint16(value) {
|
|
this.buf += (value & 0xff).toString(16).toUpperCase();
|
|
this.buf += ((value >> 8) & 0xff).toString(16).toUpperCase();
|
|
},
|
|
|
|
writeHexOctet: function writeHexOctet(octet) {
|
|
this.buf += this.toHexString(octet, 2);
|
|
},
|
|
|
|
writeSwappedNibbleBCD: function writeSwappedNibbleBCD(data) {
|
|
data = data.toString();
|
|
let zeroCharCode = '0'.charCodeAt(0);
|
|
|
|
for (let i = 0; i < data.length; i += 2) {
|
|
let low = data.charCodeAt(i) - zeroCharCode;
|
|
let high;
|
|
if (i + 1 < data.length) {
|
|
high = data.charCodeAt(i + 1) - zeroCharCode;
|
|
} else {
|
|
high = 0xF;
|
|
}
|
|
|
|
this.writeHexOctet((high << 4) | low);
|
|
}
|
|
},
|
|
|
|
writeStringAsSeptets: function writeStringAsSeptets(message,
|
|
paddingBits,
|
|
langIndex,
|
|
langShiftIndex)
|
|
{
|
|
const langTable = RIL.PDU_NL_LOCKING_SHIFT_TABLES[langIndex];
|
|
const langShiftTable = RIL.PDU_NL_SINGLE_SHIFT_TABLES[langShiftIndex];
|
|
|
|
let dataBits = paddingBits;
|
|
let data = 0;
|
|
for (let i = 0; i < message.length; i++) {
|
|
let septet = langTable.indexOf(message[i]);
|
|
if (septet == RIL.PDU_NL_EXTENDED_ESCAPE) {
|
|
continue;
|
|
}
|
|
|
|
if (septet >= 0) {
|
|
data |= septet << dataBits;
|
|
dataBits += 7;
|
|
} else {
|
|
septet = langShiftTable.indexOf(message[i]);
|
|
if (septet == -1) {
|
|
throw new Error(message[i] + " not in 7 bit alphabet "
|
|
+ langIndex + ":" + langShiftIndex + "!");
|
|
}
|
|
|
|
if (septet == RIL.PDU_NL_RESERVED_CONTROL) {
|
|
continue;
|
|
}
|
|
|
|
data |= RIL.PDU_NL_EXTENDED_ESCAPE << dataBits;
|
|
dataBits += 7;
|
|
data |= septet << dataBits;
|
|
dataBits += 7;
|
|
}
|
|
|
|
for (; dataBits >= 8; dataBits -= 8) {
|
|
this.writeHexOctet(data & 0xFF);
|
|
data >>>= 8;
|
|
}
|
|
}
|
|
|
|
if (dataBits != 0) {
|
|
this.writeHexOctet(data & 0xFF);
|
|
}
|
|
},
|
|
|
|
buildAddress: function buildAddress(address) {
|
|
let addressFormat = RIL.PDU_TOA_ISDN; // 81
|
|
if (address[0] == '+') {
|
|
addressFormat = RIL.PDU_TOA_INTERNATIONAL | RIL.PDU_TOA_ISDN; // 91
|
|
address = address.substring(1);
|
|
}
|
|
|
|
this.buf = "";
|
|
this.writeHexOctet(address.length);
|
|
this.writeHexOctet(addressFormat);
|
|
this.writeSwappedNibbleBCD(address);
|
|
|
|
return this.buf;
|
|
},
|
|
|
|
// assumes 7 bit encoding
|
|
buildUserData: function buildUserData(options) {
|
|
let headerLength = 0;
|
|
this.buf = "";
|
|
if (options.headers) {
|
|
for each (let header in options.headers) {
|
|
headerLength += 2; // id + length octets
|
|
if (header.octets) {
|
|
headerLength += header.octets.length;
|
|
}
|
|
};
|
|
}
|
|
|
|
let encodedBodyLength = options.body.length;
|
|
let headerOctets = (headerLength ? headerLength + 1 : 0);
|
|
|
|
let paddingBits;
|
|
let userDataLengthInSeptets;
|
|
let headerSeptets = Math.ceil(headerOctets * 8 / 7);
|
|
userDataLengthInSeptets = headerSeptets + encodedBodyLength;
|
|
paddingBits = headerSeptets * 7 - headerOctets * 8;
|
|
|
|
this.writeHexOctet(userDataLengthInSeptets);
|
|
if (options.headers) {
|
|
this.writeHexOctet(headerLength);
|
|
|
|
for each (let header in options.headers) {
|
|
this.writeHexOctet(header.id);
|
|
this.writeHexOctet(header.length);
|
|
|
|
if (header.octets) {
|
|
for each (let octet in header.octets) {
|
|
this.writeHexOctet(octet);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
this.writeStringAsSeptets(options.body, paddingBits,
|
|
RIL.PDU_NL_IDENTIFIER_DEFAULT,
|
|
RIL.PDU_NL_IDENTIFIER_DEFAULT);
|
|
return this.buf;
|
|
}
|
|
};
|