2022年7月24日 星期日

AT command and PLS83

read: cat /dev/ttyACM0
write: echo "ACT" > /dev/ttyACM0
read line: get_next_line.git


main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h> 

#include <limits.h>
#include "get_next_line.h"
#include "utool.h"

#define TEST_THERMAL 1

#if TEST_THERMAL
const char *Thermal_atc[] = 
{   
    "at\r",
    "ati1\r",
    "at+csq\r",
    "at^sctm=1,1\r",
    "at^sctm?\r"
};
#else //connect to Internet
const char *QMI_atc[] = 
{   
    "at\r",
    "at+cpin?\r",
    "at+cops?\r",
};
const char *ECM_atc[] = 
{   
    "at\r",
    "at+cpin?\r",
    "at+cops?\r",
    "AT+CGPADDR=?\r,"
    "AT+CGPADDR\r",
    "AT+CGPADDR=1,1\r",
    "AT^SWWAN=?\r",
    "AT^SWWAN?\r",
    "AT^SWWAN=1,1,1\r",
};

//QMI, PID=006F
const char *QMIMODE[] =
{
    "at^ssrvset=\"actSrvset\",11\r",
    "at+cfun=1,1"
};

//ECM, PID=0069
const char *ECMMODE[] =
{
    "at^ssrvset=\"actSrvset\",1\r",
    "at+cfun=1,1"
};

#endif

int STOP_PROCESS=0;

void *test_cat(void *fd_)
{
    #ifdef TEST_THERMAL
    #else
    char *err="";
    #endif
    int fd= *((int *)fd_);
    int ret=0;
    char *line;

    while ((ret = get_next_line(fd, &line)) == STATUS_LINE)
    {
        printf("output=%s\n", line);
        #ifdef TEST_THERMAL
        #else
        err=strstr(line, "ERR");
        if ( err != NULL)
        {
            STOP_PROCESS=1;
            printf(cRED "err=%s\n" cRESET, err);
            pthread_exit(NULL);
        }
        err=strstr(line, "SHUTDOWN");
        if ( err != NULL)
        {
            STOP_PROCESS=1;
            printf(cRED "err=%s\n" cRESET, err);
            pthread_exit(NULL);
        }
        #endif
        free(line);
    }

    if (ret == -1)
        printf("error\n");
    else if (ret == 0)
    {
        printf("at EOF: [%s]\n", line);
        free(line);
        printf("EOF\n");
    }
    printf("thread done\n");

    return NULL;
}

int todoECM(void)
{
    ssize_t size=128;
    char *file_path=(char *)malloc(sizeof(char)*size);
    char *wwan_path=(char *)malloc(sizeof(char)*size);
    char *wwan;
    char *cmd=(char *)malloc(sizeof(char)*size);

    int fd;
    DIR *d;
    struct dirent *dir;
    char *line;
    int ret=0;
    char *sret;
    ssize_t slen=0;


    d = opendir("/sys/class/net");
    if (d) 
    {
        while ((dir = readdir(d)) != NULL) 
        {
            printf("%s\n", dir->d_name);
            if (strlen (dir->d_name) <= 2)
                continue;
            sprintf(file_path, "/sys/class/net/%s/uevent", dir->d_name);
            printf("file_path=%s\n", file_path);
            fd=open(file_path, O_RDONLY);
            while ((ret = get_next_line(fd, &line)) == STATUS_LINE)
            {
                printf("line=%s\n", line);
                sret=strstr(line, "wwan");
                slen =( sret == NULL ? 0 : strlen(sret));
                if (slen > 0)
                    break;
            }
            if (slen > 0)
                if (get_next_line(fd, &line) == STATUS_LINE)
                {
                    printf("line2=%s\n", line);
                    break;
                }
        }
        closedir(d);
    }

    wwan=strtok(line, "=");
    wwan=strtok(NULL, "=");
    printf("wwan=%s\n", wwan);

    sprintf(cmd, "sudo ifconfig %s up", wwan);
    printf("cmd=%s\n", cmd);
    system(cmd);
    memset(cmd, '\0', sizeof(char));
    
    sprintf(cmd, "sudo dhclient %s", wwan);
    printf("cmd=%s\n", cmd);
    system(cmd);
    memset(cmd, '\0', sizeof(char));
    
    free(cmd);
    free(wwan_path);

    return 0;
}

int todoQMI(void)
{
    int i=0;
    ssize_t size=128;
    char *cdcwdm_path =(char *)malloc(sizeof(char)*size);
    char *wwan_path=(char *)malloc(sizeof(char)*size);
    char wwan[8];
    char *cmd=(char *)malloc(sizeof(char)*size);

    for (i=0; i<9; i++) // Suppose cdc-wdm ranges from 0 to 9
    {
        memset(cdcwdm_path, '\0', sizeof(char)*size);
        sprintf(cdcwdm_path, "/dev/cdc-wdm%d", i);
        if ( access(cdcwdm_path, F_OK) == 0 )  //file exists
            break;
    }
    sprintf(cmd, "sudo qmicli -d %s -p --dms-get-operating-mode", cdcwdm_path);
    printf("cmd=%s\n", cmd);
    system(cmd);
    memset(cmd, '\0', sizeof(char)*size);
    sprintf(cmd, "sudo qmicli -d %s -p --get-wwan-iface", cdcwdm_path);
    printf("cmd=%s\n", cmd);
    system(cmd);
    memset(cmd, '\0', sizeof(char));
    
    for (i=0; i<9; i++) // Suppose cdc-wdm ranges from 0 to 9
    {
        memset(wwan_path, '\0', sizeof(char)*size);
        sprintf(wwan_path, "/sys/class/net/wwan%d", i);
        if ( access(wwan_path, F_OK) == 0 )  //file exists
        {
            sprintf(wwan, "wwan%d", i);
            break;
        }
    }
    sprintf(cmd, "sudo ip link set %s down", wwan);
    printf("cmd=%s\n", cmd);
    system(cmd);
    memset(cmd, '\0', sizeof(char));
    
    sprintf(cmd, "echo \'Y\' | sudo tee /sys/class/net/%s/qmi/raw_ip", wwan);
    printf("cmd=%s\n", cmd);
    system(cmd);
    memset(cmd, '\0', sizeof(char));
    
    sprintf(cmd, "udo ip link set %s up", wwan);
    printf("cmd=%s\n", cmd);
    system(cmd);
    memset(cmd, '\0', sizeof(char));

    sprintf(cmd, "sudo qmicli -p -d %s -p --wds-start-network=\"apn='Internet',ip-type=4\" --client-no-release-cid", cdcwdm_path);
    printf("cmd=%s\n", cmd);
    system(cmd);
    memset(cmd, '\0', sizeof(char));

    sprintf(cmd, "sudo udhcpc -i %s", wwan);
    printf("cmd=%s\n", cmd);
    system(cmd);
    memset(cmd, '\0', sizeof(char));
    
    free(cmd);
    free(wwan_path);
    free(cdcwdm_path);
    return 0;
}

int main (void)
{

    pthread_t thread1;
    char *getMode=(char *)malloc(sizeof(char)*32);
    void *ret;

    int fd=-1;
    int i=0;
    ssize_t count=0;
    int sleep_time=0;
    const char **MODE_atc;
    int (*todoMode)(void)=NULL;

    fd=open("/dev/ttyACM0", O_RDWR);
    if (fd < 0)
    {
        printf("cant' find the ACM0\n");
    }
    
    isPID69or6f(&getMode);

    printf("get_mode=%s\n", getMode);

    pthread_create(&thread1, NULL, test_cat, (void *)&fd);

#if TEST_THERMAL
    //count=sizeof(Thermal_atc)/sizeof(Thermal_atc[0]);
    count=NUM_ELEMS(Thermal_atc);
    printf("count=%ld\n", count);
    sleep_time = 500*2;
    for (i=0 ; STOP_PROCESS == 0; i++)
    {
        if (i == count)
            i=0;
        //printf(cGREEN "start the process...atc=%s\n" cRESET, Thermal_atc[i]);
        //write(fd, Thermal_atc[i], strlen(Thermal_atc[i]));
        MODE_atc=Thermal_atc;
#else
    if (!strcmp("QMI", getMode))
    {
        //QMI to do
        //count=sizeof(QMI_atc)/sizeof(QMI_atc[0]);
        count=NUM_ELEMS(QMI_atc[0]);
        printf("count=%ld\n", count);
        MODE_atc=QMI_atc;
        todoMode=todoQMI;
    }
    else
    {
        //ECM to do
        //count=sizeof(ECM_atc)/sizeof(ECM_atc[0]);
        count=NUM_ELEMS(ECM_atc);
        printf("count=%ld\n", count);
        MODE_atc=ECM_atc;
        todoMode=todoECM;
    }
    sleep_time = 500;
    for (i=0; i < count && STOP_PROCESS == 0; i++)
    {   
#endif
        printf(cGREEN "start the process...%s, atc=%s\n" cRESET, getMode, MODE_atc[i]);
        write(fd, MODE_atc[i], strlen(MODE_atc[i]));
        msleep(sleep_time);
    }
    todoMode();
    if (i == count)
    {
        printf("iiii=%d, count=%ld\n", i, count);
        pthread_cancel(thread1);
        close(fd);
    }

    pthread_join( thread1, (void *)(&ret));
    

    printf("main done\n");

    free(getMode);

    return 0;
}

utool.c
#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <dirent.h> 
#include <signal.h>
#include <errno.h>
#include <time.h>
#include "utool.h"


void msleep(unsigned long msec) {
    struct timespec ts;
    int err;

    ts.tv_sec = (msec / 1000);
    ts.tv_nsec = (msec % 1000) * 1000 * 1000;

    do {
        err = nanosleep (&ts, &ts);
    } while (err < 0 && errno == EINTR);
}

//缺點:USB沒有拔掉的話,路徑好像不會被移除
int isPID69or6f(char **mode)
{
    const char *QMIpath="/sys/bus/usb/drivers/qmi_wwan";
    const char *ECMpath="/sys/bus/usb/drivers/cdc_acm"; //or cdc_ether

    if ( access(QMIpath, F_OK) == 0 )  //file exists
    {
	strcpy( *mode, "QMI");
        printf(cRED "QMI mode\n" cRESET);
    }
    else if ( access(ECMpath, F_OK) == 0 )
    {
	strcpy( *mode, "ECM");
        printf(cRED "ECM mode\n" cRESET);
    }

    return 0;
}

utool.h
#include <pthread.h>

#define cRED "\x1b[;31;1m"
#define cGREEN "\x1b[;32;1m"
#define cRESET "\x1b[0;m"

#define NUM_ELEMS(a)        (sizeof(a) / sizeof(a[0]))

int isPID69or6f(char **mode);
void msleep(unsigned long msec);
int executeSystemCmd(const char *cmd, char **response, int timeout);

沒有留言:

張貼留言