mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 778093 - Part 5/9: support base GSM CBS message, r=hsinyi
This commit is contained in:
parent
94efa23152
commit
edebfa589d
@ -937,7 +937,33 @@ this.CB_FORMAT_ETWS = 1;
|
||||
this.CB_FORMAT_CMAS = 2;
|
||||
this.CB_FORMAT_UMTS = 3;
|
||||
|
||||
// CBS Data Coding Scheme: Language groups
|
||||
// see 3GPP TS 23.038 section 5
|
||||
this.CB_DCS_LANG_GROUP_1 = [
|
||||
"de", "en", "it", "fr", "es", "nl", "sv", "da", "pt", "fi",
|
||||
"no", "el", "tr", "hu", "pl", null
|
||||
];
|
||||
this.CB_DCS_LANG_GROUP_2 = [
|
||||
"cs", "he", "ar", "ru", "is", null, null, null, null, null,
|
||||
null, null, null, null, null, null
|
||||
];
|
||||
|
||||
// User Data max length in septets
|
||||
this.CB_MAX_CONTENT_7BIT = 93;
|
||||
// User Data max length in octets
|
||||
this.CB_MAX_CONTENT_8BIT = 82;
|
||||
// User Data max length in chars
|
||||
this.CB_MAX_CONTENT_UCS2 = 41;
|
||||
|
||||
this.CB_MESSAGE_SIZE_ETWS = 56;
|
||||
this.CB_MESSAGE_SIZE_GSM = 88;
|
||||
|
||||
// GSM Cell Broadcast Geographical Scope
|
||||
// See 3GPP TS 23.041 clause 9.4.1.2.1
|
||||
this.CB_GSM_GEOGRAPHICAL_SCOPE_CELL_WIDE_IMMEDIATE = 0;
|
||||
this.CB_GSM_GEOGRAPHICAL_SCOPE_PLMN_WIDE = 1;
|
||||
this.CB_GSM_GEOGRAPHICAL_SCOPE_LOCATION_AREA_WIDE = 2;
|
||||
this.CB_GSM_GEOGRAPHICAL_SCOPE_CELL_WIDE = 3;
|
||||
|
||||
// GSM Cell Broadcast Geographical Scope
|
||||
// See 3GPP TS 23.041 clause 9.4.1.2.1
|
||||
@ -948,6 +974,11 @@ this.CB_GSM_GEOGRAPHICAL_SCOPE_NAMES = [
|
||||
"cell"
|
||||
];
|
||||
|
||||
// GSM Cell Broadcast Message Identifiers
|
||||
// see 3GPP TS 23.041 clause 9.4.1.2.2
|
||||
this.CB_GSM_MESSAGEID_ETWS_BEGIN = 0x1100;
|
||||
this.CB_GSM_MESSAGEID_ETWS_END = 0x1107;
|
||||
|
||||
// ETWS Warning-Type
|
||||
// see 3GPP TS 23.041 clause 9.3.24
|
||||
this.CB_ETWS_WARNING_TYPE_NAMES = [
|
||||
@ -1141,6 +1172,8 @@ this.PDU_DCS_MSG_CLASS_0 = 0x00;
|
||||
this.PDU_DCS_MSG_CLASS_1 = 0x01;
|
||||
this.PDU_DCS_MSG_CLASS_2 = 0x02;
|
||||
this.PDU_DCS_MSG_CLASS_3 = 0x03;
|
||||
this.PDU_DCS_MSG_CLASS_USER_1 = 0x04;
|
||||
this.PDU_DCS_MSG_CLASS_USER_2 = 0x05;
|
||||
this.PDU_DCS_CODING_GROUP_BITS = 0xF0;
|
||||
this.PDU_DCS_MSG_CLASS_BITS = 0x03;
|
||||
this.PDU_DCS_MWI_ACTIVE_BITS = 0x08;
|
||||
@ -1157,6 +1190,8 @@ GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_0] = "class-0";
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_1] = "class-1";
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2] = "class-2";
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_3] = "class-3";
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_USER_1] = "user-1";
|
||||
GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_USER_2] = "user-2";
|
||||
|
||||
// Because service center timestamp omit the century. Yay.
|
||||
this.PDU_TIMESTAMP_YEAR_OFFSET = 2000;
|
||||
|
@ -270,6 +270,21 @@ let Buf = {
|
||||
return this.readUint8Unchecked();
|
||||
},
|
||||
|
||||
readUint8Array: function readUint8Array(length) {
|
||||
// Translate to 0..currentParcelSize
|
||||
let last = this.currentParcelSize - this.readAvailable;
|
||||
last += (length - 1);
|
||||
this.ensureIncomingAvailable(last);
|
||||
|
||||
let array = new Uint8Array(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
array[i] = this.readUint8Unchecked();
|
||||
}
|
||||
|
||||
this.readAvailable -= length;
|
||||
return array;
|
||||
},
|
||||
|
||||
readUint16: function readUint16() {
|
||||
return this.readUint8() | this.readUint8() << 8;
|
||||
},
|
||||
@ -6434,7 +6449,7 @@ let GsmPDUHelper = {
|
||||
*/
|
||||
readDataCodingScheme: function readDataCodingScheme(msg) {
|
||||
let dcs = this.readHexOctet();
|
||||
if (DEBUG) debug("PDU: read dcs: " + dcs);
|
||||
if (DEBUG) debug("PDU: read SMS dcs: " + dcs);
|
||||
|
||||
// No message class by default.
|
||||
let messageClass = PDU_DCS_MSG_CLASS_NORMAL;
|
||||
@ -6965,6 +6980,122 @@ let GsmPDUHelper = {
|
||||
*/
|
||||
readCbMessageIdentifier: function readCbMessageIdentifier(msg) {
|
||||
msg.messageId = Buf.readUint8() << 8 | Buf.readUint8();
|
||||
|
||||
if ((msg.format != CB_FORMAT_ETWS)
|
||||
&& (msg.messageId >= CB_GSM_MESSAGEID_ETWS_BEGIN)
|
||||
&& (msg.messageId <= CB_GSM_MESSAGEID_ETWS_END)) {
|
||||
// `In the case of transmitting CBS message for ETWS, a part of
|
||||
// Message Code can be used to command mobile terminals to activate
|
||||
// emergency user alert and message popup in order to alert the users.`
|
||||
msg.etws = {
|
||||
emergencyUserAlert: msg.messageCode & 0x0200 ? true : false,
|
||||
popup: msg.messageCode & 0x0100 ? true : false
|
||||
};
|
||||
|
||||
let warningType = msg.messageId - CB_GSM_MESSAGEID_ETWS_BEGIN;
|
||||
if (warningType < CB_ETWS_WARNING_TYPE_NAMES.length) {
|
||||
msg.etws.warningType = warningType;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Read CBS Data Coding Scheme.
|
||||
*
|
||||
* @param msg
|
||||
* message object for output.
|
||||
*
|
||||
* @see 3GPP TS 23.038 section 5.
|
||||
*/
|
||||
readCbDataCodingScheme: function readCbDataCodingScheme(msg) {
|
||||
let dcs = Buf.readUint8();
|
||||
if (DEBUG) debug("PDU: read CBS dcs: " + dcs);
|
||||
|
||||
let language = null, hasLanguageIndicator = false;
|
||||
// `Any reserved codings shall be assumed to be the GSM 7bit default
|
||||
// alphabet.`
|
||||
let encoding = PDU_DCS_MSG_CODING_7BITS_ALPHABET;
|
||||
let messageClass = PDU_DCS_MSG_CLASS_NORMAL;
|
||||
|
||||
switch (dcs & PDU_DCS_CODING_GROUP_BITS) {
|
||||
case 0x00: // 0000
|
||||
language = CB_DCS_LANG_GROUP_1[dcs & 0x0F];
|
||||
break;
|
||||
|
||||
case 0x10: // 0001
|
||||
switch (dcs & 0x0F) {
|
||||
case 0x00:
|
||||
hasLanguageIndicator = true;
|
||||
break;
|
||||
case 0x01:
|
||||
encoding = PDU_DCS_MSG_CODING_16BITS_ALPHABET;
|
||||
hasLanguageIndicator = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x20: // 0010
|
||||
language = CB_DCS_LANG_GROUP_2[dcs & 0x0F];
|
||||
break;
|
||||
|
||||
case 0x40: // 01xx
|
||||
case 0x50:
|
||||
//case 0x60: Text Compression, not supported
|
||||
//case 0x70: Text Compression, not supported
|
||||
case 0x90: // 1001
|
||||
encoding = (dcs & 0x0C);
|
||||
if (encoding == 0x0C) {
|
||||
encoding = PDU_DCS_MSG_CODING_7BITS_ALPHABET;
|
||||
}
|
||||
messageClass = (dcs & PDU_DCS_MSG_CLASS_BITS);
|
||||
break;
|
||||
|
||||
case 0xF0:
|
||||
encoding = (dcs & 0x04) ? PDU_DCS_MSG_CODING_8BITS_ALPHABET
|
||||
: PDU_DCS_MSG_CODING_7BITS_ALPHABET;
|
||||
switch(dcs & PDU_DCS_MSG_CLASS_BITS) {
|
||||
case 0x01: messageClass = PDU_DCS_MSG_CLASS_USER_1; break;
|
||||
case 0x02: messageClass = PDU_DCS_MSG_CLASS_USER_2; break;
|
||||
case 0x03: messageClass = PDU_DCS_MSG_CLASS_3; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x30: // 0011 (Reserved)
|
||||
case 0x80: // 1000 (Reserved)
|
||||
case 0xA0: // 1010..1100 (Reserved)
|
||||
case 0xB0:
|
||||
case 0xC0:
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Error("Unsupported CBS data coding scheme: " + dcs);
|
||||
}
|
||||
|
||||
msg.dcs = dcs;
|
||||
msg.encoding = encoding;
|
||||
msg.language = language;
|
||||
msg.messageClass = GECKO_SMS_MESSAGE_CLASSES[messageClass];
|
||||
msg.hasLanguageIndicator = hasLanguageIndicator;
|
||||
},
|
||||
|
||||
/**
|
||||
* Read GSM CBS message page parameter.
|
||||
*
|
||||
* @param msg
|
||||
* message object for output.
|
||||
*
|
||||
* @see 3GPP TS 23.041 section 9.4.1.2.4
|
||||
*/
|
||||
readCbPageParameter: function readCbPageParameter(msg) {
|
||||
let octet = Buf.readUint8();
|
||||
msg.pageIndex = (octet >>> 4) & 0x0F;
|
||||
msg.numPages = octet & 0x0F;
|
||||
if (!msg.pageIndex || !msg.numPages) {
|
||||
// `If a mobile receives the code 0000 in either the first field or the
|
||||
// second field then it shall treat the CBS message exactly the same as a
|
||||
// CBS message with page parameter 0001 0001 (i.e. a single page message).`
|
||||
msg.pageIndex = msg.numPages = 1;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -6984,6 +7115,53 @@ let GsmPDUHelper = {
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Read CBS-Message-Information-Page
|
||||
*
|
||||
* @param msg
|
||||
* message object for output.
|
||||
* @param length
|
||||
* length of cell broadcast data to read in octets.
|
||||
*
|
||||
* @see 3GPP TS 23.041 section 9.3.19
|
||||
*/
|
||||
readGsmCbData: function readGsmCbData(msg, length) {
|
||||
let bufAdapter = {
|
||||
readHexOctet: function readHexOctet() {
|
||||
return Buf.readUint8();
|
||||
}
|
||||
};
|
||||
|
||||
msg.body = null;
|
||||
msg.data = null;
|
||||
switch (msg.encoding) {
|
||||
case PDU_DCS_MSG_CODING_7BITS_ALPHABET:
|
||||
msg.body = this.readSeptetsToString.call(bufAdapter,
|
||||
(length * 8 / 7), 0,
|
||||
PDU_NL_IDENTIFIER_DEFAULT,
|
||||
PDU_NL_IDENTIFIER_DEFAULT);
|
||||
if (msg.hasLanguageIndicator) {
|
||||
msg.language = msg.body.substring(0, 2);
|
||||
msg.body = msg.body.substring(3);
|
||||
}
|
||||
break;
|
||||
|
||||
case PDU_DCS_MSG_CODING_8BITS_ALPHABET:
|
||||
msg.data = Buf.readUint8Array(length);
|
||||
break;
|
||||
|
||||
case PDU_DCS_MSG_CODING_16BITS_ALPHABET:
|
||||
if (msg.hasLanguageIndicator) {
|
||||
msg.language = this.readSeptetsToString.call(bufAdapter, 2, 0,
|
||||
PDU_NL_IDENTIFIER_DEFAULT,
|
||||
PDU_NL_IDENTIFIER_DEFAULT);
|
||||
length -= 2;
|
||||
}
|
||||
msg.body = this.readUCS2String.call(bufAdapter, length);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Read Cell GSM/ETWS/UMTS Broadcast Message.
|
||||
*
|
||||
@ -6996,11 +7174,21 @@ let GsmPDUHelper = {
|
||||
// Internally used in ril_worker:
|
||||
updateNumber: null, // O O O
|
||||
format: null, // O O O
|
||||
dcs: 0x0F, // O X O
|
||||
encoding: PDU_DCS_MSG_CODING_7BITS_ALPHABET, // O X O
|
||||
hasLanguageIndicator: false, // O X O
|
||||
data: null, // O X O
|
||||
body: null, // O X O
|
||||
pageIndex: 1, // O X X
|
||||
numPages: 1, // O X X
|
||||
|
||||
// DOM attributes:
|
||||
geographicalScope: null, // O O O
|
||||
messageCode: null, // O O O
|
||||
messageId: null, // O O O
|
||||
language: null, // O X O
|
||||
fullBody: null, // O X O
|
||||
fullData: null, // O X O
|
||||
messageClass: GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_NORMAL], // O x O
|
||||
etws: null // ? O ?
|
||||
/*{
|
||||
@ -7015,9 +7203,36 @@ let GsmPDUHelper = {
|
||||
return this.readEtwsCbMessage(msg);
|
||||
}
|
||||
|
||||
if (pduLength <= CB_MESSAGE_SIZE_GSM) {
|
||||
msg.format = CB_FORMAT_GSM;
|
||||
return this.readGsmCbMessage(msg, pduLength);
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Read GSM Cell Broadcast Message.
|
||||
*
|
||||
* @param msg
|
||||
* message object for output.
|
||||
* @param pduLength
|
||||
* total length of the incomint PDU in octets.
|
||||
*
|
||||
* @see 3GPP TS 23.041 clause 9.4.1.2
|
||||
*/
|
||||
readGsmCbMessage: function readGsmCbMessage(msg, pduLength) {
|
||||
this.readCbSerialNumber(msg);
|
||||
this.readCbMessageIdentifier(msg);
|
||||
this.readCbDataCodingScheme(msg);
|
||||
this.readCbPageParameter(msg);
|
||||
|
||||
// GSM CB message header takes 6 octets.
|
||||
this.readGsmCbData(msg, pduLength - 6);
|
||||
|
||||
return msg;
|
||||
},
|
||||
|
||||
/**
|
||||
* Read ETWS Primary Notification Message.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user