def test_mt_sms(self): smpp_helper = yield self.get_smpp_helper() msg = self.tx_helper.make_outbound('hello world') yield self.tx_helper.dispatch_outbound(msg) [pdu] = yield smpp_helper.wait_for_pdus(1) self.assertEqual(command_id(pdu), 'submit_sm') self.assertEqual(short_message(pdu), 'hello world')
def test_submit_and_deliver_ussd_close(self): smpp_helper = yield self.get_smpp_helper() yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", session_event=TransportUserMessage.SESSION_CLOSE) [submit_sm_pdu] = yield smpp_helper.wait_for_pdus(1) self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(pdu_tlv(submit_sm_pdu, 'ussd_service_op'), '02') self.assertEqual(pdu_tlv(submit_sm_pdu, 'its_session_info'), '0001') # Server delivers a USSD message to the Client pdu = DeliverSM(seq_no(submit_sm_pdu) + 1, short_message="reply!") pdu.add_optional_parameter('ussd_service_op', '02') pdu.add_optional_parameter('its_session_info', '0001') yield smpp_helper.handle_pdu(pdu) [mess] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(mess['content'], "reply!") self.assertEqual(mess['transport_type'], "ussd") self.assertEqual(mess['session_event'], TransportUserMessage.SESSION_CLOSE)
def test_mt_sms_unicode(self): smpp_helper = yield self.get_smpp_helper() msg = self.tx_helper.make_outbound(u'Zoë') yield self.tx_helper.dispatch_outbound(msg) [pdu] = yield smpp_helper.wait_for_pdus(1) self.assertEqual(command_id(pdu), 'submit_sm') self.assertEqual(short_message(pdu), 'Zo\xc3\xab')
def test_start_sequence(self): """ The service goes through several states while starting. """ # New service, never started. service = yield self.get_service(start=False) self.assertEqual(service.running, False) self.assertEqual(service.get_bind_state(), EsmeProtocol.CLOSED_STATE) # Start, but don't connect. yield self.start_service(service, accept_connection=False) self.assertEqual(service.running, True) self.assertEqual(service.get_bind_state(), EsmeProtocol.CLOSED_STATE) # Connect, but don't bind. yield self.fake_smsc.accept_connection() self.assertEqual(service.running, True) self.assertEqual(service.get_bind_state(), EsmeProtocol.OPEN_STATE) bind_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(bind_pdu), 'bind_transceiver') # Bind. yield self.fake_smsc.bind(bind_pdu) self.assertEqual(service.running, True) self.assertEqual(service.get_bind_state(), EsmeProtocol.BOUND_STATE_TRX)
def test_start_sequence(self): """ The service goes through several states while starting. """ # New service, never started. service = yield self.get_service(start=False) self.assertEqual(service.running, False) self.assertEqual(service.get_bind_state(), EsmeProtocol.CLOSED_STATE) # Start, but don't connect. yield self.start_service(service, accept_connection=False) self.assertEqual(service.running, True) self.assertEqual(service.get_bind_state(), EsmeProtocol.CLOSED_STATE) # Connect, but don't bind. yield self.fake_smsc.accept_connection() self.assertEqual(service.running, True) self.assertEqual(service.get_bind_state(), EsmeProtocol.OPEN_STATE) bind_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(bind_pdu), 'bind_transceiver') # Bind. yield self.fake_smsc.bind(bind_pdu) self.assertEqual(service.running, True) self.assertEqual( service.get_bind_state(), EsmeProtocol.BOUND_STATE_TRX)
def test_on_enquire_link_resp(self): calls = [] self.patch(EsmeTransceiver, 'handle_enquire_link_resp', lambda p, pdu: calls.append(pdu)) transport, protocol = yield self.setup_bind() [pdu] = calls # bind_transceiver is sequence_number 1 self.assertEqual(seq_no(pdu), 2) self.assertEqual(command_id(pdu), 'enquire_link_resp')
def test_on_enquire_link_resp(self): protocol = yield self.get_protocol() calls = [] protocol.handle_enquire_link_resp = calls.append yield self.fake_smsc.bind() [pdu] = calls # bind_transceiver is sequence_number 1 self.assertEqual(seq_no(pdu), 2) self.assertEqual(command_id(pdu), 'enquire_link_resp')
def _bind_resp(self, bind_pdu): resp_pdu_classes = { 'bind_transceiver': BindTransceiverResp, 'bind_receiver': BindReceiverResp, 'bind_transmitter': BindTransmitterResp, } self.assert_command_id(bind_pdu, *resp_pdu_classes) resp_pdu_class = resp_pdu_classes.get(command_id(bind_pdu)) self.send_pdu(resp_pdu_class(seq_no(bind_pdu))) eq_d = self.respond_to_enquire_link() return eq_d.addCallback(self._bound_d.callback)
def on_unsupported_command_id(self, pdu): """ Called when an SMPP PDU is received for which no handler function has been defined. :param dict pdu: The dict result one gets when calling ``smpp.pdu.unpack_pdu()`` on the received PDU """ log.warning('Received unsupported SMPP command_id: %r' % (command_id(pdu), ))
def on_unsupported_command_id(self, pdu): """ Called when an SMPP PDU is received for which no handler function has been defined. :param dict pdu: The dict result one gets when calling ``smpp.pdu.unpack_pdu()`` on the received PDU """ self.log.warning( 'Received unsupported SMPP command_id: %r' % (command_id(pdu),))
def test_handle_unbind(self): """ If the SMSC sends an unbind command, we respond and disconnect. """ service = yield self.get_service() yield self.fake_smsc.bind() self.assertEqual(service.is_bound(), True) self.fake_smsc.send_pdu(Unbind(7)) unbind_resp_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(unbind_resp_pdu), 'unbind_resp') self.assertEqual(service.is_bound(), False)
def on_pdu(self, pdu): """ Handle a PDU that was received & decoded. :param dict pdu: The dict result one gets when calling ``smpp.pdu.unpack_pdu()`` on the received PDU """ self.emit('INCOMING << %r' % (pdu,)) handler = getattr(self, 'handle_%s' % (command_id(pdu),), self.on_unsupported_command_id) return maybeDeferred(handler, pdu)
def on_pdu(self, pdu): """ Handle a PDU that was received & decoded. :param dict pdu: The dict result one gets when calling ``smpp.pdu.unpack_pdu()`` on the received PDU """ self.emit('INCOMING << %r' % (pdu, )) handler = getattr(self, 'handle_%s' % (command_id(pdu), ), self.on_unsupported_command_id) return maybeDeferred(handler, pdu)
def test_submit_sm(self): """ When bound, we can send a message. """ service = yield self.get_service() yield self.fake_smsc.bind() seq_nums = yield service.submit_sm( 'abc123', 'dest_addr', short_message='foo') submit_sm = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm), 'submit_sm') stored_ids = yield self.lookup_message_ids(service, seq_nums) self.assertEqual(['abc123'], stored_ids)
def test_submit_sm(self): """ When bound, we can send a message. """ service = yield self.get_service() yield self.fake_smsc.bind() seq_nums = yield service.submit_sm('abc123', 'dest_addr', short_message='foo') submit_sm = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm), 'submit_sm') stored_ids = yield self.lookup_message_ids(service, seq_nums) self.assertEqual(['abc123'], stored_ids)
def test_submit_and_deliver_ussd_close(self): yield self.get_transport() session_identifier = 12345 yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", session_event=TransportUserMessage.SESSION_CLOSE, transport_metadata={"session_info": {"session_identifier": session_identifier}}, ) submit_sm_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm_pdu), "submit_sm") self.assertEqual(pdu_tlv(submit_sm_pdu, "ussd_service_op"), "17") self.assertEqual(pdu_tlv(submit_sm_pdu, "user_message_reference"), session_identifier)
def test_partial_pdu_data_received(self): protocol = yield self.get_protocol() calls = [] protocol.handle_deliver_sm = calls.append yield self.fake_smsc.bind() deliver_sm = DeliverSM(1, short_message='foo') pdu = deliver_sm.get_bin() half = len(pdu) / 2 pdu_part1, pdu_part2 = pdu[:half], pdu[half:] yield self.fake_smsc.send_bytes(pdu_part1) self.assertEqual([], calls) yield self.fake_smsc.send_bytes(pdu_part2) [handled_pdu] = calls self.assertEqual(command_id(handled_pdu), 'deliver_sm') self.assertEqual(seq_no(handled_pdu), 1) self.assertEqual(short_message(handled_pdu), 'foo')
def test_partial_pdu_data_received(self): calls = [] self.patch(EsmeTransceiver, 'handle_deliver_sm', lambda p, pdu: calls.append(pdu)) transport, protocol = yield self.setup_bind() deliver_sm = DeliverSM(sequence_number=1, short_message='foo') pdu = deliver_sm.get_bin() half = len(pdu) / 2 pdu_part1, pdu_part2 = pdu[:half], pdu[half:] protocol.dataReceived(pdu_part1) self.assertEqual([], calls) protocol.dataReceived(pdu_part2) [handled_pdu] = calls self.assertEqual(command_id(handled_pdu), 'deliver_sm') self.assertEqual(seq_no(handled_pdu), 1) self.assertEqual(short_message(handled_pdu), 'foo')
def test_submit_csm_sar_single_part(self): """ If the content fits in a single message, all the multipart madness is avoided. """ service = yield self.get_service({'send_multipart_sar': True}) yield self.fake_smsc.bind() content = 'a' * 160 seq_numbers = yield service.submit_csm_sar( 'abc123', 'dest_addr', short_message=content) self.assertEqual(len(seq_numbers), 1) submit_sm_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(short_message(submit_sm_pdu), content) self.assertEqual(unpacked_pdu_opts(submit_sm_pdu), {})
def test_submit_and_deliver_ussd_continue(self): user_msisdn = 'msisdn' session_identifier = 12345 vumi_session_identifier = make_vumi_session_identifier( user_msisdn, session_identifier) transport = yield self.get_transport() deliver_sm_processor = transport.deliver_sm_processor session_manager = deliver_sm_processor.session_manager yield session_manager.create_session(vumi_session_identifier, ussd_code='*123#') yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", transport_metadata={ 'session_info': { 'session_identifier': session_identifier } }, to_addr=user_msisdn) submit_sm_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(pdu_tlv(submit_sm_pdu, 'ussd_service_op'), '02') self.assertEqual(pdu_tlv(submit_sm_pdu, 'user_message_reference'), session_identifier) # Server delivers a USSD message to the Client pdu = DeliverSM(seq_no(submit_sm_pdu) + 1, short_message="reply!", source_addr=user_msisdn) # 0x12 is 'continue' pdu.add_optional_parameter('ussd_service_op', '12') pdu.add_optional_parameter('user_message_reference', session_identifier) yield self.fake_smsc.handle_pdu(pdu) [mess] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(mess['content'], "reply!") self.assertEqual(mess['transport_type'], "ussd") self.assertEqual(mess['to_addr'], '*123#') self.assertEqual(mess['session_event'], TransportUserMessage.SESSION_RESUME)
def test_submit_csm_sar_single_part(self): """ If the content fits in a single message, all the multipart madness is avoided. """ service = yield self.get_service({'send_multipart_sar': True}) yield self.fake_smsc.bind() content = 'a' * 160 seq_numbers = yield service.submit_csm_sar('abc123', 'dest_addr', short_message=content) self.assertEqual(len(seq_numbers), 1) submit_sm_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(short_message(submit_sm_pdu), content) self.assertEqual(unpacked_pdu_opts(submit_sm_pdu), {})
def test_submit_and_deliver_ussd_close(self): session = SessionInfo(continue_session=False) yield self.get_transport() yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", session_event=TransportUserMessage.SESSION_CLOSE, transport_metadata={ 'session_info': { 'session_identifier': session.sixdee_id, } }) submit_sm_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(pdu_tlv(submit_sm_pdu, 'ussd_service_op'), '17') self.assertEqual(pdu_tlv(submit_sm_pdu, 'its_session_info'), session.its_info)
def test_submit_csm_udh_single_part(self): """ If the content fits in a single message, all the multipart madness is avoided. """ service = yield self.get_service({'send_multipart_udh': True}) yield self.fake_smsc.bind() content = 'a' * 160 seq_numbers = yield service.submit_csm_udh( 'abc123', 'dest_addr', short_message=content) self.assertEqual(len(seq_numbers), 1) submit_sm_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(short_message(submit_sm_pdu), content) self.assertEqual( submit_sm_pdu['body']['mandatory_parameters']['esm_class'], 0)
def test_submit_and_deliver_ussd_close(self): smpp_helper = yield self.get_smpp_helper() session_identifier = 12345 yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", session_event=TransportUserMessage.SESSION_CLOSE, transport_metadata={ 'session_info': { 'session_identifier': session_identifier } }) [submit_sm_pdu] = yield smpp_helper.wait_for_pdus(1) self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(pdu_tlv(submit_sm_pdu, 'ussd_service_op'), '17') self.assertEqual(pdu_tlv(submit_sm_pdu, 'user_message_reference'), session_identifier)
def test_submit_csm_udh_single_part(self): """ If the content fits in a single message, all the multipart madness is avoided. """ service = yield self.get_service({'send_multipart_udh': True}) yield self.fake_smsc.bind() content = 'a' * 160 seq_numbers = yield service.submit_csm_udh('abc123', 'dest_addr', short_message=content) self.assertEqual(len(seq_numbers), 1) submit_sm_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(short_message(submit_sm_pdu), content) self.assertEqual( submit_sm_pdu['body']['mandatory_parameters']['esm_class'], 0)
def test_submit_and_deliver_ussd_continue(self): user_msisdn = 'msisdn' session_identifier = 12345 vumi_session_identifier = make_vumi_session_identifier( user_msisdn, session_identifier) smpp_helper = yield self.get_smpp_helper() deliver_sm_processor = smpp_helper.transport.deliver_sm_processor session_manager = deliver_sm_processor.session_manager yield session_manager.create_session( vumi_session_identifier, ussd_code='*123#') yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", transport_metadata={ 'session_info': { 'session_identifier': session_identifier } }, to_addr=user_msisdn) [submit_sm_pdu] = yield smpp_helper.wait_for_pdus(1) self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(pdu_tlv(submit_sm_pdu, 'ussd_service_op'), '02') self.assertEqual( pdu_tlv(submit_sm_pdu, 'user_message_reference'), session_identifier) # Server delivers a USSD message to the Client pdu = DeliverSM(seq_no(submit_sm_pdu) + 1, short_message="reply!", source_addr=user_msisdn) # 0x12 is 'continue' pdu.add_optional_parameter('ussd_service_op', '12') pdu.add_optional_parameter('user_message_reference', session_identifier) yield smpp_helper.handle_pdu(pdu) [mess] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(mess['content'], "reply!") self.assertEqual(mess['transport_type'], "ussd") self.assertEqual(mess['to_addr'], '*123#') self.assertEqual(mess['session_event'], TransportUserMessage.SESSION_RESUME)
def assertCommand(self, pdu, cmd_id, sequence_number=None, status=None, params={}): self.assertEqual(command_id(pdu), cmd_id) if sequence_number is not None: self.assertEqual(seq_no(pdu), sequence_number) if status is not None: self.assertEqual(command_status(pdu), status) pdu_params = {} if params: if 'body' not in pdu: raise Exception('Body does not have parameters.') mandatory_parameters = pdu['body']['mandatory_parameters'] for key in params: if key in mandatory_parameters: pdu_params[key] = mandatory_parameters[key] self.assertEqual(params, pdu_params)
def test_submit_and_deliver_ussd_continue(self): session = SessionInfo() smpp_helper = yield self.get_smpp_helper() deliver_sm_processor = smpp_helper.transport.deliver_sm_processor session_manager = deliver_sm_processor.session_manager yield session_manager.create_session(session.vumi_id, ussd_code='*123#') yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", transport_metadata={ 'session_info': { 'session_identifier': session.sixdee_id, } }, to_addr=session.addr) [submit_sm_pdu] = yield smpp_helper.wait_for_pdus(1) self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(pdu_tlv(submit_sm_pdu, 'ussd_service_op'), '02') self.assertEqual(pdu_tlv(submit_sm_pdu, 'its_session_info'), session.its_info) # Server delivers a USSD message to the Client pdu = DeliverSM(seq_no(submit_sm_pdu) + 1, short_message="reply!", source_addr=session.addr) # 0x12 is 'continue' pdu.add_optional_parameter('ussd_service_op', '12') pdu.add_optional_parameter('its_session_info', session.its_info) yield smpp_helper.handle_pdu(pdu) [mess] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(mess['content'], "reply!") self.assertEqual(mess['transport_type'], "ussd") self.assertEqual(mess['to_addr'], '*123#') self.assertEqual(mess['session_event'], TransportUserMessage.SESSION_RESUME)
def test_submit_and_deliver_ussd_continue(self): session = SessionInfo() transport = yield self.get_transport() deliver_sm_processor = transport.deliver_sm_processor session_manager = deliver_sm_processor.session_manager yield session_manager.create_session( session.vumi_id, ussd_code='*123#') yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", transport_metadata={ 'session_info': { 'session_identifier': session.sixdee_id, } }, to_addr=session.addr) submit_sm_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm_pdu), 'submit_sm') self.assertEqual(pdu_tlv(submit_sm_pdu, 'ussd_service_op'), '02') self.assertEqual(pdu_tlv(submit_sm_pdu, 'its_session_info'), session.its_info) # Server delivers a USSD message to the Client pdu = DeliverSM(seq_no(submit_sm_pdu) + 1, short_message="reply!", source_addr=session.addr) # 0x12 is 'continue' pdu.add_optional_parameter('ussd_service_op', '12') pdu.add_optional_parameter('its_session_info', session.its_info) yield self.fake_smsc.handle_pdu(pdu) [mess] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(mess['content'], "reply!") self.assertEqual(mess['transport_type'], "ussd") self.assertEqual(mess['to_addr'], '*123#') self.assertEqual(mess['session_event'], TransportUserMessage.SESSION_RESUME)
def test_submit_and_deliver_ussd_continue(self): user_msisdn = "msisdn" session_identifier = 12345 vumi_session_identifier = make_vumi_session_identifier(user_msisdn, session_identifier) transport = yield self.get_transport() deliver_sm_processor = transport.deliver_sm_processor session_manager = deliver_sm_processor.session_manager yield session_manager.create_session(vumi_session_identifier, ussd_code="*123#") yield self.tx_helper.make_dispatch_outbound( "hello world", transport_type="ussd", transport_metadata={"session_info": {"session_identifier": session_identifier}}, to_addr=user_msisdn, ) submit_sm_pdu = yield self.fake_smsc.await_pdu() self.assertEqual(command_id(submit_sm_pdu), "submit_sm") self.assertEqual(pdu_tlv(submit_sm_pdu, "ussd_service_op"), "02") self.assertEqual(pdu_tlv(submit_sm_pdu, "user_message_reference"), session_identifier) # Server delivers a USSD message to the Client pdu = DeliverSM(seq_no(submit_sm_pdu) + 1, short_message="reply!", source_addr=user_msisdn) # 0x12 is 'continue' pdu.add_optional_parameter("ussd_service_op", "12") pdu.add_optional_parameter("user_message_reference", session_identifier) yield self.fake_smsc.handle_pdu(pdu) [mess] = yield self.tx_helper.wait_for_dispatched_inbound(1) self.assertEqual(mess["content"], "reply!") self.assertEqual(mess["transport_type"], "ussd") self.assertEqual(mess["to_addr"], "*123#") self.assertEqual(mess["session_event"], TransportUserMessage.SESSION_RESUME)
def assert_command_id(self, pdu, *command_ids): if command_id(pdu) not in command_ids: raise ValueError( "Expected PDU with command_id in [%s], got %s." % ( ", ".join(command_ids), command_id(pdu)))
def pdu_received(self, pdu): self.pdu_queue.put(pdu) if self.auto_unbind and command_id(pdu) == 'unbind': self.send_pdu(UnbindResp(seq_no(pdu)))
def assert_command_id(self, pdu, *command_ids): if command_id(pdu) not in command_ids: raise ValueError("Expected PDU with command_id in [%s], got %s." % (", ".join(command_ids), command_id(pdu)))