Example #1
0
 def handle_deliver_sm(self, pdu):
     if pdu['header']['command_status'] == 'ESME_ROK':
         sequence_number = pdu['header']['sequence_number']
         message_id = str(uuid.uuid4())
         pdu_resp = DeliverSMResp(sequence_number,
                 **self.defaults)
         self.sendPDU(pdu_resp)
         pdu_params = pdu['body']['mandatory_parameters']
         delivery_report = re.search(
                 # SMPP v3.4 Issue 1.2 pg. 167 is wrong on id length
                   'id:(?P<id>\S{,65}) +sub:(?P<sub>...)'
                 + ' +dlvrd:(?P<dlvrd>...)'
                 + ' +submit date:(?P<submit_date>\d*)'
                 + ' +done date:(?P<done_date>\d*)'
                 + ' +stat:(?P<stat>[A-Z]{7})'
                 + ' +err:(?P<err>...)'
                 + ' +[Tt]ext:(?P<text>.{,20})'
                 + '.*',
                 pdu_params['short_message'] or ''
                 )
         if delivery_report:
             self.__delivery_report_callback(
                     destination_addr=pdu_params['destination_addr'],
                     source_addr=pdu_params['source_addr'],
                     delivery_report=delivery_report.groupdict(),
                     )
         elif detect_multipart(pdu):
             redis_key = "%s#multi_%s" % (
                     self.r_prefix, multipart_key(detect_multipart(pdu)))
             log.msg("Redis multipart key: %s" % (redis_key))
             value = json.loads(self.r_server.get(redis_key) or 'null')
             log.msg("Retrieved value: %s" % (repr(value)))
             multi = MultipartMessage(value)
             multi.add_pdu(pdu)
             completed = multi.get_completed()
             if completed:
                 self.r_server.delete(redis_key)
                 log.msg("Reassembled Message: %s" % (completed['message']))
                 # and we can finally pass the whole message on
                 self.__deliver_sm_callback(
                         destination_addr=completed['to_msisdn'],
                         source_addr=completed['from_msisdn'],
                         short_message=completed['message'],
                         message_id=message_id,
                         )
             else:
                 self.r_server.set(redis_key, json.dumps(multi.get_array()))
         else:
             decoded_msg = self._decode_message(pdu_params['short_message'],
                                                pdu_params['data_coding'])
             self.__deliver_sm_callback(
                     destination_addr=pdu_params['destination_addr'],
                     source_addr=pdu_params['source_addr'],
                     short_message=decoded_msg,
                     message_id=message_id,
                     )
Example #2
0
 def handle_deliver_sm(self, pdu):
     if pdu['header']['command_status'] == 'ESME_ROK':
         sequence_number = pdu['header']['sequence_number']
         message_id = str(uuid.uuid4())
         pdu_resp = DeliverSMResp(sequence_number,
                 **self.defaults)
         self.send_pdu(pdu_resp)
         pdu_params = pdu['body']['mandatory_parameters']
         delivery_report = self.config.delivery_report_re.search(
                 pdu_params['short_message'] or ''
                 )
         if delivery_report:
             self.esme_callbacks.delivery_report(
                     destination_addr=pdu_params['destination_addr'],
                     source_addr=pdu_params['source_addr'],
                     delivery_report=delivery_report.groupdict(),
                     )
         elif detect_multipart(pdu):
             redis_key = "%s#multi_%s" % (
                     self.r_prefix, multipart_key(detect_multipart(pdu)))
             log.msg("Redis multipart key: %s" % (redis_key))
             value = json.loads(self.r_server.get(redis_key) or 'null')
             log.msg("Retrieved value: %s" % (repr(value)))
             multi = MultipartMessage(value)
             multi.add_pdu(pdu)
             completed = multi.get_completed()
             if completed:
                 self.r_server.delete(redis_key)
                 log.msg("Reassembled Message: %s" % (completed['message']))
                 # and we can finally pass the whole message on
                 self.esme_callbacks.deliver_sm(
                         destination_addr=completed['to_msisdn'],
                         source_addr=completed['from_msisdn'],
                         short_message=completed['message'],
                         message_id=message_id,
                         )
             else:
                 self.r_server.set(redis_key, json.dumps(multi.get_array()))
         else:
             decoded_msg = self._decode_message(pdu_params['short_message'],
                                                pdu_params['data_coding'])
             self.esme_callbacks.deliver_sm(
                     destination_addr=pdu_params['destination_addr'],
                     source_addr=pdu_params['source_addr'],
                     short_message=decoded_msg,
                     message_id=message_id,
                     )
Example #3
0
 def handle_deliver_sm(self, pdu):
     if pdu['header']['command_status'] == 'ESME_ROK':
         sequence_number = pdu['header']['sequence_number']
         message_id = str(uuid.uuid4())
         pdu_resp = DeliverSMResp(sequence_number, **self.defaults)
         self.send_pdu(pdu_resp)
         pdu_params = pdu['body']['mandatory_parameters']
         delivery_report = self.config.delivery_report_re.search(
             pdu_params['short_message'] or '')
         if delivery_report:
             self.esme_callbacks.delivery_report(
                 destination_addr=pdu_params['destination_addr'],
                 source_addr=pdu_params['source_addr'],
                 delivery_report=delivery_report.groupdict(),
             )
         elif detect_multipart(pdu):
             redis_key = "%s#multi_%s" % (
                 self.r_prefix, multipart_key(detect_multipart(pdu)))
             log.msg("Redis multipart key: %s" % (redis_key))
             value = json.loads(self.r_server.get(redis_key) or 'null')
             log.msg("Retrieved value: %s" % (repr(value)))
             multi = MultipartMessage(value)
             multi.add_pdu(pdu)
             completed = multi.get_completed()
             if completed:
                 self.r_server.delete(redis_key)
                 log.msg("Reassembled Message: %s" % (completed['message']))
                 # and we can finally pass the whole message on
                 self.esme_callbacks.deliver_sm(
                     destination_addr=completed['to_msisdn'],
                     source_addr=completed['from_msisdn'],
                     short_message=completed['message'],
                     message_id=message_id,
                 )
             else:
                 self.r_server.set(redis_key, json.dumps(multi.get_array()))
         else:
             decoded_msg = self._decode_message(pdu_params['short_message'],
                                                pdu_params['data_coding'])
             self.esme_callbacks.deliver_sm(
                 destination_addr=pdu_params['destination_addr'],
                 source_addr=pdu_params['source_addr'],
                 short_message=decoded_msg,
                 message_id=message_id,
             )
Example #4
0
    def handle_multipart_pdu(self, pdu):
        if not detect_multipart(pdu):
            return succeed(False)

        # We have a multipart SMS.
        pdu_params = pdu['body']['mandatory_parameters']
        d = self.handle_deliver_sm_multipart(pdu, pdu_params)
        d.addCallback(lambda _: True)
        return d
Example #5
0
    def handle_multipart_pdu(self, pdu):
        if not detect_multipart(pdu):
            return succeed(False)

        # We have a multipart SMS.
        pdu_params = pdu['body']['mandatory_parameters']
        d = self.handle_deliver_sm_multipart(pdu, pdu_params)
        d.addCallback(lambda _: True)
        return d
Example #6
0
    def handle_deliver_sm(self, pdu):
        if self.state not in ['BOUND_RX', 'BOUND_TRX']:
            log.err('WARNING: Received deliver_sm in wrong state: %s' % (
                self.state))
            return

        if pdu['header']['command_status'] != 'ESME_ROK':
            return

        # TODO: Only ACK messages once we've processed them?
        sequence_number = pdu['header']['sequence_number']
        pdu_resp = DeliverSMResp(sequence_number, **self.bind_params)
        yield self.send_pdu(pdu_resp)

        pdu_params = pdu['body']['mandatory_parameters']
        pdu_opts = unpacked_pdu_opts(pdu)

        # This might be a delivery receipt with PDU parameters. If we get a
        # delivery receipt without these parameters we'll try a regex match
        # later once we've decoded the message properly.
        receipted_message_id = pdu_opts.get('receipted_message_id', None)
        message_state = pdu_opts.get('message_state', None)
        if receipted_message_id is not None and message_state is not None:
            yield self.esme_callbacks.delivery_report(
                message_id=receipted_message_id,
                message_state={
                    1: 'ENROUTE',
                    2: 'DELIVERED',
                    3: 'EXPIRED',
                    4: 'DELETED',
                    5: 'UNDELIVERABLE',
                    6: 'ACCEPTED',
                    7: 'UNKNOWN',
                    8: 'REJECTED',
                }.get(message_state, 'UNKNOWN'),
            )

        # We might have a `message_payload` optional field to worry about.
        message_payload = pdu_opts.get('message_payload', None)
        if message_payload is not None:
            pdu_params['short_message'] = message_payload.decode('hex')

        if detect_ussd(pdu_opts):
            # We have a USSD message.
            yield self._handle_deliver_sm_ussd(pdu, pdu_params, pdu_opts)
        elif detect_multipart(pdu):
            # We have a multipart SMS.
            yield self._handle_deliver_sm_multipart(pdu, pdu_params)
        else:
            # We have a standard SMS.
            yield self._handle_deliver_sm_sms(pdu_params)
Example #7
0
    def handle_deliver_sm(self, pdu):
        if self.state not in ['BOUND_RX', 'BOUND_TRX']:
            log.err('WARNING: Received deliver_sm in wrong state: %s' %
                    (self.state))
            return

        if pdu['header']['command_status'] != 'ESME_ROK':
            return

        # TODO: Only ACK messages once we've processed them?
        sequence_number = pdu['header']['sequence_number']
        pdu_resp = DeliverSMResp(sequence_number, **self.bind_params)
        yield self.send_pdu(pdu_resp)

        pdu_params = pdu['body']['mandatory_parameters']
        pdu_opts = unpacked_pdu_opts(pdu)

        # This might be a delivery receipt with PDU parameters. If we get a
        # delivery receipt without these parameters we'll try a regex match
        # later once we've decoded the message properly.
        receipted_message_id = pdu_opts.get('receipted_message_id', None)
        message_state = pdu_opts.get('message_state', None)
        if receipted_message_id is not None and message_state is not None:
            yield self.esme_callbacks.delivery_report(
                message_id=receipted_message_id,
                message_state={
                    1: 'ENROUTE',
                    2: 'DELIVERED',
                    3: 'EXPIRED',
                    4: 'DELETED',
                    5: 'UNDELIVERABLE',
                    6: 'ACCEPTED',
                    7: 'UNKNOWN',
                    8: 'REJECTED',
                }.get(message_state, 'UNKNOWN'),
            )

        # We might have a `message_payload` optional field to worry about.
        message_payload = pdu_opts.get('message_payload', None)
        if message_payload is not None:
            pdu_params['short_message'] = message_payload.decode('hex')

        if detect_ussd(pdu_opts):
            # We have a USSD message.
            yield self._handle_deliver_sm_ussd(pdu, pdu_params, pdu_opts)
        elif detect_multipart(pdu):
            # We have a multipart SMS.
            yield self._handle_deliver_sm_multipart(pdu, pdu_params)
        else:
            # We have a standard SMS.
            yield self._handle_deliver_sm_sms(pdu_params)
Example #8
0
 def handle_deliver_sm_multipart(self, pdu, pdu_params):
     redis_key = "multi_%s" % (multipart_key(detect_multipart(pdu)),)
     self.log.debug("Redis multipart key: %s" % (redis_key))
     multi = yield self.load_multipart_message(redis_key)
     multi.add_pdu(pdu)
     completed = multi.get_completed()
     if completed:
         yield self.redis.delete(redis_key)
         self.log.msg("Reassembled Message: %s" % (completed["message"]))
         # We assume that all parts have the same data_coding here, because
         # otherwise there's nothing sensible we can do.
         decoded_msg = self.dcs_decode(completed["message"], pdu_params["data_coding"])
         # and we can finally pass the whole message on
         yield self.handle_short_message_content(
             source_addr=completed["from_msisdn"], destination_addr=completed["to_msisdn"], short_message=decoded_msg
         )
     else:
         yield self.save_multipart_message(redis_key, multi)
Example #9
0
 def _handle_deliver_sm_multipart(self, pdu, pdu_params):
     redis_key = "multi_%s" % (multipart_key(detect_multipart(pdu)), )
     log.debug("Redis multipart key: %s" % (redis_key))
     multi = yield self.load_multipart_message(redis_key)
     multi.add_pdu(pdu)
     completed = multi.get_completed()
     if completed:
         yield self.redis.delete(redis_key)
         log.msg("Reassembled Message: %s" % (completed['message']))
         # We assume that all parts have the same data_coding here, because
         # otherwise there's nothing sensible we can do.
         decoded_msg = self._decode_message(completed['message'],
                                            pdu_params['data_coding'])
         # and we can finally pass the whole message on
         yield self._deliver_sm(source_addr=completed['from_msisdn'],
                                destination_addr=completed['to_msisdn'],
                                short_message=decoded_msg)
     else:
         yield self.save_multipart_message(redis_key, multi)
Example #10
0
 def get_multipart(m):
     return detect_multipart(unpack_pdu(m.get_bin()))