Anton Klapatun

STM32+LWIP+PPP проблемы с аутентификацией

4 сообщения в этой теме

День добрый!

 

Имеется sim-карта со статическим IP и модем SIM800C, который через UART соединен с STM32F0.

Прочитав статью на хабре, которая и являлась отправной точкой, было решено повторить подвиг, но в версии lwip 2.0.3, которой я пользуюсь, ppp изменился до неузнаваемости, что сначала внесло некоторый сумбур. Но в документации к lwip был найден текстовый файл с настройкой ppp-соединения (ppp.txt, прикреплю его ниже), в котором было все, что нужно для счастья, но когда модем начал общаться с контроллером, дальше фазы LCP дело не зашло. Как я понял из документа (ppp_connect.docx), который оказался у меня уже-и-не-помню-откуда, после конфигурирования параметров соединения в фазе 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, но после подтверждения контроллера запроса опций, наступает тишина.

В интернете мне удалось найти довольно мало исчерпывающей информации и примеров по связке stm32+lwip+ppp, если кто-нибудь занимался подобным или сталкивался с похожей проблемой, буду очень признателен за помощь и за пинки в нужном направлении. Заранее спасибо.

 

 

ppp.txt

ppp_connect.docx

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


Ссылка на сообщение
Поделиться на других сайтах
ruhi    34
В 12.07.2018 в 10:58, Anton Klapatun сказал:

... в версии lwip 2.0.3, которой я пользуюсь, ppp ...

Это слишком специфичная задача, вряд ли найдется кто то, кто занимался.

Я например работаю с lwip, но на Атмелах и без использования PPP (возможно в этом была наша ошибка, надо посмотреть может и нам подходит, так что спасибо за пост!).

Может поможет информация: нам пришлось драйвер эзернетовский править в Атмеловской реализации LWIP, чтобы TCP пакеты любой разрешенной длинны (до 1.5кб) проходили.

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


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

а просто прозрачный моносокет открывается? без использования стороннего IP стэка...

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


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

Без стороннего стека все работает хорошо, но это не совсем то, что мне необходимо)

Спустя некоторое время, как я написал сюда, на хабре вышла очень полезная статья, собственно, благодаря ей у меня все получилось, но только я так и не понял, почему я столкнулся с проблемами, используя код выше. Судя по документации, я все делал верно, но lwip явно что-то не нравилось.

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


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

Ваша публикация должна быть проверена модератором

Гость
Вы не авторизованы. Если у вас есть аккаунт, пожалуйста, войдите.
Ответить в тему...

×   Вставлено в виде отформатированного текста.   Восстановить форматирование

  Разрешено не более 75 смайлов.

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

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

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

Загрузка...

  • Похожие публикации

    • Автор: michaelukolov
      Доброго времени суток.
      Сразу скажу: я не прошу писать за меня код, просто натолкните, как правильнее это реализовать.
      Имеется STM32F103C8T6, необходимо на ней построить одноканальный генератор сигнала, желательно разной формы (синус/меандр) с регулировкой частоты и скважности от переменного резистора. Регулировки частоты хватило бы в пределах 1Гц - 20кГц (отсюда еще вопрос, годится ли для этого F103C8T6?). Хотелось бы еще иметь разные уровни (5В/12В), но это и сам сообразить могу.
      Если использовать HAL таймер, то когда он уже будет запущен, можно будет менять частоту/скважность?
      Как реализовать переключение синус/меандр?
    • Автор: artos5
      Всем привет! Столкнулся с проблемой которую не удается решить.
      прописал в файле Drive.h так:
      typedef struct { uint8_t FlgL; uint8_t FlgR; uint16_t Speed; uint16_t PulseL1; uint16_t PulseL2; uint16_t PulseR1; uint16_t PulseR2; } Motor_; typedef struct { uint8_t Status; } Button_; extern struct Motor_ Motor; extern struct Button_ Button; а в с файле:
      #include "Drive.h" Motor.Pulse = 3; // зададим значение переменной в структуре Motor в итоге 2 ошибки редефайн....
       
      как правильно с ними работать? За вчера и за сегодня уже наверное 1000 вариантов попробовал.
    • Автор: artos5
      Всем доброго времени суток!
      Необходима стабилизация частоты вращения двигателей по энкодерам. Энкодеры состоят из одного датчика холла на валу двигателя.
      Эту задачу на АВР я решил при помощи INT0 и аппаратного таймера , попробовал перенести код на STM32 . Попробовал через EXTI , результат не понравился .. Решил через таймер .
       
      void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { static uint8_t InpCaptIndexL=0, InpCaptIndexR=0; if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) // =RISING= EDGE DETECTED { // Get =RISING= EDGE Capture value if(InpCaptIndexR==0) { Motor.TimerOldR = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); InpCaptIndexR=1; } else { Motor.TimerNewR = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); InpCaptIndexR=0; } if (Motor.TimerOldR > Motor.TimerNewR) { Motor.MotorRData = (Motor.TimerOldR - Motor.TimerNewR); } else { Motor.MotorRData = (Motor.TimerNewR - Motor.TimerOldR); } // Reset Counter After Input Capture Interrupt Occurs __HAL_TIM_SET_COUNTER(&htim1,0x00); } if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) // =FALLING= EDGE DETECTED { // Get =FALLING= EDGE Capture value if(InpCaptIndexL==0) { Motor.TimerOldL = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); InpCaptIndexL=1; } else { Motor.TimerNewL = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); InpCaptIndexL=0; } if (Motor.TimerOldL > Motor.TimerNewL) { Motor.MotorLData = (Motor.TimerOldL - Motor.TimerNewL); } else { Motor.MotorLData = (Motor.TimerNewL - Motor.TimerOldL); } // Reset Counter After Input Capture Interrupt Occurs } StabMotorSpeed1(); __HAL_TIM_SET_COUNTER(&htim2, 0x00); } в интернете подсмотрел применение захвата но получается какая то каша . Осциллографом четко вижу меандр одинаковой частоты , а в юарт сыпет постоянно разные значения ...
      (имею ввиду переменную Motor.MotorLData и Motor.MotorRData)
      Тактирование 64МГц
      настройки таймера такие:
      TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; TIM_IC_InitTypeDef sConfigIC = {0}; htim2.Instance = TIM2; htim2.Init.Prescaler = 6400; htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 65535; htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; if (HAL_TIM_Base_Init(&htim2) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } if (HAL_TIM_IC_Init(&htim2) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK) { Error_Handler(); } sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING; sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler = TIM_ICPSC_DIV1; sConfigIC.ICFilter = 0; if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_1) != HAL_OK) { Error_Handler(); } if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_2) != HAL_OK) { Error_Handler(); } что то я или недопонимаю , или что то не так приготавливаю..
       
      Пробовал и так:
      void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) // =RISING= EDGE DETECTED { // Get =RISING= EDGE Capture value Motor.TimerR = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_2); // Reset Counter After Input Capture Interrupt Occurs __HAL_TIM_SET_COUNTER(&htim1,0x00); } if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) // =FALLING= EDGE DETECTED { // Get =FALLING= EDGE Capture value Motor.TimerL = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); // Reset Counter After Input Capture Interrupt Occurs } StabMotorSpeed(); __HAL_TIM_SET_COUNTER(&htim2, 0x00); } Результат тоже хуже чем на АВР , и в юарт сыпет каша (имею ввиду переменную Motor.TimerL и Motor.TimerR)
      Помогите пожалуйста разобраться в чем дело.
    • Автор: Grampus
      Добрый день!
      ПОМОГИТЕ ПОЖАЛУЙСТА!
      в описании для одного дисплея нашел код для STM на СИ
      там есть строчка которая мне не понятна, точнее смысл ее понятен но нет объявления аргументов функции
      помогите пожалуйста. В общем ситуация такая 
       
      spi_write ( DTA, 0x00 )                                     spi_write ( CMD, 0x01) 
      вот эта функция
      DTA - выполняет установку пина в 1 ,    CMD -  выполняет установку пина в 0 
      0x00 , 0x01, .........0xFF     это либо данные либо команда. 
       и все бы ничего но все это нужно передать по HAL_SPI_Transmit 
      помогите написать эту функцию с описанием аргументов и всех действий.
    • Автор: Mars36
      Добрый день. Имею желание вкатиться в разработку на stm32. Не много погуглив обнаружил копеечный программатор(tt-link), но отладочной платы как у какой нибудь avr'ки не нашел(аля вставил камень, прошил, впаял в плату). Существует множество всяких discovery  и им подобных, для проверки работы штука удобная, но для использовании в конечном устройстве нерациональная. Поэтому хотелось бы знать, существуют ли какие либо платы, переходники и т.д.? И если подобных промышленных вариантов нету, то единственный вариант это развести такую самостоятельно и вкорячивать переходники c LQFPхх и т.д.?
      P.S. Когда то видел вариант у аврки c tqfp корпусом, когда к подобной домашней плате аврку цепляли с помощью прищепки.