Разборка SMS и отправка на e-mail

Здесь выкладываем скрипты
Правила форума
Уважаемые Пользователи форума, обратите внимание!
Ни при каких обстоятельствах, Администрация форума, не несёт ответственности за какой-либо, прямой или косвенный, ущерб причиненный в результате использования материалов, взятых на этом Сайте или на любом другом сайте, на который имеется гиперссылка с данного Сайта. Возникновение неисправностей, потерю программ или данных в Ваших устройствах, даже если Администрация будет явно поставлена в известность о возможности такого ущерба.
Просим Вас быть предельно осторожными и внимательными, в использовании материалов раздела. Учитывать не только Ваши пожелания, но и границы возможностей вашего оборудования.
Ответить
pepelxl
Сообщения: 161
Зарегистрирован: 23 июл 2013, 18:47

Meteor пробуем так

Код: Выделить всё

:global extractSmsModem do={
# Функция не принимает аргументов.
# возвращает массив
# строку errorString текст ошибки, если таковая присутствует
# вложенный массив со значениями - pdu-name modem
# поддержка двух симочных моделей не реализована
# концепция скрипта подразумевает возможную потерю pdu при отсутствии поддержки команд модемом

# вложенная функция запросов
:local chat do={
:local t {"r"="";"f"=""}
:if ($1 = "lte") do={:set ($t->"r") ([/interface lte at-chat $2 input=$3 wait=yes as-value]->"output")}
:if ($1 = "ppp-client") do={:set ($t->"r") ([/interface ppp-client at-chat $2 input=$3 as-value]->"output")}
:if (($t->"r")~"(^|\n)OK(\$|\r)" != true) do={:set ($t->"f") true} else={:set ($t->"f") false}
:return $t
}
# массив с найдеными модемами
:local nameFind [:toarray ""]
# ищем модемы lte
:foreach i in=[/interface lte find] do={
if ([/interface lte get $i value-name=disabled] = false) do={
:local tmp [/interface lte info $i once as-value]
:set $nameFind ($nameFind , {{"name"=[/interface lte get $i value-name=name];"type"="lte";"manufacturer"=($tmp->"manufacturer");"model"=($tmp->"model");"revision"=($tmp->"revision")}})
}}
# ищем модемы ppp-client
:foreach i in=[/interface ppp-client find] do={
if ([/interface ppp-client get $i value-name=disabled] = false) do={
:local manufacturer 
:set $nameFind ($nameFind , {"name"=[/interface ppp-client get $i value-name=name];"type"="ppp-client"})
}}
:if ([:len $nameFind] = 0) do={:return "No found Modem"}

# объявляем возврат с обязательной инициализацией
:local output [[:parse "({\"errorStr\"=[:tostr \"\"];\"arr\"=[:toarray \"\"]})"]]

# опрашиваем все модемы по очереди
:foreach m in=$nameFind do={
:local tmp
:local tmp2
:local stStart
:local stEnd
:local mode
do {
# проверяем режим
:set $tmp [$chat ($m->"type") ($m->"name") "AT+CMGF?"]
:if (($tmp->"f")) do={:set $tmp2 "wrong answer to AT+CMGF\r\n"; throw;}
:set $stStart [:find ($tmp->"r") "+CMGF"]
:if ([:typeof $stStart] != "num") do={:set $tmp2 "wrong answer to AT+CMGF\r\n"; throw;}
:set $stEnd [:find ($tmp->"r") "\r\n" $stStart]
:if ([:typeof $stEnd] != "num") do={:set $tmp2 "wrong answer to AT+CMGF\r\n"; throw;}
:set $tmp2 [:pick ($tmp->"r") ($stStart + 7)]
:if ($tmp2 = "0") do={:set $mode false} else={:set $mode true}
# устанавливаем режим PDU
:if ($mode) do={:set $tmp [$chat ($m->"type") ($m->"name") "AT+CMGF=0"]}
:if (($tmp->"f")) do={:set $tmp2 "wrong answer to AT+CMGF=0\r\n"; throw;}
# временное хранение
:local curStruct {"pdu"=[:toarray ""];"index"=[:toarray ""]}
# читаем
# CMGL read sms
# 0 Received unread messages
# 1 Received read messages
# 2 Stored unsent messages
# 3 Stored sent messages
# 4 All messages
:set $tmp [$chat ($m->"type") ($m->"name") "AT+CMGL=4"]
:if (!($tmp->"f")) do={
:local flagend true
# проверяем что sms есть
:set $stStart [:find ($tmp->"r") "+CMGL"]
:if ([:typeof $stStart] != "num") do={:set $flagend false;}
:set $stStart
# извлекаем строки из текста
:while ($flagend) do={
:set $stStart [:find ($tmp->"r") "+CMGL" $stStart]
:if ([:typeof $stStart] != "num") do={:set $tmp2 "wrong answer to AT+CMGL\r\n"; throw;}
:set $stEnd [:find ($tmp->"r") "\r\n" $stStart]
:if ([:typeof $stEnd] != "num") do={:set $tmp2 "wrong answer to AT+CMGL\r\n"; throw;}
:set $tmp2 [:pick ($tmp->"r") $stStart $stEnd]
:local stat [:tonum [:pick $tmp2 ([:find $tmp2 ","] + 1)]]
:if (($stat = 0) or ($stat = 1)) do={
:local length [:tonum [ pick $tmp2 ([:find $tmp2 ",,"] + 2) [:len $tmp2]]]
:local index  [:tonum [ pick $tmp2 ([:find $tmp2 " "] + 1) [:find $tmp2 ","]]]
:set $stStart ($stEnd + 2)
:local coretka true
:while ($coretka) do={
:if (([:pick ($tmp->"r") $stStart] = "\r") or ([:pick ($tmp->"r") $stStart] = "\n")) do={
:set $stStart ($stStart + 1)} else={:set $coretka false}}
:set $stEnd [:find ($tmp->"r") "\r\n" $stStart]
:if ([:typeof $stEnd] != "num") do={:set $tmp2 "wrong answer to AT+CMGL\r\n"; throw;}
:set $tmp2 [:pick ($tmp->"r") $stStart $stEnd]
:set $length (($length + 1 + [:tonum ("0x".[ pick $tmp2 0 2])]) * 2)
:if ($length != [:len $tmp2]) do={:set $tmp2 "wrong length in CMGL\r\n"; throw;}
:set ($curStruct->"pdu") (($curStruct->"pdu") , {{"pdu"=$tmp2;"name"=($m->"name");"mode"="sms"}})
:set ($curStruct->"index") (($curStruct->"index") , $index)
}
:set $tmp2 [:pick ($tmp->"r") $stEnd [:len ($tmp->"r")]]
:if (($tmp2~"\\+CMGL" != true) and ($tmp2~"(^|\n)OK(\$|\r)" = true)) do={:set $flagend false}
}
} else={:local simFill
do {
:set $tmp [$chat ($m->"type") ($m->"name") "AT+CMGD=?"]
:if (($tmp->"f")) do={throw;}
:set $stStart [:find ($tmp->"r") "+CMGD"]
:if ([:typeof $stStart] != "num") do={throw;}
:set $stEnd [:find ($tmp->"r") "\r\n" $stStart]
:if ([:typeof $stEnd] != "num") do={throw;}
:set $tmp2 [:pick ($tmp->"r") $stStart $stEnd]
:set $stStart [:find $tmp2 "("]
:if ([:typeof $stStart] != "num") do={throw;}
:set $stEnd [:find $tmp2 ")"]
:if ([:typeof $stEnd] != "num") do={throw;}
:set $simFill [:toarray [:pick $tmp2 ($stStart + 1) $stEnd]]
} on-error={:set $tmp2 "wrong answer to AT+CMGD=?\r\n"; throw;}
:foreach i in=$simFill do={do { 
:set $tmp [$chat ($m->"type") ($m->"name") ("AT+CMGR=".[:tostr $i])]
:if (($tmp->"f")) do={throw;}
:set $stStart [:find ($tmp->"r") "+CMGR"]
:if ([:typeof $stStart] != "num") do={throw;}
:set $stEnd [:find ($tmp->"r") "\r\n" $stStart]
:if ([:typeof $stEnd] != "num") do={throw;}
:set $tmp2 [:pick ($tmp->"r") $stStart $stEnd]
:local stat [:tonum [:pick $tmp2 ([:find $tmp2 " "] + 1)]]
:if (($stat = 0) or ($stat = 1)) do={
:local length [:tonum [ pick $tmp2 ([:find $tmp2 ",,"] + 2) [:len $tmp2]]]
:set $stStart ($stEnd + 2)
:local coretka true
:while ($coretka) do={
:if (([:pick ($tmp->"r") $stStart] = "\r") or ([:pick ($tmp->"r") $stStart] = "\n")) do={
:set $stStart ($stStart + 1)} else={:set $coretka false}}
:set $stEnd [:find ($tmp->"r") "\r\n" $stStart]
:if ([:typeof $stEnd] != "num") do={throw;}
:set $tmp2 [:pick ($tmp->"r") $stStart $stEnd]
:set $length (($length + 1 + [:tonum ("0x".[ pick $tmp2 0 2])]) * 2)
:if ($length != [:len $tmp2]) do={throw;}
:set ($curStruct->"pdu") (($curStruct->"pdu") , {{"pdu"=$tmp2;"name"=($m->"name");"mode"="sms"}})
:set ($curStruct->"index") (($curStruct->"index") , $i)
}} on-error={:set $tmp2 ("wrong answer to AT+CMGR=$i; simfill=".[:tostr $simFill]."\r\n"); throw;}}
}
# стираем
:if ([:len ($curStruct->"index")] > 0) do={
:set $tmp [$chat ($m->"type") ($m->"name") "AT+CMGD=1,1"]
:if (($tmp->"f")) do={
:foreach i in=($curStruct->"index") do={
:local iterError 20
:while ($iterError > 0) do={
:set $tmp [$chat ($m->"type") ($m->"name") ("AT+CMGD=".[:tostr $i])]
:set $iterError ($iterError - 1)
:if (!($tmp->"f")) do={:set $iterError 0}}
:if (($tmp->"f")) do={:set $tmp2 "wrong answer in CMGD\r\n"; throw;}
}}}
# возвращаем режим обратно
:if ($mode) do={:set $tmp [$chat ($m->"type") ($m->"name") "AT+CMGF=1"]}
:if (($tmp->"f")) do={:set $tmp2 "wrong answer to AT+CMGF=1\r\n"; throw;}
# добавляем извлечённые pdu в возврат функции
:if ([:len ($curStruct->"index")] > 0) do={
:set ($output->"arr") (($output->"arr") , ($curStruct->"pdu"))}
} on-error={
# сохраняем значение в переменную, т.к. tmp является указателем 
:local es ($tmp->"r")
# опрашиваем идентификаторы модема
:if (($m->"type") = "ppp-client") do={
:local man [$chat ($m->"type") ($m->"name") "AT+GMI"]
:if (($man->"f")) do={:set $man [$chat ($m->"type") ($m->"name") "AT+CGMI"]}
:if (($man->"f")) do={:set $man "no information"} else={:set $man ($man->"r")}
:local mod [$chat ($m->"type") ($m->"name") "AT+GMM"]
:if (($mod->"f")) do={:set $mod [$chat ($m->"type") ($m->"name") "AT+CGMM"]}
:if (($mod->"f")) do={:set $mod "no information"} else={:set $mod ($mod->"r")}
:local rev [$chat ($m->"type") ($m->"name") "AT+GMR"]
:if (($rev->"f")) do={:set $rev [$chat ($m->"type") ($m->"name") "AT+CGMR"]}
:if (($rev->"f")) do={:set $rev "no information"} else={:set $rev ($rev->"r")}
:set $m ($m , {"manufacturer"=$man;"model"=$mod;"revision"=$rev})
}
:set ($output->"errorStr") (($output->"errorStr")."Modem: ".[:tostr $m]."\r\nError: ".$tmp2."Returned:\r\n$es\r\n")}
}
:return $output
}


Meteor
Сообщения: 7
Зарегистрирован: 27 июл 2018, 11:15

Все получилось, спасибо.


pepelxl
Сообщения: 161
Зарегистрирован: 23 июл 2013, 18:47

Отправил текущую версию в первый пост.

А так владельцам r11e сочувствую.
Дописал костыль для такого поведения
Пример лога:

Код: Выделить всё

11:47:11 lte,async lte1: sent AT+CMGD=1,1 
11:47:14 lte,async lte1: rcvd +CMS ERROR: 304 
11:47:16 lte,async lte1: sent AT+CMGD=8 
11:47:19 lte,async lte1: rcvd OK 
11:47:21 lte,async lte1: sent AT+CMGD=9 
11:47:24 lte,async lte1: rcvd +CMS ERROR: 500 
Причём обе ячейки гарантированно заполнены. :po_zor:


Meteor
Сообщения: 7
Зарегистрирован: 27 июл 2018, 11:15

Может стоит написать в суппорт производителя? Глядишь подшаманят.


pepelxl
Сообщения: 161
Зарегистрирован: 23 июл 2013, 18:47

у меня такого модема нет, так что писать точно не мне.
Но как показал опыт - писать лучше на их форум, публично обосрать, может зачешутся быстрее.


Zlodeyz
Сообщения: 7
Зарегистрирован: 02 июн 2019, 14:01

Здравствуйте. В можно прикрутить функцию пересылки смс на другой номер. ?


pepelxl
Сообщения: 161
Зарегистрирован: 23 июл 2013, 18:47

В этом скрипте нет.
Это можно реализовать отдельным простым скриптом. Кроме того большинство операторов предоставляют готовую услугу по переадресации смс.


Zlodeyz
Сообщения: 7
Зарегистрирован: 02 июн 2019, 14:01

Если вам не сложно можете показать скрипт для пересылки смс.
Операторы хотят деньги за эту функцию.


pepelxl
Сообщения: 161
Зарегистрирован: 23 июл 2013, 18:47

Такое решение я могу реализовать при финансовом стимулировании. И оно будет дороже хотелок операторов, правда разово.


Sertik
Сообщения: 1598
Зарегистрирован: 15 сен 2017, 09:03

Я тоже могу на рубль дешевле чем pepelxl, но не буду, так как первый в списке исполнителей он. Только если откажется. :-)


фрагменты скриптов, готовые работы, статьи, полезные приемы, ссылки
viewtopic.php?f=14&t=13947
Ответить