/*! * SMPP Widget * Copyright 2022 Melrose Labs Ltd and Mark Hay (melroselabs.com) */ /* GSM/SMS + SMPP + WS + SOCKS script */ var loggingDisabled = true; function enableLogging() { loggingDisabled = false; } function disableLogging() { loggingDisabled = true; } $(document).ready(function () { }); function pad(n, width, z) { z = z || '0'; n = n + ''; return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; } const unicodeToGsm = { 0x000A: [0x0A], 0x000C: [0x1B, 0x0A], 0x000D: [0x0D], 0x0020: [0x20], 0x0021: [0x21], 0x0022: [0x22], 0x0023: [0x23], 0x0024: [0x02], 0x0025: [0x25], 0x0026: [0x26], 0x0027: [0x27], 0x0028: [0x28], 0x0029: [0x29], 0x002A: [0x2A], 0x002B: [0x2B], 0x002C: [0x2C], 0x002D: [0x2D], 0x002E: [0x2E], 0x002F: [0x2F], 0x0030: [0x30], 0x0031: [0x31], 0x0032: [0x32], 0x0033: [0x33], 0x0034: [0x34], 0x0035: [0x35], 0x0036: [0x36], 0x0037: [0x37], 0x0038: [0x38], 0x0039: [0x39], 0x003A: [0x3A], 0x003B: [0x3B], 0x003C: [0x3C], 0x003D: [0x3D], 0x003E: [0x3E], 0x003F: [0x3F], 0x0040: [0x00], 0x0041: [0x41], 0x0042: [0x42], 0x0043: [0x43], 0x0044: [0x44], 0x0045: [0x45], 0x0046: [0x46], 0x0047: [0x47], 0x0048: [0x48], 0x0049: [0x49], 0x004A: [0x4A], 0x004B: [0x4B], 0x004C: [0x4C], 0x004D: [0x4D], 0x004E: [0x4E], 0x004F: [0x4F], 0x0050: [0x50], 0x0051: [0x51], 0x0052: [0x52], 0x0053: [0x53], 0x0054: [0x54], 0x0055: [0x55], 0x0056: [0x56], 0x0057: [0x57], 0x0058: [0x58], 0x0059: [0x59], 0x005A: [0x5A], 0x005B: [0x1B, 0x3C], 0x005C: [0x1B, 0x2F], 0x005D: [0x1B, 0x3E], 0x005E: [0x1B, 0x14], 0x005F: [0x11], 0x0061: [0x61], 0x0062: [0x62], 0x0063: [0x63], 0x0064: [0x64], 0x0065: [0x65], 0x0066: [0x66], 0x0067: [0x67], 0x0068: [0x68], 0x0069: [0x69], 0x006A: [0x6A], 0x006B: [0x6B], 0x006C: [0x6C], 0x006D: [0x6D], 0x006E: [0x6E], 0x006F: [0x6F], 0x0070: [0x70], 0x0071: [0x71], 0x0072: [0x72], 0x0073: [0x73], 0x0074: [0x74], 0x0075: [0x75], 0x0076: [0x76], 0x0077: [0x77], 0x0078: [0x78], 0x0079: [0x79], 0x007A: [0x7A], 0x007B: [0x1B, 0x28], 0x007C: [0x1B, 0x40], 0x007D: [0x1B, 0x29], 0x007E: [0x1B, 0x3D], 0x00A1: [0x40], 0x00A3: [0x01], 0x00A4: [0x24], 0x00A5: [0x03], 0x00A7: [0x5F], 0x00BF: [0x60], 0x00C4: [0x5B], 0x00C5: [0x0E], 0x00C6: [0x1C], 0x00C9: [0x1F], 0x00D1: [0x5D], 0x00D6: [0x5C], 0x00D8: [0x0B], 0x00DC: [0x5E], 0x00DF: [0x1E], 0x00E0: [0x7F], 0x00E4: [0x7B], 0x00E5: [0x0F], 0x00E6: [0x1D], 0x00C7: [0x09], 0x00E8: [0x04], 0x00E9: [0x05], 0x00EC: [0x07], 0x00F1: [0x7D], 0x00F2: [0x08], 0x00F6: [0x7C], 0x00F8: [0x0C], 0x00F9: [0x06], 0x00FC: [0x7E], 0x0393: [0x13], 0x0394: [0x10], 0x0398: [0x19], 0x039B: [0x14], 0x039E: [0x1A], 0x03A0: [0x16], 0x03A3: [0x18], 0x03A6: [0x12], 0x03A8: [0x17], 0x03A9: [0x15], 0x20AC: [0x1B, 0x65] } function dumpMessage(message) { var hexstr = ""; for(var i = 0; i < message.length; i++) { var char = message[i].charCodeAt(0); hexstr += char.toString(16) + " "; } console.log(hexstr); } function isGSM7Message(message) { for(var i = 0; i < message.length; i++) { var char = message[i]; if (! (char && unicodeToGsm[char.charCodeAt(0)] ? true : false)) return false; } return true; } function getString(view,i) { var str = ""; while (true) { var ch = view.getUint8(i++,false); if (ch == 0) break; str += String.fromCharCode(ch); } return str; } function dv(val) { return ""+val+""; } function dv_str(str) { var out = ""; for(var a=0;a127)) out += " " + pad(ch.toString(16),2) + " "; else out += str[a]; } out += ""; return out; } function logTLVs(view,i,command_length) { if (!loggingDisabled) return; while (i!=command_length) { let tag = view.getUint16(0*2+i,false); let len = view.getUint16(1*2+i,false); i+=4; var str = "",str_b = ""; for(var a=0;a32)&&(v<128)) str_b += " "+String.fromCharCode(v)+""; else { str_b += " "; str_b += pad(view.getUint8(i+a,false).toString(16),2); str_b += ""; } } //str += pad(view.getUint8(i+a,false).toString(16),2)+" "; } i+=len; logRaw("TLV [tag:"+tag+" len:"+len+" val:"+str+" text: "+str_b+"] "); } } function smppTLVStr(tag) { switch (tag) { case 0x0005: return "dest_addr_subunit"; case 0x0006: return "dest_network_type"; case 0x0007: return "dest_bearer_type"; case 0x0017: return "qos_time_to_live"; case 0x0019: return "payload_type"; case 0x001d: return "additional_status_info_text"; case 0x001e: return "receipted_message_id"; case 0x001f: return "ms_msg_wait_facilities"; case 0x0204: return "user_message_reference"; case 0x020c: return "sar_msg_ref_num"; case 0x020e: return "sar_total_segments"; case 0x020f: return "sar_segment_seqnum"; case 0x0210: return "sc_interface_version"; case 0x420: return "dpf_result"; case 0x421: return "set_dpf"; case 0x422: return "ms_availability_status"; case 0x423: return "network_error_code"; case 0x424: return "message_payload"; case 0x425: return "delivery_failure_reason"; case 0x426: return "more_messages_to_send"; case 0x427: return "message_state"; } return "UNKNOWN"; } function smppCommandStr(command_id) { switch (command_id) { case 0x00000004: return "submit_sm"; case 0x80000004: return "submit_sm_resp"; case 0x00000005: return "deliver_sm"; case 0x80000005: return "deliver_sm_resp"; case 0x00000006: return "unbind"; case 0x80000006: return "unbind_resp"; case 0x00000009: return "bind_transceiver"; case 0x80000009: return "bind_transceiver_resp"; case 0x00000015: return "enquire_link"; case 0x80000015: return "enquire_link_resp"; } return "UNKNOWN"; } function smppCmdStatusStr(command_status) { switch (command_status) { case 0x0: return "ROK"; case 0x1: return "RINVMSGLEN"; case 0x2: return "RINVCMDLEN"; case 0x3: return "RINVCMDID"; case 0x4: return "RINVBNDSTS"; case 0x5: return "RALYBND"; case 0x6: return "RINVPRTFLG"; case 0x7: return "RINVREGDLVFLG"; case 0x8: return "RSYSERR"; case 0x9: return "RINVSRCADR"; case 0xa: return "RINVSRCADR"; case 0xb: return "RINVDSTADR"; case 0xc: return "RINVMSG"; case 0xd: return "RBINDFAIL"; case 0xe: return "RINVPASWD"; case 0xf: return "RINVSYSID"; case 0x11: return "RCANCELFAIL"; case 0x13: return "RREPLACEFAIL"; case 0x14: return "RMSGQFUL"; case 0x15: return "RINVSERTYP"; case 0x33: return "RINVNUMDESTS"; case 0x34: return "RRINVDLNAME"; case 0x40: return "RINVDESTFLAG"; case 0x42: return "RINVSUBREP"; case 0x43: return "RINVESMCLASS"; case 0x44: return "RCNTSUBDL"; case 0x45: return "RSUBMITFAIL"; case 0x48: return "RINVSRCTON"; case 0x49: return "RINVSRCNPI"; case 0x50: return "RINVDSTTON"; case 0x51: return "RINVDSTNPI"; case 0x53: return "RINVSYSTYP"; case 0x54: return "RINVREPFLAG"; case 0x55: return "RINVNUMMSGS"; case 0x58: return "RTHROTTLED"; case 0x61: return "RINVSCHED"; case 0x63: return "RINVDFTMSGID"; case 0x64: return "RX_T_APPN"; case 0x65: return "RX_P_APPN"; case 0x66: return "RX_R_APPN"; case 0x67: return "RQUERYFAIL"; case 0xc0: return "RINVTLVSTREAM"; case 0xc1: return "RTLVNOTALLWD"; case 0xc2: return "RINVTLVLEN"; case 0xc3: return "RMISSINGTLV"; case 0xc4: return "RINVTLVVAL"; case 0xfe: return "RDELIVERYFAILURE"; case 0xff: return "RUNKNOWNERR"; case 0x100: return "RSERTYPUNAUTH"; case 0x101: return "RPROHIBITED"; case 0x102: return "RSERTYPUNAVAIL"; case 0x103: return "RSERTYPDENIED"; case 0x104: return "RINVDCS"; } return "UNKNOWN"; } function strTLVs(view,i,command_length) { var str_tlvs = ""; while (i!=command_length) { let tag = view.getUint16(0*2+i,false); let len = view.getUint16(1*2+i,false); i+=4; var str = "",str_b = ""; for(var a=0;a32)&&(v<128)) str_b += " "+String.fromCharCode(v)+""; else { str_b += " "; str_b += pad(view.getUint8(i+a,false).toString(16),2); str_b += ""; } } } i+=len; if (str_tlvs!="") str_tlvs += " "; str_tlvs += 'TLV tag:0x'+tag.toString(16)+' ('+smppTLVStr(tag)+') len:'+len+' val(hex):'+str+' text: '+str_b+''; } return str_tlvs; } function getNumSMSParts(dataCoding, msg) { var isGSM7Msg = isGSM7Message( msg ); var bitsPerChar = isGSM7Msg?7:16; if ( dataCoding == 8 ) bitsPerChar=16; // var sms_len = msg.length; var sms_count = 0; var sms_concat_space = (140*8 - 6*8) / bitsPerChar; if (sms_len>0) { if (sms_len<= Math.floor(140*8/bitsPerChar) ) sms_count = 1; else { sms_count = Math.floor(sms_len / sms_concat_space); if ((sms_len % sms_concat_space) > 0) sms_count++; } } return sms_count; } function logLow(a,b){ if (!loggingDisabled) console.log(a); } class SMPPSession { constructor(host,port,systemid,password) { this.wsSocket = null; /* SOCKS */ this.socksState = 0; this.socksTargetHost = host; this.socksTargetPort = port; /* SMPP */ this.smppSeqNoOut = 1; this.stateBound = false; this.smppSystemID = systemid; this.smppPassword = password; this.smppSystemType = ""; this.smppAddressRange = ""; this.smppVersion = 0x34; //console.log("SMPPSession"); //console.log(this); } userBindTRXRespSuccessFunc() {} userWSCloseFunc() {} showState(state) {} logLow(a,b){ if (!loggingDisabled) console.log(a); } log(direction,command_id,command_status,sequence_number,str,str_tlvs,pdu_hex_dump) { if (loggingDisabled) return; var badgeColour = "secondary"; var outcome = '' + smppCommandStr(command_id) + ""; // + " (0x" + pad(command_id.toString(16),8) + ")"; if (command_id>=0x80000000) { if (command_status==0) outcome += ' OK'; else outcome += ' ERROR: ' + smppCmdStatusStr(command_status) + ' (0x'+pad(command_status.toString(16),3)+')'; } //outcome += " 0x" + pad(command_status.toString(16),8) + " "; outcome += " "; if (str) outcome += str; if (this.stateBound) badgeColour = "success"; var seqno_block = ""; switch (direction) { case 0: chDir = '-'; break; case 1: chDir = '<'; break; case -1: chDir = '>'; break; } seqno_block = ' ' + pad(sequence_number,4) + ' ' + chDir + '' + ' '; var localDateTime = new Date(); var outline = ""; outline += '
'; outline += '
'; outline += '' + pad(localDateTime.getHours(),2) + ":" + pad(localDateTime.getMinutes(),2) + ":" + pad(localDateTime.getSeconds(),2) + '  ' + seqno_block; outline += '
'; outline += '
'; outline += outcome + '  '; if (str_tlvs) outline += '
'+str_tlvs; outline += '
'; outline += '
'; if (pdu_hex_dump) outline += ""+pdu_hex_dump+""; outline += '
'; outline += '
'; console.log(outline); } connect() { this.logLow("Connecting",false); this.mppSeqNoOut = 1; this.wsSocket = new WebSocket("wss://melroselabs.com/wssmppproxy/"); this.wsSocket.binaryType = 'arraybuffer'; var _self = this; this.wsSocket.onopen = function (event) { console.log(this); console.log(event); console.log(_self); console.log("Open"); logLow("Connected (WS) - attempting TCP connect to SMPP host...",true); _self.socksConnect(); }; this.wsSocket.onmessage = function (event) { //console.log("wsSocket.onmessage"); //console.log(this); //console.log(_self); if (_self.socksState<3) console.log("> WS"); if (_self.socksState==0) { console.log("socksState==0 in onmessage - SNO"); return; } else if (_self.socksState==1) { _self.socksConnect2(_self); return; } else if (_self.socksState==2) { // CONNECT response _self.logLow("Connected (SMPP)",true); let view = new DataView(event.data,0); if ((view.getUint8(0,false)==0x05) && (view.getUint8(1,false)==0x00)) { // CONNECT successful _self.socksState = 3; // connection to target host established _self.smppBindTRX(_self.smppSystemID,_self.smppPassword,_self.smppSystemType,_self.smppAddressRange,_self.smppVersion); return; } else { // CONNECT failed // TODO cleanup return; } } if (_self.socksState<3) return; // let view = new DataView(event.data,0); var pidx = 0; while ( pidx < event.data.byteLength ) { let command_length = view.getUint32(0*4+pidx,false); let command_id = view.getUint32(1*4+pidx,false); let command_status = view.getUint32(2*4+pidx,false); let sequence_number = view.getUint32(3*4+pidx,false); // var str = ""; var pdu_hex_dump = ""; for(var i=16;i"; var str_tlvs = strTLVs(view,i,command_length+pidx); _self.log(-1, command_id,command_status,sequence_number,line,str_tlvs,pdu_hex_dump); } else { _self.log(-1, command_id,command_status,sequence_number,str,null,pdu_hex_dump); } } else if (command_id==0x80000004) { /*submit_sm_resp*/ if (command_status==0) { var i=16+pidx; var message_id = getString(view,i); i += message_id.length+1; var str_tlvs = strTLVs(view,i,command_length+pidx); //log(-1, command_id,command_status,sequence_number,"Message ID: "+message_id+"",str_tlvs,pdu_hex_dump); if (typeof _self.userSubmitSMRespSuccessFunc == 'function') { _self.userSubmitSMRespSuccessFunc(message_id,sequence_number); } } else { var str_tlvs = strTLVs(view,i,command_length+pidx); //log(-1, command_id,command_status,sequence_number,str,str_tlvs,pdu_hex_dump); console.log(pdu_hex_dump); if (typeof _self.userSubmitSMRespFailFunc == 'function') { _self.userSubmitSMRespFailFunc(command_status,sequence_number); } } } else if (command_id==0x00000005) { /* deliver_sm */ var i=16+pidx; var service_type = getString(view,i); i += service_type.length+1; var source_addr_ton = view.getUint8(i++,false); var source_addr_npi = view.getUint8(i++,false); var source_addr = getString(view,i); i += source_addr.length+1; var dest_addr_ton = view.getUint8(i++,false); var dest_addr_npi = view.getUint8(i++,false); var destination_addr = getString(view,i); i += destination_addr.length+1; var esm_class = view.getUint8(i++,false); var protocol_id = view.getUint8(i++,false); var priority_flag = view.getUint8(i++,false); var schedule_delivery_time = getString(view,i); i += schedule_delivery_time.length+1; var validity_period = getString(view,i); i += validity_period.length+1; var registered_delivery = view.getUint8(i++,false); var replace_if_present_flag = view.getUint8(i++,false); var data_coding = view.getUint8(i++,false); var sm_default_msg_id = view.getUint8(i++,false); var sm_length = view.getUint8(i++,false); var short_message = ""; for(var a=0;a"+dv(dest_addr_ton)+"."+dv(dest_addr_npi)+"."+dv(destination_addr); line += "; esm_class: "+dv(esm_class); line += "; protocol_id: "+dv(protocol_id); line += "; priority_flag: "+dv(priority_flag); line += "; registered_delivery: "+dv(registered_delivery); line += "; replace_if_present_flag: "+dv(replace_if_present_flag); line += "; data_coding: "+dv(data_coding); line += "; sm_default_msg_id: "+dv(sm_default_msg_id); line += "; sm_length: "+dv(sm_length); line += "; short_message: "+dv_str(short_message); var str_tlvs = strTLVs(view,i,command_length+pidx); _self.log(-1, command_id,command_status,sequence_number,line,str_tlvs,pdu_hex_dump); if (typeof _self.userDeliverSMFunc == 'function') { if ((esm_class&(4+8+16+32))!=0) { // DLR or intermediate DLR var smArr = short_message.split(" "); var msgId = smArr[0].substr(3); var status = 1; if (smArr[7]=='stat:SCHEDLD') status = 0; if (smArr[7]=='stat:ENROUTE') status = 1; if (smArr[7]=='stat:DELIVRD') status = 2; if (smArr[7]=='stat:EXPIRED') status = 3; if (smArr[7]=='stat:DELETED') status = 4; if (smArr[7]=='stat:UNDELIV') status = 5; if (smArr[7]=='stat:ACCEPTD') status = 6; if (smArr[7]=='stat:UNKNOWN') status = 7; if (smArr[7]=='stat:REJECTD') status = 8; if (smArr[7]=='stat:SKIPPED') status = 9; _self.userDeliverSMFunc(msgId,status); } } if (typeof _self.userDeliverSMMOFunc == 'function') { if ((esm_class&(4+8+16+32))==0) { // MO _self.userDeliverSMMOFunc(source_addr,destination_addr,esm_class,data_coding,short_message); } } _self.smppDeliverSMResp(sequence_number); } else if ((command_id==0x80000006)||(command_id==0x00000006)) { /* unbind_resp or unbind */ stateBound = false; //log(-1, command_id,command_status,sequence_number,str,null,pdu_hex_dump); _self.disconnect(); } else if (command_id==0x00000015) { /* enquire_link */ //log(-1, command_id,command_status,sequence_number,str,null,pdu_hex_dump); _self.smppEnquireLinkResp(sequence_number); } else if (command_id==0x80000015) { /* enquire_link_resp */ var str_tlvs = strTLVs(view,i,command_length+pidx); //log(-1, command_id,command_status,sequence_number,str,str_tlvs,pdu_hex_dump); if (typeof _self.userEnquireLinkRespFunc == 'function') { _self.userEnquireLinkRespFunc(); } } else { var i = 16+pidx; var str_tlvs = strTLVs(view,i,command_length+pidx); //log(-1, command_id,command_status,sequence_number,str,str_tlvs,pdu_hex_dump); } _self.showState(_self.stateBound); pidx += command_length; } } this.wsSocket.onclose = function (event) { console.log("Close"); logLow("Disconnected",false); _self.stateBound = false; _self.showState(_self.stateBound); if (typeof _self.userWSCloseFunc == 'function') { _self.userWSCloseFunc(); } } } disconnect() { if (this.stateBound) this.smppUnbind(); else this.wsSocket.close(); } /**/ logRaw(str) { if (!elMessageArea) return; var badgeColour = "light"; var localDateTime = new Date(); var existingMessages = elMessageArea.innerHTML; if (existingMessages.length>10) existingMessages = '
' + existingMessages; elMessageArea.innerHTML = '' + pad(localDateTime.getHours(),2) + ":" + pad(localDateTime.getMinutes(),2) + ":" + pad(localDateTime.getSeconds(),2) + '  ' + str + '' + existingMessages; } logLow(str,outcome) { if (!elMessageArea) return; var badgeColour = "dark"; if (outcome) badgeColour = "secondary"; var localDateTime = new Date(); var existingMessages = elMessageArea.innerHTML; if (existingMessages.length>10) existingMessages = '
' + existingMessages; elMessageArea.innerHTML = '' + pad(localDateTime.getHours(),2) + ":" + pad(localDateTime.getMinutes(),2) + ":" + pad(localDateTime.getSeconds(),2) + '  ' + str + '' + existingMessages; } log(direction,command_id,command_status,sequence_number,str,str_tlvs,pdu_hex_dump) { if (loggingDisabled) return; var badgeColour = "secondary"; var outcome = '' + smppCommandStr(command_id) + ""; // + " (0x" + pad(command_id.toString(16),8) + ")"; if (command_id>=0x80000000) { if (command_status==0) outcome += ' OK'; else outcome += ' ERROR: ' + smppCmdStatusStr(command_status) + ' (0x'+pad(command_status.toString(16),3)+')'; } //outcome += " 0x" + pad(command_status.toString(16),8) + " "; outcome += " "; if (str) outcome += str; //if (command_status==0) badgeColour = "success"; if (this.stateBound) badgeColour = "success"; var seqno_block = ""; var chDir = ""; switch (direction) { case 0: chDir = '-'; break; case 1: chDir = '<'; break; case -1: chDir = '>'; break; } seqno_block = ' ' + pad(sequence_number,4) + ' ' + chDir + '' + ' '; var localDateTime = new Date(); var outline = ""; outline += '
'; outline += '
'; outline += '' + pad(localDateTime.getHours(),2) + ":" + pad(localDateTime.getMinutes(),2) + ":" + pad(localDateTime.getSeconds(),2) + '  ' + seqno_block; outline += '
'; outline += '
'; outline += outcome + '  '; //if (str_tlvs) outline += '   '+str_tlvs+''; if (str_tlvs) outline += '
'+str_tlvs; outline += '
'; outline += '
'; if (pdu_hex_dump) outline += ""+pdu_hex_dump+""; outline += '
'; outline += '
'; if (elMessageArea) { var existingMessages = elMessageArea.innerHTML; elMessageArea.innerHTML = outline + existingMessages; } else console.log(outline); } /**/ socksConnect() { console.log("socksConnect"); //console.log(this); var buffer = new ArrayBuffer(3); const uint8 = new Uint8Array(buffer); var i=0; uint8[i++]=0x5; // SOCKS version uint8[i++]=0x1; // NMETHODS uint8[i++]=0x0; // METHODS this.sendSocket(buffer); this.socksState = 1; // SOCKS hello sent } socksConnect2(_self) { console.log("socksConnect2"); //console.log(this); var buffer = new ArrayBuffer(7+_self.socksTargetHost.length); const uint8 = new Uint8Array(buffer); var i=0; uint8[i++]=0x5; // SOCKS version uint8[i++]=0x1; // CONNECT uint8[i++]=0x0; // reserved uint8[i++]=0x3; // ATYP uint8[i++]=_self.socksTargetHost.length; // DST.ADDR for(var v=0;v<_self.socksTargetHost.length;v++) { uint8[i++] = _self.socksTargetHost.charCodeAt(v); } uint8[i++]=_self.socksTargetPort >> 8; // DST.PORT uint8[i++]=_self.socksTargetPort & 0xff; _self.sendSocket(buffer); _self.socksState = 2; // SOCKS connect sent } /**/ sendSocket(buffer) { this.wsSocket.send(buffer); } sendSMPPCmd(buffer,command_id,logit=true) { if (logit) { const uint8 = new Uint8Array(buffer); var pdu_hex_dump = ""; for(var i=16;i>8 & 0xff],14); uint8.set([seqno>>16 & 0xff],13); uint8.set([seqno>>24 & 0xff],12); this.wsSocket.send(buffer); this.smppSeqNoOut++ //console.log("< SMPP "+command_id.toString(16)); return seqno; } sendSMPPResp(buffer,command_id,sequence_number) { const uint8 = new Uint8Array(buffer); uint8.set([0x80],4); uint8.set([command_id & 0xff],7); uint8.set([command_id>>8 & 0xff],6); uint8.set([command_id>>16 & 0xff],5); uint8.set([command_id>>24 & 0xff],4); uint8.set([sequence_number & 0xff],15); uint8.set([sequence_number>>8 & 0xff],14); uint8.set([sequence_number>>16 & 0xff],13); uint8.set([sequence_number>>24 & 0xff],12); this.wsSocket.send(buffer); var pdu_hex_dump = ""; for(var i=16;i"+dv(dest_addr_ton)+"."+dv(dest_addr_npi)+"."+dv(destination_addr)+"; esm_class: "+dv(esm_class)+"; registered_delivery: "+dv(registered_delivery)+"; data_coding: "+dv(data_coding) + "; sm_length: "+dv(short_message.length)+"; short_message: "+dv_str(short_message), null, pdu_hex_dump); return this.sendSMPPCmd(buffer,0x00000004,false); } smppDeliverSMResp(sequence_number) { var smppHeadLen=16; var buffer = new ArrayBuffer(smppHeadLen+1); const uint8 = new Uint8Array(buffer); uint8.set([smppHeadLen+1],3); uint8[16]=0x0; // var pdu_hex_dump = ""; for(var i=16;i1) { messageOut += String.fromCharCode(0x05); messageOut += String.fromCharCode(0x00); messageOut += String.fromCharCode(0x03); messageOut += String.fromCharCode(0x01); // cref messageOut += String.fromCharCode(nparts); // nparts messageOut += String.fromCharCode(npart); // npart esm_class = esm_class | 64; // set UDHI forcedUDHI = true; } while (i> 8); messageOut += String.fromCharCode(char & 0xff); i = i + 1 } var seqno = smppSubmitsM(source_addr_ton,source_addr_npi,source_addr, dest_addr_ton,dest_addr_npi,destination_addr, esm_class,protocol_id,priority_flag, "","",registered_delivery,data_coding,messageOut); seqnos.push(seqno); if (npart==10) break; npart = npart + 1 } } else { /* GSM */ var i = 0 var nparts = getNumSMSParts(data_coding,short_message) var npart = 1 while (i1) { messageOut += String.fromCharCode(0x05); messageOut += String.fromCharCode(0x00); messageOut += String.fromCharCode(0x03); messageOut += String.fromCharCode(0x01); // cref messageOut += String.fromCharCode(nparts); // nparts messageOut += String.fromCharCode(npart); // npart esm_class = esm_class | 64; // set UDHI forcedUDHI = true; } while (i*/ /* define in UI script for SMPP script*/ var formHost,formPort,formSystemID,formPassword,formSystemType,formAddressRange,formVersion; var elMessageArea = null; // element where to write logs /* var widget_data = null var widget_button = null */ var debug = false function htmlEscape(str) { return str .replace(/&/g, '&') .replace(/'/g, ''') .replace(/"/g, '"') .replace(/>/g, '>') .replace(/ '+time+' '+msisdn+'
'+htmlEscape(msg)+'
'); } submitListMessageID(seqno,msgid) { console.log("submitListMessageID"); var msisdn = ""; if ($('#seq_'+seqno).length!=0) { msisdn = $('#seq_'+seqno).text(); } $('#seq_'+seqno).replaceWith(''+msisdn+''+''); this.countDestSubmitted++; this.showState(true); } submitListDLR(msgid,status) { console.log("submitListDLR"); console.log(this); if (status<2) $('#msgid_'+msgid).addClass("text-warning"); else { if (status==2) { $('#status_msgid_'+msgid).html(''); $('#msgid_'+msgid).addClass("text-success"); } else { $('#msgid_'+msgid).addClass("text-danger"); } } if (status==2) this.countDestDelivered++; this.showState(true); } // userDeliverSMMOFunc(source_addr,destination_addr,esm_class,data_coding,short_message) { console.log("userDeliverSMMOFunc"); var dt = new Date(); var time = String( dt.getHours() ).padStart(2,'0') + ":" + String( dt.getMinutes() ).padStart(2,'0') + ":" + String( dt.getSeconds() ).padStart(2,'0'); var msg = ""; if (data_coding==0x08 /*UCS2*/) { for(i=0;i '+time+' '+source_addr+'>'+destination_addr+'
'+htmlEscape(msg)+'
'); } userDeliverSMFunc(msgID,status) { console.log("userDeliverSMFunc"); console.log(this); this.submitListDLR(msgID,status); } userSubmitSMRespSuccessFunc(msgID,seqNo) { console.log("userSubmitSMRespSuccessFunc"); console.log(this.smppSystemID + " " + msgID); this.submitListMessageID(seqNo,msgID); } userSubmitSMRespFailFunc(err,seqNo) { console.log("userSubmitSMRespFailFunc"); var msisdn = ""; if ($('#seq_'+seqNo).length!=0) { msisdn = $('#seq_'+seqNo).text(); } $('#seq_'+seqNo).replaceWith(msisdn+''); alert("FAILED - Error "+smppCmdStatusStr(err)+" ("+err+")"); } userBindTRXRespSuccessFunc() { console.log("userBindTRXRespSuccessFunc"); this.restartEnquireLinkTimeout(); } userEnquireLinkRespFunc() { console.log("userEnquireLinkRespFunc"); this.restartEnquireLinkTimeout(); } userWSCloseFunc() { console.log("userWSCloseFunc"); if (debug) console.log(this); if (this.timerEnquireLink) clearTimeout(this.timerEnquireLink); var s = this; setTimeout(function() { s.connect(); }, 3*1000); } showState(ignore) { this.widget_button.innerHTML = this.widget_data.label + " "; const destinations = this.widget_data.destination.split(","); this.countDestinations = destinations.length; for(let a=0;a▮"; } else if (a▮"; } } if (debug) this.widget_button.innerHTML += " " + widget_id; this.widget_button.querySelector("span.widget-status").innerHTML = ""; //this.stateBound?"●":"○"; this.widget_button.disabled = !this.stateBound; } } /* */ function uuidv4() { return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c => (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) ); } var widgetButtons = {}; function isWidgetConfigured(el) { var d = el.dataset; // mandatory params if ( (typeof d.label === 'undefined') || (typeof d.host === 'undefined') || (typeof d.port === 'undefined') || (typeof d.systemid === 'undefined') || (typeof d.password === 'undefined') || (typeof d.source === 'undefined') || (typeof d.destination === 'undefined') || (typeof d.message === 'undefined') ) { return false; } return true; } $(document).ready(function () { elMessageArea = null; // log area var widget_divs = document.getElementsByClassName("smppWidget"); // create each widget for(var i=0;i"; // const destinations = widget_data.destination.split(","); // this.countDestinations = destinations.length; // for(let a=0;a'+destination); const [ hasForcedUDHI, seqnos ] = smppWidget.smppHelperSubmitSM( 0,0,smppWidget.widget_data.source, 1,1,destination, formESMClass,formProtocolID,formPriorityFlag, "","",formRegisteredDelivery,formDataCoding, smppWidget.widget_data.message); if (hasForcedUDHI) { formESMClass = formESMClass | 64; // set UDHI //$('#esmClass').val(formESMClass); } smppWidget.submitListAdd(seqnos[0],smppWidget.widget_data.destination,smppWidget.widget_data.message /*$('#smppMessage').val()*/); } ); // } /* function messageChange() { var isGSM7Msg = isGSM7Message( $("#smppMessage").val() ); if (isGSM7Msg) $('#message_sms_mode').html("GSM7"); else { $('#message_sms_mode').html("UCS2"); $('#dataCoding').val(8); } var bitsPerChar = isGSM7Msg?7:16; if ( $('#dataCoding').val() == 8 ) bitsPerChar=16; // var sms_len = 0; if (isGSM7Msg) { for(let i=0;i<$("#smppMessage").val().length;i++) { sms_len += unicodeToGsm[ $("#smppMessage").val().charCodeAt(i) ].length; } } else sms_len = $("#smppMessage").val().length; var sms_count = 0; var sms_concat_space = (140*8 - 6*8) / bitsPerChar; if (sms_len>0) { if (sms_len<= Math.floor(140*8/bitsPerChar) ) sms_count = 1; else { sms_count = Math.floor(sms_len / sms_concat_space); if ((sms_len % sms_concat_space) > 0) sms_count++; } $('#message_sms_counter').html(sms_count); } $('#message_char_counter').html(sms_len + " chars ("+bitsPerChar*sms_len+" bits)"); } $("#dataCoding").on('input', messageChange); $("#smppMessage").on('input', messageChange); $("#smppMessage").val("Hello world!"); messageChange(); */ }); /**/