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

📄 check_gsm.c

📁 车载GPS监控终端的完整代码,与监控中心的通讯采用GPRS.
💻 C
📖 第 1 页 / 共 5 页
字号:
/********************************************************\
*	函数名:Check_Command
	作用域:本文件调用
*	功能:  针对全局变量缓冲gGeneral_Buffer[]中的数据进行数据有效果判断,如果有效则返回
			有效数据包中的命令字

*	参数:  需要对全局变量缓冲gGeneral_Buffer[]进行操作

*	返回值:0:无效的数据包
			gGeneral_Buffer[2]:数据包有效,返回其中命令字

*	创建人:
*
*	修改历史:(每条详述)

	补充说明:	校验数据包,提取命令字,并判断返回命令字,主要是针对gGeneral_Buffer[]
				gGeneral_Buffer[]的具体分布如下:
				gGeneral_Buffer[0]表示整个数据包的长度(但不包括这个长度本身这个字节)
				gGeneral_Buffer[1]消息头0XFF
				gGeneral_Buffer[2]命令字 gGeneral_Buffer[2]命令字的取反
				............

\********************************************************/
unsigned char Check_Command(void)
{
	unsigned int i,j,k;
	if(gGeneral_Buffer[0]==0)	return(0);
	if(gGeneral_Buffer[1]!=0xFF)	return(0);
	if(gGeneral_Buffer[2]!=(char)(~gGeneral_Buffer[3]) ) return(0);
	//计算校验核
	i=gGeneral_Buffer[4]+1;							//数据包长度
    k=0;
    for( j=1;j<=i;j++ ) k=k+gGeneral_Buffer[j];		//计算校验核
    if( k/256!=gGeneral_Buffer[gGeneral_Buffer[4]+2] ) return(0);
    if( k%256!=gGeneral_Buffer[gGeneral_Buffer[4]+3] ) return(0);
    return( gGeneral_Buffer[2] );
}
/********************************************************\
*	函数名:IP_SOCKET_Switch
	作用域:本文件调用
*	功能: 	这里是将从接收到的参数设置中的IP地址和端口号(long int)型的数据。
			IP地址直接是N个ASCII字符,则只需要直接存储在FLASH和buffer1中
			SOCKET因为是long int的数值,则需要转换成ASCLL字符的形式表示。这里做个限制
			最多5位数字的ASCII。并存储在Flash 和buffer1中
*	参数:

*	返回值:
*	创建人:
*
*	修改历史:(每条详述)

	补充说明1:
	long int变量为IP_Port_Num,将这个变量所表示的数值转换为最多5位的ASCII数字形式
	处理结果是在Flash和buffer1中存储断口数据
	调用这个子程序,是在收到下行的设置服务器地址和端口号以后,处理好数据后,所得到的结果
	先处理IP地址的数据,
	还包括一个长度字节(General_Buffer[0])

	补充说明2:	在运行这个子程序的时候,判断在gGeneral_Buffer[]中的命令字是属于设置服务器地址,端口
				gGeneral_Buffer[]的数据结构分布如下:
				gGeneral_Buffer[0]表示整个数据包的长度(但不包括这个长度字节本身)
				gGeneral_Buffer[1]----gGeneral_Buffer[9] 				前面固定的(包括消息头,消息号等等)
				gGeneral_Buffer[10]----gGeneral_Buffer[10+N]			IP地址的字符串,以0x00作为结束符号(ASCII字符串)
				gGeneral_Buffer[10+N+1]----gGeneral_Buffer[10+N+1+4]	为服务器通讯端口号(4个字节,为一个long int型数据)

	//处理第二类型GPRS数据的详细步骤

	//0x7B----0xB6用来存储针对下行信息的反馈信息(长度不固定)根据协议,此存储空间以60个字节存储
	//#define  ECHO_SMS_2	0x7B
	//0x7B	存储表示这个区域的SMS是否处理,为1(VAILD_2)则表示后面还有未处理的SMS,为0(NULL_2)则表示已经处理完了SMS
	//0x7C	存储数据包的命令字在这里则为nCommand
	//0x7D	存储数据包的ACK的值ACK
	//0x7E	存储后面数据包的长度(但注意没有存储CHK(MSB),CHK(LSB),EOT,这三个字节)
	//0x7F  从这开始存储数据包
	在这个命令中的数据包为从在gGeneral_Buffer[10]开始
\********************************************************/
void IP_SOCKET_Switch(void)
{
	unsigned int i,j,k;
	unsigned char APN_Length=0;
	unsigned char Check_Data=0;
	//在gGeneral_Buffer[i]中表示IP地址的第一个数
	i=10;
	while(1)
	{
		if(gGeneral_Buffer[i]==0x00) break;
		i++;
		if(i>gGeneral_Buffer[0]) 	return;
	}
	//存储IP地址的长度,不包括长度本身
	SRAM_Init();
	SRAM_Write(GPRS_IP_ADDRESS1_2,i-10);
	//一,+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	//1,IP的服务器地址的处理
	Check_Data=0;
	for(j=10;j<i;j++)
	{
		SRAM_Write(GPRS_IP_ADDRESS1_2+j-9,gGeneral_Buffer[j]);
		Check_Data += gGeneral_Buffer[j];
	}
	SRAM_Write(GPRS_IP_ADDRESS1_CHECK_2,Check_Data);

	//2,将IP地址的SOCKET数据存储在buffer1相应的缓冲区中,因为上面gGeneral_Buffer[i]=0x00
	gIP_Port_Num = gGeneral_Buffer[i+1];
	gIP_Port_Num<<=8;
	gIP_Port_Num += gGeneral_Buffer[i+2];
	gIP_Port_Num<<=8;
	gIP_Port_Num += gGeneral_Buffer[i+3];
	gIP_Port_Num<<=8;
	gIP_Port_Num += gGeneral_Buffer[i+4];
	//3,将GPRS的APN的内容存储在buffer1中
	k=i+5;
	while(1)
	{
		if(gGeneral_Buffer[k]==0x00) break;
		k++;
		if(k>gGeneral_Buffer[0]) return;
	}
	//4,存储APN地址的长度,不包括长度本身这个字节的内容
	APN_Length=k-i-5;
	if( (APN_Length>=4)&&(APN_Length<=25) )
	{
		SRAM_Write(GPRS_APN_ADDRESS2_2,APN_Length);
		//5,存储APN的数据值到相应的BUFFER1中
		Check_Data=0;
		for(j=i+5;j<k;j++)
		{
			SRAM_Write(GPRS_APN_ADDRESS2_2+j-i-4,gGeneral_Buffer[j]);
			Check_Data += gGeneral_Buffer[j];
		}
		SRAM_Write(GPRS_APN_END_2,Check_Data);
	}
	else
	{
		SRAM_Write(GPRS_APN_ADDRESS2_2,sizeof(APN_DEFAULT));
		//5,存储APN的数据值到相应的BUFFER1中
		Check_Data=0;
		for(i=0;i<sizeof(APN_DEFAULT);i++)
		{
			SRAM_Write(GPRS_APN_ADDRESS2_2+i+1,APN_DEFAULT[i]);
			Check_Data += APN_DEFAULT[i];
		}
		SRAM_Write(GPRS_APN_END_2,Check_Data);
	}
	//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	//存储作为第2类信息发送的响应数据的存储
	//服务器端口设置成功后的响应
	SRAM_Write(ECHO_SMS_2,VAILD_2);
	SRAM_Write(ECHO_SMS_2+1,ADDRESS_PORT_ECHO_UP);
	SRAM_Write(ECHO_SMS_2+2,gGeneral_Buffer[5]);
	SRAM_Write(ECHO_SMS_2+3,k-10);
	for(j=10;j<k;j++)
	{
		SRAM_Write(ECHO_SMS_2+4+j-10,gGeneral_Buffer[j]);
	}
	//因为端口号为一个long int 型的数据,则需要转换为ASCII字符的形式做实际应用
	//这里最多能表示5位的端口号,
	Check_Data=0;
	SRAM_Write(GPRS_SOCKET1_2+0,ASCII(gIP_Port_Num/10000));
	Check_Data += ASCII(gIP_Port_Num/10000);
	SRAM_Write(GPRS_SOCKET1_2+1,ASCII((gIP_Port_Num%10000)/1000));
	Check_Data += ASCII((gIP_Port_Num%10000)/1000);
	SRAM_Write(GPRS_SOCKET1_2+2,ASCII((gIP_Port_Num%1000)/100));
	Check_Data += ASCII((gIP_Port_Num%1000)/100);
	SRAM_Write(GPRS_SOCKET1_2+3,ASCII((gIP_Port_Num%100)/10));
	Check_Data +=ASCII((gIP_Port_Num%100)/10);
	SRAM_Write(GPRS_SOCKET1_2+4,ASCII(gIP_Port_Num%10));
	Check_Data += ASCII(gIP_Port_Num%10);
	SRAM_Write(GPRS_SOCKET1_END_2,Check_Data);
	gTimer=0;Clear_Exter_WatchDog();
	while(gTimer<100){}
	Clear_Exter_WatchDog();
	//二,++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	//注意,这里在程序刚上电的最开始已经检查过了FLASH的第1,第2扇区的数据
	//在这里则不需要在继续检查
	//读第一个扇区的数据到buffer2中
//	OperateSPIEnd();ReadOnePageToBuffer2(FLASH_INFO1_ONE_2);OperateSPIEnd();
	Deal_Sector(FLASH_INFO1_ONE_2);
	//1,将IP地址数据已经写入相应的buffer2中
	i=10;
	while(1)
	{
		if(gGeneral_Buffer[i]==0x00) break;
		i++;
		if(i>26) return;
	}
	//1-1,写IP地址数据长度
	OperateSPIEnd();
	WriteOneByteToBuffer2(GPRS_IP_ADDRESS1_F_2,i-10);
	//1-2,写IP地址数据包
	for(j=10;j<i;j++)
	{
		WriteNextByteToBuffer2(gGeneral_Buffer[j]);
	}
	OperateSPIEnd();
	gGeneral_Flag|=TCP_IP_VALID_1;
	gStatus2_Flag|=IP_VAILD_F_1;
	//2,将SOCKET的数据写入相应的buffer2中
	i=i+4;//此时的gGeneral_Buffer[i]=0x00
	i++;
	OperateSPIEnd();
	WriteOneByteToBuffer2(GPRS_SOCKET1_F_2,ASCII(gIP_Port_Num/10000));
	WriteNextByteToBuffer2(ASCII((gIP_Port_Num%10000)/1000));
	WriteNextByteToBuffer2(ASCII((gIP_Port_Num%1000)/100));
	WriteNextByteToBuffer2(ASCII((gIP_Port_Num%100)/10));
	WriteNextByteToBuffer2(ASCII(gIP_Port_Num%10));
	OperateSPIEnd();
	//3,将APN的内容写入相应的buffer2中
	OperateSPIEnd();
	//3-1,写入APN数据的长度
	WriteOneByteToBuffer2(GPRS_APN_DATA_F_2,APN_Length);
	//3-2,写APN数据包
	for(j=i;j<i+APN_Length;j++)
	{
		WriteNextByteToBuffer2(gGeneral_Buffer[j]);
	}
	OperateSPIEnd();
	RFlash_Sector(FLASH_INFO1_ONE_2);
	Re430_Flash(0);
	if(gM22_Status!=GSM_WORK)	gOther_Flag|=QUIT_TCP_F_1;
	gCheck_Par_Timer=CHECK_SYS_PAR_TIME+1;
	Judge_SMS_Way();
}

/********************************************************\
*	函数名:Do_Parameter_Set
	作用域:本文件调用
*	功能:  如果在Deal_Command()模块中判断属于处理下行的数据命令字为
			参数设置,则调用这个函数进行处理,收到的参数有
			车型,类别,组别,车号,目标号码1(以0x00结束),目标号码2(备用)(以0x00结束)
			对于上面信息的处理,一是存储在Flash相应的区域,一是存储在buffer1相应的区域
			同时设置参数设置响应的标志(发送第一类的SMS),存储此ACK到gSMS_ACK[]相应的区域
*	参数:	全局变量gGeneral_Buffer[]中的数据

*	返回值:进行和参数相关的设置

*	创建人:
*
*	修改历史:(每条详述)

	补充说明:	在运行这个子程序的时候,判断在gGeneral_Buffer[]中的数据是参数设置,此时
				gGeneral_Buffer[]的数据结构分布如下:
				gGeneral_Buffer[0]表示整个数据包的长度(但不包括这个长度字节本身)
				gGeneral_Buffer[1]----gGeneral_Buffer[9] 			前面固定的(包括消息头,消息号等等)
				gGeneral_Buffer[10]----gGeneral_Buffer[14]  		需要设置的车型,类别,组别,车号
				gGeneral_Buffer[15]----gGeneral_Buffer[15+N]		中心的短消息接收号码(以0x00作为结束符)
				gGeneral_Buffer[15+N+1]-----gGeneral_Buffer[15+N+M]	中心的短消息接收备用号码 (以0x00作为结束符)

	如果收到参数设置的下行命令,则首先的需要恢复出厂时的设置,将第0个扇区,第1个扇区,第2个扇区里的数据ERASE
	执行条件:只有处于GSM工作方式下才处理
\********************************************************/
void Do_Parameter_Set(void)
{
	//进行参数设置响应(上行数据发送)
	//表示第一类SMS的数据发送:参数设置响应
	//设置发送参数设置响应的标志
	Load_Buffer1_Echo(PARAMETER_SETECHO_UP,gGeneral_Buffer[5]);
	Do_Par();
}

/********************************************************\
*	函数名:Position_Echo
	作用域:本文件调用
*	功能:  收到下行的需要定位查询的命令,则做相关的处理
			将此时此刻的效果的经度,纬度,时间信息打成数据包
			存储在第二类SMS数据的存储区(buffer1的0x7B----0xB6区域)
			0x7B设置为1(VAILD_2),并将数据包依次存储在后面的字节缓冲中。
			后面数据包的形式为

*	参数:	全局变量gGeneral_Buffer[]中的数据

*	返回值:进行和参数相关的设置

*	创建人:
*
*	修改历史:(每条详述)

	补充说明:

	补充说明:具体在buffer1中存储第2类SMS的数据形式如下:0x7B----0xB6(整个分配的区域大小)
			  0x7B	存储表示这个区域的SMS是否处理,为1则表示后面还有未处理的SMS,为0则表示已经处理完了SMS
			  0x7C	存储数据包的命令字在这里则为nCommand
			  0x7D	存储数据包的ACK的值ACK
			  0x7E	存储后面数据包的长度(但注意没有存储CHK(MSB),CHK(LSB),EOT,这三个字节)
			  0x7F  从这开始存储数据包
数据区的内容:
LONGTITUDE	4 bytes,无符号整型	经度
LATITUDE	4 bytes,无符号整型	纬度
SPEED	1 byte, 无符号整型	速度,单位:米/秒
AZIMUTH	1 byte, 无符号整型	方位角/15,单位:度
FLAG	1 byte, 无符号整型	标志
TIME	6 bytes,字符型	时间(YYMMDDHHMISS)

\********************************************************/
void Position_Echo(void)
{
	unsigned char nCheck=0;
	unsigned int i=0;
	//1,如果中心号码无效果,则进行暂时的返回发送
	if(   ((gGeneral_Flag&NUM1_VAILD_F_1)==0)
		&&(gNum_Phone_Temp[0]<=14) )
	{
		//1,存储目标号码
		SRAM_Init();
		SRAM_Write(TARGET_NUMBER1_2+0,gNum_Phone_Temp[0]);
		for(i=1;i<=gNum_Phone_Temp[0];i++)
		{
			SRAM_Write(TARGET_NUMBER1_2+i,gNum_Phone_Temp[i]);
			nCheck += gNum_Phone_Temp[i];
		}
		SRAM_Write(TARGET_NUMBER1_CHECK_2,nCheck);
		//2,存储车组,车类,车型,车号
		gKind=gGeneral_Buffer[6];
		gGroup=gGeneral_Buffer[7];
		gVID = gGeneral_Buffer[8];
		gVID<<=8;
		gVID += gGeneral_Buffer[9];
		gGeneral_Flag|=NUM1_VAILD_F_1;
	}
	SRAM_Init();
	SRAM_Write(ECHO_SMS_2+0,VAILD_2);
	SRAM_Write(ECHO_SMS_2+1,POSITION_ASKECHO_UP);
	SRAM_Write(ECHO_SMS_2+2,gGeneral_Buffer[5]);
	SRAM_Write(ECHO_SMS_2+3,17+4);
	Write_PartData_Sram(ECHO_SMS_2+3);	//17
	SRAM_Write(ECHO_SMS_2+3+18,0);
	SRAM_Write(ECHO_SMS_2+3+19,0);
	SRAM_Write(ECHO_SMS_2+3+20,gStatus2_Flag);
	SRAM_Write(ECHO_SMS_2+3+21,gStatus1_Flag);
	Judge_SMS_Way();
}

/********************************************************\
*	函数名:Set_Cycle_Timer
	作用域:本地文件调用
*	功能:	收到设置上传位置时间间隔的下行命令后,做一些相关的处理
			一是附给变量gCycle_GPRS和gCycle_GSM,二是存储在相应的Flash区中
			gCycle_GPRS变量存储的是在GPRS在线的状态下发送行驶状态数据上行信息的时间间隔
			gCycle_GSM变量存储的是在GSM在线的但GPRS不在线的状态下发送行驶状态数据上行信息的时间间隔

*	参数:  无
*	返回值:无
*	创建人:
*
*	修改历史:(每条详述)
\********************************************************/
void Set_Cycle_Timer(void)
{
	unsigned int i=0,j=0;
	unsigned char nACK=0;
	nACK=gGeneral_Buffer[5];
	gCycle_TCP = gGeneral_Buffer[1+9];
	gCycle_TCP <<= 8;
	gCycle_TCP += gGeneral_Buffer[1+10];

	gCycle_GSM = gGeneral_Buffer[1+11];
	gCycle_GSM <<= 8;
	gCycle_GSM += gGeneral_Buffer[1+12];

	if( (gCycle_TCP>0)&&(gCycle_TCP<5) )	gCycle_TCP=5;
	if( (gCycle_GSM>0)&&(gCycle_GSM<5) )	gCycle_GSM=5;

	//如果间隔距离符合条件,则将间隔距离设置为0
	if( gCycle_TCP>=5 )
	{
		gCycle_Distance=0;
	}
	gPublic_Flag &=~ SET_DISTANCE_OK_F_1;
	gSet_Distance_Info_Count=WAIT_DISPINFO_TIME-2;
//	OperateSPIEnd();ReadOnePageToBuffer2(FLASH_INFO2_ONE_2);OperateSPIEnd();
	Deal_Sector(FLASH_INFO2_ONE_2);
	WriteOneByteToBuffer2(TCP_TIMER_2,gGeneral_Buffer[1+9]);
	WriteNextByteToBuffer2(gGeneral_Buffer[1+10]);
	WriteNextByteToBuffer2(gGeneral_Buffer[1+11]);
	WriteNextByteToBuffer2(gGeneral_Buffer[1+12]);
	WriteNextByteToBuffer2(0);
	WriteNextByteToBuffer2(0);
	OperateSPIEnd();
	RFlash_Sector(FLASH_INFO2_ONE_2);
	Re430_Flash(1);
	OperateSPIEnd();
	Clear_Exter_WatchDog();

	SRAM_Init();
	SRAM_Write(ECHO_SMS_2+0,VAILD_2);
	SRAM_Write(ECHO_SMS_2+1,TIME_INTERVAL_ECHO_UP);
	SRAM_Write(ECHO_SMS_2+2,nACK);
	SRAM_Write(ECHO_SMS_2+3,21);
	Write_PartData_Sram(ECHO_SMS_2+3);	//17
	SRAM_Write(ECHO_SMS_2+3+18,0);
	SRAM_Write(ECHO_SMS_2+3+19,0);
	SRAM_Write(ECHO_SMS_2+3+20,gStatus2_Flag);
	SRAM_Write(ECHO_SMS_2+3+21,gStatus1_Flag);
	Judge_SMS_Way();

⌨️ 快捷键说明

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