Почему PPP через последовательный порт не отвечает на запрос ping?

Я использую модуль GSM Telit GL865 для связи UART с микроконтроллером STM32F7 и программным обеспечением STM32CubeMX, Keil.

Когда я отправляю AT-команды через UART на модуль GSM, как показано ниже, я получаю IP-адрес от внутреннего стека модуля GSM и успешно проверяю его:

AT
AT&K0
AT#SCFG=3,1,300,600,300,10
AT+CGDCONT=1,"IP","mgbs","0.0.0.0",0,0
AT+CGSN
AT#ICMP=2
AT#GPPPCFG="000.000.000.000",25,1
AT#GPPPCFGEXT=0
ATDT*99#
CONNECT

Однако, когда я запускаю сеанс PPPoS, я не могу пропинговать IP-адрес, который был успешно установлен через PPP.

Адреса IP, шлюза и маски сети, которые устанавливаются через стек PPP, следующие:

IP      = 5.26.61.173
Gateway = 192.168.202.0
Netmask = 255.255.255.255

Первое, что я увидел, это адрес сетевой маски; однако LwIP PPPoS устанавливает это.

Во-вторых, после установки, описанной выше, MCU и модуль GSM начинают отправлять друг другу периодические данные как "~y " с длиной 49 и 53 соответственно.

Это означает, что моя отладка printf( ) не может показать мне все периодические данные.

В-третьих, самое важное, когда я пингую вышеупомянутый IP-адрес GSM, периодические данные "~y " длиной 68 отправляются гораздо дольше во времени между MCU и GSM, это означает, что пинг запускает связь. между GSM и MCU, но ответа нет.

Я использую приемопередатчик UART на основе прерываний, который начинает заполнять полученный буфер и помещать его в pppos_input_tcpip(ppp, recBuffer, recIndex), если новые данные не поступают в течение 10 мс.

Основной поток и прерывание по таймеру выглядят следующим образом:

/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "cmsis_os.h"
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include "string.h"
#include "main.h"
#include "stm32f7xx_hal.h"
#include "cmsis_os.h"
#include "lwip.h"
#include "usart.h"
#include "gpio.h"
#include <stdio.h>
#include "string.h"
#include <time.h>
#include "lwip/opt.h"
#include "lwip/sys.h"
#include "lwip/timeouts.h"
#include "lwip/debug.h"
#include "lwip/stats.h"
#include "lwip/init.h"
#include "lwip/tcpip.h"
#include "lwip/netif.h"
#include "lwip/api.h"
#include "lwip/tcp.h"
#include "lwip/udp.h"
#include "lwip/dns.h"
#include "lwip/dhcp.h"
#include "lwip/autoip.h"
#include "lwip/etharp.h"
#include "netif/ethernet.h"
#include "lwip/apps/netbiosns.h"
#include "lwip/apps/httpd.h"
#include "lwip/sio.h"
//#include "ppp/ppp.h"
//#include "netif/ppp/pppapi.h"
//#include "netif/ppp/pppos.h"
#include "pppapi.h"
#include <lwip/sockets.h> 
#include "usart.h"
#include "test.h"

#define RX_SIZE 4096
/* USER CODE END Includes */

/* Variables -----------------------------------------------------------------*/
osThreadId defaultTaskHandle;

/* USER CODE BEGIN Variables */
uint8_t lcpBuffer[RX_SIZE];
uint8_t lcpBufferIndex, quantityOfPackages = 0;
uint8_t pppBuffer[4096];
uint32_t sysTickCounter = 0;
uint8_t sendData[50] = "                    \n";
uint8_t recData, recDataOlder, recDataOlder2,recDataOlder3,recDataOlder4,recDataOlder5,recDataOlder6;
uint8_t receivedValue,connected,called = 0;
uint32_t recIndex = 0;
uint8_t recBuffer[RX_SIZE];
uint8_t sent, send, connect, connectionStatus, endOfLcpNegotiation, NCPNegotiation = 0;
ppp_pcb *ppp;
struct netif ppp_netif;
u8_t sio_idx = 0;
sio_fd_t ppp_sio;
uint8_t ATconnected,lcpCame,length = 0;
uint8_t lcpStartIndex, lcpStopIndex, lcpStartOld, lcpStart, lcpStop, dataReceived, timeOut, fillThePPPBuffer, gsmInitEnd, sendLCP, sendNCP, socketOpened, socketBind, socketOpen = 0;
uint32_t pppBufferIndex = 0;
ip4_addr_t addr;
int socketStatus;
int socket_fd,accept_fd;
int addr_size,sent_data; char data_buffer[80]; 
struct sockaddr_in sa,ra,isa;
uint32_t runTimeCnt = 0;

void StartDefaultTask(void const * argument);

extern void MX_LWIP_Init(void);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */

//PPP function
static void status_cb(ppp_pcb *pcb, int err_code, void *ctx) {
    struct netif *pppif = ppp_netif(pcb);
    called = 1;

    switch(err_code) {
        case PPPERR_NONE: {
            connectionStatus = 1;
            printf("status_cb: Connected\n");
            printf("   our_ipaddr  = %s\r\n", ipaddr_ntoa(&pppif->ip_addr));
            printf("   gatewayaddr = %s\r\n", ipaddr_ntoa(&pppif->gw));
            printf("   netmask     = %s\r\n", ipaddr_ntoa(&pppif->netmask));
            break;
        }
        case PPPERR_PARAM: {
            connectionStatus = 2;
            printf("status_cb: Invalid parameter\r\n");
            break;
        }
        case PPPERR_OPEN: {
            connectionStatus = 3;
            printf("status_cb: Unable to open PPP session\r\n");
            break;
        }
        case PPPERR_DEVICE: {
            connectionStatus = 4;
            printf("status_cb: Invalid I/O device for PPP\r\n");
            break;
        }
        case PPPERR_ALLOC: {
            connectionStatus = 5;
            printf("status_cb: Unable to allocate resources\r\n");
            break;
        }
        case PPPERR_USER: {
            connectionStatus = 6;
            ppp_free(pcb);
            printf("status_cb: User interrupt\r\n");
            break;
        }
        case PPPERR_CONNECT: {
            connectionStatus = 7;
            printf("status_cb: Connection lost\r\n");
            break;
        }
        case PPPERR_AUTHFAIL: {
            connectionStatus = 8;
            printf("status_cb: Failed authentication challenge\r\n");
            break;
        }
        case PPPERR_PROTOCOL: {
            connectionStatus = 9;
            printf("status_cb: Failed to meet protocol\r\n");
            break;
        }
        case PPPERR_PEERDEAD: {
            connectionStatus = 10;
            printf("status_cb: Connection timeout\r\n");
            break;
        }
        case PPPERR_IDLETIMEOUT: {
            connectionStatus = 11;
            printf("status_cb: Idle Timeout\r\n");
            break;
        }
        case PPPERR_CONNECTTIME: {
            connectionStatus = 12;
            printf("status_cb: Max connect time reached\r\n");
            break;
        }
        case PPPERR_LOOPBACK: {
            connectionStatus = 13;
            printf("status_cb: Loopback detected\r\n");
            break;
        }
        default: {
            connectionStatus = 14;
            printf("status_cb: Unknown error code %d\r\n", err_code);
            break;
        }
    }
}
//PPP function
static u32_t output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx){
    printf("sent:     %s with length: %d\r\n",data,len);
    return HAL_UART_Transmit_IT(&huart1, data, len);
}

/* Init FreeRTOS */
void MX_FREERTOS_Init(void) {
  /* Create the thread(s) */
  /* definition and creation of defaultTask */
  osThreadDef(defaultTask, StartDefaultTask, osPriorityNormal, 0, 1024);
  defaultTaskHandle = osThreadCreate(osThread(defaultTask), NULL);
}

/* StartDefaultTask function */
void StartDefaultTask(void const * argument)
{
  /* init code for LWIP */
  MX_LWIP_Init();

  /* USER CODE BEGIN StartDefaultTask */
    //SysTick_Config(SystemCoreClock/1000); 
    HAL_UART_Receive_IT(&huart1, &recData, 1);

    // Start of AT commands

    HAL_Delay(1000);    
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT\r\n", strlen("AT\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT&K0\r\n", strlen("AT&K0\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#SCFG=3,1,300,600,300,10\r\n", strlen("AT#SCFG=3,1,300,600,300,10\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#SLED=2,2,2\r\n", strlen("AT#SLED=2,2,2\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#SLEDSAV\r\n", strlen("AT#SLEDSAV\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT+CGDCONT=1,\"IP\",\"mgbs\",\"0.0.0.0\",0,0\r\n", strlen("AT+CGDCONT=1,\"IP\",\"mgbs\",\"0.0.0.0\",0,0\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT+CGSN\r\n", strlen("AT+CGSN\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#ICMP=2\r\n", strlen("AT#ICMP=2\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT+CSQ\r\n", strlen("AT+CSQ\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT+CCLK?\r\n", strlen("AT+CCLK?\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#SGACT?\r\n", strlen("AT#SGACT?\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#SGACT=1,0\r\n", strlen("AT#SGACT=1,0\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#SGACT=1,1\r\n", strlen("AT#SGACT=1,1\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#SGACT?\r\n", strlen("AT#SGACT?\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#FRWL=1,\"10.0.1.1\",\"255.255.0.0\"\r\n", strlen("AT#FRWL=1,\"10.0.1.1\",\"255.255.0.0\"\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#GPPPCFG=\"000.000.000.000\",25,1\r\n", strlen("AT#GPPPCFG=\"000.000.000.000\",25,1\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#GPPPCFGEXT=0\r\n", strlen("AT#GPPPCFGEXT=0\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"AT#GAUTH=0\r\n", strlen("AT#GAUTH=0\r\n"));
    HAL_Delay(1000);
    memset(recBuffer, 0, sizeof(recBuffer));
    recIndex = 0;
    HAL_UART_Transmit_IT(&huart1, (uint8_t*)"ATDT*99***1#\r\n", strlen("ATDT*99***1#\r\n"));
    //End of AT commands

    //Start PPP
    ppp = pppapi_pppos_create(&ppp_netif, output_cb, status_cb, NULL);
    if (ppp == NULL) {
        printf("Error init pppos");
        return;
    }
    pppapi_set_default(ppp);
    ppp_set_auth(ppp, PPPAUTHTYPE_NONE, "", "");
    pppapi_listen(ppp);


    for(;;)
    {
        //if GSM is initialized, give data to ppp if stops coming after 10ms, 
        //send flag is set by systick(10ms) and gsmInitEnd is set after LCP session starts

        if(gsmInitEnd){
            if(send){
                send = 0;
                pppos_input_tcpip(ppp, recBuffer, recIndex);
                printf("received: %s with length: %d\r\n", recBuffer, recIndex);
                recIndex = 0;
                runTimeCnt++;
                memset(recBuffer, 0, sizeof(recBuffer));
            }
        }
    }
}

// UART rx callback, called over 1 data received
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
    if (UartHandle->Instance == USART1)
    {
        //callback reset
        HAL_UART_Receive_IT(&huart1, &recData, 1);

        //receive buffer overflow check
        if(recIndex >= RX_SIZE){
            recIndex = 0;
        }   

        //3 variables below are externed to send data if stops coming to
        //buffer after 10ms with Systick interrupt later than GSM initialization
        dataReceived = 1;    
        sysTickCounter = 0;
        send = 0;

        //LCP packets start with 0x7E, that means the end of GSM initialization.
        if(recData == 0x7E) 
        {
            if(gsmInitEnd == 0){
                recIndex = 0;
                memset(recBuffer, 0, sizeof(recBuffer));
            }
            gsmInitEnd = 1;
        }
        recBuffer[recIndex++] = recData;
    }
}

Systick Handler, который проверяет буфер RX и устанавливает флаг отправки для отправки данных в ppp, если данные перестают поступать через 10 мс:

void SysTick_Handler(void)
{
    if(dataReceived){
        sysTickCounter++;
        if (sysTickCounter >= 10)
        {
            send = 1;
            dataReceived = 0;
            sysTickCounter = 0;
        }
    }
  osSystickHandler();
}

Обмен данными между GSM и STM32 мне кажется нормальным (!) И запускается запросом ping; однако нет ответа на эхо-запрос ..

На мой взгляд, проблема может заключаться в соединении между ppp_netif и ppp_netif(ppp), сетевой маске или реализации ping стека LwIP ...


person Sarp Engin Daltaban    schedule 23.05.2018    source источник


Ответы (2)


Ответ - активация параметров исходящей и входящей контрольной суммы ICMP STM32CubeMX ... Таким образом, активации модуля LWIP_ICMP недостаточно для ответа на запросы ping ..

person Sarp Engin Daltaban    schedule 24.05.2018

Если вы включите программные контрольные суммы для PPPOS, Ethernet сломается, потому что STM32 выполняет их в HW на Ethernet - GRRR

person Keith Suhoza    schedule 09.05.2020