Skip to content

Commit

Permalink
Merge pull request #102 from jookies/v0.6-beta
Browse files Browse the repository at this point in the history
V0.6b3
  • Loading branch information
farirat committed Feb 26, 2015
2 parents 7c5cc10 + 91421ad commit 012b9bf
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ python:
# Command to install dependencies
install:
- python setup.py sdist
- sudo pip install dist/jasmin-0.6b2.tar.gz
- sudo pip install dist/jasmin-0.6b3.tar.gz
# Commands to run tests:
script:
# Add jasmind to system autostartup:
Expand Down
2 changes: 1 addition & 1 deletion jasmin/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

MAJOR = 0
MINOR = 6
PATCH = 2
PATCH = 3
META = 'b'

def get_version():
Expand Down
4 changes: 4 additions & 0 deletions jasmin/managers/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ class SMPPClientSMListenerConfig(ConfigFile):

def __init__(self, config_file = None):
ConfigFile.__init__(self, config_file)

self.publish_submit_sm_resp = self._getbool('sm-listener',
'publish_submit_sm_resp',
True)

self.log_level = logging.getLevelName(self._get('sm-listener',
'log_level',
Expand Down
21 changes: 11 additions & 10 deletions jasmin/managers/listeners.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ def submit_sm_resp_event(self, r, amqpMessage):
hashValues = {'msgid': msgid,
'connector_type': 'httpapi',}
self.redisClient.set(hashKey, pickle.dumps(hashValues, self.pickleProtocol)).addCallback(
self.setKeyExpiry, hashKey, smpps_map_expiry)
self.setKeyExpiry, hashKey, dlr_expiry)
elif pickledSmppsMap is not None:
self.log.debug('There is a SMPPs mapping for msgid[%s] ...' % (msgid))

Expand Down Expand Up @@ -392,15 +392,16 @@ def submit_sm_resp_event(self, r, amqpMessage):
routing_key=pubQueueName,
content=content)

# Send back submit_sm_resp to submit.sm.resp.CID queue
# There's no actual listeners on this queue, it can be used to
# track submit_sm_resp messages from a 3rd party app
content = SubmitSmRespContent(r.response, msgid, pickleProtocol = self.pickleProtocol)
self.log.debug("Sending back SubmitSmRespContent[%s] with routing_key[%s]" %
(msgid, amqpMessage.content.properties['reply-to']))
yield self.amqpBroker.publish(exchange='messaging',
routing_key=amqpMessage.content.properties['reply-to'],
content=content)
if self.config.publish_submit_sm_resp:
# Send back submit_sm_resp to submit.sm.resp.CID queue
# There's no actual listeners on this queue, it can be used to
# track submit_sm_resp messages from a 3rd party app
content = SubmitSmRespContent(r.response, msgid, pickleProtocol = self.pickleProtocol)
self.log.debug("Sending back SubmitSmRespContent[%s] with routing_key[%s]" %
(msgid, amqpMessage.content.properties['reply-to']))
yield self.amqpBroker.publish(exchange='messaging',
routing_key=amqpMessage.content.properties['reply-to'],
content=content)

def submit_sm_errback(self, error):
"""It appears that when closing a queue with the close() method it errbacks with
Expand Down
23 changes: 13 additions & 10 deletions jasmin/protocols/http/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def render(self, request):
updated_request.args['coding'] = ['0']

# Set default for undefined updated_request.arguments
if 'dlr-url' in updated_request.args:
if 'dlr-url' in updated_request.args or 'dlr-level' in updated_request.args:
updated_request.args['dlr'] = ['yes']
if 'dlr' not in updated_request.args:
# Setting DLR updated_request to 'no'
Expand Down Expand Up @@ -144,15 +144,18 @@ def render(self, request):
# 2 # Terminal level (only) # x x x x x x 0 1 #
# 3 # SMS-C level and Terminal level # x x x x x x 0 1 #
####################################################################
if updated_request.args['dlr'][0] == 'yes' and 'dlr-url' in updated_request.args:
if updated_request.args['dlr'][0] == 'yes':
if updated_request.args['dlr-level'][0] == '1':
SubmitSmPDU.params['registered_delivery'] = RegisteredDelivery(RegisteredDeliveryReceipt.NO_SMSC_DELIVERY_RECEIPT_REQUESTED)
elif updated_request.args['dlr-level'][0] == '2' or updated_request.args['dlr-level'][0] == '3':
SubmitSmPDU.params['registered_delivery'] = RegisteredDelivery(RegisteredDeliveryReceipt.SMSC_DELIVERY_RECEIPT_REQUESTED_FOR_FAILURE)
self.log.debug("SubmitSmPDU registered_delivery is set to %s" % str(SubmitSmPDU.params['registered_delivery']))

dlr_url = updated_request.args['dlr-url'][0]
dlr_level = int(updated_request.args['dlr-level'][0])
if 'dlr-url' in updated_request.args:
dlr_url = updated_request.args['dlr-url'][0]
else:
dlr_url = None
if updated_request.args['dlr-level'][0] == '1':
dlr_level_text = 'SMS-C'
elif updated_request.args['dlr-level'][0] == '2':
Expand Down Expand Up @@ -200,13 +203,13 @@ def render(self, request):
# Send SubmitSmPDU through smpp client manager PB server
self.log.debug("Connector '%s' is set to be a route for this SubmitSmPDU" % routedConnector.cid)
c = self.SMPPClientManagerPB.perspective_submit_sm(routedConnector.cid,
SubmitSmPDU,
priority,
pickled = False,
dlr_url = dlr_url,
dlr_level = dlr_level,
dlr_method = dlr_method,
submit_sm_resp_bill = bill.getSubmitSmRespBill())
SubmitSmPDU,
priority,
pickled = False,
dlr_url = dlr_url,
dlr_level = dlr_level,
dlr_method = dlr_method,
submit_sm_resp_bill = bill.getSubmitSmRespBill())

# Build final response
if not c.result:
Expand Down
18 changes: 18 additions & 0 deletions jasmin/protocols/smpp/test/test_encoding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import unittest, binascii, StringIO
from jasmin.vendor.smpp.pdu.sm_encoding import SMStringEncoder
from jasmin.vendor.smpp.pdu.pdu_types import *
from jasmin.vendor.smpp.pdu.gsm_types import *
from jasmin.vendor.smpp.pdu.pdu_encoding import PDUEncoder

class PDUDecoderTest(unittest.TestCase):

def getPDU(self, hexStr):
return PDUEncoder().decode(StringIO.StringIO(binascii.a2b_hex(hexStr)))

def test_deliver_sm_unknown_param_network_error_code(self):
pduHex = '000000e40000000500000000542e0f21312e303030000101323434393335353535300005005a4150000400000000000000008069643a3661336564393861363634343465386162616333616364396262613836353666207375623a30303120646c7672643a303030207375626d697420646174653a31343130313630303336353020646f6e6520646174653a31343130313630303338303020737461743a554e44454c4956206572723a30303020746578743a042300033030300427000105001e0021366133656439386136363434346538616261633361636439626261383635366600'
pdu = self.getPDU(pduHex)
SMStringEncoder().decodeSM(pdu)

# Asserts
self.assertEquals('000', pdu.params['network_error_code'])
86 changes: 86 additions & 0 deletions jasmin/vendor/smpp/pdu/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,83 @@
'description': 'Unknown Error',
},
# Jasmin update:
0x00000100L : {
'name' : 'ESME_RSERTYPUNAUTH',
'description': 'ESME Not authorised to use specified service_type',
},
0x00000101L : {
'name' : 'ESME_RPROHIBITED',
'description': 'ESME Prohibited from using specified operation',
},
0x00000102L : {
'name' : 'ESME_RSERTYPUNAVAIL',
'description': 'Specified service_type is unavailable',
},
0x00000103L : {
'name' : 'ESME_RSERTYPDENIED',
'description': 'Specified service_type is denied',
},
0x00000104L : {
'name' : 'ESME_RINVDCS',
'description': 'Invalid Data Coding Scheme',
},
0x00000105L : {
'name' : 'ESME_RINVSRCADDRSUBUNIT',
'description': 'Source Address Sub unit is Invalid',
},
0x00000106L : {
'name' : 'ESME_RINVDSTADDRSUBUNIT',
'description': 'Destination Address Sub unit is Invalid',
},
0x00000107L : {
'name' : 'ESME_RINVBCASTFREQINT',
'description': 'Broadcast Frequency Interval is invalid',
},
0x00000108L : {
'name' : 'ESME_RINVBCASTALIAS_NAME',
'description': 'Broadcast Alias Name is invalid',
},
0x00000109L : {
'name' : 'ESME_RINVBCASTAREAFMT',
'description': 'Broadcast Area Format is invalid',
},
0x0000010aL : {
'name' : 'ESME_RINVNUMBCAST_AREAS',
'description': 'Number of Broadcast Areas is invalid',
},
0x0000010bL : {
'name' : 'ESME_RINVBCASTCNTTYPE',
'description': 'Broadcast Content Type is invalid',
},
0x0000010cL : {
'name' : 'ESME_RINVBCASTMSGCLASS',
'description': 'Broadcast Message Class is invalid',
},
0x0000010dL : {
'name' : 'ESME_RBCASTFAIL',
'description': 'broadcast_sm operation failed',
},
0x0000010eL : {
'name' : 'ESME_RBCASTQUERYFAIL',
'description': 'query_broadcast_sm operation failed',
},
0x0000010fL : {
'name' : 'ESME_RBCASTCANCELFAIL',
'description': 'cancel_broadcast_sm operation failed',
},
0x00000110L : {
'name' : 'ESME_RINVBCAST_REP',
'description': 'Number of Repeated Broadcasts is invalid',
},
0x00000111L : {
'name' : 'ESME_RINVBCASTSRVGRP',
'description': 'Broadcast Service Group is invalid',
},
0x00000112L : {
'name' : 'ESME_RINVBCASTCHANIND',
'description': 'Broadcast Channel Indicator is invalid',
},
# Jasmin update:
-1 : {
'name' : 'RESERVEDSTATUS_SMPP_EXTENSION',
'description': 'Reserved for SMPP extension',
Expand Down Expand Up @@ -475,6 +552,15 @@
}
ms_availability_status_value_map = dict([(val, key) for (key, val) in ms_availability_status_name_map.items()])

# Jasmin update:
network_error_code_name_map = {
'ANSI-136': 0x01,
'IS-95': 0x02,
'GSM': 0x03,
'RESERVED': 0x04,
}
network_error_code_value_map = dict([(val, key) for (key, val) in network_error_code_name_map.items()])

network_type_name_map = {
'UNKNOWN': 0x00,
'GSM': 0x01,
Expand Down
10 changes: 9 additions & 1 deletion jasmin/vendor/smpp/pdu/pdu_encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,13 @@ class MsAvailabilityStatusEncoder(IntegerWrapperEncoder):
encoder = Int1Encoder()
pduType = pdu_types.MsAvailabilityStatus

# Jasmin update:
class NetworkErrorCodeEncoder(OctetStringEncoder):
fieldName = 'network_error_code'
nameMap = constants.network_error_code_name_map
valueMap = constants.network_error_code_value_map
pduType = pdu_types.NetworkErrorCode

class DeliveryFailureReasonEncoder(IntegerWrapperEncoder):
fieldName = 'delivery_failure_reason'
nameMap = constants.delivery_failure_reason_name_map
Expand Down Expand Up @@ -775,7 +782,8 @@ def __init__(self):
#T.dpf_result: DpfResultEncoder(),
#T.set_dpf: SetDpfEncoder(),
T.ms_availability_status: MsAvailabilityStatusEncoder(),
#T.network_error_code: NetworkErrorCodeEncoder(),
# Jasmin update:
T.network_error_code: NetworkErrorCodeEncoder(self.getLength),
T.message_payload: OctetStringEncoder(self.getLength),
T.delivery_failure_reason: DeliveryFailureReasonEncoder(),
T.more_messages_to_send: MoreMessagesToSendEncoder(),
Expand Down
1 change: 1 addition & 0 deletions jasmin/vendor/smpp/pdu/pdu_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ def __repr__(self):
LanguageIndicator = Enum(*constants.language_indicator_name_map.keys())
DisplayTime = Enum(*constants.display_time_name_map.keys())
MsAvailabilityStatus = Enum(*constants.ms_availability_status_name_map.keys())
NetworkErrorCode = Enum(*constants.network_error_code_name_map.keys())
DeliveryFailureReason = Enum(*constants.delivery_failure_reason_name_map.keys())
MoreMessagesToSend = Enum(*constants.more_messages_to_send_name_map.keys())

Expand Down
5 changes: 5 additions & 0 deletions misc/config/jasmin.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@
# SM listener consumes submit_sm and deliver_sm messages from amqp broker
# refer to "Message flows" documentation for more details

# If publish_submit_sm_resp is True, any received SubmitSm PDU will be published
# to the 'messaging' exchange on 'submit.sm.resp.CID' route, useful when you have
# a third party application waiting for these messages.
#publish_submit_sm_resp = True

# Specify the server verbosity level.
# This can be one of:
# NOTSET (disable logging)
Expand Down

0 comments on commit 012b9bf

Please sign in to comment.