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

 
 
> STM32+LWIP+PPP проблемы с аутентификацией
Klapatun
сообщение Jul 13 2018, 09:53
Сообщение #1





Группа: Участник
Сообщений: 5
Регистрация: 12-07-18
Из: Новосибирск
Пользователь №: 105 858



Доброго времени суток!

Имеется sim-карта со статическим IP и модем SIM800C, который через UART соединен с STM32F0. Пытаюсь обойтись без встроенного в модем стека, чтобы обеспечить себе беззаботную жизнь, когда придет нужда менять модем, для этого в качестве внешнего стека юзаю lwip.

Видел на хабре статью про это дело, которая, собственно, и являлась отправной точкой, было решено повторить подвиг, но в версии lwip 2.0.3, которой я пользуюсь, ppp немного изменился и это все хорошо описано в документации (ppp.txt, прикреплю его ниже). Следуя инструкциям из упомянутого файла, реализовал все функции, которые надо реализовать и все заработало.... почти. Когда модем начал общаться с контроллером, дальше фазы LCP дело не зашло. Как я понял из документа (ppp_connect.pdf), который оказался у меня уже-и-не-помню-откуда, после конфигурирования параметров соединения в фазе LCP контроллер должен посылать в модем пакет с заголовком PAP (C0 23), но он почему-то этого не делает... Он вообще больше ничего не делает. Я пытался проследить в отладчике весь путь запроса, что приходит от модема, но это только больше меня запутало.

Собственно, прием данных у меня организован через прерывание. После ввода AT-команды "ATD*99***1#" и получения ответа "CONNECT", устанавливается флаг "ppp_enable" и при приходе байта он кладется в очередь `xQueue_PPP_Package`.

Код
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  uint8_t u8;
  if(huart == &huart1)
  {

    if (ppp_enable == true)
    {
      portBASE_TYPE xHigherPriorityTaskWoken_PPP_Rx;

      u8 = Sim800.UsartRxTemp;

      xHigherPriorityTaskWoken_PPP_Rx = pdFALSE;
      xQueueSendFromISR(xQueue_PPP_Package, &u8, &xHigherPriorityTaskWoken_PPP_Rx);
    }
    else
    {
      /*Reception of AT commands*/
    }

    HAL_UART_Receive_IT(&huart1,&Sim800.UsartRxTemp,1);
  }
}


В задаче `StartLwIPTask` в бесконечном цикле проверяется эта очередь и при появлении элементов, записывает их в массив `PPPx.Data` и при фиксации второго HDLC-заголовка (0x7E), отправляет данные в lwip функцией `pppos_input`.

P.S. Переменная `PPPx.Last_Index` это размер пришедшего ppp-пакета.

Код
void StartLwIPTask(void const * argument)
{
  /* USER CODE BEGIN StartLwIPTask */
  /*Создаем очередь*/
  xQueue_Sim800_Package = xQueueCreate(128, sizeof(uint8_t));
  xQueue_PPP_Package = xQueueCreate(128, sizeof(uint8_t));
  uint8_t u8=0;
  volatile int setup = 0;

  tcpip_init( NULL, NULL );             /*Инициализация стека tcp/ip*/

  /*Create a new PPPoS interface*/
    ppp = pppos_create(&ppp_netif,
         output_cb, status_cb, 0);

//    
    /* Auth configuration, this is pretty self-explanatory */
    ppp_set_auth(ppp, PPPAUTHTYPE_PAP, "beeline", "beeline");


    /* Require peer to authenticate */
    ppp_set_auth_required(ppp, 1);

    /*Only for PPPoS, the PPP session should be up and waiting for input.*/
    ppp_set_silent(ppp, 1);

    /*
    * Initiate PPP listener (i.e. wait for an incoming connection), can only
    * be called if PPP session is in the dead state (i.e. disconnected).
    */
    ppp_listen(ppp);

  /* Infinite loop */
  for(;;)
  {    
    if (sim800_init() == S_RESET)          /*Настройка модуля Sim800*/
      continue;


    for (;;)
    {

      if (pdPASS == xQueueReceive(xQueue_PPP_Package, &u8, 100/portTICK_RATE_MS))
      {
        if (u8 == 0x7E)
          t++;

        PPPx.Data[PPPx.Last_Index++] = u8;

        if (t==2)
        {
          PPPx.Last_Index--;
          pppos_input(ppp, PPPx.Data, PPPx.Last_Index);
          t=0;
          memset(&PPPx, 0, sizeof(PPPx));
        }
      }      
    }
  }
  /* USER CODE END StartLwIPTask */
}


Как я писал выше, все идет хорошо, пока идет фаза LCP, но после подтверждения контроллером запроса опций, наступает тишина. Интуиция мне говорит, что у меня какой-то косяк в настройках ppp в lwip, но неопытность в этом вопросе мешает понять, где именно и что именно я делаю не так

В интернете мне удалось найти довольно мало исчерпывающей информации и примеров по связке stm32+lwip+ppp (не исключаю, что это просто я искать не умею, если поделитесь ссылками на полезные ресурсы, буду очень признателен), если кто-нибудь занимался подобным или сталкивался с похожей проблемой, буду ноги целовать очень благодарен за помощь и за пинки в нужном направлении.
Прикрепленные файлы
Прикрепленный файл  ppp.txt ( 15.92 килобайт ) Кол-во скачиваний: 8
Прикрепленный файл  ppp_connect.pdf ( 200.95 килобайт ) Кол-во скачиваний: 7
 
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Grigorij
сообщение Jul 19 2018, 08:11
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 10-03-07
Пользователь №: 26 038



День добрый

У меня сейчас в приборе как раз работает связка SIM800C+STM32F405+LWIP+FreeRTOS. Версия LWIP 2.0.0, но в ней вроде как нет глобальных отличий от 2.0.3 в плате PPPOS.

По сравнению с вашим кодом:

1) Для передачи данных в LWIP я использую ф-цию pppos_input_tcpip()
2) После того, как я получил сообщение CONNECT от модем, я перестаю сам анализировать данные, и все данные от модема полностью передаю в LWIP на обработку


Порядок включения и работы с LWIP и PPP у меня примерно следующий:

Код
    sys_sem_new(&sem, 0);
        tcpip_init(TCPIPDoneCB, &sem);
        sys_sem_wait(sem);
    sys_sem_free(sem);

    pppapi_pppos_create(...,PPPOSOutputCB, PPPOSStatusCB, ...)

    ppp_set_usepeerdns(ctx->network.ppp, 1);    // только если DNS нужен

    ppp_set_auth(...., PPPAUTHTYPE_CHAP, user, password);

    pppapi_set_default();

    pppapi_connect();


static u32_t PPPOSOutputCB(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx)
{
    LWIP_UNUSED_ARG(pcb);
    LWIP_UNUSED_ARG(ctx);

    // шлем данные в UART как есть, без какого-либо разбора

    return sio_write(0, data, len);
}

static void PPPOSStatusCB(ppp_pcb *pcb, int err_code, void *ctx)
{
    ...

    switch (err_code)
    {
        case PPPERR_NONE:
        {
            // здесь уже есть IP у прибора
        }
        // обработка других кодов
    }
}

// есть отдельная задача, в которой вызывается следующая функция, которая
// в свою очередь забирает данные с UART и прямиком без какого-либо разбора отправляет
// их в LWIP.

void GSMrocessData(struct ModemContext *ctx)
{
    // gsmRawRxBuf - буфер для данных
    // GSM_RAW_RX_BUF_SIZE - максимальный размер буфера (должен быть около 1600 байт, у меня 2048)
    // 10 - таймут на ожидания данных в мс.
    // rb - количество данных полученных от модема

    int rb = sio_read(gsmRawRxBuf, GSM_RAW_RX_BUF_SIZE, 10);
    if (rb)
    {
        pppos_input_tcpip(ppp, (u8_t *)gsmRawRxBuf, rb);
    }
}


Также не стоит забывать о настроке самой LWIP (часть для PPP)

Код
// PPP

#define PPP_SUPPORT                 1
#define PPPOS_SUPPORT               1
#define PPP_IPV4_SUPPORT            1
#define PAP_SUPPORT                 1
#define CHAP_SUPPORT                1
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 12:42
Рейтинг@Mail.ru


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