I am in big trouble..I want to know why my client is only receiving submit_sm not deliver_sm. even though i tried online simulator for testing. it do shows me Deliver_sm ( https://melroselabs.com/tools/smppsender/?host=smscsim.melroselabs.com ) ..But in client dashboard it only shows Accepted ( Submit_sm ) not Delivered ( delivered_sm )
/*
* IMPORTS
*/
import Debug from 'debug/src/node' // NPM: Debug module for debugging.
import Smpp from './node_modules/smpp' // NPM: Smpp module for handling Smpp connections.
import { Buffer } from 'safer-buffer' // NPM: Buffer module for handling buffers.
import _ from 'underscore' // NPM: Utility module for handling objects.
import { format } from 'fecha' // NPM: Date formatting module.
/*
* PACKAGES
*/
import Context from 'context'
import Tag from 'tag'
const generateDeliverSmBuffer = (sequenceNumber, serviceType, sourceAddr, destAddr, shortMessage) => {
// Command ID for deliver_sm
const commandId = 0x00000005
// Create a buffer to hold the PDU
const buffer = Buffer.alloc(100) // Adjust the size as needed
// Write the PDU fields to the buffer
buffer.writeUInt32BE(buffer.length, 0) // Command Length
buffer.writeUInt32BE(commandId, 4) // Command ID
buffer.writeUInt32BE(0, 8) // Command Status (No Error)
buffer.writeUInt32BE(sequenceNumber, 12) // Sequence Number
// Service Type
buffer.write(serviceType, 16, 'ascii')
buffer.writeUInt8(0, 16 + serviceType.length) // Null-terminated
// Source Address
buffer.write(sourceAddr, 40, 'ascii')
buffer.writeUInt8(0, 40 + sourceAddr.length) // Null-terminated
// Destination Address
buffer.write(destAddr, 70, 'ascii')
buffer.writeUInt8(0, 70 + destAddr.length) // Null-terminated
// Short Message
buffer.write(shortMessage, 100, 'utf8')
return buffer
}
/*
* OBJECTS
*/
Smpp.createServer({ 'enable_proxy_protocol_detection': true, 'debug': global.WORKING_ENV.DEVELOPMENT.value !== global.CONFIG_RC.env }, __Session => {
// Local variable.
let _functionName
// Const assignment.
const _events = ['submit_sm', 'query_sm', 'cancel_sm', 'deliver_sm']
// Object assignment.
const _BindTransceiver = async __pdu => {
// Create Context for incoming request.
const _SharedContext = await Context({ 'request': __Session })
console.log(__pdu)
// Variable assignment.
_functionName = 'WwwSmppBindTransceiver'
// Error handling.
try {
/*
* We pause the session to prevent further incoming pdu events,
* until we authorize the session with some async operation.
*/
__Session.pause()
// Debug incoming request.
_SharedContext.Debug({ 'message': `Bind request received from ${String.ipv6ToIpv4(__Session.remoteAddress)}`, 'status': 'BIND_TRANSCEIVER' }, _functionName)
// Get smpp details from database.
const _SmppFindMany = await _SharedContext.DataBase.smpp.findMany({ 'where': { 'ip': { 'equals': 'smscsim.melroselabs.com' } } })
// If details are empty then report failure.
if (_SmppFindMany instanceof Error || _.isEmpty(_SmppFindMany)) {
// Style guide.
await _SharedContext.Debug({ 'message': `Could not find smpp with given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}`, 'error': _SmppFindMany instanceof Error ? _SmppFindMany : new Error('NO_SMPP_WITH_THIS_IP_FOUND') }, _functionName)
// Close the session.
return __Session.send(__pdu.response({ 'command_status': Smpp.ESME_RBINDFAIL }))
}
// Style Guide.
await _SharedContext.Debug({ 'message': `Found ${_SmppFindMany.length} smpp with given username for given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}.` }, _functionName)
await _SharedContext.Debug({ 'message': `Looking for smpp with correct password for given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}` }, _functionName)
/*
* Loop over all smpp details.
* and look if any one smpp finds a match.
*/
for await (const josh of _SmppFindMany) {
// Respond with success if given username and password matches.
if (josh.username === __pdu.system_id.toString() && josh.password === __pdu.password.toString()) {
// Style guide.
await _SharedContext.Debug({ 'message': `Found smpp with correct password for given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}` }, _functionName)
await _SharedContext.Debug({ 'message': `Responding ip: ${String.ipv6ToIpv4(__Session.remoteAddress)} with successful bind.` }, _functionName)
// Send successful pdu response.
__Session.send(__pdu.response({ 'command_status': Smpp.ESME_ROK }))
// Resume the session.
__Session.resume()
// Debug incoming request.
return _SharedContext.Debug({ 'message': `Bind request accepted from ${String.ipv6ToIpv4(__Session.remoteAddress)}`, 'status': 'BIND_TRANSCEIVER' }, _functionName)
}
}
// Style guide.
await _SharedContext.Debug({ 'message': `Could not find smpp with correct password for given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}` }, _functionName)
// Close the session.
__Session.close()
// Report failure.
return __Session.send(__pdu.response({ 'command_status': Smpp.ESME_RBINDFAIL }))
} catch (error) {
// Report failure.
_SharedContext.Debug({ error })
// End the session.
return __Session.send(__pdu.response({ 'command_status': Smpp.ESME_RBINDFAIL }))
}
}
const _PushPDU = async (__command, __pdu) => {
// Create Context for incoming request.
const _SharedContext = await Context({ 'request': __Session })
console.log(__command, __pdu)
// Variable assignment.
_functionName = 'WwwSmppSubmitSm'
// Error handling.
try {
// Debug incoming request.
_SharedContext.Debug({ 'message': `Message received from ${String.ipv6ToIpv4(__Session.remoteAddress)}` }, _functionName)
// Get client by source and destination.
const _RouteGet = _SharedContext.Route.get(Tag.Route.ClientByIp('smscsim.melroselabs.com'))
// If route is empty then report failure.
if (_.isEmpty(_RouteGet)) {
// Style guide.
await _SharedContext.Debug({ 'message': `Could not find client for given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}` }, _functionName)
// Report failure.
return __Session.send(__pdu.response({ 'command_status': Smpp.ESME_RSYSERR }))
}
// Style guide.
await _SharedContext.Debug({ 'message': `Found client for given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}` }, _functionName)
// Get pooled client.
const _RouteGetUse = _RouteGet.use()
// Style Guide.
await _SharedContext.Debug({ 'message': `Pooled route from route pool for ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}` }, _functionName)
await _SharedContext.Debug({ 'message': `Pushing pdu to client with given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}` }, _functionName)
// Push pdu to this route.
const _RouteGetUsePush = await _RouteGetUse.Push(__command, __pdu)
// If pushing pdu caught exception then report failure.
if (_RouteGetUsePush instanceof Error) {
// Style Guide.
await _SharedContext.Debug({ 'message': `Failed to push pdu to client with given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}`, 'error': _RouteGetUsePush }, _functionName)
// Report failure.
return __Session.send(__pdu.response({ 'command_status': Smpp.ESME_RSYSERR }))
}
// Style Guide.
await _SharedContext.Debug({ 'message': `Successfully pushed pdu to client with given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}` }, _functionName)
console.log(_RouteGetUsePush)
// Respond with submit response.
__Session.send(__pdu.response({ 'message_state': Smpp.ESME_ROK, 'message_id': _RouteGetUsePush.message_id }))
// Report success.
if ('submit_sm' === __command) {
// Style Guide.
await _SharedContext.Debug({ 'message': `Responding to client with given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}` }, _functionName)
// Object assignment.
const _DeliverSm = () => __Session.deliver_sm({
'source_addr': __pdu.destination_addr,
'destination_addr': __pdu.source_addr,
'short_message': __pdu.short_message,
'esm_class': 4,
'delivery_state': 0,
'message_id': _RouteGetUsePush.message_id,
'final_date': new Date(),
'message_state': 'DELIVERED',
'receipted_message_id': _RouteGetUsePush.message_id,
'text': _RouteGetUsePush.message
})
// Handle registered delivery accordingly.
if (1 === __pdu.registered_delivery) {
// Respond with receipt.
_DeliverSm()
} else if (2 === __pdu.registered_delivery) {
/*
* Only response with receipt if
* error has been occurred.
*/
if (0 !== _RouteGetUsePush.command_status) {
// Respond with receipt.
_DeliverSm()
}
} else if (3 === __pdu.registered_delivery) {
// Only respond back if no error has been occurred.
if (0 === _RouteGetUsePush.command_status) {
// Respond with receipt.
_DeliverSm()
}
}
} else if ('query_sm' === __command) {
// Style Guide.
await _SharedContext.Debug({ 'message': `Responding to client with given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}` }, _functionName)
// Respond with success.
__Session.send(__pdu.response({
'message_id': __pdu.message_id,
'final_date': new Date(),
'message_state': 'DELIVERED',
'receipted_message_id': __pdu.message_id,
'text': _RouteGetUsePush.message
}))
} else if ('cancel_sm' === __command) {
// Style Guide.
await _SharedContext.Debug({ 'message': `Responding to client with given ip: ${String.ipv6ToIpv4(__Session.remoteAddress)}` }, _functionName)
// Respond with success.
__Session.send(__pdu.response({ 'message_state': Smpp.ESME_ROK }))
}
// Recycle route.
return _RouteGet.recycle(_RouteGetUse)
} catch (error) {
// Report failure.
_SharedContext.Debug({ error })
// Report failure that pdu has not been sent.
return __Session.send(__pdu.response({ 'command_status': Smpp.ESME_RSYSERR }))
}
}
// Smpp handler for handling server bind.
__Session.on('bind_transceiver', _BindTransceiver)
// Loop over events which can be handled by Route.
_events.forEach(_event => __Session.on(_event, __pdu => _PushPDU(_event, __pdu)))
// Other common events to listen on.
__Session.on('error', async error => {
// Create Context for incoming request.
const _SharedContext = await Promise.resolve(Context(__Session))
// Handle errors
_SharedContext.Debug({ error })
// Close smpp connection and return success.
__Session.close()
})
__Session.on('unbind', pdu => {
// Close smpp connection and return success.
__Session.send(pdu.response())
__Session.close()
})
__Session.on('enquire_link', __pdu => __Session.send(__pdu.response()))
__Session.on('close', () => __Session.close())
}).listen(global.CONFIG_RC.smppPort, () => Debug('WwwSmpp')(`=> Executing => Running on ${global.CONFIG_RC.smppPort}`))
I am in big trouble..I want to know why my client is only receiving submit_sm not deliver_sm. even though i tried online simulator for testing. it do shows me Deliver_sm ( https://melroselabs.com/tools/smppsender/?host=smscsim.melroselabs.com ) ..But in client dashboard it only shows Accepted ( Submit_sm ) not Delivered ( delivered_sm )