Страница 4 из 21

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

Добавлено: 05 июл 2020, 10:25
pepelxl
Без Wait в буфер считывается от 0 до 3-4 PDU из 10 в Inbox в ответ на команду "AT+CMGL=4"
Тут думал как поступить дальше, ведь проблеме будут следовать многие железки.
Сначала пришла простое гениальное решение - указывать везде wait=yes, а ответ обрезать от "+<команда>" до "OK"
И в конце "NO clear SMS"

такое обрезание надо делать для любой посылаемой команды.
Потому что даже после at+cmgd в терминале приходит много мусора.
Потом мне прислали образец того, что приходит после AT+CMGL=4 и у меня произошёл взрыв мозга. Чем думали разрабы модема создавая этот код. :ps_ih:
Внутри ответа идёт выхлоп другой команды +MMSG
Это надо было так бредово сделать.
Придётся писать код так, что бы парсить ответ построчно, а это тот ещё гемор, так-как по спецификации каждое сообщение с новой строки и конец удачной пересылки всегда подтверждается "OK" с новой строки

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

Добавлено: 05 июл 2020, 10:46
pepelxl
EagleNN пришлите пожалуйста выхлоп от этих команд, пока остаётся не ясно, как удалять смс в модемах mikrotik

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

Добавлено: 05 июл 2020, 17:34
EagleNN
pepelxl писал(а): 05 июл 2020, 10:46 EagleNN пришлите пожалуйста выхлоп от этих команд, пока остаётся не ясно, как удалять смс в модемах mikrotik
Выхлоп ниже:

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

[admin@MikroTik] > :put [/interface lte at-chat lte1 input="AT+CMGF\?" as-value wait=yes]
output=+CMGF: 0
OK
+CSQ: 11,99
+CESQ: 99,99,31,36,255,255
*CESQ: 99,99,31,36,255,255,0
+CSQ: 12,99
+CESQ: 99,99,32,35,255,255
*CESQ: 99,99,32,35,255,255,0
+CSQ: 11,99
+CESQ: 99,99,31,34,255,255
*CESQ: 99,99,31,34,255,255,0

[admin@MikroTik] > :put [/interface lte at-chat lte1 input="at+cmgd\?" as-value wait=yes]
output=+CMS ERROR: operation not allowed
+CSQ: 11,99
+CESQ: 99,99,31,32,255,255
*CESQ: 99,99,31,32,255,255,0
+CSQ: 12,99
+CESQ: 99,99,32,31,255,255
*CESQ: 99,99,32,31,255,255,0

[admin@MikroTik] > :put [/interface lte at-chat lte1 input="at+cmgd=\?" as-value wait=yes]
output=+MMSG: 1, 1
+MMSG: 1, 1
+MMSG: 1, 1
+MMSG: 1, 1
+MMSG: 1, 1
+MMSG: 1, 1
+MMSG: 1, 1
+MMSG: 1, 1
+MMSG: 1, 1
+CMGD: (1,2,3,4,5,6,7,8,9,10),(0-4)
OK
+MMSG: 1, 1
+CSQ: 12,99
+CESQ: 99,99,32,39,255,255
*CESQ: 99,99,32,39,255,255,0
+CSQ: 12,99
+CESQ: 99,99,33,35,255,255
*CESQ: 99,99,33,35,255,255,0

[admin@MikroTik] > :put [/interface lte at-chat lte1 input="at+cmgd=0,1" as-value wait=yes]
output=+CMS ERROR: invalid memory index
+CSQ: 12,99
+CESQ: 99,99,32,31,255,255
*CESQ: 99,99,32,31,255,255,0

[admin@MikroTik] > :put [/interface lte at-chat lte1 input="at+cmgd=1" as-value wait=yes] 
output=+MMSG: 1, 0
OK
+MMSG: 1, 0


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

Добавлено: 05 июл 2020, 22:28
pepelxl
прекрасный кусок дебилизма разрабов mikrotik-a

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

[admin@MikroTik] > :put [/interface lte at-chat lte1 input="at+cmgd=1" as-value wait=yes] 
output=+MMSG: 1, 0
OK
+MMSG: 1, 0
Хоть стой, хоть падай.
На кой мне этот отчёт "+MMSG" по десять раз в секунду.
Как я должен поймать отсюда "OK" на свою команду, если "OK" может быть в любом месте, а поскольку at-chat подразумевает - "подсмотреть в терминал за общением чужих", то понять, что "OK" пришло на мою команду вообще не возможно.
Хоть сейчас создавать тикет и долбить поддержку.

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

Добавлено: 05 июл 2020, 22:31
pepelxl
Не удивительно, что все с родными модемами видят NO clear SMS
Для отладки закоментируйте в основном скрипте следующие строки

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

:local flagSend [$extractSmsModem action="clear"]
:if ($flagSend != true) do={:set $flagSend [$extractSmsModem action="clear"]}
:if ($flagSend != true) do={:log warning "NO clear SMS"; $exitFunctionPDU; :error}

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

Добавлено: 06 июл 2020, 22:28
EagleNN
pepelxl писал(а): 05 июл 2020, 22:31 Не удивительно, что все с родными модемами видят NO clear SMS
Для отладки закоментируйте в основном скрипте следующие строки

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

:local flagSend [$extractSmsModem action="clear"]
:if ($flagSend != true) do={:set $flagSend [$extractSmsModem action="clear"]}
:if ($flagSend != true) do={:log warning "NO clear SMS"; $exitFunctionPDU; :error}
Может кто еще сможет протестить?
У меня доступ к тушке только по выходным, и то не факт...

Если не пришлют ранее, попробую в районе 25-го июля прислать.

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

Добавлено: 15 июл 2020, 16:57
pepelxl
в общем времени так и не смог найти, на скорую руку переписал функцию извлечения

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

:global extractSmsModem do={
# Функция принимает один аргумент со значениями “read” или “clear”.
# При “read” возвращать должна один из трёх вариантов:
# 1 - Строку “NO SMS” в случаи отсутствия sms
# 2 - Строку с текстом ошибки при сбоях в выполнении функции
# 3 - Массив из строк PDU
# При “clear” должно вернутся булево значение
# true - при удачном стирании sms из памяти
# false - если стереть sms не удалось


: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={
: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 [:toarray ""]
:local errorString
:local flagErrorExtract false
:local nosms false
:local clearSms true
:global storageMessageIndex
:if ($action = "read") do={:set $storageMessageIndex [:toarray ""]}

# опрашиваем все модемы по очереди
:foreach m in=$nameFind do={
:local tmp
:local tmp2
:local stStart
:local stEnd
:local mode
do {
# проверяем режим
:if (($m->"type") = "lte") do={:set $tmp ([/interface lte at-chat ($m->"name") input="AT+CMGF\?" wait=yes as-value]->"output")}
:if (($m->"type") = "ppp-client") do={:set $tmp ([/interface ppp-client at-chat ($m->"name") input="AT+CMGF\?" as-value]->"output")}
:set $stStart [:find $tmp "+CMGF"]
:if ([:typeof $stStart] != "num") do={:set $tmp2 "wrong answer to AT+CMGF\r\n"; throw;}
:set $stEnd [:find $tmp "\r\n" $stStart]
:if ([:typeof $stEnd] != "num") do={:set $tmp2 "wrong answer to AT+CMGF\r\n"; throw;}
:set $tmp2 [:pick $tmp ($stEnd + 2) ($stEnd + 4)]
:if ($tmp2 != "OK") do={:set $tmp2 "wrong answer to AT+CMGF\r\n"; throw;}
:set $tmp2 [:pick $tmp ($stStart + 7)]
:if ($tmp2 = "0") do={:set $mode false} else={:set $mode true}
:if ($mode) do={
:if (($m->"type") = "lte") do={/interface lte at-chat ($m->"name") input="AT+CMGF=0"}
:if (($m->"type") = "ppp-client") do={/interface ppp-client at-chat ($m->"name") input="AT+CMGF=0"}}
# читаем
:if ($action = "read") do={
# CMGL read sms
# 0 Received unread messages
# 1 Received read messages
# 2 Stored unsent messages
# 3 Stored sent messages
# 4 All messages
:if (($m->"type") = "lte") do={:set $tmp ([/interface lte at-chat ($m->"name") input="AT+CMGL=4" wait=yes as-value]->"output")}
:if (($m->"type") = "ppp-client") do={:set $tmp ([/interface ppp-client at-chat ($m->"name") input="AT+CMGL=4" as-value]->"output")}
:local flagend true
:local curStruct {"pdu"=[:toarray ""];"index"=[:toarray ""]}
:set $stStart [:find $tmp "+CMGL"]
:if ([:typeof $stStart] != "num") do={:if ($tmp~"OK" = true) do={:set $flagend false; set $nosms true} else={:set $tmp2 "wrong answer to AT+CMGL\r\n"; throw;}}
:set $stStart
:if ($flagend) do={[:parse ":global storageMessageIndex; :set \$storageMessageIndex (\$storageMessageIndex , {$($m->"name")=[:toarray \"\"]})"]}
:while ($flagend) do={
:set $stStart [:find $tmp "+CMGL" $stStart]
:if ([:typeof $stStart] != "num") do={:set $tmp2 "wrong answer to AT+CMGL\r\n"; throw;}
:set $stEnd [:find $tmp "\r\n" $stStart]
:if ([:typeof $stEnd] != "num") do={:set $tmp2 "wrong answer to AT+CMGL\r\n"; throw;}
:set $tmp2 [:pick $tmp $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)
:set $stEnd [:find $tmp "\r\n" $stStart]
:if ([:typeof $stEnd] != "num") do={:set $tmp2 "wrong answer to AT+CMGL\r\n"; throw;}
:set $tmp2 [:pick $tmp $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") , $tmp2)
:set ($curStruct->"index") (($curStruct->"index") , $index)
:if ([:pick $tmp ($stEnd + 2) ($stEnd + 4)] = "OK") do={:set $flagend false}
}
}
:set ($storageMessageIndex->($m->"name")) (($storageMessageIndex->($m->"name")) , ($curStruct->"index"))
:set $output ($output , ($curStruct->"pdu"))
}

# стираем
:if ($action = "clear") do={
:if (($m->"type") = "lte") do={:set $tmp ([/interface lte at-chat ($m->"name") input="AT+CMGD=1,1" wait=yes as-value]->"output")}
:if (($m->"type") = "ppp-client") do={:set $tmp ([/interface ppp-client at-chat ($m->"name") input="AT+CMGD=1,1" as-value]->"output")}
:if ($tmp~"OK" != true) do={
:foreach i in=($storageMessageIndex->($m->"name")) do={
:if (($m->"type") = "lte") do={:set $tmp ([/interface lte at-chat ($m->"name") input="AT+CMGD=$i" wait=yes as-value]->"output")}
:if (($m->"type") = "ppp-client") do={:set $tmp ([/interface ppp-client at-chat ($m->"name") input="AT+CMGD=$i" as-value]->"output")}
:if ($tmp~"OK" != true) do={:set $clearSms false}
}
}
}
} on-error={:set $flagErrorExtract true; :log info $m; :local na $m; :set $errorString ($errorString."Modem: ".[:tostr $m]."\r\nError: ".$tmp2."Returned:\r\n".$tmp."\r\n")}
:if ($mode) do={
:if (($m->"type") = "lte") do={/interface lte at-chat ($m->"name") input="AT+CMGF=1"}
:if (($m->"type") = "ppp-client") do={/interface ppp-client at-chat ($m->"name") input="AT+CMGF=1"}}
}
:if ($flagErrorExtract) do={
:set $storageMessageIndex
:if ([:len $output] > 0) do={:set $output ($errorString."Extracted from other modems:\r\n".[:tostr $output])
} else={:set $output $errorString}}
:if ($action = "clear") do={:set $storageMessageIndex
:if (!$clearSms) do={:set $output false} else={:set $output true}}
:if ($nosms and ([:len $output] = 0)) do={:set $output "NO SMS"; set $storageMessageIndex}
:return $output
}
Тестируйте, добавлено - автоматический поиск модемов, извлечение pdu из каши по присланным образцам, два режима стирания.
Но учтите, что хоть скрипт и обрабатывает все найденные модемы по порядку, но лучше пока не использовать если модемов больше чем один, там всё скорее всего развалится, вплоть до потери sms.
Обязательно отписывайтесь.

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

Добавлено: 16 июл 2020, 10:41
pepelxl
скрипт простоял ночь, вышел косяк, -
регулярка вида ~"^OK\$" не отрабатывает на тексте вида:

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

OK
^RSSI: 25
^HCSQ: "LTE",59,52,156,28
я так понимаю, что в синтаксисе регулярок ros нет модификаторов.
немного поправил код выше, кто уже скачал - перекачайте.

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

Добавлено: 16 июл 2020, 13:46
Sertik

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

:if (($m->"type") = "lte") do={/interface lte at-chat ($m->"name") input="AT+CMGF=1"}
:if (($m->"type") = "ppp-client") do={/interface ppp-client at-chat ($m->"name") input="AT+CMGF=1"}
А нельзя сразу типа так, для рациональности (вместо двух строк уже одна):

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

:if  (($m->"type") = "lte") or  ($m->"type") = "ppp-client")) do={/interface ($m->"type") at-chat ($m->"name") input="AT+CMGF=1"}
?

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

Добавлено: 16 июл 2020, 14:10
pepelxl
А нельзя сразу типа так, для рациональности (вместо двух строк уже одна):
оно изначально так и думал, но не работает, разбираться не стал, это черновик, что бы понять, заработает у людей или нет.
тем более там разница в wait=yes
Весь получившийся код я бы слил в унитаз, если мне бы принесли "как решение"