import gsm7
import ems
class EmsSplit:
def __init__(self, contents):
self.segments = []
self.max_packet_len = 140
self.base_len = 0 # or 6 UDHL + IE Concat
self.segment_reset()
try:
self.split(contents)
except:
self.segments = []
self.base_len = 6
self.segment_reset()
self.split(contents)
def split(self, contents):
for type, content in contents:
if type == 'Text':
self.add_text(content)
continue
if type == 'Bitmap':
bitmap = content
content = ems.Picture(bitmap.width, bitmap.height, bitmap.data)
elif type == 'Melody':
sound = content
if sound.predefined:
content = ems.PredefinedSound(sound.id, raw_data=True)
else:
content = ems.UserDefinedSound(sound.data, raw_data=True)
if content.size + self.packet_len > self.max_packet_len:
self.add_segment()
self.add_ie(content)
if self.ies or self.user_data:
self.add_segment()
self.make_payloads()
def segment_reset(self):
self.packet_len = self.base_len
self.user_data = ''
self.cursor_pos = 0
self.ies = []
def add_segment(self):
if len(self.segments) >= 1 and self.base_len <= 1:
raise ValueError, (self.segments, self.base_len)
self.segments.append((self.ies, self.user_data))
self.segment_reset()
def get_max_text_len(self):
return (160 * 7 - self.packet_len * 8) / 7 - len(self.user_data)
def add_text(self, text):
text = gsm7.gsm7bit_encode(text)
while text:
max_text_len = self.get_max_text_len()
if len(text) <= max_text_len:
self.cursor_pos += len(text)
self.user_data += text
return
self.user_data += text[:max_text_len]
self.add_segment()
text = text[max_text_len:]
def add_ie(self, ie):
if not self.ies and self.base_len == 0:
self.base_len = 1
ie.pos = self.cursor_pos
self.ies.append(ie)
self.packet_len += ie.size + 3
def make_payloads(self):
import status
self.payloads = []
for i, (ies, user_data) in enumerate(self.segments):
if len(self.segments) > 1:
udh = '\x00\x03' + chr(status.message_reference) + chr(len(self.segments)) + chr(i+1)
else:
udh = ''
for ie in ies:
udh += ie.make_header()
if udh:
udh = chr(len(udh)) + udh
pad = (len(udh) * 8) % 7
if pad:
pad = 7 - pad
udl = (len(udh) * 8 + pad + len(user_data) * 7)/7
payload = chr(udl) + udh + gsm7.gsm7_pack(user_data, pad)
self.payloads.append((udh, payload))
status.message_reference += 1
if status.message_reference > 255:
status.message_reference = 0
def split_test():
contents = [('Text', 'i'*640)]
ems = EmsSplit(contents)
contents = [('Text', 'eoie'*10)]
ems = EmsSplit(contents)
def split_bitmap():
class o:
pass
b = o()
b.width = 32
b.height = 32
b.data = '0' * (32 * 4)
contents = [('Text', 'eoie'*6),('Bitmap',b),('Bitmap',b)]
if __name__ == '__main__':
split_test()