|
|
  |
Эффективно парсить принимаемые ответы модема, Нужен быстрый алгоритм фильтрации |
|
|
|
Sep 1 2008, 19:37
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Доброго времени суток, господа. Хочу поинтересоваться как лучше всего организовать работу с модемом(а точнее с моб.телом). Я объявил структуру, которая описывает состояние телефона Код typedef struct { unsigned int ATState; unsigned int ATError; //Последний код ATResult unsigned int UserState; unsigned int CallState; unsigned int KeyPressed; unsigned char* CallNumber; //Номер телефона звонящего или вызываемого абонента unsigned int MenuID; }PhoneState; Для каждого State задефайнен набор констант... Планирую сделать 2 логические части, одна часть принимает данные с тела и соответствующим образом меняет поля структуры, вторая часть выполняет определенные действия, "глядя" только на структуру. Естественно первая часть, сделав хотя-бы одно изменение, сразу вызывает вторую, чтобы та вызвала определённую реакцию на изменение состояния тела. Вопрос стоит в эффективном написании первой части,которая принимает данные и парсит их в структуру. Нужен эффективный алгоритм, позволяющий на лету выявлять нужные строки в непрерывном потоке. Особенно это актуально в режиме данных, когда нужно поймать \r\nNO CARRIER\r\n в случае разрыва коннекта. Да и вообще. Посоветуйте что-нибудь по фильтрации или может быть по концепции в общем.
--------------------
The truth is out there...
|
|
|
|
|
Sep 1 2008, 19:49
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(sigmaN @ Sep 1 2008, 21:37)  Особенно это актуально в режиме данных, когда нужно поймать \r\nNO CARRIER\r\n в случае разрыва коннекта. Это вообще-то ловят по отсутствию/наличию CD Цитата Да и вообще. А "вообще" и не надо, поскольку поблемы нет.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Sep 1 2008, 21:05
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(sigmaN @ Sep 1 2008, 23:19)  Я то наваяю чё-ниить по любому, но не хотелось-бы изобретать велосипед лишний раз Ну вот что-то наваял навскидку Код typedef struct { const char * const string; const char * current; } entry;
entry table[] = { { "NO CARRIER", 0}, { "ERROR", 0}, }
void init() { entry *ent = table;
for( int i = 0; i < sizeof(table)/sizeof(table[0]); ++i, ++ent) ent->current = ent->string; }
// возвращает номер последнего найденного вхождения или -1 int check( char ch) { entry *ent = table;
int found = -1;
for( int i = 0; i < sizeof(table)/sizeof(table[0]); ++i, ++ent) { char *p = ent->current; if( ch == *p++ ) { if(*p == 0) { found = i; p = ent->string; // опять готовы принимать это слово } } else { p = ent->string; // начнём сначала, раз не совпало } ent->current = p; } return found; } "возвращает последнее" - это в смысле если в таблице есть Код "ERROR" "ROR" то на поток "EEERROR" выдаст номер для "ROR", так как оно последнее будет по порядку просмотра таблицы. Или так: Код typedef struct { const char * const string; const char * current; } entry;
entry table[] = { { "NO CARRIER", 0}, { "ERROR", 0}, { 0, 0} }
void init() { entry *ent = table;
while( ent->string ) { ent->current = ent->string; ++ent; } }
int check( char ch) { entry *ent = table;
int found = -1;
while( ent->string) { char *p = ent->current; if( ch == *p++ ) { if(*p == 0) { found = i; p = ent->string; } } else { p = ent->string; } ent->current = p; ++ent; } return found; } но это мало повлияет на скорость, да и на объём кода тоже.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 1 2008, 22:22
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(ReAl @ Sep 1 2008, 23:05)  Ну вот что-то наваял навскидку Сразу верю, что работоспособно, но если кто-то не удосужился CD использовать, то "NO CARRIER" ищется не в потоке, а только в случае таймаута в потоке/ошибки в протоколе верхнего уровня поиском назад от CR.Поток при этом без всяких тормозов складыватся в буфер, а поиски идут во время битья баклуш. С прочими сообщениями и того проще - они возникают на самом деле не по инициативе модема. Жевать весь поток - лобовое решение - очень понятное, но не эффективное.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Sep 2 2008, 07:51
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Цитата С прочими сообщениями и того проще - они возникают на самом деле не по инициативе модема. Возникают и по инициативе модема(а точнее телефона). Не в режиме данных, конечно. К примеру, пользователь вызывает абонента - в порт телефон стучит номер телефона, по которому звонит абонент(SonyEricsson Call monitor) И мне это нужно ловить. Также, при входящем звонке будет сначала сообщение Callмонитора с номером звонящего, а потом RING. Это тоже надо ловить и парсить. Может быть в процессе передачи данных и нет смысла всё время искать NO CARRIER, но вот в режиме команд мне будут приходить данные(причём целыми пачками) по инициативе телефона. В потоке NO CARRIER встретится никак не может в силу специфики передаваемых данных. Примерно прикину на сколько решение в лоб займёт проц. Скорость у меня всего 9600..Может быть прокатит и так )
--------------------
The truth is out there...
|
|
|
|
|
Sep 2 2008, 09:49
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(zltigo @ Sep 2 2008, 01:22)  Сразу верю, что работоспособно, но если кто-то не удосужился CD использовать, "а мне пофиг", я отвечал на часть вопроса "как эффективнео парсить"  (типа Райкинского "кто сшил костюм?" - "к пуговицам претензии есть?" - "нет, пришито намертво, не оторвёшь"  ) Цитата(zltigo @ Sep 2 2008, 01:22)  "NO CARRIER" ищется не в потоке, а только в случае таймаута в потоке/ошибки в протоколе верхнего уровня поиском назад от CR. Ну значит занести в таблицу Код "REIRRAC ON" и на случай ещё чего-то в буфере после NO CARRIER топать указателем Код ptr = buffer_end; ... check( *ptr--)  Ну не имею я опыта непосредственно поток модема смотреть, глубже логов dmail/DOS UUPC не рылся никогда. А как вопрошавший применит довольно эффективный, надеюсь, код поиска разных подстрок - его проблемы.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Sep 2 2008, 13:21
|

Гуру
     
Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515

|
Цитата В потоке NO CARRIER встретится никак не может в силу специфики передаваемых данных Цитата Особенно это актуально в режиме данных, когда нужно поймать \r\nNO CARRIER\r\n в случае разрыва коннекта. Это ваши слова. Это вы ищите это слово во входном потоке. А люди руководствуются протокольными таймаутами. Модем вообще вам может ничего не выдавать по причине удара по нему кирпичом. И по массе других причин.
--------------------
On the road again (Canned Heat)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|