Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 64 additions & 2 deletions smpplib/client.py
Copy link
Collaborator

@eigenein eigenein Feb 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a couple of things that I don't really like about this implementation:

  1. It breaks the public interface, read_pdu() will now return a tuple. It isn't a bad thins per se, but I believe it could be implemented in a non-breaking way (1 or 2). PS. The tests also failed because of interface change
  2. It will always perform the conversion even though vast majority of users will most likely ignore the result. The display this way can't be changed either. It would be more generic to return/forward a byte-string and leave the conversion to user

Could you adjust the implementation perhaps?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for your comments. I created some new parallel functions for read_once, read_pdu and send_message to avoid affection on already implemented systems.
pdu, submit_sm_resp = client.send_message_rawpdu
deliver_pdu = client.read_once_rawpdu()

Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,13 @@ def unbind(self):
p = smpp.make_pdu('unbind', client=self)

self.send_pdu(p)
'''
try:
return self.read_pdu()
except socket.timeout:
raise exceptions.ConnectionError()

'''

def send_pdu(self, p):
"""Send PDU to the SMSC"""

Expand Down Expand Up @@ -237,7 +239,7 @@ def _recv_exact(self, exact_size):
received += len(part)
parts.append(part)
return b"".join(parts)

def read_pdu(self):
"""Read PDU from the SMSC"""

Expand Down Expand Up @@ -270,6 +272,22 @@ def read_pdu(self):
self.state = consts.STATE_SETTERS[pdu.command]

return pdu

def read_rawpdu(self):
"""Read PDU from the SMSC"""

raw_len = self._recv_exact(4)

try:
length = struct.unpack('>L', raw_len)[0]
except struct.error:
self.logger.warning('Receive broken pdu... %s', repr(raw_len))
raise exceptions.PDUError('Broken PDU')

raw_pdu = raw_len + self._recv_exact(length - 4)
raw_pdu = binascii.b2a_hex(raw_pdu)

return raw_pdu

def accept(self, obj):
"""Accept an object"""
Expand Down Expand Up @@ -332,7 +350,29 @@ def error_pdu_handler(self, pdu):
consts.DESCRIPTIONS.get(pdu.status, 'Unknown status')),
int(pdu.status),
)

def read_once_rawpdu(self, ignore_error_codes=None, auto_send_enquire_link=True):

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:
ascii_pdu = self.read_rawpdu()
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

return ascii_pdu

def read_once(self, ignore_error_codes=None, auto_send_enquire_link=True):
"""Read a PDU and act"""

Expand Down Expand Up @@ -406,7 +446,29 @@ def send_message(self, **kwargs):

ssm = smpp.make_pdu('submit_sm', client=self, **kwargs)
self.send_pdu(ssm)

return ssm

def send_message_rawpdu(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)

try:
ascii_pdu = self.read_rawpdu()
except socket.timeout:
raise exceptions.ConnectionError()

return ssm, ascii_pdu

def query_message(self, **kwargs):
"""Query message state
Expand Down