Beispiel #1
0
    def test_delivery_failover_route(self):
        """#467: Will ensure a failover route will deliver the message"""

        yield self.connect('127.0.0.1', self.pbPort)
        # Connect to SMSC
        source_connector = Connector(id_generator())
        wrong_port = self.AckServer.getHost().port + 1000
        route = FailoverMORoute([TransparentFilter()], [
            HttpConnector(id_generator(),
                          'http://127.0.0.1:%s/send' % wrong_port, 'POST'),
            HttpConnector(
                id_generator(), 'http://127.0.0.1:%s/send' %
                self.AckServer.getHost().port, 'POST')
        ])
        yield self.prepareRoutingsAndStartConnector(source_connector, route)

        # Send a data_sm from the SMSC
        pdu = DataSM(
            source_addr='1234',
            destination_addr='4567',
            message_payload='any content',
        )
        yield self.triggerDataSmFromSMSC([pdu])

        # Run tests
        # Test callback in router
        self.assertEqual(self.pbRoot_f.deliver_sm_callback.call_count, 1)
        # Destination connector must receive the message one time (no retries)
        self.assertEqual(self.AckServerResource.render_POST.call_count, 1)

        # Disconnector from SMSC
        yield self.stopConnector(source_connector)
Beispiel #2
0
    def setUp(self):
        SMPPServerTestCases.setUp(self)

        self.SubmitSmPDU = SubmitSM(
            source_addr='1234',
            destination_addr='4567',
            short_message='hello !',
            seqNum=1,
        )
        self.DeliverSmPDU = DeliverSM(
            source_addr='4567',
            destination_addr='1234',
            short_message='hello !',
            seqNum=1,
        )
        self.DataSmPDU = DataSM(
            source_addr='4567',
            destination_addr='1234',
            short_message='hello !',
            seqNum=1,
        )

        # SMPPClientConfig init
        args = {
            'id': 'smppc_01',
            'port': self.smpps_config.port,
            'log_level': logging.DEBUG,
            'reconnectOnConnectionLoss': False,
            'username': '******',
            'password': '******'
        }
        self.smppc_config = SMPPClientConfig(**args)

        # SMPPClientFactory init
        self.smppc_factory = LastProtoSMPPClientFactory(self.smppc_config)
Beispiel #3
0
    def test_delivery_HttpConnector(self):
        yield self.connect('127.0.0.1', self.pbPort)
        # Connect to SMSC
        source_connector = Connector(id_generator())
        yield self.prepareRoutingsAndStartConnector(source_connector)

        # Send a data_sm from the SMSC
        pdu = DataSM(
            source_addr='1234',
            destination_addr='4567',
            message_payload='any content',
        )
        yield self.triggerDataSmFromSMSC([pdu])

        # Run tests
        # Test callback in router
        self.assertEqual(self.pbRoot_f.deliver_sm_callback.call_count, 1)
        # Destination connector must receive the message one time (no retries)
        self.assertEqual(self.AckServerResource.render_POST.call_count, 1)
        # Assert received args
        receivedHttpReq = self.AckServerResource.last_request.args
        self.assertEqual(len(receivedHttpReq), 7)
        self.assertEqual(receivedHttpReq[b'from'], [pdu.params['source_addr']])
        self.assertEqual(receivedHttpReq[b'to'],
                         [pdu.params['destination_addr']])
        self.assertEqual(receivedHttpReq[b'content'],
                         [pdu.params['message_payload']])
        self.assertEqual(receivedHttpReq[b'origin-connector'],
                         [source_connector.cid.encode()])

        # Disconnector from SMSC
        yield self.stopConnector(source_connector)
Beispiel #4
0
    def setUp(self, interceptorpb_client=None):
        yield HappySMSCTestCase.setUp(self)

        self.encoder = pdu_encoding.PDUEncoder()

        # SMPPServerConfig init
        self.smpps_config = SMPPServerConfig()

        # Portal init
        _portal = portal.Portal(SmppsRealm(self.smpps_config.id,
                                           self.pbRoot_f))
        _portal.registerChecker(RouterAuthChecker(self.pbRoot_f))

        # Install mocks
        self.clientManager_f.perspective_submit_sm = Mock(
            wraps=self.clientManager_f.perspective_submit_sm)

        # SMPPServerFactory init
        self.smpps_factory = LastProtoSMPPServerFactory(
            self.smpps_config,
            auth_portal=_portal,
            RouterPB=self.pbRoot_f,
            SMPPClientManagerPB=self.clientManager_f,
            interceptorpb_client=interceptorpb_client)
        self.smpps_port = reactor.listenTCP(self.smpps_config.port,
                                            self.smpps_factory)

        # Init protocol for testing
        self.smpps_proto = self.smpps_factory.buildProtocol(('127.0.0.1', 0))
        self.smpps_tr = proto_helpers.StringTransport()
        self.smpps_proto.makeConnection(self.smpps_tr)

        # Add SMPPs factory to DLRThrower
        self.DLRThrower.addSmpps(self.smpps_factory)

        # Install mocks
        self.smpps_proto.sendPDU = Mock(wraps=self.smpps_proto.sendPDU)

        # PDUs used for tests
        self.SubmitSmPDU = SubmitSM(
            source_addr='1234',
            destination_addr='4567',
            short_message='hello !',
            seqNum=1,
        )
        self.DeliverSmPDU = DeliverSM(
            source_addr='4567',
            destination_addr='1234',
            short_message='any content',
            seqNum=1,
        )
        self.DataSmPDU = DataSM(
            source_addr='4567',
            destination_addr='1234',
            message_payload='any content',
            seqNum=1,
        )
Beispiel #5
0
    def test_take_message_state_from_tlv_first(self):
        """Related to #427
        When message_state is provided in short_message and in TLV param, consider the latter"""
        pdu = DataSM(
            source_addr='24206155423',
            destination_addr='JOOKIES',
            message_state=MessageState.ACCEPTED,
            receipted_message_id='5000',
            short_message=
            'id:5000 submit date:201506201641 done date:201506201641 stat:DELIVRD err:000',
        )

        isDlr = self.opFactory.isDeliveryReceipt(pdu)
        self.assertEqual(isDlr['stat'], 'ACCEPTD')
Beispiel #6
0
 def test_data_handler_return_resp(self):
     smpp = self.getProtocolObject()
     smpp.sendPDU = Mock()
     reqPDU = DataSM(6)
     smpp.PDURequestSucceeded(
         DataHandlerResponse(CommandStatus.ESME_RINVSRCTON,
                             delivery_failure_reason=DeliveryFailureReason.
                             PERMANENT_NETWORK_ERROR), reqPDU)
     self.assertEquals(1, smpp.sendPDU.call_count)
     sent = smpp.sendPDU.call_args[0][0]
     self.assertEquals(
         DataSMResp(6,
                    CommandStatus.ESME_RINVSRCTON,
                    delivery_failure_reason=DeliveryFailureReason.
                    PERMANENT_NETWORK_ERROR), sent)
Beispiel #7
0
    def test_unordered_long_content_delivery_HttpConnector(self):
        yield self.connect('127.0.0.1', self.pbPort)
        # Connect to SMSC
        source_connector = Connector(id_generator())
        yield self.prepareRoutingsAndStartConnector(source_connector)

        # Send a data_sm from the SMSC
        basePdu = DataSM(
            source_addr='1234',
            destination_addr='4567',
            message_payload='',
            sar_total_segments=3,
            sar_msg_ref_num=int(id_generator(size=2, chars=string.digits)),
        )
        pdu_part1 = copy.deepcopy(basePdu)
        pdu_part2 = copy.deepcopy(basePdu)
        pdu_part3 = copy.deepcopy(basePdu)
        pdu_part1.params[
            'message_payload'] = b'__1st_part_with_153_char________________________________________________________________________________________________________________________________.'
        pdu_part1.params['sar_segment_seqnum'] = 1
        pdu_part2.params[
            'message_payload'] = b'__2nd_part_with_153_char________________________________________________________________________________________________________________________________.'
        pdu_part2.params['sar_segment_seqnum'] = 2
        pdu_part3.params['message_payload'] = b'__3rd_part_end.'
        pdu_part3.params['sar_segment_seqnum'] = 3
        yield self.triggerDataSmFromSMSC([pdu_part2, pdu_part1, pdu_part3])

        # Run tests
        # Destination connector must receive the message one time (no retries)
        self.assertEqual(self.AckServerResource.render_POST.call_count, 1)
        # Assert received args
        receivedHttpReq = self.AckServerResource.last_request.args
        self.assertEqual(len(receivedHttpReq), 7)
        self.assertEqual(receivedHttpReq[b'from'],
                         [basePdu.params['source_addr']])
        self.assertEqual(receivedHttpReq[b'to'],
                         [basePdu.params['destination_addr']])
        self.assertEqual(receivedHttpReq[b'content'], [
            pdu_part1.params['message_payload'] +
            pdu_part2.params['message_payload'] +
            pdu_part3.params['message_payload']
        ])
        self.assertEqual(receivedHttpReq[b'origin-connector'],
                         [source_connector.cid.encode()])

        # Disconnector from SMSC
        yield self.stopConnector(source_connector)
Beispiel #8
0
    def trigger_DLR(self, _id=None, pdu_type='deliver_sm', stat='DELIVRD'):
        if self.lastSubmitSmRestPDU is None:
            raise Exception(
                'A submit_sm must be sent to this SMSC before requesting sendDeliverSM !'
            )

        # Pick the last submit_sm
        submitsm_pdu = self.lastSubmitSmPDU

        # Pick the last submit_sm_resp
        submitsm_resp_pdu = self.lastSubmitSmRestPDU
        if _id is None:
            _id = submitsm_resp_pdu.params['message_id']

        if isinstance(_id, bytes):
            _id = _id.decode()
        if isinstance(pdu_type, bytes):
            pdu_type = pdu_type.decode()

        if pdu_type == 'deliver_sm':
            # Send back a deliver_sm with containing a DLR

            pdu = DeliverSM(
                source_addr=submitsm_pdu.params['source_addr'],
                destination_addr=submitsm_pdu.params['destination_addr'],
                short_message=
                'id:%s sub:001 dlvrd:001 submit date:1305050826 done date:1305050826 stat:%s err:000 text:%s'
                % (str(_id), stat, submitsm_pdu.params['short_message'][:20]),
                message_state=message_state_map[stat],
                receipted_message_id=str(_id),
            )
            return self.trigger_deliver_sm(pdu)
        elif pdu_type == 'data_sm':
            # Send back a data_sm with containing a DLR
            pdu = DataSM(
                source_addr=submitsm_pdu.params['source_addr'],
                destination_addr=submitsm_pdu.params['destination_addr'],
                message_state=message_state_map[stat],
                receipted_message_id=str(_id),
            )
            return self.trigger_data_sm(pdu)
        else:
            raise Exception(
                'Unknown pdu_type (%s) when calling trigger_DLR()' % pdu_type)
Beispiel #9
0
    def test_is_delivery_mmg_data_sm_92(self):
        """Related to #92, this is a Sicap's MMG data_sm receipt"""
        pdu = DataSM(
            source_addr='24206155423',
            destination_addr='JOOKIES',
            message_state=MessageState.DELIVERED,
            receipted_message_id='362d9701',
        )

        isDlr = self.opFactory.isDeliveryReceipt(pdu)
        self.assertTrue(isDlr is not None)
        self.assertEqual(isDlr['id'], b'362d9701')
        self.assertEqual(isDlr['sub'], 'ND')
        self.assertEqual(isDlr['dlvrd'], 'ND')
        self.assertEqual(isDlr['sdate'], 'ND')
        self.assertEqual(isDlr['ddate'], 'ND')
        self.assertEqual(isDlr['stat'], 'DELIVRD')
        self.assertEqual(isDlr['err'], 'ND')
        self.assertEqual(isDlr['text'], '')
Beispiel #10
0
    def getReceipt(self, dlr_pdu, msgid, source_addr, destination_addr,
                   message_status, err, sub_date, source_addr_ton,
                   source_addr_npi, dest_addr_ton, dest_addr_npi):
        """Will build a DataSm or a DeliverSm (depending on dlr_pdu) containing a receipt data"""

        if isinstance(message_status, bytes):
            message_status = message_status.decode()
        if isinstance(msgid, bytes):
            msgid = msgid.decode()
        sm_message_stat = message_status
        # Prepare message_state
        if message_status[:5] == 'ESME_':
            if message_status == 'ESME_ROK':
                message_state = MessageState.ACCEPTED
                sm_message_stat = 'ACCEPTD'
            else:
                message_state = MessageState.UNDELIVERABLE
                sm_message_stat = 'UNDELIV'
        elif message_status == 'UNDELIV':
            message_state = MessageState.UNDELIVERABLE
        elif message_status == 'REJECTD':
            message_state = MessageState.REJECTED
        elif message_status == 'DELIVRD':
            message_state = MessageState.DELIVERED
        elif message_status == 'EXPIRED':
            message_state = MessageState.EXPIRED
        elif message_status == 'DELETED':
            message_state = MessageState.DELETED
        elif message_status == 'ACCEPTD':
            message_state = MessageState.ACCEPTED
        elif message_status == 'ENROUTE':
            message_state = MessageState.ENROUTE
        elif message_status == 'UNKNOWN':
            message_state = MessageState.UNKNOWN
        else:
            raise UnknownMessageStatusError('Unknown message_status: %s' %
                                            message_status)

        # Build pdu
        if dlr_pdu == 'deliver_sm':
            short_message = r"id:%s submit date:%s done date:%s stat:%s err:%s" % (
                msgid,
                parser.parse(sub_date).strftime("%y%m%d%H%M"),
                datetime.datetime.now().strftime("%y%m%d%H%M"),
                sm_message_stat,
                err,
            )

            # Build DeliverSM pdu
            pdu = DeliverSM(
                source_addr=destination_addr,
                destination_addr=source_addr,
                esm_class=EsmClass(EsmClassMode.DEFAULT,
                                   EsmClassType.SMSC_DELIVERY_RECEIPT),
                receipted_message_id=msgid,
                short_message=short_message,
                message_state=message_state,
                source_addr_ton=self.get_enum(AddrTon, dest_addr_ton),
                source_addr_npi=self.get_enum(AddrNpi, dest_addr_npi),
                dest_addr_ton=self.get_enum(AddrTon, source_addr_ton),
                dest_addr_npi=self.get_enum(AddrNpi, source_addr_npi),
            )
        else:
            # Build DataSM pdu
            pdu = DataSM(
                source_addr=destination_addr,
                destination_addr=source_addr,
                esm_class=EsmClass(EsmClassMode.DEFAULT,
                                   EsmClassType.SMSC_DELIVERY_RECEIPT),
                receipted_message_id=msgid,
                message_state=message_state,
                source_addr_ton=self.get_enum(AddrTon, dest_addr_ton),
                source_addr_npi=self.get_enum(AddrNpi, dest_addr_npi),
                dest_addr_ton=self.get_enum(AddrTon, source_addr_ton),
                dest_addr_npi=self.get_enum(AddrNpi, source_addr_npi),
            )

        return pdu
Beispiel #11
0
    def test_long_content_delivery_UDH_SmppsConnector(self):
        yield self.connect('127.0.0.1', self.pbPort)
        yield self.prepareRoutingsAndStartConnector()

        # Bind
        yield self.smppc_factory.connectAndBind()

        # Install mocks
        self.smppc_factory.lastProto.PDUDataRequestReceived = Mock(
            wraps=self.smppc_factory.lastProto.PDUDataRequestReceived)

        # Build a UDH
        baseUdh = []
        baseUdh.append(struct.pack('!B', 5))  # Length of User Data Header
        baseUdh.append(
            struct.pack('!B', 0)
        )  # Information Element Identifier, equal to 00 (Concatenated short messages, 8-bit reference number)
        baseUdh.append(
            struct.pack('!B', 3)
        )  # Length of the header, excluding the first two fields; equal to 03
        baseUdh.append(
            struct.pack('!B',
                        int(id_generator(size=2,
                                         chars=string.digits))))  # msg_ref_num
        baseUdh.append(struct.pack('!B', 3))  # total_segments

        # Send a data_sm from the SMSC
        basePdu = DataSM(
            source_addr='1234',
            destination_addr='4567',
            message_payload='',
            esm_class=EsmClass(EsmClassMode.DEFAULT, EsmClassType.DEFAULT,
                               [EsmClassGsmFeatures.UDHI_INDICATOR_SET]),
        )
        pdu_part1 = copy.deepcopy(basePdu)
        udh_part1 = copy.deepcopy(baseUdh)
        pdu_part2 = copy.deepcopy(basePdu)
        udh_part2 = copy.deepcopy(baseUdh)
        pdu_part3 = copy.deepcopy(basePdu)
        udh_part3 = copy.deepcopy(baseUdh)
        udh_part1.append(struct.pack('!B', 1))  # segment_seqnum
        pdu_part1.params[
            'more_messages_to_send'] = MoreMessagesToSend.MORE_MESSAGES
        pdu_part1.params['message_payload'] = b''.join(
            udh_part1
        ) + b'__1st_part_with_153_char________________________________________________________________________________________________________________________________.'
        udh_part2.append(struct.pack('!B', 2))  # segment_seqnum
        pdu_part2.params[
            'more_messages_to_send'] = MoreMessagesToSend.MORE_MESSAGES
        pdu_part2.params['message_payload'] = b''.join(
            udh_part2
        ) + b'__2nd_part_with_153_char________________________________________________________________________________________________________________________________.'
        udh_part3.append(struct.pack('!B', 3))  # segment_seqnum
        pdu_part3.params[
            'more_messages_to_send'] = MoreMessagesToSend.NO_MORE_MESSAGES
        pdu_part3.params['message_payload'] = b''.join(
            udh_part3) + b'__3rd_part_end.'
        yield self.triggerDataSmFromSMSC([pdu_part1, pdu_part2, pdu_part3])

        # Run tests
        self.assertEqual(
            self.smppc_factory.lastProto.PDUDataRequestReceived.call_count, 3)
        # First received pdu
        received_pdu_1 = self.smppc_factory.lastProto.PDUDataRequestReceived.call_args_list[
            0][0][0]
        self.assertEqual(received_pdu_1.seqNum, 1)
        self.assertEqual(received_pdu_1.id, CommandId.data_sm)
        self.assertEqual(received_pdu_1.params['source_addr'],
                         basePdu.params['source_addr'])
        self.assertEqual(received_pdu_1.params['destination_addr'],
                         basePdu.params['destination_addr'])
        self.assertEqual(received_pdu_1.params['esm_class'],
                         basePdu.params['esm_class'])
        self.assertEqual(received_pdu_1.params['message_payload'][6:],
                         pdu_part1.params['message_payload'][6:])
        # Second received pdu
        received_pdu_2 = self.smppc_factory.lastProto.PDUDataRequestReceived.call_args_list[
            1][0][0]
        self.assertEqual(received_pdu_2.seqNum, 2)
        self.assertEqual(received_pdu_2.id, CommandId.data_sm)
        self.assertEqual(received_pdu_2.params['source_addr'],
                         basePdu.params['source_addr'])
        self.assertEqual(received_pdu_2.params['destination_addr'],
                         basePdu.params['destination_addr'])
        self.assertEqual(received_pdu_2.params['esm_class'],
                         basePdu.params['esm_class'])
        self.assertEqual(received_pdu_2.params['message_payload'][6:],
                         pdu_part2.params['message_payload'][6:])
        # Third received pdu
        received_pdu_3 = self.smppc_factory.lastProto.PDUDataRequestReceived.call_args_list[
            2][0][0]
        self.assertEqual(received_pdu_3.seqNum, 3)
        self.assertEqual(received_pdu_3.id, CommandId.data_sm)
        self.assertEqual(received_pdu_3.params['source_addr'],
                         basePdu.params['source_addr'])
        self.assertEqual(received_pdu_3.params['destination_addr'],
                         basePdu.params['destination_addr'])
        self.assertEqual(received_pdu_3.params['esm_class'],
                         basePdu.params['esm_class'])
        self.assertEqual(received_pdu_3.params['message_payload'][6:],
                         pdu_part3.params['message_payload'][6:])

        # Unbind and disconnect
        yield self.smppc_factory.smpp.unbindAndDisconnect()
        yield self.stopSmppClientConnectors()
Beispiel #12
0
    def test_long_content_delivery_SAR_SmppsConnector(self):
        yield self.connect('127.0.0.1', self.pbPort)
        yield self.prepareRoutingsAndStartConnector()

        # Bind
        yield self.smppc_factory.connectAndBind()

        # Install mocks
        self.smppc_factory.lastProto.PDUDataRequestReceived = Mock(
            wraps=self.smppc_factory.lastProto.PDUDataRequestReceived)

        # Send a data_sm from the SMSC
        basePdu = DataSM(
            source_addr='1234',
            destination_addr='4567',
            message_payload='',
            sar_total_segments=3,
            sar_msg_ref_num=int(id_generator(size=2, chars=string.digits)),
        )
        pdu_part1 = copy.deepcopy(basePdu)
        pdu_part2 = copy.deepcopy(basePdu)
        pdu_part3 = copy.deepcopy(basePdu)
        pdu_part1.params[
            'message_payload'] = b'__1st_part_with_153_char________________________________________________________________________________________________________________________________.'
        pdu_part1.params['sar_segment_seqnum'] = 1
        pdu_part2.params[
            'message_payload'] = b'__2nd_part_with_153_char________________________________________________________________________________________________________________________________.'
        pdu_part2.params['sar_segment_seqnum'] = 2
        pdu_part3.params['message_payload'] = b'__3rd_part_end.'
        pdu_part3.params['sar_segment_seqnum'] = 3
        yield self.triggerDataSmFromSMSC([pdu_part1, pdu_part2, pdu_part3])

        # Run tests
        self.assertEqual(
            self.smppc_factory.lastProto.PDUDataRequestReceived.call_count, 3)
        # First received pdu
        received_pdu_1 = self.smppc_factory.lastProto.PDUDataRequestReceived.call_args_list[
            0][0][0]
        self.assertEqual(received_pdu_1.seqNum, 1)
        self.assertEqual(received_pdu_1.id, CommandId.data_sm)
        self.assertEqual(received_pdu_1.params['source_addr'],
                         basePdu.params['source_addr'])
        self.assertEqual(received_pdu_1.params['destination_addr'],
                         basePdu.params['destination_addr'])
        self.assertEqual(received_pdu_1.params['message_payload'],
                         pdu_part1.params['message_payload'])
        self.assertEqual(received_pdu_1.params['sar_segment_seqnum'],
                         pdu_part1.params['sar_segment_seqnum'])
        # Second received pdu
        received_pdu_2 = self.smppc_factory.lastProto.PDUDataRequestReceived.call_args_list[
            1][0][0]
        self.assertEqual(received_pdu_2.seqNum, 2)
        self.assertEqual(received_pdu_2.id, CommandId.data_sm)
        self.assertEqual(received_pdu_2.params['source_addr'],
                         basePdu.params['source_addr'])
        self.assertEqual(received_pdu_2.params['destination_addr'],
                         basePdu.params['destination_addr'])
        self.assertEqual(received_pdu_2.params['message_payload'],
                         pdu_part2.params['message_payload'])
        self.assertEqual(received_pdu_2.params['sar_segment_seqnum'],
                         pdu_part2.params['sar_segment_seqnum'])
        self.assertNotEqual(received_pdu_2.params['message_payload'],
                            received_pdu_1.params['message_payload'])
        self.assertNotEqual(received_pdu_2.params['sar_segment_seqnum'],
                            received_pdu_1.params['sar_segment_seqnum'])
        # Third received pdu
        received_pdu_3 = self.smppc_factory.lastProto.PDUDataRequestReceived.call_args_list[
            2][0][0]
        self.assertEqual(received_pdu_3.seqNum, 3)
        self.assertEqual(received_pdu_3.id, CommandId.data_sm)
        self.assertEqual(received_pdu_3.params['source_addr'],
                         basePdu.params['source_addr'])
        self.assertEqual(received_pdu_3.params['destination_addr'],
                         basePdu.params['destination_addr'])
        self.assertEqual(received_pdu_3.params['message_payload'],
                         pdu_part3.params['message_payload'])
        self.assertEqual(received_pdu_3.params['sar_segment_seqnum'],
                         pdu_part3.params['sar_segment_seqnum'])
        self.assertNotEqual(received_pdu_3.params['message_payload'],
                            received_pdu_2.params['message_payload'])
        self.assertNotEqual(received_pdu_3.params['sar_segment_seqnum'],
                            received_pdu_2.params['sar_segment_seqnum'])

        # Unbind and disconnect
        yield self.smppc_factory.smpp.unbindAndDisconnect()
        yield self.stopSmppClientConnectors()
Beispiel #13
0
    def test_long_content_delivery_UDH_HttpConnector(self):
        yield self.connect('127.0.0.1', self.pbPort)
        # Connect to SMSC
        source_connector = Connector(id_generator())
        yield self.prepareRoutingsAndStartConnector(source_connector)

        # Build a UDH
        baseUdh = []
        baseUdh.append(struct.pack('!B', 5))  # Length of User Data Header
        baseUdh.append(
            struct.pack('!B', 0)
        )  # Information Element Identifier, equal to 00 (Concatenated short messages, 8-bit reference number)
        baseUdh.append(
            struct.pack('!B', 3)
        )  # Length of the header, excluding the first two fields; equal to 03
        baseUdh.append(
            struct.pack('!B',
                        int(id_generator(size=2,
                                         chars=string.digits))))  # msg_ref_num
        baseUdh.append(struct.pack('!B', 3))  # total_segments

        # Send a data_sm from the SMSC
        basePdu = DataSM(
            source_addr='1234',
            destination_addr='4567',
            message_payload='',
            esm_class=EsmClass(EsmClassMode.DEFAULT, EsmClassType.DEFAULT,
                               [EsmClassGsmFeatures.UDHI_INDICATOR_SET]),
        )
        pdu_part1 = copy.deepcopy(basePdu)
        udh_part1 = copy.deepcopy(baseUdh)
        pdu_part2 = copy.deepcopy(basePdu)
        udh_part2 = copy.deepcopy(baseUdh)
        pdu_part3 = copy.deepcopy(basePdu)
        udh_part3 = copy.deepcopy(baseUdh)
        udh_part1.append(struct.pack('!B', 1))  # segment_seqnum
        pdu_part1.params[
            'more_messages_to_send'] = MoreMessagesToSend.MORE_MESSAGES
        pdu_part1.params['message_payload'] = b''.join(
            udh_part1
        ) + b'__1st_part_with_153_char________________________________________________________________________________________________________________________________.'
        udh_part2.append(struct.pack('!B', 2))  # segment_seqnum
        pdu_part2.params[
            'more_messages_to_send'] = MoreMessagesToSend.MORE_MESSAGES
        pdu_part2.params['message_payload'] = b''.join(
            udh_part2
        ) + b'__2nd_part_with_153_char________________________________________________________________________________________________________________________________.'
        udh_part3.append(struct.pack('!B', 3))  # segment_seqnum
        pdu_part3.params[
            'more_messages_to_send'] = MoreMessagesToSend.NO_MORE_MESSAGES
        pdu_part3.params['message_payload'] = b''.join(
            udh_part3) + b'__3rd_part_end.'
        yield self.triggerDataSmFromSMSC([pdu_part1, pdu_part2, pdu_part3])

        # Run tests
        # Destination connector must receive the message one time (no retries)
        self.assertEqual(self.AckServerResource.render_POST.call_count, 1)
        # Assert received args
        receivedHttpReq = self.AckServerResource.last_request.args
        self.assertEqual(len(receivedHttpReq), 7)
        self.assertEqual(receivedHttpReq[b'from'],
                         [basePdu.params['source_addr']])
        self.assertEqual(receivedHttpReq[b'to'],
                         [basePdu.params['destination_addr']])
        self.assertEqual(receivedHttpReq[b'content'], [
            pdu_part1.params['message_payload'][6:] +
            pdu_part2.params['message_payload'][6:] +
            pdu_part3.params['message_payload'][6:]
        ])
        self.assertEqual(receivedHttpReq[b'origin-connector'],
                         [source_connector.cid.encode()])

        # Disconnector from SMSC
        yield self.stopConnector(source_connector)