smppjs
Version:
Modern approach to smpp protocol.
195 lines • 8.83 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const index_1 = require("./dtos/index");
const octets_1 = require("./octets");
const constains_1 = require("./constains");
const HEADER_COMMAND_LENGTH = 16;
class PDU {
constructor(socket, secure) {
this.socket = socket;
this.secure = secure;
}
call({ command, sequenceNumber, dto }) {
const commandParams = dto.command;
const tlvs = dto.tlvs;
const commandId = constains_1.commandsId[command];
let commandLength = HEADER_COMMAND_LENGTH;
const paramEntries = Object.entries(commandParams);
for (let index = 0; index < paramEntries.length; index++) {
const element = paramEntries[index][1];
if (element.encode && element.type === 'Cstring' && typeof element.value === 'string') {
element.value = octets_1.octets[element.type].convertToUtf16be(element.value);
}
commandLength += octets_1.octets[element.type].size(element.value);
}
if (tlvs) {
const tlvsEntries = Object.entries(tlvs);
for (let index = 0; index < tlvsEntries.length; index++) {
const element = tlvsEntries[index][1];
if (element.value) {
if (element.encode && element.type === 'Cstring' && typeof element.value === 'string') {
element.value = octets_1.octets[element.type].convertToUtf16be(element.value);
}
commandLength += octets_1.octets[element.type].size(element.value) + 4;
}
}
}
const buffer = this.createPdu({ pduParams: commandParams, commandLength, commandId, sequenceNumber, tlvs, unsafeBuffer: this.secure.unsafeBuffer });
return this.socket.write(buffer);
}
createPdu({ commandLength, commandId, sequenceNumber, pduParams, tlvs, unsafeBuffer, commandStatus = 0, }) {
let pduBuffer = unsafeBuffer ? Buffer.allocUnsafe(commandLength) : Buffer.alloc(commandLength);
pduBuffer = this.writeHeaderPdu({ buffer: pduBuffer, commandLength, commandId, sequenceNumber, commandStatus });
const pduWithParams = this.writeParamsPdu({ offset: HEADER_COMMAND_LENGTH, pduBuffer, pduParams });
pduBuffer = pduWithParams.pduBuffer;
pduBuffer = this.writeTlvsPdu({ offset: pduWithParams.offset, pduBuffer, tlvs });
return pduBuffer;
}
writeHeaderPdu({ buffer, commandLength, commandId, sequenceNumber, commandStatus, }) {
buffer.writeUInt32BE(commandLength, 0);
buffer.writeUInt32BE(commandId, 4);
buffer.writeUInt32BE(commandStatus, 8);
buffer.writeUInt32BE(sequenceNumber, 12);
return buffer;
}
writeParamsPdu({ pduParams, pduBuffer, offset, }) {
for (const key in pduParams) {
const param = pduParams[key];
const type = param.type;
const value = param.value;
if (type === 'Cstring') {
const encode = param.encode || 'ascii';
const setLength = param.setLength || false;
pduBuffer = octets_1.octets.Cstring.write({ buffer: pduBuffer, offset, value: value, encoding: encode, setLength });
offset += octets_1.octets.Cstring.size(value);
}
if (type === 'Int8') {
pduBuffer = octets_1.octets.Int8.write({ buffer: pduBuffer, offset, value: value });
offset += octets_1.octets.Int8.size();
}
}
return { pduBuffer, offset };
}
writeTlvsPdu({ tlvs, pduBuffer, offset, }) {
if (tlvs && Object.entries(tlvs)) {
for (const key in tlvs) {
const param = tlvs[key];
const type = param.type;
const value = param.value;
if (value) {
const valueSize = octets_1.octets.Cstring.size(value) + 4;
octets_1.octets.Int16.write({ buffer: pduBuffer, offset, value: constains_1.optionalParams[key] });
offset += octets_1.octets.Int16.size();
octets_1.octets.Int16.write({ buffer: pduBuffer, offset, value: valueSize });
offset += octets_1.octets.Int16.size();
if (type === 'Cstring') {
const encode = param.encode || 'ascii';
const setLength = param.setLength || false;
pduBuffer = octets_1.octets.Cstring.write({ buffer: pduBuffer, offset, value: value, encoding: encode, setLength });
offset += valueSize;
}
}
}
}
return pduBuffer;
}
readParamsPdu({ pduParams, pduBuffer, offset, }) {
const params = {};
let dataCoding;
let smLength;
for (const key in pduParams) {
const param = pduParams[key];
const type = param.type;
const value = param.value;
if (type === 'Cstring') {
if (key === 'short_message' && dataCoding !== undefined) {
const encoding = constains_1.encodesName[dataCoding];
params[key] = octets_1.octets.Cstring.read({
buffer: pduBuffer,
offset,
encoding,
length: smLength,
});
if (smLength) {
offset += smLength;
}
}
else {
params[key] = octets_1.octets.Cstring.read({ buffer: pduBuffer, offset });
offset += octets_1.octets.Cstring.size(params[key] || value);
}
}
if (type === 'Int8') {
params[key] = octets_1.octets.Int8.read({ buffer: pduBuffer, offset });
offset += octets_1.octets.Int8.size();
if (key === 'data_coding') {
dataCoding = params[key];
}
if (key === 'sm_length') {
smLength = params[key];
}
}
}
return { params, offset };
}
readTlvsPdu({ pduTlvs, pduBuffer, offset, }) {
const params = {};
for (const key in pduTlvs) {
const param = pduTlvs[key];
const type = param.type;
const value = param.value;
if (value) {
if (type === 'Cstring') {
params[key] = octets_1.octets.Cstring.read({ buffer: pduBuffer, offset });
offset += octets_1.octets.Cstring.size(params[key] || value);
}
if (type === 'Int8') {
params[key] = octets_1.octets.Int8.read({ buffer: pduBuffer, offset });
offset += octets_1.octets.Cstring.size(value);
}
}
}
return params;
}
readHeaderPdu({ buffer, pdu }) {
if (buffer.length < HEADER_COMMAND_LENGTH) {
throw new Error('PDU: Buffer too small for header.');
}
pdu.command_length = buffer.readUInt32BE(0);
if (pdu.command_length < 16 || pdu.command_length > 65536) {
throw new Error('PDU: Invalid command length.');
}
pdu.command_id = buffer.readUInt32BE(4);
pdu.command_status = buffer.readUInt32BE(8);
pdu.sequence_number = buffer.readUInt32BE(12);
return pdu;
}
readPdu(buffer) {
const pdu = {
command: '',
command_id: 0,
command_length: 0,
command_status: 0,
sequence_number: 0,
};
this.readHeaderPdu({ buffer, pdu });
pdu.command = constains_1.commandsName[pdu.command_id];
const DTO = (0, index_1.getDTO)(pdu.command);
if (!DTO) {
throw new Error(`Command {${pdu.command}} not found.`);
}
const commandParams = DTO({});
const { params, offset } = this.readParamsPdu({ pduBuffer: buffer, pduParams: commandParams.command, offset: HEADER_COMMAND_LENGTH });
let tlvs = undefined;
if (commandParams.tlvs) {
tlvs = this.readTlvsPdu({ pduBuffer: buffer, pduTlvs: commandParams.tlvs, offset });
}
if (pdu.command_status !== constains_1.CommandStatus.ESME_ROK) {
const errorInfo = constains_1.CommandStatusInfo[pdu.command_status];
throw new Error(`Command {${pdu.command}} return error {${errorInfo.name}} with info {${errorInfo.description}}.`);
}
return Object.assign({}, pdu, params, tlvs);
}
}
exports.default = PDU;
//# sourceMappingURL=PDU.js.map