?? sms.c
字號:
#include<reg54.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/////////////////////////////////////////////////////////////
//|Function:int cal_crc
//| 16位CRC:按位計算,速度最慢,占用空間最少
//| 注:數據流是高位先行
//|輸入:整數以及初始crc值
//|輸出:按位計算的16位crc值,余式采用0x1021
//////////////////////////////////////////////////////////////
xdata char buf[128];
unsigned int cal_crc(unsigned int command,unsigned int crc){
unsigned int i;
crc=crc^(command<<8);
for(i=0; i<=7; i++) {
if((crc&0x8000)!=0)
crc=(crc<<1)^0x1021;
else
crc=(crc<<1);
}
return crc;
}
//////////////////////////////////////////////////////////////////
//|Function:char *left
//|獲得字符串子串,從走到右
//|
//|輸入:字符串以及截取的長度
//|
//|輸出:子串的地址
//|
//|Example: char p[] = "TTTT1234";
//| char t[5];
//| t = left(p,4); //Should Return "TTTT"
/////////////////////////////////////////////////////////////////////
char *left(const char *chString,unsigned int len)
{
unsigned int i; //Loop VAR
int k, nIndex; //More Loop VARs
// char *buf; //Temp String VARs
if (!strlen(chString)) //If There Is No String
return NULL; //Return NULL
if (len > strlen(chString)) //If The Amount To Copy Is Larger Than The String
len = strlen(chString); //Set The Length To The Length Of The String
// buf = (char *)malloc(len + 1);
//Copy The Part We Want From The Orginal String To The Result
for (i = 0, nIndex = 0, k = 0; i < len; i++)
{
if (chString[nIndex] != '\0') //If Not A NULL Char
buf[k++] = chString[nIndex++];
else
break;
}
buf[k] = '\0'; //Add A NULL Char To The End Of The String
return buf;
}
////////////////////////////////////////////////
//|Function:int HexToInt
//|十六進制格式字符串轉換為整數
//|
//|輸入:十六進制字符串
//|
//|輸出:轉換后對應的整數數值,錯誤則返回-1
//|
//|
//| Example: int result;
//| char str[]="123";
//| result=HexToInt(str); //result=0x0123
///////////////////////////////////////////////
int HexToInt(char * Hexvalue){
int i,tempint,len,sum=0;
char buffer[2];
len=strlen(Hexvalue);
for(i=0;i<len;i++){
buffer[0]= Hexvalue[i];
buffer[1]='\0';
switch(buffer[0]){
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':tempint=atoi(buffer) ;break;
case 'a':
case 'A':tempint=10;break;
case 'b':
case 'B':tempint=11;break;
case 'c':
case 'C':tempint=12;break;
case 'd':
case 'D':tempint=13;break;
case 'e':
case 'E':tempint=14;break;
case 'f':
case 'F':tempint=15;break;
default :return -1;
}
sum=sum*16+tempint;
}
return sum;
}
///////////////////////////////////////////////////////////////////////
//| Function: BinaryFuse()
//| 二進制融合將輸入的字符串按照每兩位結合所代表的整數原則,轉變為一半長度的整數數組
//|
//| 輸入:源字符串,起始位置,融合長度,目標數組,數據開始位置
//|
//| 返回:void
//|
//| Example:
//| char str[]="1234";
//| int data[2];
//| BinaryFuse(str,0,4,data,0); //data=0x2,0x12,0x34
/////////////////////////////////////////////////////////////////////////
void BinaryFuse(unsigned char* Str,int SStart, int Len,unsigned int* Data,int DStart){
// int i,charvalue;
unsigned char i,charvalue;
char buffer[3];
if(DStart==0)
Data[0]=Len/2;
else
Data[0]+=Len/2;
for(i=1;i<=Len/2;i++){
buffer[0]=Str[SStart+2*i-2];
buffer[1]=Str[SStart+2*i-1];
buffer[2]='\0';
charvalue=HexToInt(buffer);
if(charvalue>=0)
Data[DStart+i]=charvalue;
else{
//printf("BianryFuse String Error!");
Data=NULL;
return ;
}
}
}
/////////////////////////////////////////////////////////////////////////
//| Function: unsigned char ParseString()
//|從源字符串中獲取命令包、對命令包進行CRC校驗、解析出命令單元的數據保存到目的數組
//|
//|輸入:源字符串,目的數組,消息來源電話,消息編號
//|
//|返回:解析成功則返回0x00,出錯則返回相應的出錯編碼
//|
//| Example:
//| char Phone[15];
//| int Record;
//| int Data[100];
//| char Str[]="+CMGL: 14,\"REC UNREAD\",\"8613575588314\",,\"04/05/29,21:07:08+00\"\xD\xAX010101032012345678FF002613666673107 13800571500 011234005600000014F6X\xD\xAOK";
//| PareString(Str,Data,Phone,&Record);
/////////////////////////////////////////////////////////////////////////
unsigned char ParseString(unsigned char *Str,unsigned int *Data,unsigned char* Phone,unsigned int *Record){
int pos,len,i;
unsigned int RcvCrc,CalCrc=0;
Str=strstr(Str,"+CMGL:");//搜索消息字符串的起始標志位+CMGL
if(Str==NULL){
Data=NULL;
Phone=NULL;
*Record=0;
return 0x07;
}
Str=Str+7;
pos=strpos(Str,',');
*Record=atoi(left(Str,pos));//接受到的消息編號
Str=(Str+pos+1);
pos=strpos(Str,',');
Str=(Str+pos+2);
pos=strpos(Str,',');
strcpy(Phone,left(Str,pos-1)); //消息來源電話號碼
Str=strstr(Str,"\r\n");//搜索消息數據起始位
if(Str==NULL){
Data=NULL;
Phone=NULL;
// *Record=0;
return 0x08;
}
Str=Str+2;
pos=strpos(Str,'X'); //搜索消息命令起始位
if(pos==-1){
Str=NULL;
Data=NULL;
Phone=NULL;
// *Record=0;
return 0x0a;
}
Str=(Str+pos+1);
pos=strpos(Str,'X'); //搜索消息命令結束位
if(pos==-1){
Str=NULL;
Data=NULL;
Phone=NULL;
// *Record=0;
return 0x0b;
}
//對命令單元和檢驗單元字符串進行二進制合并,若是31命令則對電話號碼不做合并
if(Str[8]=='3'&&Str[9]=='1'){
BinaryFuse(Str,0,24,Data,0);
len=Data[0];
Data[0]+=30;
for(i=0;i<30;i++)
Data[len+1+i]=Str[24+i];
BinaryFuse(Str,54,pos-54,Data,Data[0]);
}
else
BinaryFuse(Str,0,pos,Data,0);
//CRC 校驗
RcvCrc=Data[(Data[0])]*256+Data[(Data[0])-1];
for(i=1;i<=Data[0]-2;i++)
CalCrc=cal_crc(Data[i],CalCrc);
if(RcvCrc!=CalCrc){
Str=NULL;
return 0x05;
}
Data[0]-=2;
//命令體長度檢驗
if(Data[12]!=Data[0]-12){
Str=NULL;
Data=NULL;
Phone=NULL;
*Record=0;
return 0x0c;
}
Str=(Str+2);//消息命令體處理完畢
Str=NULL;
return 0x00;
}
/////////////////////////////////////////////////////////////////
//| Function: GetSetValue()
//|從調試串口接收到的字符串中,解析出有效數據
//|
//|輸入:源字符串,目的數組,命令號
//|
//|返回:解析成功則返回0x00,出錯則返回相應的出錯編碼
//|
//| Example:
//| char result;
//| unsigned int kind;
//| unsigned char Data[100];
//| char Str[]="set 1=1234";
//| result=GetSetValue(Str,Data,&kind);
/////////////////////////////////////////////////////////////////////////
char GetSetValue(unsigned char* Str,unsigned int* Data,unsigned int* kind)
{
int pos,i;
Str=strstr(Str,"set");
if (Str==NULL)
return -1;
Str=Str+3;
pos=strpos(Str,'=');
if (pos==-1)
return -2;
*kind=atoi(left(Str,pos));
Str=Str+pos+1;
pos=strpos(Str,'\r');
if ((pos==-1)||(pos>32))
return -3;
if ((*kind==1)||(*kind==2)) //電話號碼
{
Data[0]=pos;
for (i=1;i<=pos;i++)
Data[i]=Str[i-1];
}
else
{
BinaryFuse(Str,0,pos,Data,0);
}
return 0;
}
/////////////////////////////////////////////////////////////////
//| Function: GetEEPROMValue()
//|從調試串口接收EEPROM內容讀取命令
//|
//|輸入:源字符串,目的數組,命令號
//|
//|返回:解析成功則返回0x00,出錯則返回相應的出錯編碼
//|
//| Example:
//| char result;
//| unsigned int *start,*length;
//| char Str[]="get 1,5";
//| result=GetEEPROMValue(Str,&start,&length);
/////////////////////////////////////////////////////////////////////////
char GetEEPROMValue(unsigned char* Str,unsigned int* start,unsigned int* length)
{
int pos;
Str=strstr(Str,"get");
if (Str==NULL)
return -1;
Str=Str+3;
pos=strpos(Str,',');
if (pos==-1)
return -2;
*start=atoi(left(Str,pos));
Str=Str+pos+1;
pos=strpos(Str,'\r');
if ((pos==-1)||(pos>32))
return -3;
*length=atoi(left(Str,pos));
return 0;
}
/////////////////////////////////////////////////////////////////
//| Function: BinaryDivide()
//|將源整數數組進行如下處理,從數組的第二位起逐個將整數轉換成ASCII碼
//|
//|輸入:源整數數組,起始位置,拆分的長度,目的字符串
//|
//|返回:void
//|
//|Example:
//| int data[3]={0x02,0x12,0x34};
//| char str[4];
//| BinaryDivide(data,1,2,str,0); //str[]="1234"
///////////////////////////////////////////////////////////
void BinaryDivide(unsigned int* Data,int DStart, int Len,unsigned char* Str){
int i;
char buffer[3];
if(DStart<=0)
DStart=1;
if(Len<=0)
Len=1;
if(Len>Data[0])
Len=Data[0];
for(i=0;i<Len;i++){
sprintf(buffer,"%2X",Data[DStart+i]);
if(buffer[0]==' ')
buffer[0]='0';
Str[2*i]=buffer[0];
Str[2*i+1]=buffer[1];
// strcat(Str,buffer);
}
Str[2*i]='\0';
}
/////////////////////////////////////////////////////////
//| Function: BuildCmd()
//|功能: 根據命令單元生成校驗單元,然后進行二字節拆分,然后添加結束標志生成最終命令包
//|
//|輸入: 源整數數組命令單元,字符串格式的命令包
//|
//|輸出: void
//|
//| Example:
//| int Data[100]={0x11,0x01,0x01,0x01,0x03,0x30,0x12,0x34,0x56,0x78,0x01,0x00,0x05,0x12,0x34,0x56,0x78,0x01};;
//| char Cmd[100];
//| BuildCmd(Data,Cmd); //Cmd="010101033012345678010005123456780144F7" +X +26數字
////////////////////////////////////////////////////
void BuildCmd(unsigned int* Data,unsigned char * Cmd){
int i,len;
unsigned int CalCrc=0;
// char flag[3];
CalCrc=0; //modified
for(i=1;i<=Data[0];i++)
CalCrc=cal_crc(Data[i],CalCrc);
Data[Data[0]+1]=CalCrc%256;
Data[Data[0]+2]=CalCrc/256;
Data[0]+=2;
// if(Data[5]==0x20||Data[5]==0x31){
if((Data[5]==0x20)&&(Data[0]>15)) //鑒權正確的20命令,去處鑒權錯誤20命令的干擾
{
BinaryDivide(Data,1,12,Cmd);
for(i=0;i<30;i++)
Cmd[24+i]=Data[13+i];
BinaryDivide(Data,43,Data[0]-42,Cmd+54);
len=74;
}
else
{
BinaryDivide(Data,1,Data[0],Cmd);
len=Data[0]*2;
}
Cmd[len]='X';
Cmd[len+1]=26;
Cmd[len+2]='\0';
}
/////////////////////////////////////////////////////////////////////////
//| Function: unsigned char ParseCellInfo()
//|從源字符串中獲取網絡小區的基本參數
//|
//|輸入:源字符串,小區號,Bcch,Bsic,Rxlev
//|
//|返回:解析成功則返回0x00,出錯則返回相應的出錯編碼
//|
//| Example:
//| char Phone[15];
//| unsigned int Bcch;
//| unsigned char Bsic,Rxlev;
//| char Str[]="+MCELL: 1 BC 0085 02-082B<LF>460000 10471 33<LF>018 018 *** ***<LF>0 A1aI 22298 20<LF>8 *** 7 1 20 14<LF>-100 GPI1 ****\rOK";
//| ParseCellInfo(Str,CellNo,&Bcch,&Bsic,&Rxlev);
/////////////////////////////////////////////////////////////////////////
unsigned char ParseCellInfo(unsigned char *Str,unsigned char CellNo,unsigned int *Bcch,unsigned char* Bsic,unsigned char *Rxlev,unsigned int *CellId){
unsigned int i;
unsigned char screen[5];
Str=strstr(Str,"+MCELL:");//搜索消息字符串的起始標志位+MCELL
if(Str==NULL){
*Bcch=0;
*Bsic=0;
*Rxlev=0;
return 0x1;
}
if (CellNo==0)
{
Str=Str+7;
Str=Str+6;
*Bcch=atoi(left(Str,4)); //Bcch:6~9
Str=Str+5;
*Bsic=atoi(left(Str,2)); //Bsic:11~12
Str=Str+3;
*Rxlev=atoi(left(Str,3)); //Rxlev:13~16
Str=Str+12;
*CellId=atoi(left(Str,5));
return 0;
}
else
{
i=CellNo;
sprintf(screen,"N%u",i);
Str=strstr(Str,screen);//搜索相鄰小區信息起始標志"N*"
if(Str==NULL){
*Bcch=0;
*Bsic=0;
*Rxlev=0;
return 0x2;
}
Str=Str+3;
*Bcch=atoi(left(Str,4));
Str=Str+5;
*Bsic=atoi(left(Str,2));
Str=Str+3;
*Rxlev=atoi(left(Str,3));
*CellId=0;
return 0;
}
}
unsigned char gsmInvertNumbers(const char *pSrc, char *pDst, unsigned char nSrcLength)
{
unsigned char nDstLength; // 目標字符串長度
char ch; // 用于保存一個字符
unsigned char i;
// 復制串長度
nDstLength = nSrcLength;
// 兩兩顛倒
for(i=0; i<nSrcLength;i+=2)
{
ch = *pSrc++; // 保存先出現的字符
*pDst++ = *pSrc++; // 復制后出現的字符
*pDst++ = ch; // 復制先出現的字符
}
// 源串長度是奇數嗎?
if(nSrcLength & 1)
{
*(pDst-2) = 'F'; // 補'F'
nDstLength++; // 目標串長度加1
}
// 輸出字符串加個結束符
*pDst = '\0';
// 返回目標字符串長度
return nDstLength;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -