Данный модем не является модемом, как таковым. Это роутер с процессором arm v7 на базе Linux, в системе отображается в виде сетевой карты, без проблем заводится в Линуксе (сетевой интерфейс usb0, подсеть 192.168.0.0).
К устройству можно подключаться по telnet (ip: 192.168.0.1, login: root, password: zte9x15), дальше внедрять свои iptables, вешать скрипты в crontab и многое другое, даже устанавливать собственное по, но сегодня речь не об этом.
Для выполнения операций с модемом необходимо выполнять CGI запросы к веб-интерфейсу, подойдет wget или curl. В модеме от мегафон нет веб-морды, а вот в билайновском есть. Web-морда представляет из себя браузерное JavaScript-приложение, которое отправляет аяксом эти самые CGI запросы, ни каких годных документаций по работе с sms на просторах интернета я найти не смог, поэтому решил залить веб-морду и отловить запросы.
Для работы с SMS нужно отправлять POST-запросы на адрес 192.168.0.1/goform/goform_set_cmd_process
Отправка SMS
goformId=SEND_SMS
notCallback=true
Number=номер абонента
sms_time= дата в формате y;m;d;h;i;s
MessageBody=текст сообщения
ID=-1
encode_type=UNICODE
Удаление SMS
goformId=DELETE_SMS
msg_id=список id сообщений, разделенный точкой с запятой
notCallback=true
Получение SMS
Для получения всех сообщений в формате json, нужно обратиться по адресу
192.168.0.1/goform/goform_get_cmd_process?cmd=sms_data_total&page=0&data_per_page=5000&mem_store=1&tags=10&order_by=order+by+id+desc
в ответ мы получим массив всех SMS в формате JSON.
C удалением sms всё просто, а вот с получением и отправкой следующая беда — каждый символ кодируется HEX-кодом UTF, получаем код символа функцией ord(), переводим то что получилось в 16-ричную систему счисления и добиваем нулями до 4х сиволов, для обратной раскодировки сообщений делим текст по 4 символа, переводим в 10-ричную систему счисления и получаем символ по его номеру функцией chr(). Казалось бы, всё так просто, да вот только php не особо то хорошо работает с юникодов, поэтому пришлось изобретать какие то велосипеды и быдлокодить, в итоге 3х часовых опытов получился PHP класс для работы с sms на данном модеме.
<?php
mb_internal_encoding("UTF-8");
class ZTE_WEB
{
public $ip="192.168.0.1",$tz="+5";
public function url($url,$post="")
{
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
curl_setopt($ch,CURLOPT_BINARYTRANSFER,false);
curl_setopt($ch,CURLOPT_HEADER,false);
curl_setopt($ch,CURLOPT_TIMEOUT, 90);
$header = array();
$header[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8';
$header[] = 'Accept-Charset: Windows-1251,utf-8;q=0.7,*;q=0.7';
$header[] = 'Accept-Language: ru-ru,ru;q=0.8,en-us;q=0.5,en;q=0.3';
$header[] = 'Pragma: ';
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
unset ($header);
if(!empty($post)) {curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post);}
$content = curl_exec($ch);
curl_close($ch);
return $content;
}
public function utf2hex($str)
{
$l=mb_strlen($str);
$res='';
for ($i=0;$i<$l;$i++)
{
$s = mb_substr($str,$i,1);
$s = mb_convert_encoding($s, 'UCS-2LE', 'UTF-8');
$s = dechex(ord(substr($s, 1, 1))*256+ord(substr($s, 0, 1)));
if (mb_strlen($s)<4) $s = str_repeat("0",(4-mb_strlen($s))).$s;
$res.=$s;
}
return $res;
}
public function hex2utf($str)
{
$l=mb_strlen($str)/4;
$res='';
for ($i=0;$i<$l;$i++) $res.=html_entity_decode('&#'.hexdec(mb_substr($str,$i*4,4)).';',ENT_NOQUOTES,'UTF-8');
return $res;
}
//отправляет смску
public function send($number,$text)
{
$url = 'http://'.$this->ip.'/goform/goform_set_cmd_process';
$post='isTest=false&';
$post.= 'goformId=SEND_SMS&';
$post.= 'notCallback=true&';
$post.= 'Number='.urlencode($number).'&';
$date = gmdate('y;m;d;h;i;s;'.$this->tz,time()+($this->tz*3600));
$post.= 'sms_time='.urlencode($date).'&';
$post.= 'MessageBody='.($this->utf2hex($text)).'&';
$post.= 'ID=-1&';
$post.= 'encode_type=UNICODE';
return $this->url($url,$post);
}
//возвращает массив всех смсок
public function get_sms()
{
$cont=$this->url('https://'.$this->ip.'/goform/goform_get_cmd_process?cmd=sms_data_total&page=0&data_per_page=5000&mem_store=1&tags=10&order_by=order+by+id+desc');
$cont = json_decode($cont,true);
$cont = $cont['messages'];
foreach ($cont as $id => $arr) $cont[$id]['content']=$this->hex2utf(($cont[$id]['content']));
return $cont;
}
//удаляет все смс
public function clear_sms($cont=0)
{
if ($cont===0) $cont=$this->get_sms();
$list_id='';
$url = 'http://'.$this->ip.'/goform/goform_set_cmd_process';
foreach ($cont as $id => $arr) $list_id.=$cont[$id]['id'].';';
$post='isTest=false&goformId=DELETE_SMS&msg_id='.urlencode($list_id).'¬Callback=true';
return $this->url($url,$post);
}
}
$zte = new ZTE_WEB;
//отправка $zte->send("+79220000000","проверка");
//чистка $zte->clear_sms($zte->get_sms());
//получение $zte->get_sms();
?>
Предполагается, что скрипты на php будут получать все сообщения, а потом делать зачистку памяти модема.
Данный модем подключен к Raspberry Pi, в кронтабе будут висеть различные обработчики sms и бот, который будет реагировать на команды, отправленные с доверенных номеров и принимать определенные решения.
Автор: PavelBelyaev