⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dialsrv.c

📁 ARM_CORTEX-M3应用实例开发详解光盘
💻 C
字号:
#include <ucos_ii.h>
#include <stdio.h>
#include <string.h>
#include "uart_std.h"
#include "uart2.h"
#include "ppp.h"
#include "cdrs_op.h"

OS_STK Sys_TaskDialSrvStk[SYS_TASK_DIAL_SRV_STK_SIZE];

#define AT_CMD_DEBUG    1

#define CDMA    0

#define GPRS    (!CDMA)

struct at_cmd_t {
    char *cmd;
    char *res;
    int  sec;
};
#if GPRS
struct at_cmd_t atcmds[] = 
{   
    {"AT\r\n",                              "OK",       3},
    {"ATE0\r\n",                            "OK",       3},
    {"AT+CGDCONT=1,\"IP\",\"cmnet\"\r\n",   "OK",       5},
    {"AT+CGACT=1,1\r\n",	                "OK",		5},
    {"ATDT*99***1#\r\n",                    "CONNECT",  5},
};
#else
struct at_cmd_t atcmds[] = 
{   
    {"AT\r\n",                  "OK",       3},
    {"ATE0\r\n",                "OK",       3},
    {"AT\r\n",                  "OK",       3},
    {"ATDT#777 CONNECT\r\n",    "CONNECT",  5},

   // {"AT\r\n",                "OK",       3},
  //  {NULL, NULL, 0},
};
#endif

int at_cmd_send(char *cmd)
{
#if  AT_CMD_DEBUG 
	char* s;

	// printf("\r\nDEBUG : AT CMD SEND [%s]", cmd);
	printf("\r\nDEBUG : AT CMD SEND [");
	s = cmd;
    	while (*s != 0) {
		if (*s == 0x0D) {
			printf("\\r");
		} else if (*s == 0x0A) {
			printf("\\n");
		} else {
			printf("%c", *s);
		}
		++s;
	}
	printf("]");
#endif
    uart2_flush();
    while (*cmd)
        uart2_send_ch(*cmd++);
    return 0;    
}
char * mystrstr(const char *str1, const char *str2)
{
    int i, j;

    if (str1 == NULL || str2 == NULL)
        return NULL;
    for (i=0; str1[i]; i++) {
        for (j=0; str2[j]; j++) {
            if (str1[i+j] != str2[j])
                break;
        }
        if (str2[j] == '\0')
            return (char *)&str1[i];
    }
    return NULL;
}
int at_cmd_resp(char *res, int sec)
{
    char tmp[80], *flg = NULL;
    int ch, i = 0;
#if  AT_CMD_DEBUG 
    printf("\r\nDEBUG : AT CMD RECV [");
#endif
    sec *= 1000;
    do {
        ch = uart2_peek_key();
        if (ch == EOF) {
            OSTimeDlyHMSM(0, 0, 0, 100);
            sec -= 100;
        } else {
#if  AT_CMD_DEBUG
		if (ch == 0x0D) {
			printf("\\r");
		} else if (ch == 0x0A) {
			printf("\\n");
		} else {
			printf("%c", ch);
		}
#endif
            tmp[i++] = ch;   
            tmp[i] = 0;
            flg = mystrstr(tmp, res);
        }
    } while (sec > 0 && flg == NULL);
#if  AT_CMD_DEBUG 
    if (flg == NULL) {
        printf("]\r\nDEBUG : Time Out!\r\n");
    } else {
        printf("]\r\nDEBUG : Cmd OK!\r\n");
    }
#endif
    return flg == NULL ? -1 : 0;
}

int dial(void)
{
    int cnt = sizeof atcmds / sizeof atcmds[0];
    int i, ret;

    for (i=0; i<cnt; i++) {
        at_cmd_send(atcmds[i].cmd);
        ret = at_cmd_resp(atcmds[i].res, atcmds[i].sec);
        OSTimeDlyHMSM(0, 0, 2, 0);
        if (ret < 0)
            return ret;
    }
    return 0;          
}

static char *strip(unsigned int ip)
{
    static char buf[20];
    sprintf(buf, "%u.%u.%u.%u", 
        (ip>>24)&0xff, (ip>>16)&0xff,
        (ip>>8)&0xff, (ip)&0xff);
    return buf;
}
#define PPPDEBUG(x...) printf(##x)
void vBasicWEBServer(void *pvParameters);

__packed typedef struct _ihdr { 
    unsigned char i_type; 
    unsigned char i_code; /* type sub code */ 
    unsigned short i_cksum; 
    unsigned int i_id; 
//    unsigned int i_seq; 
/* This is not the std header, but we reserve space for time */ 
//    unsigned int timestamp; 
}IcmpPkg;

/* The IP header */ 
typedef __packed struct iphdr { 
unsigned int h_len:4; // length of the header 
unsigned int version:4; // Version of IP 
unsigned char tos; // Type of service 
unsigned short total_len; // total length of the packet 
unsigned short ident; // unique identifier 
unsigned short frag_and_flags; // flags 
unsigned char ttl; 
unsigned char proto; // protocol (TCP, UDP etc) 
unsigned short checksum; // IP checksum 

unsigned int sourceIP; 
unsigned int destIP; 

}IpHeader; 
 
#define ICMP_ECHO       8 
#define ICMP_ECHOREPLY  0 
#define ICMP_MIN        8 // minimum 8 byte icmp packet (just header) 

#define IPPROTO_ICMP    1

#define RECV_BFLEN      64

//#define PULSE_HOUR      0
//#define PULSE_MIN       1
#define PULSE_SEC       120   //90 S

#define MAXLINKCNT      3

unsigned short I_checksum(__packed unsigned short *buffer, int size) { 

    unsigned long cksum=0; 

    while(size >1) { 
    cksum+=*buffer++; 
    size -=sizeof(unsigned short); 
    } 
    
    if(size ) { 
    cksum += *(unsigned char*)buffer; 
    } 
    
    cksum = (cksum >> 16) + (cksum & 0xffff); 
    cksum += (cksum >>16); 
    return (unsigned short)(~cksum); 
} 

static IcmpPkg icmp_dat;

static char pRecv[RECV_BFLEN];

unsigned int MakeIcmpDat(void)
{
    static unsigned int seq = 0;

    IcmpPkg *icmp_hdr = &icmp_dat;

    ++seq;

    icmp_hdr->i_type = ICMP_ECHO; 
    icmp_hdr->i_code = 0; 
    icmp_hdr->i_id = seq; 
    icmp_hdr->i_cksum = 0; 
//    icmp_hdr->i_seq = seq;

//    ((IcmpHeader*)icmp_data)->i_cks
//    icmp_hdr->timestamp = 0;     
//    ((IcmpHeader*)icmp_data)->i_seq = seq_no++; 

    icmp_hdr->i_cksum = I_checksum((unsigned short *)icmp_hdr, 
        sizeof icmp_dat);

    return seq;
    
}

static int LinkState = -2;
int GetLinkState(void)
{
    return LinkState;
}

static int Send_Pulse(int sock, u32_t ip)
{

    struct sockaddr_in saddr, raddr;

    unsigned int id;
    u32_t alen = sizeof raddr;//, timo = 3000;
    int ret;

    saddr.sin_family = AF_INET;
//    IP4_ADDR(&addr, 121, 14, 89, 14);
    saddr.sin_addr.s_addr = ip;

    printf("\r\n Send Pulse ...");
    memset(&icmp_dat, 0, sizeof icmp_dat);
    id = MakeIcmpDat();

    do { //清缓冲
        ret = recvfrom(sock, pRecv,  RECV_BFLEN, 0, (struct sockaddr *)&raddr, &alen);
    } while (ret>0);
    ret = sendto(sock, &icmp_dat, sizeof icmp_dat, 0, (struct sockaddr *)&saddr, sizeof saddr);
    if (0 > ret) {
        printf("\r\nErr : Sendto");  
        return -1;
    }
    ret = recvfrom(sock, pRecv,  RECV_BFLEN, 0, (struct sockaddr *)&raddr, &alen);
    if (0 > ret) {
        printf("\r\nErr : Recvfrom");
        return -1;
    }
{
    unsigned int iphdrlen;    
    IpHeader __packed *iphdr = (IpHeader *)pRecv;
    IcmpPkg __packed *icmphdr;

    iphdrlen = iphdr->h_len * 4 ;
    if (ret < iphdrlen + ICMP_MIN)
        printf("\r\nErr : ICMP data");

    icmphdr = (IcmpPkg*)(pRecv + iphdrlen); 

    if (icmphdr->i_type != ICMP_ECHOREPLY) { 
        printf("\r\nnon-echo type %d recvd",icmphdr->i_type); 
         
    } 
    if (icmphdr->i_id != id) { 
        printf("\r\nsomeone else's packet!"); 
    } 

} 
    return 0;
}


void Dial_Srv(void *parg)
{
    int pd;

    LinkState = -1;
    if(dial() < 0) {
        LinkState = -2;
        printf("\r\nErr : Dial.");
        return;
    }

#if GPRS    
    pppSetAuth(PPPAUTHTYPE_ANY, "", "");
#else
    pppSetAuth(PPPAUTHTYPE_ANY, "card", "card");
#endif
    pd = pppOpen(0, NULL, NULL);
    if (pd < 0) {
        LinkState = -2;
        printf("\r\nErr : ppp open.");

        return;
    }

    LinkState = 0;

    PPPDEBUG("\r\nOpen PPP Successed!");
    
    {
        struct ppp_addrs *paddr;
        u32_t ip;
        int sock;
     
        unsigned int timo = 3000;
        int ret;
        int exit = 0;
        int i;  

        /* 获得ip地址信息 */

        pppIOCtl(pd, PPPCTLG_PPPADDR, &paddr);
        PPPDEBUG("\r\nOur IP : %s", strip(htonl(paddr->our_ipaddr.addr)));
        PPPDEBUG("\r\nISP IP : %s", strip(htonl(paddr->his_ipaddr.addr)));
    
        ip = paddr->his_ipaddr.addr;
       
        sock = socket(NULL, SOCK_RAW, IPPROTO_ICMP/*IPPROTO_IP*/);
        
        setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timo, 4);
        
        /* 发送心跳包 */ 
        for (; LinkState<MAXLINKCNT && exit == 0; ) {
           for (i=0; i<PULSE_SEC && exit == 0; i++){
                OSTimeDlyHMSM(0, 0, 1, 0);
                if (OSTaskDelReq(OS_PRIO_SELF) == OS_TASK_DEL_REQ)
                    exit = 1;
            }
            printf("\r\n LinkState %d", LinkState);
            ret = Send_Pulse(sock, ip);
            if (ret < 0)
                 LinkState++;
            else
                LinkState = 0; //链路完好
   
        } 

        LinkState = - 1;

        close(sock);
    }
    
    pppClose(pd);

    LinkState = - 2;

    printf("\r\npppClosed ");
   
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -