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

📄 pppphy.c

📁 本人亲手实现且用在一商用产品上的一个简单的ppp协议
💻 C
字号:

#include <string.h>
#include "stacktsk.h"
#include "timer.h"
#include "uart.h"
#include "ppp.h"
#include "pppPhy.h"
#include "alarm_sms.h"

extern char ISPTel[];

UH  ModemStatus;

BYTE Waitfor_str (char *String, BYTE Time) {
    BYTE c;
    BYTE cyc;
    char ch[2]={0,0};
    char buf[200];
//    BYTE Offset = 0;
    
    memset(buf,0,sizeof buf);
    while (Time-- > 0) {
    	cyc=1;
        dly_ms(150);                        // Wait =~ 150 mSec
        while (cyc && (Comm_getchar(&c)==1)) {       // Wait for characters
            ch[0]=c;
            strncat(buf,ch,sizeof(buf));
            if (c == '\n') {
            	if(strcmp(buf,"\r\n")) cyc=0;		//eliminate unwanted carriage return
            	else memset(buf,0,sizeof buf);
            } 
        }
        if(strstr(buf,String)) return 1;  
    }
	return 0;
}


BYTE Waitfor (char *String, BYTE Time) {
    BYTE c = 0;
    BYTE Offset = 0;
    
    while (Time-- > 0) {
        dly_ms(150);                        // Wait =~ 150 mSec
        while (Comm_getchar(&c)==1) {       // Wait for characters
            if (c == String [Offset]) {     // Is C a part of the string? 
                Offset++;                   // Compare with next character
                if (String [Offset] == 0) { // is this the end of string?
                    return 1;               // match = True
                }
            }
            else                            // c does not belong to String
                Offset = 0;	                // Reset String pointer
        }
    }
	return 0;
}


const char * ModemCommand [] = {	// Array of modem initialization commands
	"ATZ\r",			// Reset Command
	"ATE0\r",			// Disable Echo 
	"AT&C1\r",			// Track presence of data carrier
	"AT&D3\r"			// Reset modem when an on-to-off transition of DTR ocurres	
};

/**********************************************************
 * return 0 : Modem init OK
 *        1 : no success
 **********************************************************/
BYTE ModemCmdInit() {
    BYTE Res = 0;                                   // Create two temp vars in the stack
    BYTE index;

    ModemStatus &= ~(MODEM_EXIST);
    
    for (index = 0; index <= 1; index++) {          // Loop through Modem initiazation commands
        SendString ((char *)ModemCommand [index]);	// Transmit modem command
        Res = Waitfor ("OK", 30);		            // Wait for OK 

        if (!Res) {				                    // Invalid response received
            // Do something here
            // ModemReset ();                       // Reset modem 
            index = 0;                              // Loop again	
            return 1;
        }	
    }
    ModemStatus |= MODEM_EXIST;                     // net physical-layer normally
    return 0;
}

/***********************************************************************
Function : 	ModemHandler

Parameters : 	Code - Numeric response code from a Modem dial command

Date : 		January 2001

Desc : 		This function handles the numeric responses from a dial command
		issued to the modem

***********************************************************************/
void ModemHandler (BYTE Code) {
    BYTE    ch;
    
    switch (Code) {
        case '0':		// OK
        break;

        case '1':		// CONNECT
            Comm_getchar(&ch);
            if ( ch!= 0x7F) {           // Test for PPP packets
                Waitfor (":", 100);     // Wait for "Username:" of ISP script
                ModemStatus |= MODEM_ONLINE;    // Modem已经连上线
                if (AppConfig.GprsEnable)
                    dly_ms(500);
                PPPSendVoidLCP ();      // Force PPP transactions instead of scripts
		    }
    		break;

        case '2':		// RING
	        break;

        case '3':		// NO CARRIER
            break;

        case '4':		// ERROR
            break;

        case '6':		// NO DIAL TONE
            break;

        case '7':		// BUSY
            break;

        case '8':		// NO ANSWER
            break;

        case '9':		// CONNECT 2400
            break;

        default:		// TIME OUT, NO RESPONSE FROM MODEM RECEIVED!
            break;
    }
}


//***************************************************
int ModemDial () {
    BYTE delayCount = 80;
    BYTE ch;
    char str[256];
        
    //FlushPPPBuf();
	SendString("ATV0\r");               // Force a numeric response from modem
   	if (!Waitfor ("0", 30)) {			// Wait for an OK response
		return -1;
	}
  
    strcpy(str,"ATDT");                 // Dial the ISP number
    strcat(str,ISPTel);
    strcat(str,"\r");

    SendString(str);
        
                                        // Wait for a reply
 	while ((Comm_getchar(&ch)==0) && (--delayCount > 0)) {
		dly_ms(500);                    // delay 500ms
   	}
	if (delayCount) {
        ModemHandler(ch);
		return 0;                      // Return the numeric response to caller
   	}
	return -1;					// No response received from modem
}
//***************************************************
int GprsDial () {
    BYTE delayCount = 5;
    char str[256];
    int status;
        
    //FlushPPPBuf();
    while (delayCount){
        //SendString("ATV0\r");               // Force a numeric response from modem
        //if (!Waitfor ("0", 30)) {			// Wait for an OK response
        //return -1;
        //}
  
	    strcpy(str,"ATDT");                 // Dial the ISP number
    	strcat(str,ISPTel);
	    strcat(str,"\r");

	    SendString(str);
    	status=Waitfor_str("CONNECT",50);
        //dly_ms(500);
	    if(status)  {
	    	ModemStatus |= MODEM_ONLINE;    // Modem已经连上线
	    	return 0;
	    }
	    else	{
	    	SendString("atz\r\n");
	    	status=Waitfor_str("OK",8);
	    	SendString("at+cfun=1\r\n");
	    	status=Waitfor_str("OK",100);
	    	status=GPRS_init(AppConfig.GprsConPoint);
	    	delayCount--;
	   	}
    }
	return -1;					// No response received from modem
}
//*******************************************************
// return :     0 -- success
//           else -- fail
//*******************************************************
UB GPRS_init(char *ARP){
	char str1[60];
	BYTE status=0;
	int loop;
	UB  rst;
	
	strcpy(str1,"at+CGDCONT=1,\"IP\",\"");
	strncat(str1,ARP,20);
	strcat(str1,"\"\r\n");
	
	SendString("at+cfun=1\r\n");
	status=Waitfor_str("OK",100);
	dly_ms(5000);	//wait at least 3 seconds before entering GPRS session
	RxBufReset();

//	SendString("at+ipr=57600;&w\r\n");
//	status=Waitfor("OK",8);
//    if(status==0) return 0xff;    //Modem error
    SendString("at+CGATT=1\r\n");
    status=Waitfor_str("OK",100);
    if(status==0) {
        rst=1;  //GPRS service not available
        goto Return_Err;
    }
	dly_ms(200);
	RxBufReset();
	status=0;
	for(loop=10;loop && (status==0);loop--){
		dly_ms(200);
	    SendString("at+CGREG?\r\n");
   		status=Waitfor_str("+CGREG: 0,1",8);
   	}
    if(loop==0) {
        rst=1;  //GPRS service not available
        goto Return_Err;
    }
	dly_ms(200);
	RxBufReset();
    SendString(str1);
    status=Waitfor_str("OK",10);
    if(status==0) {
        rst=2;      //GPRS ARP error
        goto Return_Err;
    }        
	dly_ms(200);
	RxBufReset();
    SendString("at+CGQREQ=1,0,0,3,0,0\r\n");
    status=Waitfor_str("OK",8);
    if(status==0) {
        rst=3;      //GPRS QoS error
        goto Return_Err;
    }        
	dly_ms(200);
	RxBufReset();
    SendString("at+CGACT=1,1\r\n");
    status=Waitfor_str("OK",100);
    if(status==0) {
        rst=4;      //GPRS Gateway error
        goto Return_Err;
    } 

	status=0;
    SendString("at+CGACT?\r\n");
   	for(loop=10;loop && (status==0);loop--){
		dly_ms(200);
   		status=Waitfor_str("1,1",20);
   	}
    if(status==0) ModemStatus &= ~(MODEM_GPRS_ISP_OK); 		//GPRS Gateway error
    else ModemStatus |= MODEM_GPRS_ISP_OK;
    return 0;    
    
Return_Err:
    ModemStatus &= ~(MODEM_GPRS_ISP_OK); 
    return rst;    
}    

//*************************************************************************
// 初始化成功后,系统会将ModemStatus的相应位置高,表示modem存在
// 且初始化成功
//*************************************************************************
UB PhyInit() {
    UB rst;
    
    rst=ModemCmdInit();
    if (rst)
        return rst;                 // 初始化失败,物理层没连结好

    if (AppConfig.GprsEnable) {
     	rst=GPRS_init(AppConfig.GprsConPoint);
        if (rst != 0)
            return rst;
    }
    else {  // 当用普通modem时,故意set此标志,作为检测用
        ModemStatus |= MODEM_GPRS_ISP_OK;
    }    
    RxBufReset();
    
    return rst;
}
//***************************************************
void ModemOffLine() {
    char  str[20];
    UB  i;
    
    str[0]='+';
    str[1]=0;

    for (i=0;i<3;i++) {
        SendString(str);
        dly_ms(200);
    }
            
    strcpy(str,"ath0\r");
   	RxBufReset();
    SendString(str);
    //ModemStatus |= (MODEM_OFFLINE);
    dly_ms(5000);

    ModemStatus &= ~(MODEM_ONLINE);
    
}
//***************************************************
void GprsOffLine() {
    char  str[2]="+";
    int status=0;
	
	dly_ms(5000);
	SendString(str);
	dly_ms(200);
	SendString(str);
	dly_ms(200);
	SendString(str);

   	RxBufReset();
    status=Waitfor_str("OK",100);
    
    strcpy(str,"ath0\r");
   	RxBufReset();
    SendString(str);
    status=Waitfor_str("OK",20);
  
    status=GPRS_init(AppConfig.GprsConPoint);
    status=SMS_Init();
    
    // 假如sms报警enable,需要发送sms
    if (AppConfig.AlarmMode & SMS_ALARM_ENABLE)
        SMS_Alarm();
        
    ModemStatus &= ~(MODEM_ONLINE);
    
}
//***************************************************
// 处理
//***************************************************
extern UB   bAlarmEnable;

void ModemTask() {
    UB  rst;
    
    // 是否需要报警,如果不需要,检测是否modem还在线,如果在线
    // 那么断线
    if (bAlarmEnable==0) {              // 此时scan是否断开modem
        if (ModemStatus & MODEM_ONLINE) {
            //PPPInit();
            if (AppConfig.GprsEnable) 
                GprsOffLine();
            else 
                ModemOffLine();
        }            
        return;
        
    }
    
    // 报警没被撤销,需要报警
    // 检测modem是否存在且初始化成功
    if ( !(ModemStatus & MODEM_GPRS_ISP_OK) ) {
        // modem 以前初始化不成功
        PhyInit();
    }

    // 经过上一步骤,modem仍旧没能初始化,只能exit
    if ( !(ModemStatus & MODEM_GPRS_ISP_OK) ) 
        return;     // 初始化仍旧不成功,exit

    if ( !(ModemStatus & MODEM_ONLINE) ) {
        PPPInit();    

        // if SMS 报警模式enable,并且SMS优先权高于Gprs        
        if ( (AppConfig.AlarmMode & SMS_ALARM_ENABLE) && AppConfig.AlarmPrefrence==1)
            SMS_Alarm();
            
        // modem以前不在线,于是拨号
        if (AppConfig.GprsEnable) {
            rst=GprsDial();
        }
        else {        
            rst=ModemDial();
        }
    }
}
//***************************************************



⌨️ 快捷键说明

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