Exemple #1
0
def remote_pass_pdu(pdu, dest_ip):

    try:
        log.info('Making SMMP Connection to %s for %s' %
                 (dest_ip, pdu.destination_addr))
        smpp_client = smpplib.client.Client(dest_ip, 2775, 5)
        smpp_client.set_message_sent_handler(
            lambda pdu: log.info("Sent (%s)", pdu.message_id))
        smpp_client.connect()
        smpp_client.bind_transceiver(system_id="ISMPP", password="******")
        log.debug('Submitting to %s from %s' %
                  (pdu.destination_addr, pdu.source_addr))
        #rand = randint(5, 15)
        #log.debug('GOING BUSY NOW for %s secs' % rand)
        #time.sleep(rand)
        rpdu = smpp.make_pdu('submit_sm',
                             client=smpp_client,
                             service_type=pdu.service_type,
                             sequence=pdu.sequence,
                             source_addr_ton=int(pdu.source_addr_ton),
                             source_addr_npi=int(pdu.source_addr_npi),
                             source_addr=pdu.source_addr,
                             dest_addr_ton=int(pdu.dest_addr_ton),
                             dest_addr_npi=int(pdu.dest_addr_npi),
                             destination_addr=pdu.destination_addr,
                             data_coding=int(pdu.data_coding),
                             esm_class=int(pdu.esm_class),
                             short_message=pdu.short_message,
                             registered_delivery=int(pdu.registered_delivery),
                             user_message_reference=int(
                                 pdu.user_message_reference))
        rpdu.sequence = pdu.sequence
        try:
            smpp_client.send_pdu(rpdu)
            log.debug('Sumbit_SM is sent. waiting response...')
            smpp_client.read_once()
            return smpplib.consts.SMPP_ESME_ROK
        except smpplib.exceptions.PDUError as ex:
            smpp_client.unbind()
            smpp_client.disconnect()
            raise Exception('Unable to Submit Message via Remote SMPP (%s)' %
                            ex)
        smpp_client.unbind()
        smpp_client.disconnect()
        del smpp_client
        if p.sequence == rpdu.sequence:
            log.debug('Remote SMPP Resp Received for Sequence# %s' %
                      pdu.sequence)
            return smpplib.consts.SMPP_ESME_ROK
    except (IOError, smpplib.exceptions.ConnectionError) as ex:
        smpp_client.disconnect()
        raise Exception('Unable to connect to Remote SMPP (%s)' % ex)
    except Exception as ex:
        log.debug("Other Exception: %s", str(ex))
        template = "An exception of type {0} occurred. Arguments:\n{1!r}"
        message = template.format(type(ex).__name__, ex.args)
        log.debug(message)
        del smpp_client
        raise Exception(ex)
Exemple #2
0
 def _message_received(self, pdu):
     """Handler for received message event"""
     status = self.message_received_handler(pdu=pdu)
     if status is None:
         status = consts.SMPP_ESME_ROK
     dsmr = smpp.make_pdu('deliver_sm_resp', client=self, status=status)
     dsmr.sequence = pdu.sequence
     self.send_pdu(dsmr)
Exemple #3
0
 def _message_received(self, pdu):
     """Handler for received message event"""
     status = self.message_received_handler(pdu=pdu)
     if status is None:
         status = consts.SMPP_ESME_ROK
     dsmr = smpp.make_pdu('deliver_sm_resp', client=self, status=status)
     dsmr.sequence = pdu.sequence
     self.send_pdu(dsmr)
Exemple #4
0
    def unbind(self):
        """Unbind from the SMSC"""

        p = smpp.make_pdu('unbind', client=self)

        self.send_pdu(p)
        try:
            return self.read_pdu()
        except socket.timeout:
            raise exceptions.ConnectionError()
Exemple #5
0
    def unbind(self):
        """Unbind from the SMSC"""

        p = smpp.make_pdu('unbind', client=self)

        self.send_pdu(p)
        try:
            return self.read_pdu()
        except socket.timeout:
            raise exceptions.ConnectionError()
def test_client_error_pdu_custom_handler():
    client = Client("localhost", 5679)
    error_pdu = make_pdu("submit_sm_resp")
    error_pdu.status = consts.SMPP_ESME_RINVMSGLEN
    client.read_pdu = Mock(return_value=error_pdu)

    mock_error_pdu_handler = Mock()
    client.set_error_pdu_handler(mock_error_pdu_handler)

    client.read_once()

    assert mock_error_pdu_handler.mock_calls == [call(error_pdu)]
Exemple #7
0
def remote_pass_pdu(pdu, dest_ip):

    try:
        log.info('Making SMMP Connection to %s for %s' % (dest_ip, pdu.destination_addr))
        smpp_client = smpplib.client.Client(dest_ip, 2775, 5)
        smpp_client.set_message_sent_handler(lambda pdu: log.info("Sent (%s)", pdu.message_id))
        smpp_client.connect()
        smpp_client.bind_transceiver(system_id="ISMPP", password="******")
        log.debug('Submitting to %s from %s' % (pdu.destination_addr, pdu.source_addr))
        #rand = randint(5, 15)
        #log.debug('GOING BUSY NOW for %s secs' % rand)
        #time.sleep(rand)
        rpdu = smpp.make_pdu('submit_sm', client=smpp_client,
                             service_type=pdu.service_type,
                             sequence=pdu.sequence,
                             source_addr_ton=int(pdu.source_addr_ton),
                             source_addr_npi=int(pdu.source_addr_npi),
                             source_addr=pdu.source_addr,
                             dest_addr_ton=int(pdu.dest_addr_ton),
                             dest_addr_npi=int(pdu.dest_addr_npi),
                             destination_addr=pdu.destination_addr,
                             data_coding=int(pdu.data_coding),
                             esm_class=int(pdu.esm_class),
                             short_message=pdu.short_message,
                             registered_delivery=int(pdu.registered_delivery),
                             user_message_reference=int(pdu.user_message_reference)
                            )
        rpdu.sequence = pdu.sequence
        try:
            smpp_client.send_pdu(rpdu)
            log.debug('Sumbit_SM is sent. waiting response...')
            smpp_client.read_once()
            return smpplib.consts.SMPP_ESME_ROK
        except smpplib.exceptions.PDUError as ex:
            smpp_client.unbind()
            smpp_client.disconnect()
            raise Exception('Unable to Submit Message via Remote SMPP (%s)' % ex)
        smpp_client.unbind()
        smpp_client.disconnect()
        del smpp_client
        if p.sequence == rpdu.sequence:
            log.debug('Remote SMPP Resp Received for Sequence# %s' % pdu.sequence)
            return smpplib.consts.SMPP_ESME_ROK
    except (IOError, smpplib.exceptions.ConnectionError) as ex:
        smpp_client.disconnect()
        raise Exception('Unable to connect to Remote SMPP (%s)' % ex)
    except Exception as ex:
        log.debug("Other Exception: %s", str(ex))
        template = "An exception of type {0} occurred. Arguments:\n{1!r}"
        message = template.format(type(ex).__name__, ex.args)
        log.debug(message)
        del smpp_client
        raise Exception(ex)
Exemple #8
0
    def query_message(self, **kwargs):
        """Query message state

        Required Arguments:
            message_id -- SMSC assigned Message ID
            source_addr_ton -- Original source address TON
            source_addr_npi -- Original source address NPI
            source_addr -- Original source address (string)
        """

        qsm = smpp.make_pdu('query_sm', client=self, **kwargs)
        self.send_pdu(qsm)
        return qsm
def test_client_error_pdu_default():
    client = Client("localhost", 5679)
    error_pdu = make_pdu("submit_sm_resp")
    error_pdu.status = consts.SMPP_ESME_RINVMSGLEN
    client.read_pdu = Mock(return_value=error_pdu)

    with pytest.raises(exceptions.PDUError) as exec_info:
        client.read_once()

    assert exec_info.value.args[1] == consts.SMPP_ESME_RINVMSGLEN

    # Should not raise
    client.read_once(ignore_error_codes=[consts.SMPP_ESME_RINVMSGLEN])
Exemple #10
0
    def send_message(self, **kwargs):
        """Send message

        Required Arguments:
            source_addr_ton -- Source address TON
            source_addr -- Source address (string)
            dest_addr_ton -- Destination address TON
            destination_addr -- Destination address (string)
            short_message -- Message text (string)
        """

        ssm = smpp.make_pdu('submit_sm', client=self, **kwargs)
        self.send_pdu(ssm)
        return ssm
Exemple #11
0
    def send_message(self, **kwargs):
        """Send message

        Required Arguments:
            source_addr_ton -- Source address TON
            source_addr -- Source address (string)
            dest_addr_ton -- Destination address TON
            destination_addr -- Destination address (string)
            short_message -- Message text (string)
        """

        ssm = smpp.make_pdu('submit_sm', client=self, **kwargs)
        self.send_pdu(ssm)
        return ssm
Exemple #12
0
    def read_once(self, ignore_error_codes=None, auto_send_enquire_link=True):
        """Read a PDU and act"""

        if ignore_error_codes is not None:
            warnings.warn(
                "ignore_error_codes is deprecated, use set_error_pdu_handler to "
                "configure a custom error PDU handler instead.",
                DeprecationWarning,
            )

        try:
            try:
                pdu = self.read_pdu()
            except socket.timeout:
                if not auto_send_enquire_link:
                    raise
                self.logger.debug('Socket timeout, listening again')
                pdu = smpp.make_pdu('enquire_link', client=self)
                self.send_pdu(pdu)
                return

            if pdu.is_error():
                self.error_pdu_handler(pdu)

            if pdu.command == 'unbind':  # unbind_res
                self.logger.info('Unbind command received')
                return
            elif pdu.command == 'submit_sm_resp':
                self.message_sent_handler(pdu=pdu)
            elif pdu.command == 'deliver_sm':
                self._message_received(pdu)
            elif pdu.command == 'query_sm_resp':
                self.query_resp_handler(pdu)
            elif pdu.command == 'enquire_link':
                self._enquire_link_received(pdu)
            elif pdu.command == 'enquire_link_resp':
                pass
            elif pdu.command == 'alert_notification':
                self._alert_notification(pdu)
            else:
                self.logger.warning('Unhandled SMPP command "%s"', pdu.command)
        except exceptions.PDUError as e:
            if ignore_error_codes and len(
                    e.args) > 1 and e.args[1] in ignore_error_codes:
                self.logger.warning('(%d) %s. Ignored.', e.args[1], e.args[0])
            else:
                raise
Exemple #13
0
    def read_once(self, ignore_error_codes=None, auto_send_enquire_link=True):
        """Read a PDU and act"""
        try:
            try:
                pdu = self.read_pdu()
            except socket.timeout:
                if not auto_send_enquire_link:
                    raise
                self.logger.debug('Socket timeout, listening again')
                pdu = smpp.make_pdu('enquire_link', client=self)
                self.send_pdu(pdu)
                return

            if pdu.is_error():
                raise exceptions.PDUError(
                    '({}) {}: {}'.format(
                        pdu.status, pdu.command,
                        consts.DESCRIPTIONS.get(pdu.status, 'Unknown status')),
                    int(pdu.status),
                )

            if pdu.command == 'unbind':  # unbind_res
                self.logger.info('Unbind command received')
                return
            elif pdu.command == 'submit_sm_resp':
                self.message_sent_handler(pdu=pdu)
            elif pdu.command == 'deliver_sm':
                self._message_received(pdu)
            elif pdu.command == 'query_sm_resp':
                self.query_resp_handler(pdu)
            elif pdu.command == 'enquire_link':
                self._enquire_link_received(pdu)
            elif pdu.command == 'enquire_link_resp':
                pass
            elif pdu.command == 'alert_notification':
                self._alert_notification(pdu)
            else:
                self.logger.warning('Unhandled SMPP command "%s"', pdu.command)
        except exceptions.PDUError as e:
            if ignore_error_codes and len(
                    e.args) > 1 and e.args[1] in ignore_error_codes:
                self.logger.warning('(%d) %s. Ignored.', e.args[1], e.args[0])
            else:
                raise
Exemple #14
0
    def _bind(self, command_name, **kwargs):
        """Send bind_transmitter command to the SMSC"""

        if command_name in ('bind_receiver', 'bind_transceiver'):
            logger.debug('Receiver mode')

        p = smpp.make_pdu(command_name, client=self, **kwargs)

        self.send_pdu(p)
        try:
            resp = self.read_pdu()
        except socket.timeout:
            raise exceptions.ConnectionError()
        if resp.is_error():
            raise exceptions.PDUError('({}) {}: {}'.format(
                resp.status,
                resp.command,
                consts.DESCRIPTIONS.get(resp.status, 'Unknown code')),
                int(resp.status),
            )
        return resp
Exemple #15
0
    def _bind(self, command_name, **kwargs):
        """Send bind_transmitter command to the SMSC"""

        if command_name in ('bind_receiver', 'bind_transceiver'):
            logger.debug('Receiver mode')

        p = smpp.make_pdu(command_name, client=self, **kwargs)

        self.send_pdu(p)
        try:
            resp = self.read_pdu()
        except socket.timeout:
            raise exceptions.ConnectionError()
        if resp.is_error():
            raise exceptions.PDUError(
                '({}) {}: {}'.format(
                    resp.status, resp.command,
                    consts.DESCRIPTIONS.get(resp.status, 'Unknown code')),
                int(resp.status),
            )
        return resp
Exemple #16
0
    def read_once(self, ignore_error_codes=None):
        """Read a PDU and act"""
        try:
            try:
                pdu = self.read_pdu()
            except socket.timeout:
                logger.debug('Socket timeout, listening again')
                pdu = smpp.make_pdu('enquire_link', client=self)
                self.send_pdu(pdu)
                return

            if pdu.is_error():
                raise exceptions.PDUError('({}) {}: {}'.format(
                    pdu.status,
                    pdu.command,
                    consts.DESCRIPTIONS.get(pdu.status, 'Unknown status')),
                    int(pdu.status),
                )

            if pdu.command == 'unbind':  # unbind_res
                logger.info('Unbind command received')
                return
            elif pdu.command == 'submit_sm_resp':
                self.message_sent_handler(pdu=pdu)
            elif pdu.command == 'deliver_sm':
                self._message_received(pdu)
            elif pdu.command == 'enquire_link':
                self._enquire_link_received()
            elif pdu.command == 'enquire_link_resp':
                pass
            elif pdu.command == 'alert_notification':
                self._alert_notification(pdu)
            else:
                logger.warning('Unhandled SMPP command "%s"', pdu.command)
        except exceptions.PDUError as e:
            if ignore_error_codes and len(e.args) > 1 and e.args[1] in ignore_error_codes:
                logging.warning('(%d) %s. Ignored.', e.args[1], e.args[0])
            else:
                raise
Exemple #17
0
 def _enquire_link_received(self):
     """Response to enquire_link"""
     ler = smpp.make_pdu('enquire_link_resp', client=self)
     self.send_pdu(ler)
     logger.debug("Link Enquiry...")
Exemple #18
0
 def _enquire_link_received(self):
     """Response to enquire_link"""
     ler = smpp.make_pdu('enquire_link_resp', client=self)
     self.send_pdu(ler)
     logger.debug("Link Enquiry...")
Exemple #19
0
 def _enquire_link_received(self, pdu):
     """Response to enquire_link"""
     ler = smpp.make_pdu('enquire_link_resp', client=self)
     ler.sequence = pdu.sequence
     self.send_pdu(ler)
Exemple #20
0
    def listen(self):
        """This method implements the actual SMPP server. Note that we can
        only talk to one client at a time; removing that restriction
        would make the code much more complicated and we don't really
        need it.

        """

        msg_count = 0
        while True:
            self._sock.listen()
            sock, address = self._sock.accept()
            done = False
            while not done:
                # Note how we're leveraging `smpplib` to avoid the –
                # considerable – inconvenience of parsing (and
                # generating) SMPP PDUs ourselves.

                try:
                    pdu = smpp.parse_pdu(
                        self.read_raw_pdu(sock),
                        client=self,
                        allow_unknown_opt_params=None,
                    )
                    self.pdus.append(pdu)
                except exceptions.ConnectionError:
                    break

                # Do something with the PDU.

                print(f"> {pdu.command}", end="")
                if pdu.command == "bind_transceiver":
                    status = consts.SMPP_ESME_ROK
                    if self.password is not None:
                        if (pdu.system_id.decode() != self.system_id
                                or pdu.password.decode() != self.password):
                            status = consts.SMPP_ESME_RBINDFAIL

                    res_pdu = smpp.make_pdu(
                        "bind_transceiver_resp",
                        status=status,
                        sequence=pdu._sequence,
                    )
                    print("\n< OK")
                elif pdu.command == "submit_sm":
                    text = pdu.short_message.decode()
                    print(f": from={pdu.source_addr.decode()} "
                          f"to={pdu.destination_addr.decode()} "
                          f'text="{text}"')

                    # You can get the server to return any of a bunch
                    # of error codes simply by including the (textual
                    # representation of the) error code in the
                    # message. E.g., send the message `Ahoy SUBMITFAIL
                    # Ahoy` to elicit the error code,
                    # `ESME_RSUBMITFAIL`.

                    data = {
                        "status": pdu.status,
                        "sequence": pdu._sequence,
                    }
                    for err in (
                            "SYSERR",
                            "MSGQFUL",
                            "SUBMITFAIL",
                            "THROTTLED",
                            "X_T_APPN",
                            "DELIVERYFAILURE",
                    ):
                        if err in text:
                            data["status"] = getattr(consts,
                                                     "SMPP_ESME_R" + err)
                            out_msg = f"ERR {err}"
                            break
                    else:
                        msg_count += 1
                        msg_id = f"{MC_ID}:{msg_count:04d}"
                        data["message_id"] = msg_id
                        out_msg = f"OK {msg_id}"
                        self.messages.append(text)

                    res_pdu = smpp.make_pdu("submit_sm_resp", **data)
                    print(f"< {out_msg}")
                elif pdu.command == "unbind":
                    res_pdu = smpp.make_pdu(
                        "unbind_resp",
                        status=pdu.status,
                        sequence=pdu._sequence,
                    )
                    done = True
                    print("\n< OK")
                else:
                    raise ValueError(f"Unsupported SMPP command {pdu.command}")
                self.pdus.append(res_pdu)
                response = res_pdu.generate()
                # self.logger.debug(f'<< {response.hex(" ", -4)}')  # Python 3.8
                self.logger.debug("<< %s", response.hex())
                sock.send(response)
            sock.close()
            done = False