Перейти к содержанию
    

Долго искал, где создать тему, так и не нашёл. Разместил здесь, т.к. в конечном счёте, PPP необходим для GPRS. Если есть более подходящая ветка, прошу перенести.

Собственно сам вопрос. Рассчитываю CRC PPP фрейма. И CRC не совпадает. Делаю Следующее:

Сначало приходит стандартный LCP пакет:

~ }#А!}!}#} }9}"}&} }*} } }'}"}(}"}%}&ЂA}!в}#}%В#}%чи~

После преоброзования 7D, выделяем тело:

C0,21,1,3,0,19,2,6,0,A,0,0,7,2,8,2,5,6,80,41,1,E2,3,5,C2,23,5,F7,E8,

 

Функуия для расчёта CRC:

uint16 crc16_ppp(uint8 *buf,uint32 len)

{

uint32 i;

uint8 j;

uint16 crc=0x2E93; //В CRC побывало уже 0xFF и 0x03

for (i=0;i<len;i++)

{

crc^=(uint16)buf<<8;

for(j=0;j<8;j++) crc=crc&0x8000 ? (crc << 1)^0x1021 : crc<<1;

}

return crc;

}

Получаю CRC: EB1C

Инвертирую CRC: 14E3 и оно не совпадает с F7E8.

Что я делаю не так? Через CRC надо пропускать байты уже преобразованные через 7D, или абсолютно каждый байт между ~~?

Если у кого есть исxодники PPP, можете помочь страждущему?

P.S. Т.к. есть большое желание узнать, как вся эта кухня работает, не предлагать взять готовый стек PPP и TCP/IP

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

http://electronix.ru/forum/index.php?showtopic=51447

 

ps: меня всегда удивляет - а почему не подглядеть интересующие моменты в linux/freebsd/...? есть целая кучка опенсорсных реализаций ppp.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ps: меня всегда удивляет - а почему не подглядеть интересующие моменты в linux/freebsd/...? есть целая кучка опенсорсных реализаций ppp.

+1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не работал с Linux. Где искать source не представляю. На сайтах про Linux, описание такое, что не работав с этой OS, трудно понять про что вообще идёт речь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

можно посмотреть в дистрибутиве uclinux:

 

http://www.uclinux.org/pub/uClinux/dist/

 

качаете архив весь, разворачиваете, каталоге users лежит pppd. Часть поддержка находится в pppd

часть в ядре, ядра также находятся в верхнем каталоге как развернете.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что я делаю не так? Через CRC надо пропускать байты уже преобразованные через 7D, или абсолютно каждый байт между ~~?

Если у кого есть исxодники PPP, можете помочь страждущему?

P.S. Т.к. есть большое желание узнать, как вся эта кухня работает, не предлагать взять готовый стек PPP и TCP/IP

Лучше привести Hex dump пакета до и после удаления префиксации. Тогда можно будет определиться где допущена ошибка.

Для РРР контрольная сумма охватывает весь пакет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо всем ответившим. Как всегда дело оказалась в мелочи, на которую, во всех описаниях PPP, авторы посчитали не обращать внимание. Оставим это на их совести.

В общем, данные на CRC надо было подавать в зеркальном виде. Т.е. первый бит в байте должен быть последним и наоборот. Это походу связано с видом физической передачи данных в Ethernet, где как раз, так и делается. Возможно, отсюда корни растут, может я и ошибаюсь.

В теме “ppp на Siemens MC35i, помогите с CRC алгоритмом” добрые люди подсказали, как эту “зеркаляцию” встроить в сам алгоритм расчёта CRC, за что им отдельное спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вопрос может показаться кому то несколько смешным, однако всё же, ИМХО, имеет право на существование.

В процессе кодописания, одна из множества самых распространённых используемых операций это копирование переменной из памяти( стек, буфер и т.д.) в локальную переменную. В 99% случаев - это регистр. Если переменная char, то в принципе всё однозначно, а если long?

Так вот, какой минимальный код будет реализовывать эту функцию. На входе имеем номер регистра и адрес памяти первого актета long. Для определённости, я работаю на платформе ARM9. Впрочем для С, это особой роли не играет. У меня в голову приходит только два варианта:

long x;
char *p;
1)
    x=(long)p[0]<<24;
    x+=(long)p[1]<<16;
    x+=(shot)p[2]<<8; 
    x+=p[3]; 
2)
x=p[0];
for( char i=1; i<4; i++)
{
    x<<8;
    x+=p[i]
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Имхо приятнее пользовать какую memcpy из стандартной библиотеки. Вообще библиотека замечательная вещь. Она избавит вас от лишнего гемора во многих случаях.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно так:

 

long x;

char *p;

 

x=(long)*(p++);

x <<= 8; x += *(p++);

x <<= 8; x += *(p++);

x <<= 8; x += *p;

 

Здесь отсутствуют накладные расходы на организацию цикла for и на вызов функции memcpy.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все зависит от того, насколько применяемый компилятор обучен "догадываться" что вы хотите :)

Первый вариант несколько лучше. Второй вариант будет развернут в полноценный программный цикл.

Если проц поддерживает байтовые операции, тогда оптимальным будет:

long x;
char *p;
x = (long)p[0]<<24 | (long)p[1]<<16 | (long)p[2]<<8 | (long)p[3];

при этом компилер просто загрузит нужные байты в нужное место без оверхеда.

 

з.ы. а вообще-то это не вопрос для форума по сотовой связи. А в разделах по программированию на МК это было много раз... :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Этот вопрос я адресовал в эту тему, потому что он возник во время писания PPP стека. Дабы не плодить темы написал здесь.

Все зависит от того, насколько применяемый компилятор обучен "догадываться" что вы хотите

В точку! Я это и имел ввиду, только не смог выразить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Помогите решить проблему.

Сразу после CONNECT, приходит первый PPP пакет – это LCP протокол согласования настроек соединения:

FF,3,C0,21,1,3,0,19,2,6,0,A,0,0,7,2,8,2,5,6,B4,DE,E,6E,3,5,C2,23,5,35,D3,

где:

FF,3 – константы

CO,21 –LCP

1 -Запрос конфигурации

3 –ID

0,19 – длина поля ”информация”

2,6,0,A,0,0, - сервер предложил только 12 13 символ передавать через ESC

7,2, - сжатие поля протокола

8,2,- сжатие полей поля адреса и управления

5,6,B4,DE,E,6E, - магическое число

3,5,C2,23,5, - протокол аутентификации CHAP !!! Зачем здесь в конце цифра 5??? Кто знает прошу объяснить.

35,D3, -CRC

Мне не нужны все предложенные настройки. Вместо протокола CHAP нужен PAP.

Следуя алгоритму, я посылаю пакет NAK. Что написано про него в описании:

Пакет LCP типа Configure-Nak используется для сигнализации о том, что по крайней мере один из параметров, заявленных в пакете Configure-Request, не принят сервером РРР. При этом сервер должен указать, какой именно параметр не принят, и предложить альтернативное значение этого параметра в поле Опции этого пакета.

Я формирую следующий пакет:

FF,3,C0,21,3,3,0,18,2,6,0,A,0,0,3,4,C0,23,5,6,B4,DE,E,6E,7,2,8,2,5B,8D,

где:

FF,3 – константы

CO,21 –LCP

3 - Не подтверждение конфигурации

3 – ID такойже как и в запросе

0,18 - длина поля ”информация”

2,6,0,A,0,0, - не использовать параметр, т.к. значение совпадает с предложенным сервером. Но если параметр не используется, то берётся значение по умолчанию. Т.е. все первых 32 знака проходят через ESC.

3,4,C0,23,- я посылаю отвержение параметра, но т.к. тип протокола С023(PAP) не совпадает с предложенным сервером С223(CHAP) то сервер должен принять новое значение.

6,B4,DE,E,6E,- не использовать ”магическое число», я посылаю такое же число, как и в запросе сервера, следовательно, сервер должен думать, что параметр отвержен.

7,2, - сжатие протокола не использовать. Вообще, какой то бредовый параметр. Я бы и хотел его использовать, но оказывается его нельзя использовать для LCP пакетов. Тогда зачем он нужен? Что то я не пойму.

8,2, - не использовать сжатие полей поля адреса и управления

5B,8D – последний байт в этой последовательности – это старший байт рассчитанной CRC.

Вобщем, посылаю этот пакет. В ответ сервер мне присылает:

 

FF,3,C0,21,1,5,0,E,2,6,0,A,0,0,3,4,C0,23,47,5B,

Где:

 

FF,3 – константы

CO,21 –LCP

1 - Запрос конфигурации

5 – ID. Почему не 4? Куда он потерялся? Ведь должен быть простояй инкремент?

0,E - длина поля ”информация”

2,6,0,A,0,0, - ПОЧЕМУ ОСТАЛСЯ ЭТОТ ПАРАМЕТР???????

3,4,C0,23 - Пфууу... Хоть тут сервер, догадался что делаь.

 

Ответьте на вышестоящие вопросы. Что я делаю не так. Я примерно описал ход моих мыслей – укажите где вы нашли ошибку.

Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Походу Async Control Character Map обязательный параметр.

Ну что ж, я его проинитил 0xFFFFFFFF и всё OK.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Походу Async Control Character Map обязательный параметр.

Ну что ж, я его проинитил 0xFFFFFFFF и всё OK.

 

отвергай сначало все кроме CHAP,

потом подправляеш входящий пакет и отсылаеш его ему обратно

...
...
...
if ((Rx_Tx_buf [12] == 0x23) && (Rx_Tx_buf [11] == 0xC2)) 
{
Rx_Tx_buf[5] = NAK;
                                                                 
Rx_Tx_buf[8] -= 1; //correct len  PACK
                                                                 
Rx_Tx_buf[10] -= 1; //coorect len PARAM
Rx_Tx_buf[11] = 0xC0; //I wont PAP protocol
..
..
..

 

 

p.s. на чём пишеш, камень какой ? можна исходники посмотреть ?

Изменено пользователем west329_

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...