Własna bramka SMS [aktualizacja]

Od zawsze dążyłem do automatyzacji pracy. Poniższy wpis przedstawia fundament Automatycznego Centrum Powiadamiania klientów (ACP).
Wykorzystany zostanie:
– Linux z serwerem WWW
– Telefon Siemens MT50
– kabel RS-232 do podłączenia telefonu.

1. Siemens MT50 wysyła SMS’y jedynie w trybie PDU, dlatego potrzebny jest odpowieni program pozwalający na konwersję tekstu do PDU. Program napisałem w c++ (w załączeniu). Obsługa jest trywialna. Polecenie:

./t2p 48nr_centrum 48nr_telefonu "tekst"

Kod źródłowy programu w c++ (kod wymaga jeszcze optymalizacji – pisany był “na kolanie”)

/*usage
t2p 48666555444 48123456789 "witaj uzytkowniku"
where:
48666555444 - sms centrum number (48 is Poland)
48123456789 - receiver number (48 is Poland)
"witaj uzytkowniku" - message</strong></code>

*/
#include
#include
#include
#include

using namespace std;

string convert_sms_centrum(string nr);
string convert_message(string sms);
string convertInt(int);
string toHexadecimal(int num);

int main(int argc, char* argv[])
{
string tmp3="";
string final = "";
string tmp;
string tmp2;
final += convert_sms_centrum(argv[1]);
final = convertInt(final.length()/2) + final;
final += "0100";
tmp3 += "0100";
tmp = argv[2];
final += toHexadecimal(tmp.length());
final += convert_sms_centrum(argv[2]);
final += "0000";
tmp3 += toHexadecimal(tmp.length());
tmp3 += convert_sms_centrum(argv[2]);
tmp3 += "0000";
tmp = "";
tmp += argv[3];
final += toHexadecimal(tmp.length());
final += convert_message(tmp);
final += "00";
tmp3 += toHexadecimal(tmp.length());
tmp3 += convert_message(tmp);
tmp3 += "00";
cout&lt;&lt;final&lt;&lt;endl&lt;&lt;((tmp3.length())/2)&lt;0)
{
temp+=number%10+48;
number/=10;
}
for (int i=0;i&lt;temp.length();i++)
returnvalue+=temp[temp.length()-i-1];

if (returnvalue.length()%2!=0) returnvalue = '0' + returnvalue;
return returnvalue;
}

string convert_sms_centrum(string nr) //OK
{
unsigned char dl = nr.length();
if(dl%2!=0) {nr+='F'; dl++;}
string c = nr;

for(int i=0; i{
c[i] = nr[i+1];
c[i+1] = nr[i];
}
return "91" + c; //numeration type
}

string toHexadecimal(int num)
{
int dividend, remain;
string result = "";
string hexArray[16];
hexArray[0] = "0";
hexArray[1] = "1";
hexArray[2] = "2";
hexArray[3] = "3";
hexArray[4] = "4";
hexArray[5] = "5";
hexArray[6] = "6";
hexArray[7] = "7";
hexArray[8] = "8";
hexArray[9] = "9";
hexArray[10] = "A";
hexArray[11] = "B";
hexArray[12] = "C";
hexArray[13] = "D";
hexArray[14] = "E";
hexArray[15] = "F";
dividend = (int)num/16;
remain = num%16;
result = hexArray[remain];
while (dividend != 0)
{
remain = dividend%16;
dividend = (int)dividend/16;
result = hexArray[remain]+result;
}
if(result.length()%2!=0) result = '0' + result;
return result;
}

string convert_message(string sms)
{

unsigned char i,n;
unsigned char len = sms.length();
unsigned char ch_1, ch_2;
string ok2, tmp = "";
i = n = 0;

while (i &lt; len) { ch_1 = sms[i]; //pobranie pierwszego znaku tekstu ch_2 = sms[i+1]; //pobranie nastepujacego za nim znaku n = i % 8; //obliczenie ilosci przesuniec ch_1 &gt;&gt;= n; //przesuniecie pierwszego znaku w prawo
n = 7-n; //wyliczenie liczby przesuniec dla 2-go znaku
ch_2 &lt; ch_1 += ch_2; //wyliczenie kodu nowo powstalego znaku
//printf("%02x", ch_1); //wyslania znaku szesnastkowego
tmp = toHexadecimal(ch_1);
ok2 += tmp;
i++; //nastepna pozycja w lancuchu
if (n == 1) i++; //dla kazdego 8-go znaku przesuniecie o 1,
//znak jest “gubiony”
}

return ok2;
}

2. Skrypt bashowy przekierowujący wszystko na port szeregowy. Oto zawartość pliku LMSsms.sh:

#!/bin/bash
./t2p "$1" "$2" "$3" &gt; wynik.t2p
line1=$(head -1 wynik.t2p)
line2=$(tail -n 1 wynik.t2p)
#echo $line1
#echo $line2
echo -e "AT+CMGS=$line2\r" &gt; /dev/ttyS0
sleep 0.1
echo -e "$line1\x1A" &gt; /dev/ttyS0
sleep 1

Wysyłka powinna działać. Oczywiście plikom t2p i LMSsms.sh należy nadać prawa wykonywania poprzez:

chmod +x t2p
chmod +x LMSsms.sh

Pozostaje wysyłka za pośrednictwem WWW (taka swoista bramka SMS).
Na chwilę obecną są dwa pliki: index.php i index2.php
zawartość pliku index.php:

Wewnetrzna bramka SMS<script type="text/javascript">// <![CDATA[
function count_key(textarea,counter,limit)
        {
                if((a=textarea.value.length)<=limit)                         counter.value=limit-a;                 else                         textarea.value=textarea.value.substring(0,limit);         }
// ]]></script></pre>
<form action="index2.php" method="POST">Nr centrum SMS: <input type="text" name="centrum" value="48xxxxxxxxx" />
Nr odbiorcy SMS:<input type="text" name="odbiorca" value="48" />

Tresc wiadomosci SMS <textarea onkeydown="count_key(this.form.tresc,this.form.counterr,160)" onkeyup="count_key(this.form.tresc,this.form.counterr,160)" name="tresc" rows="10" cols="25">Tresc wiadomosci.</textarea>
Pozostalo znakow: <input type="text" name="counterr" value="160" disabled="disabled" />
<input type="reset" value="Resetuj" /> <input type="submit" value="Wyslij" /></form>

oraz index2.php:

<?php

    chdir('/var/www/LMSsms/');
$cmd = './LMSsms.sh '.$_POST['centrum'].' '.$_POST['odbiorca'].' '.'"'.$_POST[tresc].'"';
    echo exec($cmd);
    echo 'Raczej wyslano... :)';
?>

Powodzenia!
mirrim.eu

============================= [Aktualizacja] =============================

Niestety siemens MT50, który działał jako bramka zakończył swój żywot, postanowiłem znaleźć alternatywę zasilaną z USB. Po krótkim poszukiwaniu, wybór padł na modem Huawei E160. Mały, podłączanany jedynie pod USB z gniazdem na kartę SIM i zewnętrzną antenę.

Okazuje się, że wyśmienicie współpracuje z napisanym oprogramowaniem (które swoją drogą zostało już odpowiednio zmodyfikowane – chcesz wiedzieć więcej? marcin@mirrim.eu).

Pozdrawiamy
Zespół mirrim.eu

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *