Beispiel #1
0
def to_gammu(message, msgclass=1):
    """ converts NoSMS message to Gammu msg """

    # important to know length and type of message
    try:
        text = message.text.decode('utf-8')
    except (UnicodeEncodeError, UnicodeDecodeError):
        text = message.text
    number = message.identity
    is_unicode = msg_is_unicode(text)
    length = text.__len__()

    #logger.info(u"OUTGOING [%d] %s message: %s" \
    print(u"INFO: OUTGOING [%d] %s message: %s" \
                % (length, u"unicode" \
                           if is_unicode \
                           else u"ascii", \
                   text))

    # single ascii SMS
    # max_length of 160 chars.
    if not is_unicode and length <= 160:
        encoded = [{'Number': number, 'Text': text}]
    # multipart, ascii SMS.
    # will be split in 153 chars long SMS.
    elif not is_unicode and length > 160:
        smsinfo = {'Class': msgclass, \
                   'Unicode': False, \
                   'Entries': [{'ID': 'ConcatenatedTextLong', \
                                'Buffer': text}]}
        encoded = gammu.EncodeSMS(smsinfo)
    # single unicode SMS.
    # max_length of 70 chars.
    elif is_unicode and length <= 70:
        smsinfo = {'Class': msgclass, \
                   'Unicode': True, \
                   'Entries': [{'ID': 'ConcatenatedTextLong', \
                                'Buffer': text}]}
        encoded = gammu.EncodeSMS(smsinfo)
    # multipart unicode SMS
    # will be split in 63 chars long SMS.
    else:
        smsinfo = {'Class': msgclass, \
                   'Unicode': True, \
                   'Entries': [{'ID': 'ConcatenatedTextLong', \
                                'Buffer': text}]}
        encoded = gammu.EncodeSMS(smsinfo)

    # loop on parts
    for msg in encoded:
        msg['SMSC'] = {'Location': 1}
        msg['Number'] = number

    return msg
Beispiel #2
0
    def post(self):
        '''   Send a SMS'''
        json_data = request.json
        message = json_data["message"]
        numbers = json_data["recipients"]
        results = []
        for number in numbers:
            # Create SMS info structure
            smsinfo = {
                'Class': -1,
                'Unicode': True,
                'Entries': [{
                    'ID': 'ConcatenatedTextLong',
                    'Buffer': message
                }]
            }

            # Encode messages
            encoded = gammu.EncodeSMS(smsinfo)

            for sms in encoded:
                # Fill in numbers
                sms['SMSC'] = {'Location': 1}
                sms['Number'] = number

            msg_id = smsd.InjectSMS(encoded)
            results.append({"DestinationNumber": number, "smsID": msg_id})

        return {'results': results}, 200
Beispiel #3
0
    async def async_send_message(self, message="", **kwargs):
        """Send SMS message."""
        smsinfo = {
            "Class": -1,
            "Unicode": False,
            "Entries": [{
                "ID": "ConcatenatedTextLong",
                "Buffer": message
            }],
        }
        try:
            # Encode messages
            encoded = gammu.EncodeSMS(smsinfo)  # pylint: disable=no-member
        except gammu.GSMError as exc:  # pylint: disable=no-member
            _LOGGER.error("Encoding message %s failed: %s", message, exc)
            return

        # Send messages
        for encoded_message in encoded:
            # Fill in numbers
            encoded_message["SMSC"] = {"Location": 1}
            encoded_message["Number"] = self.number
            try:
                # Actually send the message
                await self.gateway.send_sms_async(encoded_message)
            except gammu.GSMError as exc:  # pylint: disable=no-member
                _LOGGER.error("Sending to %s failed: %s", self.number, exc)
Beispiel #4
0
def send_sms(text, number):
    # Create SMS info structure
    smsinfo = {
        'Class': 1,
        'Unicode': True,
        'Entries': [{
            'ID': 'ConcatenatedAutoTextLong',
            'Buffer': text
        }]
    }

    # Encode messages
    encoded = gammu.EncodeSMS(smsinfo)

    # Send messages
    for message in encoded:
        message['SMSC'] = {'Location': 1}
        message['Number'] = number

        # Actually send the message
        try:
            sm.SendSMS(message)
        except gammu.ERR_GETTING_SMSC as e:
            weechat.prnt('', "%s%s" % (weechat.prefix("error"), e))
        except gammu.ERR_TIMEOUT as e:
            weechat.prnt('', "%s%s" % (weechat.prefix("error"), e))
    def test_sendsms_long(self):
        state_machine = self.get_statemachine()
        text = ('Very long python-gammu testing message sent '
                'from example python script. ') * 10
        smsinfo = {
            'Class': -1,
            'Unicode': False,
            'Entries': [{
                'ID': 'ConcatenatedTextLong',
                'Buffer': text
            }]
        }

        # Encode messages
        encoded = gammu.EncodeSMS(smsinfo)

        self.assertEqual(len(encoded), 5)

        # Send messages
        for message in encoded:
            # Fill in numbers
            message['SMSC'] = {'Location': 1}
            message['Number'] = '123456'

            # Actually send the message
            state_machine.SendSMS(message)
Beispiel #6
0
    def send_SMS(self, content, targetnr):

        # Check if String holds only ASCII characters or is Unicode
        try:
            content.encode('ascii')
            isUnicode = False
        except UnicodeEncodeError:
            isUnicode = True

        smsgwglobals.pidlogger.debug("MODEM: isUnicode = " + str(isUnicode))

        # if content fits in a short sms send a standard Text message else
        # send a ConcatenatedTextLong message
        lencontent = len(content)

        if (isUnicode and lencontent <= 70):
            whichID = 'Text'
        elif (not isUnicode and lencontent <= 160):
            whichID = 'Text'
        else:
            whichID = 'ConcatenatedTextLong'

        # Fixes issue #43 - changing to not setting a SMS Class
        smsinfo = {
            'Class': -1,
            'Unicode': isUnicode,
            'Entries': [{
                'ID': whichID,
                'Buffer': content
            }]
        }

        # Encode message
        encoded = gammu.EncodeSMS(smsinfo)

        # Replace + with country exit code of Modem
        tonr = self.transform_targetnr(targetnr)

        # Send message
        for message in encoded:
            message['SMSC'] = {'Location': 1}
            message['Number'] = tonr

            try:
                msgref = self.__statemachine.SendSMS(message)
                status = True
                status_code = 1
            except gammu.GSMError as e:
                status_code = e.args[0]["Code"]
                msgref = str(e)
                status = False
            except Exception as e:
                msgref = str(e)
                status = False

        smsgwglobals.pidlogger.debug("MODEM: send_SMS to " + str(targetnr) +
                                     " has status: " + str(status) + " and " +
                                     "msgref (" + str(msgref) + ")")
        return status, status_code
Beispiel #7
0
def on_mqtt_message(client, userdata, msg):
    try:
        logging.info(f'MQTT received : {msg.payload}')
        payload = msg.payload.decode("utf-8")
        data = json.loads(payload, strict=False)
    except Exception as e:
        feedback = {"result":f'error : failed to decode JSON ({e})', "payload":payload}
        client.publish(f"{mqttprefix}/sent", json.dumps(feedback, ensure_ascii=False))
        logging.error(f'failed to decode JSON ({e}), payload: {msg.payload}')
        return

    for key, value in data.items():
        if key.lower() == 'number':
            number=value
        if key.lower() == 'text':
            text=value

    if 'number' not in locals() or not isinstance(number, str) or not number:
        feedback = {"result":'error : no number to send to', "payload":payload}
        client.publish(f"{mqttprefix}/sent", json.dumps(feedback, ensure_ascii=False))
        logging.error('no number to send to')
        return False

    if 'text' not in locals() or not isinstance(text, str):
        feedback = {"result":'error : no text body to send', "payload":payload}
        client.publish(f"{mqttprefix}/sent", json.dumps(feedback, ensure_ascii=False))
        logging.error('no text body to send')
        return False

    for num in (number.split(";")):
        num = num.replace(' ','')
        if num == '':
            continue

        smsinfo = {
            'Class': -1,
            'Entries': [{
                'ID': 'ConcatenatedAutoTextLong',
                'Buffer' : text
            }]
        }

        try:
            logging.info(f'Sending SMS To {num} containing {text}')
            encoded = gammu.EncodeSMS(smsinfo)
            for message in encoded:
                message['SMSC'] = {'Location': 1}
                message['Number'] = num
                gammusm.SendSMS(message)
            feedback = {"result":"success", "datetime":time.strftime("%Y-%m-%d %H:%M:%S"), "number":num, "text":text}
            client.publish(f"{mqttprefix}/sent", json.dumps(feedback, ensure_ascii=False))
            logging.info(f'SMS sent to {num}')
        except Exception as e:
            feedback = {"result":f'error : {e}', "datetime":time.strftime("%Y-%m-%d %H:%M:%S"), "number":num, "text":text}
            client.publish(f"{mqttprefix}/sent", json.dumps(feedback, ensure_ascii=False))
            logging.error(feedback['result'])
Beispiel #8
0
 def construct_gammu_multipart_messages(self, message):
     smsinfo = {
         'Class': 1,
         'Unicode': not self.is_gsm_charset(message['content']),
         'Entries': [{
             'ID': 'ConcatenatedTextLong',
             'Buffer': message['content'],
         }]
     }
     return gammu.EncodeSMS(smsinfo)
Beispiel #9
0
async def send_message_async(state_machine, number, message):
    smsinfo = {
        'Class': -1,
        'Unicode': False,
        'Entries':  [
            {
                'ID': 'ConcatenatedTextLong',
                'Buffer': message
            }
        ]}
    # Encode messages
    encoded = gammu.EncodeSMS(smsinfo)
    # Send messages
    for message in encoded:
        # Fill in numbers
        message['SMSC'] = {'Location': 1}
        message['Number'] = number
        # Actually send the message
        await state_machine.send_sms_async(message)
Beispiel #10
0
def sendSMS(phone, text):
    smsinfo = {
        'Class': -1,
        'Unicode': True,
        'Entries':  [
            {
                'ID': 'ConcatenatedTextLong',
                'Buffer': text
            }
        ]}
    encoded = gammu.EncodeSMS(smsinfo)

    for message in encoded:
        # Fill in numbers
        message['SMSC'] = {'Location': 1}
        message['Number'] = phone

        # Actually send the message
        sm.SendSMS(message)
Beispiel #11
0
    async def async_send_message(self, message="", **kwargs):
        """Send SMS message."""

        if SMS_GATEWAY not in self.hass.data[DOMAIN]:
            _LOGGER.error("SMS gateway not found, cannot send message")
            return

        gateway = self.hass.data[DOMAIN][SMS_GATEWAY][GATEWAY]

        targets = kwargs.get(CONF_TARGET)
        if targets is None:
            _LOGGER.error("No target number specified, cannot send message")
            return

        is_unicode = kwargs.get(CONF_UNICODE, True)
        smsinfo = {
            "Class": -1,
            "Unicode": is_unicode,
            "Entries": [{
                "ID": "ConcatenatedTextLong",
                "Buffer": message
            }],
        }
        try:
            # Encode messages
            encoded = gammu.EncodeSMS(smsinfo)
        except gammu.GSMError as exc:
            _LOGGER.error("Encoding message %s failed: %s", message, exc)
            return

        # Send messages
        for encoded_message in encoded:
            # Fill in numbers
            encoded_message["SMSC"] = {"Location": 1}

            for target in targets:
                encoded_message["Number"] = target
                try:
                    # Actually send the message
                    await gateway.send_sms_async(encoded_message)
                except gammu.GSMError as exc:
                    _LOGGER.error("Sending to %s failed: %s", target, exc)
Beispiel #12
0
    def test_link(self):
        # SMS info about message
        smsinfo = {
            'Entries': [{
                'ID': 'ConcatenatedTextLong',
                'Buffer': MESSAGE
            }]
        }

        # encode SMS
        sms = gammu.EncodeSMS(smsinfo)

        # link SMS
        linked = gammu.LinkSMS([[sms[0]], [sms[1]]], True)

        # decode back SMS
        decodedsms = gammu.DecodeSMS(linked[0])

        # compare results
        self.assertTrue(decodedsms['Entries'][0]['Buffer'], MESSAGE)
Beispiel #13
0
def pduencode(request):
    pdu = None
    if request.method == "POST":
        form = PDUEncodeForm(request.POST)
        if form.is_valid():
            # Prepare message data
            smsinfo = {
                "Class":
                form.cleaned_data["cls"],
                "Unicode":
                form.cleaned_data["unicode"],
                "Entries": [{
                    "ID": "ConcatenatedTextLong",
                    "Buffer": form.cleaned_data["text"],
                }],
            }
            # Encode SMS
            encoded = gammu.EncodeSMS(smsinfo)
            # Fill in remaining data
            for msg in encoded:
                msg["SMSC"] = {
                    "Location": 0,
                    "Number": form.cleaned_data["smsc"],
                    "Validity": "Max",
                }
                msg["Number"] = form.cleaned_data["number"]
                msg["Class"] = form.cleaned_data["cls"]
            # Encode PDU
            pdu = enumerate(
                gammu.EncodePDU(e, "Submit").hex() for e in encoded)

    else:
        form = PDUEncodeForm()
    return render(
        request,
        "tools/pduencode.html",
        {
            "form": form,
            "pdu": pdu,
        },
    )
Beispiel #14
0
    def do_smstest(self, smsinfo, expected):
        # encode SMSes
        sms = gammu.EncodeSMS(smsinfo)

        # decode back SMSes
        decodedsms = gammu.DecodeSMS(sms)

        # compare text
        self.assertEqual(decodedsms['Entries'][0]['Buffer'], expected)

        # do conversion to PDU
        pdu = [gammu.EncodePDU(s) for s in sms]

        # Convert back
        pdusms = [gammu.DecodePDU(p) for p in pdu]

        # decode back SMS from PDU
        decodedsms = gammu.DecodeSMS(pdusms)

        # compare PDU results
        self.assertEqual(decodedsms['Entries'][0]['Buffer'], expected)
Beispiel #15
0
    def Preview(self, evt):
        if len(self.entry['SMSInfo']['Entries']) == 0:
            dlg = wx.MessageDialog(self,
                                   _('Nothing to preview, message is empty.'),
                                   _('Message empty!'),
                                   wx.OK | wx.ICON_WARNING)
        else:
            self.StoreEdited()
            msg = gammu.EncodeSMS(self.entry['SMSInfo'])
            info = gammu.DecodeSMS(msg)
            result = {}
            result['SMS'] = msg
            if info is not None:
                result['SMSInfo'] = info
            Wammu.Utils.ParseMessage(result, (info is not None))
            dlg = MessagePreview(
                self, ('<i>%s</i><hr>' %
                       (_('Message will fit into %d SMSes') % len(msg))) +
                Wammu.MessageDisplay.SmsToHtml(self.cfg, result))

        dlg.ShowModal()
        del dlg
Beispiel #16
0
def pduencode(request):
    pdu = None
    if request.method == 'POST':
        form = PDUEncodeForm(request.POST)
        if form.is_valid():
            # Prepare message data
            smsinfo = {
                'Class':
                form.cleaned_data['cls'],
                'Unicode':
                form.cleaned_data['unicode'],
                'Entries': [{
                    'ID': 'ConcatenatedTextLong',
                    'Buffer': form.cleaned_data['text'],
                }]
            }
            # Encode SMS
            encoded = gammu.EncodeSMS(smsinfo)
            # Fill in remaining data
            for msg in encoded:
                msg['SMSC'] = {
                    'Location': 0,
                    'Number': form.cleaned_data['smsc'],
                    'Validity': 'Max',
                }
                msg['Number'] = form.cleaned_data['number']
                msg['Class'] = form.cleaned_data['cls']
            # Encode PDU
            pdu = enumerate([
                binascii.hexlify(gammu.EncodePDU(e, 'Submit')) for e in encoded
            ])

    else:
        form = PDUEncodeForm()
    return render(request, 'tools/pduencode.html', {
        'form': form,
        'pdu': pdu,
    })
# Create SMS info structure
smsinfo = {
    'Class':
    -1,
    'Unicode':
    False,
    'Entries': [{
        'ID':
        'ConcatenatedTextLong',
        'Buffer':
        'Very long python-gammu testing message '
        'sent from example python script. '
        'Very long python-gammu testing message '
        'sent from example python script. '
        'Very long python-gammu testing message '
        'sent from example python script. '
    }]
}

# Encode messages
encoded = gammu.EncodeSMS(smsinfo)

# Send messages
for message in encoded:
    # Fill in numbers
    message['SMSC'] = {'Location': 1}
    message['Number'] = sys.argv[1]

    # Actually send the message
    state_machine.SendSMS(message)
Beispiel #18
0
# -*- coding: UTF-8 -*-

# Simple test for testing SMS decoding/encoding
# This passes unicode string which can be transferet to GSM charset
# to Gammu and expects it to be unchanged in the SMS

import gammu

# text of sms
txt = u'.........1$........2..Ø......3...åÅ....4....Λ....5....Æ....6....ñ....7.........8.........9........0.........1.........2.........3.........4.........5.........6.........7.........8.........9........0.........1.........2.........3.........4.........5.........6.........7.........8.........9....¥€..0'

# SMS info about message
smsinfo = {'Entries': [{'ID': 'ConcatenatedTextLong', 'Buffer': txt}]}

# encode SMSes
sms = gammu.EncodeSMS(smsinfo)

# decode back SMSes
decodedsms = gammu.DecodeSMS(sms)

# show results
print "Text:", repr(decodedsms['Entries'][0]['Buffer'])
print "Comparsion:", (decodedsms['Entries'][0]['Buffer'] == txt)

# do conversion to PDU
pdu = [gammu.EncodePDU(s) for s in sms]

# Convert back
pdusms = [gammu.DecodePDU(p) for p in pdu]

# decode back SMS from PDU
def encode_sms(smsinfo):
    return gammu.EncodeSMS(smsinfo)
Beispiel #20
0
    def run(self):
        self.sm.Init()
        while not self.kill.is_set():

            # sending outgoing messages
            try:
                # retrieve a message from outgoing queue
                msg = to_modem.get_nowait()
            except Empty:
                pass
            else:
                # important to know length and type of message
                text = msg['Text'].decode('utf-8')
                number = msg['Number']
                is_unicode = self.msg_is_unicode(msg)
                length = text.__len__()

                logger.info(u"OUTGOING [%d] %s message: %s" \
                            % (length, u"unicode" \
                                       if is_unicode \
                                       else u"ascii", \
                               text))

                # single ascii SMS
                # max_length of 160 chars.
                if not is_unicode and length <= 160:
                    encoded = [msg]
                # multipart, ascii SMS.
                # will be split in 153 chars long SMS.
                elif not is_unicode and length > 160:
                    smsinfo = {'Class': 1, \
                               'Unicode': False, \
                               'Entries': [{'ID': 'ConcatenatedTextLong', \
                                            'Buffer': text}]}
                    encoded = gammu.EncodeSMS(smsinfo)
                # single unicode SMS.
                # max_length of 70 chars.
                elif is_unicode and length <= 70:
                    smsinfo = {'Class': 1, \
                               'Unicode': True, \
                               'Entries': [{'ID': 'ConcatenatedTextLong', \
                                            'Buffer': text}]}
                    encoded = gammu.EncodeSMS(smsinfo)
                # multipart unicode SMS
                # will be split in 63 chars long SMS.
                else:
                    smsinfo = {'Class': 1, \
                               'Unicode': True, \
                               'Entries': [{'ID': 'ConcatenatedTextLong', \
                                            'Buffer': text}]}
                    encoded = gammu.EncodeSMS(smsinfo)

                # loop on parts
                for msg in encoded:
                    msg['SMSC'] = {'Location': 1}
                    msg['Number'] = number

                    try:
                        logger.debug(u"Sending SMS: %s" % msg)
                        self.sm.SendSMS(msg)
                    except gammu.ERR_UNKNOWN:
                        pass

            # receiving incoming messages
            try:
                # get first SMS from Modem
                msg = self.sm.GetNextSMS(0, True)[0]
            except gammu.ERR_EMPTY:
                pass
            else:
                logger.debug(u"Received SMS: %s" % msg)

                # remove SMS from modem and move-on if not in white-list
                if not self.regex.match(msg['Number']):
                    self.delete(msg)
                else:
                    # if SMS is a part of a multipart SMS
                    # store the part and remove SMS from Modem.
                    if self.msg_is_multipart(msg):
                        self.msg_store_part(msg)
                        self.delete(msg)

                    # if SMS is a single message or was last part of a
                    # multipart message
                    if self.msg_is_complete(msg):
                        # builf concatenated multipart if required
                        if self.msg_is_multipart(msg):
                            msg = self.msg_unified(msg)

                        try:
                            logger.info(u"INCOMING [%d] from %s: %s" \
                            % (msg['Text'].__len__(), \
                               msg['Number'], msg['Text']))

                            # submit message to application
                            res = urlopen('%s?%s' \
                                 % (SENDING_URL, \
                                    urlencode({'from': msg['Number'], \
                                               'text': msg['Text']\
                                                       .encode('utf-8')})))
                        except IOError:
                            # we don't do anything so modem will find
                            # the SMS again next time
                            pass
                        else:
                            if res.code == 202:
                                # application received the SMS
                                # delete multipart from internal store
                                if self.msg_is_multipart(msg):
                                    self.msg_delete_multipart(msg)
                                else:
                                    # delete SMS from modem
                                    self.delete(msg)
            # main loop 500ms
            self.kill.wait(.5)
        try:
            # close modem connection properly
            self.sm.Terminate()
        except:
            pass