IoTReady / a9_gsm_gps_library

Libraries for the AI Thinker A9/A9G GSM/GPS modems.
39 stars 10 forks source link

GPS data send server, stops after 1 day #16

Open cityba opened 3 years ago

cityba commented 3 years ago

@KaranRajPradhan I run the gps-tracker code, rewriting it a bit, and 24 hours after turning it on, the data transfer stops, the sim card goes, it rings. What could be wrong? why does it stop after exactly 1 day? is there any hidden function that causes this? release code also stops at 24 hours.Can anyone help?

tejpochiraju commented 3 years ago

@KaranRajPradhan - didn't we see and debug this too? Did we push our reconnect changes?

cityba commented 3 years ago

@tejpochiraju Can anyone help?

KaranRajPradhan commented 3 years ago

@cityba - which code do you mean by "gps-tracker code"?

cityba commented 3 years ago

@KaranRajPradhan demo_gps_tracker.c

#include <string.h>
#include <stdio.h>
#include <api_os.h>
#include <api_gps.h>
#include <api_event.h>
#include <api_hal_uart.h>
#include <api_debug.h>
#include "buffer.h"
#include "math.h"
#include "api_hal_pm.h"
#include "time.h"
#include "api_info.h"
#include "assert.h"
#include "api_socket.h"
#include "api_network.h"
#include "api_hal_gpio.h"
#include "gps_parse.h"

#include "gps.h"
/**
 * szita gps 
 */
#define SERVER_IP   "bla.com"
#define SERVER_PORT  80

#define MAIN_TASK_STACK_SIZE    (2048 * 2)
#define MAIN_TASK_PRIORITY      0
#define MAIN_TASK_NAME          "GPS Test Task"

static HANDLE gpsTaskHandle = NULL;
bool isGpsOn = true;
bool networkFlag = false;

void EventDispatch(API_Event_t* pEvent)
{
    switch(pEvent->id)
    {
        case API_EVENT_ID_NO_SIMCARD:
            Trace(10,"!!NO SIM CARD%d!!!!",pEvent->param1);
            networkFlag = false;
            break;
        case API_EVENT_ID_NETWORK_REGISTER_SEARCHING:
            Trace(2,"network register searching");
            networkFlag = false;
            break;
        case API_EVENT_ID_NETWORK_REGISTER_DENIED:
            Trace(2,"network register denied");
        case API_EVENT_ID_NETWORK_REGISTER_NO:
            Trace(2,"network register no");
            break;

        case API_EVENT_ID_NETWORK_REGISTERED_HOME:
        case API_EVENT_ID_NETWORK_REGISTERED_ROAMING:
        {
            uint8_t status;
            Trace(2,"network register success");
            bool ret = Network_GetAttachStatus(&status);
            if(!ret)
                Trace(1,"get attach staus fail");
            Trace(1,"attach status:%d",status);
            if(status == 0)
            {
                ret = Network_StartAttach();
                if(!ret)
                {
                    Trace(1,"network attach fail");
                }
            }
            else
            {
                Network_PDP_Context_t context = {
                    .apn        ="internet",
                    .userName   = ""    ,
                    .userPasswd = ""
                };
                Network_StartActive(context);
            }
            break;
        }
        case API_EVENT_ID_NETWORK_ATTACHED:
            Trace(2,"network attach success");
            Network_PDP_Context_t context = {
                .apn        ="internet",
                .userName   = ""    ,
                .userPasswd = ""
            };
            Network_StartActive(context);
            break;

        case API_EVENT_ID_NETWORK_ACTIVATED:
            Trace(2,"network activate success");
            networkFlag = true;
            break;

        case API_EVENT_ID_GPS_UART_RECEIVED:
            // Trace(1,"received GPS data,length:%d, data:%s,flag:%d",pEvent->param1,pEvent->pParam1,flag);
            GPS_Update(pEvent->pParam1,pEvent->param1);
            break;

        case API_EVENT_ID_UART_RECEIVED:
            if(pEvent->param1 == UART1)
            {
                uint8_t data[pEvent->param2+1];
                data[pEvent->param2] = 0;
                memcpy(data,pEvent->pParam1,pEvent->param2);
                Trace(1,"uart received data,length:%d,data:%s",pEvent->param2,data);
                if(strcmp(data,"close") == 0)
                {
                    Trace(1,"close gps");
                    GPS_Close();
                    isGpsOn = false;
                }
                else if(strcmp(data,"open") == 0)
                {
                    Trace(1,"open gps");
                    GPS_Open(NULL);
                    isGpsOn = true;
                }
            }
            break;
        default:
            break;
    }
}

int Http_Post(const char* domain, int port,const char* path,uint8_t* body, uint16_t bodyLen, char* retBuffer, int bufferLen)
{
    uint8_t ip[16];
    bool flag = false;
    uint16_t recvLen = 0;

    memset(ip,0,sizeof(ip));
    if(DNS_GetHostByName2(domain,ip) != 0)
    {
        Trace(2,"get ip error");
        return -1;
    }
    // Trace(2,"get ip success:%s -> %s",domain,ip);
    char* servInetAddr = ip;
    char* temp = OS_Malloc(2048);
    if(!temp)
    {
        Trace(2,"malloc fail");
        return -1;
    }
    snprintf(temp,2048,"POST %s HTTP/1.1\r\nContent-Type: application/x-www-form-urlencoded\r\nConnection: Keep-Alive\r\nHost: %s\r\nContent-Length: %d\r\n\r\n",
                            path,domain,bodyLen);
    char* pData = temp;
    int fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(fd < 0){
        Trace(2,"socket fail");
        OS_Free(temp);
        return -1;
    }
    // Trace(2,"fd:%d",fd);

    struct sockaddr_in sockaddr;
    memset(&sockaddr,0,sizeof(sockaddr));
    sockaddr.sin_family = AF_INET;
    sockaddr.sin_port = htons(port);
    inet_pton(AF_INET,servInetAddr,&sockaddr.sin_addr);

    int ret = connect(fd, (struct sockaddr*)&sockaddr, sizeof(struct sockaddr_in));
    if(ret < 0){
        Trace(2,"socket connect fail");
        OS_Free(temp);
        close(fd);
        return -1;
    }
    // Trace(2,"socket connect success");
    Trace(2,"send request:%s",pData);
    ret = send(fd, pData, strlen(pData), 0);
    if(ret < 0){
        Trace(2,"socket send fail");
        OS_Free(temp);
        close(fd);
        return -1;
    }
    ret = send(fd, body, bodyLen, 0);
    if(ret < 0){
        Trace(2,"socket send fail");
        OS_Free(temp);
        close(fd);
        return -1;
    }
    // Trace(2,"socket send success");

    struct fd_set fds;
    struct timeval timeout={12,0};
    FD_ZERO(&fds);
    FD_SET(fd,&fds);
    while(!flag)
    {
        ret = select(fd+1,&fds,NULL,NULL,&timeout);
        // Trace(2,"select return:%d",ret);
        switch(ret)
        {
            case -1:
                Trace(2,"select error");
                flag = true;
                break;
            case 0:
                Trace(2,"select timeout");
                flag = true;
                break;
            default:
                if(FD_ISSET(fd,&fds))
                {
                    memset(retBuffer,0,bufferLen);
                    ret = recv(fd,retBuffer,bufferLen,0);
                    recvLen += ret;
                    if(ret < 0)
                    {
                        Trace(2,"recv error");
                        flag = true;
                        break;
                    }
                    else if(ret == 0)
                    {
                        Trace(2,"ret == 0");
                        break;
                    }
                    else if(ret < 1352)
                    {
                        GPS_DEBUG_I("recv len:%d,data:%s",recvLen,retBuffer);
                        close(fd);
                        OS_Free(temp);
                        return recvLen;
                    }
                }
                break;
        }
    }
    close(fd);
    OS_Free(temp);
    return -1;
}

void gps_testTask(void *pData)
{
    GPS_Info_t* gpsInfo = Gps_GetInfo();
    uint8_t buffer[600],buffer2[500];

    UART_Write(UART1,"Init now\r\n",strlen("Init now\r\n"));
    //wait for gprs register complete
    //The process of GPRS registration network may cause the power supply voltage of GPS to drop,
    //which resulting in GPS restart.
    while(!networkFlag)
    {
        Trace(1,"wait for gprs regiter complete");
        UART_Write(UART1,"wait for gprs regiter complete\r\n",strlen("wait for gprs regiter complete\r\n"));
        OS_Sleep(2000);
    }

    //open GPS hardware(UART2 open either)
    GPS_Init();

    // if(!GPS_ClearLog())
    //     Trace(1,"open file error, please check tf card");
    GPS_Open(NULL);

    //wait for gps start up, or gps will not response command
    while(gpsInfo->rmc.latitude.value == 0)
        OS_Sleep(1000);

    int inter = 5000;
    // set gps nmea output interval
    for(uint8_t i = 0;i<5;++i)
    {
        bool ret = GPS_SetOutputInterval(inter*2+1000);
        Trace(1,"set gps ret:%d",ret);
        if(ret)
            break;
        OS_Sleep(1000);
    }

    Trace(1,"init ok");
    UART_Write(UART1,"Init ok\r\n",strlen("Init ok\r\n"));

    Trace(1,"init ok");

    while(1)
    {
        if(isGpsOn)
        {

            int temp = (int)(gpsInfo->rmc.latitude.value/gpsInfo->rmc.latitude.scale/100);
            double latitude = temp+(double)(gpsInfo->rmc.latitude.value - temp*gpsInfo->rmc.latitude.scale*100)/gpsInfo->rmc.latitude.scale/60.0;
            temp = (int)(gpsInfo->rmc.longitude.value/gpsInfo->rmc.longitude.scale/100);
            double longitude = temp+(double)(gpsInfo->rmc.longitude.value - temp*gpsInfo->rmc.longitude.scale*100)/gpsInfo->rmc.longitude.scale/60.0;

            UART_Write(UART1,buffer,strlen(buffer));
            UART_Write(UART1,"\r\n\r\n",4);
            char* requestPath = buffer2;
            //uint8_t percent;
            //uint16_t v = PM_Voltage(&percent);
            //Trace(1,"power:%d %d",v,percent);
            memset(buffer,0,sizeof(buffer));
            if(!INFO_GetIMEI(buffer))
                Assert(false,"NO IMEI");
            //Trace(1,"device name:%s",buffer);
            UART_Write(UART1,buffer,strlen(buffer));
            snprintf(requestPath,sizeof(buffer2),"/gps/gpspu.php?t=%d&a=%f&o=%f", gpsInfo->gga.satellites_tracked,latitude,longitude);
            uint8_t status;
            Network_GetActiveStatus(&status);
            if(status)
            { 
                if(Http_Post(SERVER_IP,SERVER_PORT,requestPath,NULL,0,buffer,sizeof(buffer)) <0 )
                    Trace(1,"send location to server fail");
                else
                {

                Trace(1,"response:%s",buffer);

                }

            OS_Free(re);
                }

            }
            else
            {
                Trace(1,"no internet");
            }

        OS_Free(buffer);
        OS_Free(buffer2);   

        }

        PM_SetSysMinFreq(PM_SYS_FREQ_32K);
        OS_Sleep(inter);
        OS_Sleep(inter);        
        PM_SetSysMinFreq(PM_SYS_FREQ_178M);
    }
}

void gps_MainTask(void *pData)
{
    API_Event_t* event=NULL;

    TIME_SetIsAutoUpdateRtcTime(true);

    //open UART1 to print NMEA infomation
    UART_Config_t config = {
        .baudRate = UART_BAUD_RATE_115200,
        .dataBits = UART_DATA_BITS_8,
        .stopBits = UART_STOP_BITS_1,
        .parity   = UART_PARITY_NONE,
        .rxCallback = NULL,
        .useEvent   = true
    };

    UART_Init(UART1,config);

    //Create UART1 send task and location print task
    OS_CreateTask(gps_testTask,
            NULL, NULL, MAIN_TASK_STACK_SIZE, MAIN_TASK_PRIORITY, 0, 0, MAIN_TASK_NAME);

    //Wait event
    while(1)
    {
        if(OS_WaitEvent(gpsTaskHandle, (void**)&event, OS_TIME_OUT_WAIT_FOREVER))
        {
            EventDispatch(event);
            OS_Free(event->pParam1);
            OS_Free(event->pParam2);
            OS_Free(event);
        }
    }
}

void gps_tracker_Main(void)
{
    gpsTaskHandle = OS_CreateTask(gps_MainTask,
        NULL, NULL, MAIN_TASK_STACK_SIZE, MAIN_TASK_PRIORITY, 0, 0, MAIN_TASK_NAME);
    OS_SetUserMainHandle(&gpsTaskHandle);
}
KaranRajPradhan commented 3 years ago

@cityba We have noticed some issues with GPRS/GSM network disconnecting while running over longer period of time. The approach we took was to catch these network detachment/disconnect event and try to reconnect.

You can look at an example of that here

Hope this helps!

cityba commented 3 years ago

@KaranRajPradhan Then what should i modify on the me code?

KaranRajPradhan commented 3 years ago

@cityba Just add the code that captures the events as done here

And then call the appropriate reattach/reactivate function: https://github.com/IoTReady/a9_gsm_gps_library/blob/main/a9_mqtt_lib/src/mqtt_example.c#L40

cityba commented 3 years ago

@KaranRajPradhan error the build: src/demo_gps_tracker.c: In function 'AttachActivate': src/demo_gps_tracker.c:61: error: break statement not within loop or switch

...#define MAIN_TASK_NAME "GPS Test Task"

static HANDLE gpsTaskHandle = NULL; bool isGpsOn = true; bool networkFlag = false;

bool AttachActivate() { ...

KaranRajPradhan commented 3 years ago

Can you send your AttachActivate function?

cityba commented 3 years ago

@KaranRajPradhan

bool AttachActivate()
{
            uint8_t status;
            Trace(2,"network register success");
            bool ret = Network_GetAttachStatus(&status);
            if(!ret)
                Trace(1,"get attach staus fail");
            Trace(1,"attach status:%d",status);
            if(status == 0)
            {
                ret = Network_StartAttach();
                if(!ret)
                {
                    Trace(1,"network attach fail");
                }
            }
            else
            {
                Network_PDP_Context_t context = {
                    .apn        ="internet",
                    .userName   = ""    ,
                    .userPasswd = ""
                };
                Network_StartActive(context);
            }
            break;
        }
KaranRajPradhan commented 3 years ago

Please use this:

bool AttachActivate()
{
    uint8_t status;
    bool ret = Network_GetAttachStatus(&status);
    if(!ret)
    {
        Trace(2,"get attach status fail");
        return false;
    }
    Trace(2,"attach status:%d",status);
    if(!status)
    {
        ret = Network_StartAttach();
        if(!ret)
        {
            Trace(2,"network attach fail");
            return false;
        }
    }
    else
    {
        ret = Network_GetActiveStatus(&status);
        if(!ret)
        {
            Trace(2,"get activate status fail");
            return false;
        }
        Trace(2,"activate status:%d",status);
        if(!status)
        {
            Network_PDP_Context_t context = {
                    .apn        ="internet",
                    .userName   = ""    ,
                    .userPasswd = ""
                };
            Network_StartActive(context);
        }
    }
    return true;
}
cityba commented 3 years ago

@KaranRajPradhan I did not notice the difference, thank you, head to the test . I will apply tomorrow to see if it worked.

cityba commented 3 years ago

@KaranRajPradhan unfortunately it stops in exactly 24 hours.

`void EventDispatch(API_Event_t* pEvent) {

switch(pEvent->id)
{
    case API_EVENT_ID_NO_SIMCARD:
        Trace(10,"!!NO SIM CARD%d!!!!",pEvent->param1);
        networkFlag = false;
        break;

    case API_EVENT_ID_NETWORK_REGISTER_SEARCHING:
        Trace(2,"network register searching");
        networkFlag = false;
        break;

    //case API_EVENT_ID_NETWORK_REGISTER_DENIED:
     //   Trace(2,"network register denied");
    case API_EVENT_ID_NETWORK_REGISTER_NO:
        Trace(2,"network register no");
        break; 

    case API_EVENT_ID_NETWORK_REGISTERED_HOME:
    case API_EVENT_ID_NETWORK_REGISTERED_ROAMING:
        AttachActivate();
        break;

    case API_EVENT_ID_NETWORK_ATTACHED:
        Trace(2,"network attach success");
        AttachActivate();
        break;

    case API_EVENT_ID_NETWORK_REGISTER_DENIED:
        Trace(1,"network register denied");
        AttachActivate();
        break; 

    case API_EVENT_ID_NETWORK_DETACHED:
        Trace(1,"network detached");            
        AttachActivate();
        break;

    case API_EVENT_ID_NETWORK_ATTACH_FAILED:
        Trace(1,"network attach failed");            
        AttachActivate();
        break;

    case API_EVENT_ID_NETWORK_DEACTIVED:
        Trace(1,"network deactived");            
        AttachActivate();
        break;

    case API_EVENT_ID_NETWORK_ACTIVATE_FAILED:
        Trace(1,"network activate failed");            
        AttachActivate();
        break;      

    case API_EVENT_ID_NETWORK_ACTIVATED:
        Trace(2,"network activate success");
        networkFlag = true;
        break;

    case API_EVENT_ID_GPS_UART_RECEIVED:
        // Trace(1,"received GPS data,length:%d, data:%s,flag:%d",pEvent->param1,pEvent->pParam1,flag);
        GPS_Update(pEvent->pParam1,pEvent->param1);
        break;

    case API_EVENT_ID_UART_RECEIVED:
        if(pEvent->param1 == UART1)
        {
            uint8_t data[pEvent->param2+1];
            data[pEvent->param2] = 0;
            memcpy(data,pEvent->pParam1,pEvent->param2);
            Trace(1,"uart received data,length:%d,data:%s",pEvent->param2,data);
            if(strcmp(data,"close") == 0)
            {
                Trace(1,"close gps");
                GPS_Close();
                isGpsOn = false;
            }
            else if(strcmp(data,"open") == 0)
            {
                Trace(1,"open gps");
                GPS_Open(NULL);
                isGpsOn = true;
            }
        }
        break;

    default:
        break;
}

}...`

cityba commented 3 years ago

@KaranRajPradhan How can I restart every 24 hours? with what code?

cityba commented 3 years ago

@KaranRajPradhan if the gsm signal is interrupted it cannot reconnect to it network. i took out the sim card a bit, imitating the network break.

`AT 01 : old pdp context, no change

   : Fn 0609074 T1 0459 T2 24 T3 32 Time 00 03 20 682

AT 11 : Memory OS_Free p: 0, cos:0p8212b330-0p82257330, csw:0p820d3b18-0p8212b318

AT 11 : Memory OS_Free p: 0, ret:0

AT 11 : Memory OS_Free p: 0, cos:0p8212b330-0p82257330, csw:0p820d3b18-0p8212b318

AT 11 : Memory OS_Free p: 0, ret:0

AT 11 : Memory OS_Free p:0p8212d338, cos:0p8212b330-0p82257330, csw:0p820d3b18-0p8212b318

AT 11 : Memory OS_Free p:0p8212d338, ret:1

MMI 01 : gsm network deactived

AT 01 : attach status:1

MMI 02 : gsm Aattach status:1

AT 01 : get act state:0

MMI 02 : gsm Aactivate status:0

MMI 02 : gsm APDP:0

AT 01 : old pdp context, no change `