реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Эффективно парсить принимаемые ответы модема, Нужен быстрый алгоритм фильтрации
sigmaN
сообщение Sep 1 2008, 19:37
Сообщение #1


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...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 1 2008, 19:49
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Sep 1 2008, 20:19
Сообщение #3


I WANT TO BELIEVE
******

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



Есть только Rx и Tx, нет в моём распоряжении CD.

Ну если бы не было проблемы - я бы не просил помощи ))
Даже не помощи, совет нужен спеца с опытом.

Я то наваяю чё-ниить по любому, но не хотелось-бы изобретать велосипед лишний раз


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
ReAl
сообщение Sep 1 2008, 21:05
Сообщение #4


Нечётный пользователь.
******

Группа: Свой
Сообщений: 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;
}

но это мало повлияет на скорость, да и на объём кода тоже.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Sep 1 2008, 21:52
Сообщение #5


I WANT TO BELIEVE
******

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



ReAl, огромное спасибо за код!
Полностью понимаю Линуса, который говорит: "show me the code"
Код это лучший ответ на вопрос программиста:-)


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
zltigo
сообщение Sep 1 2008, 22:22
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Sep 1 2008, 22:59
Сообщение #7


Гуру
******

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



Согласен с zltigo. Хуже того, строка NO CARRIER имеет полное право легально находится во входном потоке. И при этом никаких потерь несущей... К примеру, при передаче данного текста...

А проверить, в случае ахтунга, в каком состоянии находится модем без CD ( да и без анализа буфера)- способов масса. К примеру "+++".


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Sep 2 2008, 07:51
Сообщение #8


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...
Go to the top of the page
 
+Quote Post
ReAl
сообщение Sep 2 2008, 09:49
Сообщение #9


Нечётный пользователь.
******

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



Цитата(zltigo @ Sep 2 2008, 01:22) *
Сразу верю, что работоспособно, но если кто-то не удосужился CD использовать,
"а мне пофиг", я отвечал на часть вопроса "как эффективнео парсить" smile.gif (типа Райкинского "кто сшил костюм?" - "к пуговицам претензии есть?" - "нет, пришито намертво, не оторвёшь" wink.gif )

Цитата(zltigo @ Sep 2 2008, 01:22) *
"NO CARRIER" ищется не в потоке, а только в случае таймаута в потоке/ошибки в протоколе верхнего уровня поиском назад от CR.
Ну значит занести в таблицу
Код
"REIRRAC ON"

и на случай ещё чего-то в буфере после NO CARRIER топать указателем
Код
ptr = buffer_end;
...
check( *ptr--)

smile.gif

Ну не имею я опыта непосредственно поток модема смотреть, глубже логов dmail/DOS UUPC не рылся никогда.
А как вопрошавший применит довольно эффективный, надеюсь, код поиска разных подстрок - его проблемы.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Sep 2 2008, 13:21
Сообщение #10


Гуру
******

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



Цитата
В потоке NO CARRIER встретится никак не может в силу специфики передаваемых данных


Цитата
Особенно это актуально в режиме данных, когда нужно поймать \r\nNO CARRIER\r\n в случае разрыва коннекта.


Это ваши слова. Это вы ищите это слово во входном потоке. А люди руководствуются протокольными таймаутами.

Модем вообще вам может ничего не выдавать по причине удара по нему кирпичом. И по массе других причин.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
sigmaN
сообщение Sep 3 2008, 11:59
Сообщение #11


I WANT TO BELIEVE
******

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



Цитата
Модем вообще вам может ничего не выдавать по причине удара по нему кирпичом. И по массе других причин.

Таймаут в протоколе уже взят на вооружение )))


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 3rd August 2025 - 06:29
Рейтинг@Mail.ru


Страница сгенерированна за 0.01472 секунд с 7
ELECTRONIX ©2004-2016