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

📄 main.c

📁 GPRS模块通过PPP方式实现TCPIP全过程
💻 C
字号:
/****************************************************************************
*main.c
****************************************************************************/
#ifndef MAIN_C
#define MAIN_C

#include  "config.h"
////#include "IAP.h"
////#include "ffs.h"
#include "uart.h"
#include "timer.h"
#include "main.h"

#include "udp.h"
#include "tcp.h"
#include "ip_addr.h"
#include "err.h"


#define SERVER_IP   0x5250ad3d
//#define SERVER_IP   0x1A01CECA  /*telnet:bbs.hbu.edu.cn*/
//#define SERVER_IP     0xEE086FA6
#define SERVER_PORT   23


#define GPRS_NUM  "ATD*99***1#\r"
#define MAX_GPRS_DIAL_TIMES  3
#define GPRS_DIAL_TIMEOUT  60

#define MAX_MODEM_OPEN_TIME 3

#define PARSE_STOP     ','
#define STRING_START    '"'
#define STRING_END         '"'
#define CR           '\r'
#define LF           '\n'

#define AT_PARSE_FAIL        0
#define AT_PARSE_SUCCESS   0
#define AT_SEND_OK     0
#define AT_SEND_FAIL  -1


typedef enum
{
    PPP_DEAD = 0,
    PPP_ESTABLISHED,
    UDP_ESTABLISHED,
    TCP_CONNECTING,
    TCP_ESTABLISHED,
    TCP_CLOSING,
    
    TCPIP_STATE_UNKNOWN, /*ppp expected unknown err, such as no response from Modem ,we must reset System*/
}MY_TCPIP_STATE;



typedef enum
{
   SYS_ERR_OK = 0,
   SYS_ERR_AT_FAIL,
   SYS_ERR_FAIL_OTHERS
}sys_err;

typedef struct
{
    char *command; /*the AT Command we send to Modem*/
    char *result;       /*the result we expected*/
    u8_t timeout;      /*MAX time of second that we could waiting*/
    u8_t r_time;       /*MAX times that we could re_send to Modem*/
}basic_AT;

const basic_AT basic_at[] = 
{
     { "ATE0\r",                                                  "OK\r\n",   3,   3 },
     { "AT+CGDCONT=1,\"IP\",\"CMNET\"\r",     "OK\r\n",   3,   3 },
     {  "AT+CNMI=2\r",                                     "OK\r\n",   3,   3},
     { "AT+CLIP=1\r",                                      "OK\r\n",    3,   3},
     {"AT+CSMP=53,167,,0\r",                          "OK\r\n",   3,   3},
	  
     { NULL, NULL, 0, 0},
};

extern void pppInProc(int pd, u_char *s, int l);
extern void pppInit(void);
extern int pppOpen(void *fd, void (*linkStatusCB)(void *ctx, int errCode, void *arg), void *linkStatusCtx);
extern BOOL  ppp_dead(int pd);
/*
*local function
*/
sys_err wait_atReturn(CHAR *str, u8_t second);
void lwip_init(void);
void pppStateCallback(void *ctx, int errCode, void *arg);
void local_sys_init(void);
void second_sleep(u32_t s);
sys_err open_Modem(void);
sys_err active_Modem(void);
void powerOff_Modem(void);
void shut_system(void);
sys_err init_Modem(void);
sys_err dial_GPRS(void);
void tcpip_open(void);

MY_TCPIP_STATE my_tcpip_state = PPP_DEAD;
int my_sys_err = 0;

/*
*return the state of my tcpip
*/
MY_TCPIP_STATE get_Mytcpip_state(void)
{
      return my_tcpip_state;
}

/*
*set the state of my tcpip
*/
void set_Mytcpip_state(MY_TCPIP_STATE state)
{
    my_tcpip_state = state;
}


void add_sys_err(void)
{
    my_sys_err++;
}

void clear_sys_err(void)
{
   my_sys_err = 0;
}

int get_sys_err(void)
{
    return my_sys_err;
}
/*********************************
function: wait_atReturn

input:          str:   the string for wait
                  second:  max second to wait
*********************************/
sys_err wait_atReturn(CHAR *str, u8_t second)
{

	 CHAR *tmp_str = str;
	 u32_t time = get_sys_tick();
	 u8_t ch;
	 	 
        while((get_sys_tick() - time) < second)
        {
	     if(GET_AT(&ch) EQ DATA_READ_OK)
	     {				
             /*waiting for the string that we expected*/
		  if(*tmp_str  EQ ch)
	         {
                      tmp_str++;
					  
			if(*tmp_str  EQ '\0')
	              {				
			    return SYS_ERR_OK;
	              }
	         }		 
	         else
		  {	  
			 tmp_str = str;
		   }					  
	     }	 
     }
		
   return SYS_ERR_AT_FAIL;
}


void pppStateCallback(void *ctx, int errCode, void *arg)
{
    DEBUG_FUNCTION("pppStateCallback()");

    if(errCode EQ 0)
    {
          set_Mytcpip_state(PPP_ESTABLISHED);
    }
  
    return;
}


extern void pbuf_init(void);
extern void mem_init(void);
extern void  memp_init(void);
extern void netif_init(void);
extern void ip_init(void);
extern void tcp_init(void);
extern void udp_init(void);
/*
* initialize lwip basic function
*/
void lwip_init(void)
{
      /*
      *init memory
      */
      pbuf_init();
      mem_init();
      memp_init();

     /*
     *init tcpip stack
     */
     pppInit();
     netif_init();
     ip_init(); 
     tcp_init();
     udp_init();  
}

#define	  LEDCON	0x00003c00
/*
*local system init
*/
void local_sys_init(void)
{
    //  PINSEL0 = 0x00000000;		// 设置所有管脚连接GPIO
    //  PINSEL1 = 0x00000000;
   //   IODIR = LEDCON;

     set_Mytcpip_state(PPP_DEAD);
     my_sys_err = 0;
   
    UART0_Ini();
    UART1_Ini();
}

/*
*block system for x seconds
*/

void second_sleep(u32_t s)
{
    u32_t time = get_sys_tick();

    while((get_sys_tick() - time) < s);
}

/*block system for x ms*/
void ms_sleep(u32_t ms)
{
    u32_t time = sys_jiffies();

    while(( sys_jiffies() - time) < ms);
}

/*
* send AT to GPRS Modem, test if Modem is ready
*/
sys_err open_Modem(void)
{
       SEND_AT("AT\r");
	return (wait_atReturn("OK\r\n",3));
}

/*
* active GPRS Modem
*/
sys_err active_Modem(void)
{
     int i;
	
     DEBUG_FUNCTION("active_Modem()");
	  
      //add your code here for triging GPRS Modem
      DEBUG_EVENT("System block  5 seconds!");
      second_sleep(5);

     for(i = 0; i < MAX_MODEM_OPEN_TIME; i++)
     {
          if(open_Modem() EQ SYS_ERR_OK)
		  	return SYS_ERR_OK;
     }
     
	 return SYS_ERR_FAIL_OTHERS;
}

/*
*power off GPRS Modem
*/
void powerOff_Modem(void)
{
   DEBUG_FUNCTION("powerOff_Modem()");
    //add your code  here
    return;
}
/*
*some seriours error happend
*we power off Modem,then reset System
*/
void shut_system(void)
{
   DEBUG_FUNCTION("shut_system()");
  
   powerOff_Modem();

    //waiting for Watch Dog 
    while(1);
}

/*
*send some AT Commands to Modem ,
*initlization some parametes , such as the unexpected 
*result code of SMS, Incoming Call, GPRS Paramets etc.
*/
sys_err init_Modem(void)
{
    const basic_AT* con = &(basic_at[0]);
    u8_t r_time;

    DEBUG_FUNCTION("init_Modem()");

    while(con->command  NEQ NULL)
    {
         for(r_time = 0; r_time < con->r_time; r_time++)
         {
              SEND_AT(con->command);
			  
	       DEBUG_EVENT(con->command);
		   
	       if(wait_atReturn(con->result, con->timeout) EQ SYS_ERR_OK)
	       {
		     break;
	       }
         }

	 /*
	 *one AT Commands send fail
	 */
	 if(r_time  EQ con->r_time)
	 {
           DEBUG_EVENT("one at commands init fail!");
	    return SYS_ERR_AT_FAIL;
	 }

	 con++;
    }

    return SYS_ERR_OK;
}

/*
*dial GPRS, if successful, we start LCP Config
*/
sys_err dial_GPRS(void)
{
    int i;

    for(i = 0; i < MAX_GPRS_DIAL_TIMES; i++)
    {
        SEND_AT(GPRS_NUM);
	 if(wait_atReturn("CONNECT\r\n", GPRS_DIAL_TIMEOUT) EQ SYS_ERR_OK)
	 	return SYS_ERR_OK;
	 open_Modem();
    }

   return SYS_ERR_FAIL_OTHERS;
}

/*
*receive some UDP data
*/
void udp_data_ind(u8_t *buf, u16_t len)
{
        u16_t i = 0;
		
	 DEBUG_FUNCTION("udp_data_ind()")

	 for(i = 0; i < len; i++)
	 {
	     sendByte_2_user((u8_t)buf[i]);
	 }    
}

/*
*receive some TCP data
*/
void tcp_data_ind(u8_t *buf, u16_t len)
{
        u16_t i = 0;
		
	 DEBUG_FUNCTION("tcp_data_ind()")

	 for(i = 0; i < len; i++)
	 {
	     sendByte_2_user((u8_t)buf[i]);
	 }    
}

/*
*ipcp is up, now we start open a TCP/UDP Connect
*/
void tcpip_open(void)
{
       CONNECT_TYPE  conn_type = UDP_CONNECT_DEFAULT;
	struct ip_addr  remote_ip;
	struct udp_pcb * udp;
	struct tcp_pcb * tcp;
	s8_t   err;
	   
	DEBUG_FUNCTION("tcpip_open()")

	remote_ip.addr = SERVER_IP;

	if(conn_type EQ UDP_CONNECT_DEFAULT)
	{
		/*
		*new a udp pcb
		*/
	     if((udp = udp_new()) EQ NULL)
	     {
	          DEBUG_EVENT("udp_new, but return NULL, system unexpected err!")
		   set_Mytcpip_state(TCPIP_STATE_UNKNOWN);
		   return;
	     }

          /*
          *write remote IP and server to udp pcb
          */
	   if(udp_connect(udp, &(remote_ip), SERVER_PORT) NEQ ERR_OK)
	    {
	          DEBUG_EVENT("udp_connect, but return ERR, system unexpected err!")
		   set_Mytcpip_state(TCPIP_STATE_UNKNOWN);
		   return;
	    }
	   set_Mytcpip_state(UDP_ESTABLISHED);
	}
	else
	{
              /*
		*new a tcp pcb
		*/
	     if((tcp = tcp_new()) EQ NULL)
	     {
	          DEBUG_EVENT("udp_new, but return NULL, system unexpected err!")
		   set_Mytcpip_state(TCPIP_STATE_UNKNOWN);
		   return;
	     }

	     if(tcp_connect(tcp, &(remote_ip), SERVER_PORT, NULL) NEQ ERR_OK)
	     {
	          DEBUG_EVENT("tcp_connect, but return ERR, system unexpected err!")
		   set_Mytcpip_state(TCPIP_STATE_UNKNOWN);
		   return;
	     }
	   set_Mytcpip_state(TCP_CONNECTING);		 	
	}
}

/*
*if you want to check the state of socket periodly
*this func should be called
*but the counte should be changed
*/

#if TCPIP_KEEPALIVE
int tcpip_keepalive_err = 0;

void tcpip_keepalive(void)
{
     /*
     *add you code here.
     *你可以定义一个函数,增加到
     * 定时器函数sys_timer_start(),每隔MAX_KEEPALIVE_PERIOD
     *周期调用一次,如果等待MAX_SERVER_WATI_TIME
     *没有返回的话tcpip_keepalive_err++.
     *if(tcpip_keepalive_err >= MAX_KEEPALIVE_ERR_ALLOW)
     *close TCP connect.  重新连接(对于UDP要shut PPP, Dial ppp again).
     *如果TCP仍然连接不成功,考虑PPP dial again.
     *如果PPP Congig Fail, 考虑shut system.
     *
     */

   //以上建议仅供参考。我不打算实现。
}
#endif


extern err_t udp_write(u8_t *data, u16_t len);
extern struct tcp_pcb *tcp_active_pcbs; 
/****************************************************************************
* 名称:main()
****************************************************************************/
int main(void)
{ 
	
    u8_t buf[MAX_READ_LEN + 1];
    int len,pd;
    sys_err err;
    
    int * fd = NULL;
    int *linkstateCx = NULL;
    
   /*
   *init basic parametes of ourselves
   */
    sys_timer_init();
    local_sys_init();
    lwip_init();

    DEBUG_FUNCTION("main()");

   /*
   *start config GPRS Modem, such as HUAWEI GTM900, MC35i,etc.
   */
    err = active_Modem();

    if(err NEQ SYS_ERR_OK)
    {
        DEBUG_EVENT("Modem open failed! we must shut down system");
        shut_system();
    }
   DEBUG_EVENT("Modem open successful!");
   DEBUG_EVENT("System block 30 seconds!");
   
   /*
   *wait for GPRS Modem serching network, 
   * initinalize: such as SMS, Telephone Book etc.
   */
   second_sleep(30);

   err = init_Modem();
   if(err NEQ SYS_ERR_OK)
   {
        DEBUG_EVENT("Modem basic AT Commands initialize failed! we must shut down system");
        shut_system();
   }
   DEBUG_EVENT("Modem basic AT Commands initialize successful");

 /*
 *start Dial GPRS Number, such as: *99***1#
 */
 start_tcpip:
   err = dial_GPRS();
   if(err NEQ SYS_ERR_OK)
   {
        DEBUG_EVENT("Dial GPRS Failed,we must shut down system!");
        shut_system();
   }
   DEBUG_EVENT("Dial GPRS successful, now we start PPP Config!");

  /*
  *start config PPP,and send LCP packet to GPRS Modem
  */
    pd = pppOpen((void*)fd,  &pppStateCallback, (void *)linkstateCx);/*send lcp req to peer*/

   while(1)
   {
        /*
        *check if one timer is overflow, if so, run it
        */
	 check_sys_timer();

        /*
        *check the receive buffer of Modem
        */
	 if(get_modem_datalen() > 0)
	 {
           //DEBUG_EVENT(" Receive some data from Modem:\r\n");
	    len = get_modem_data(buf);
	     pppInProc(pd,  buf, len);
	 }

      /*
      *check the receive buffer of User Equipment
      */
       if(get_user_datalen() > 0)
       {
           //DEBUG_EVENT("Receive some data from User Eqipment!");
		   
	    len = get_user_data(buf);
		   
	    if(get_Mytcpip_state() EQ UDP_ESTABLISHED)
	    {
	        if( udp_write(buf, len)NEQ ERR_OK)
		 {
	      	     DEBUG_ERR("Send some data to UDP Peer, but failed!");
		     //add you code here.
		     //store the data
	      	 }		
	    }
	    else if(get_Mytcpip_state() EQ TCP_ESTABLISHED)
	    {
	       if( tcp_write(tcp_active_pcbs, (const void *)buf,  len, 1) NEQ ERR_OK)
	      	 {
	      	     DEBUG_ERR("Send some data to TCP Peer, but failed!");
		     //add you code here.
		     //store the data
	      	 }
	    }
	    else
	    {
	        DEBUG_EVENT("No TCP or UDP Connect exist!drop the data")
	    }
       }
	   
	/*
	*check the state of ppp
	*if the link is DEAD, I deal it very simple,
	*do not release the source of PPP/TCP/IP/UDP etc. 
	*just call the function: lwip_init(). but it work.
	*then goto the head of main func.
       *The state of DCD should be checked here,but I will ignore it. 
       */ 
	if(ppp_dead(pd) EQ TRUE)
	{
	    lwip_init();
	    set_Mytcpip_state(PPP_DEAD);
	    goto start_tcpip;
	}  

        /*
        *check the state of my tcpip
        */
        switch(get_Mytcpip_state())
        {
              case PPP_ESTABLISHED:
                          if(get_sys_err() < MAX_SYS_ERR_ALLOW)
                          {
                              tcpip_open();
			         break;
                          }
			    else
				  set_Mytcpip_state(TCPIP_STATE_UNKNOWN);
			    									    
	       case  TCPIP_STATE_UNKNOWN:
		   	   shut_system();
			   break;
				
		default:
			 break;
        }

	//hit  the WATCH DOG
   }	
}

#endif

⌨️ 快捷键说明

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