📄 pro2004.c
字号:
/*
*****************************************************************************************************
*
* File name: Pro2004.c
*****************************************************************************************************
*/
#include "..\head\includes.h"
/**************************************************************************************************/
#ifdef PROTOCOL_2004
/**************************************************************************************************/
#define RESENT_BUF_NUM 4
#define STATU_IDLE 0
#define WAIT_SENT 1
#define WAIT_CONFIRM 2
#define RESENT_UNCHECKED 0 //未确认
#define RESENT_CHECKED 3 //已确认
typedef struct _resent_buf_
{
unsigned char Statu; //状态:STATU_IDLE=空闲状态 WAIT_SENT==等待运行 WAIT_CONFIRM==等待确认
unsigned char Checked; //是否已收到确认侦
unsigned char PFC; //SEQ侦序列号
unsigned char Interval; //间隔时间 单位S
unsigned char Count ; //重发次数
unsigned char Length; //侦长度
unsigned char Buf[50]; //侦内容
} ResentBufStruct;
unsigned char xdata AddBytes[4]; //地址哉四字节为BCD码,如"90201234" 转换后为0x90 0x20 0x12 0x34
unsigned char xdata PFC=0; //用来记录SEQ PSEQ 侦序号计数器,累加
ResentBufStruct xdata ResentBufS[RESENT_BUF_NUM];
/*
*****************************************************************************************************
*FUNC: 连接成功后回调函数,由用户根据自己需要表些
*NOTE: 入参:套接字编号
//发送注册包//WP+ID+SIM+MIP
// "90201234" 变成 0X20 0X90 0X34 0X12
//68H L L 68H C A AFN=02H SEQ DA=0 CS 16H
*****************************************************************************************************
*/
//控制域位定义
#define DIR (1 << 7)
#define PRM (1 << 6)
#define FCB (1 << 5)
#define ACD (1 << 5)
#define FCV (1 << 4)
#define FUNCCODE_R_A 0x09
#define FUNCCODE_S_C 0x01
//SEQ位定义
#define TPV (1 << 7)
#define FIR (1 << 6)
#define FIN (1 << 5)
#define CON (1 << 4)
typedef struct Login_Struct
{
unsigned char StartBit1;
unsigned int L_High;
unsigned int L_Low;
unsigned char StartBit2;
unsigned char Control;
unsigned char Add[5];
unsigned char AFN;
unsigned char SEQ;
unsigned char DA1;
unsigned char DA2;
unsigned char DT1;
unsigned char DT2;
unsigned char CS;
unsigned char EndBit;
}LoginStruct;
typedef union Login_Union
{
unsigned char bytes[20];
LoginStruct LoginS;
}LoginUnion;
/*
*****************************************************************************************************
*FUNC:
*NOTE: 字符变BCD 如"9" 变成 0X09
*****************************************************************************************************
*/
unsigned char CharToBcd(unsigned char ch)
{
if ((ch >= '0') && (ch <= '9')) {
return (ch - 0x30);
}
if ((ch >= 'A') && (ch <= 'F')) {
return (ch - 0x37); //0X41 - 0X37 = 10
}
if ((ch >= 'a') && (ch <= 'f')) {
return (ch - 0x57); //0x61 - 0x57 = 10
}
}
/*
*****************************************************************************************************
*FUNC: ID变成BCD码
*NOTE: //转换ID为BCD码
*****************************************************************************************************
*/
void ID2BCD(void)
{
unsigned char i=0,j=0;
unsigned char High,Low;
for (j=0; j<4; j++) {
High = CharToBcd(ModelIdBak[i++]);
Low = CharToBcd(ModelIdBak[i++]);
High <<= 4;
AddBytes[j] = High | Low; // 0x90 0x20 0x12 0x34
}
}
/*
*****************************************************************************************************
*FUNC: 数据压入重发缓冲区
*NOTE:
*****************************************************************************************************
*/
unsigned char xdata ResentIn,ResentOut;
void Push2Resent(unsigned char *source,unsigned int length)
{
unsigned int i=0;
while (ResentIn < RESENT_BUF_NUM) {
if (ResentBufS[ResentIn].Statu == STATU_IDLE) {
DebugMsg(32,NULL);
for (i=0; i<length; i++) {
ResentBufS[ResentIn].Buf[i] = source[i]; //拷贝数据
}
ResentBufS[ResentIn].Statu = WAIT_SENT; //有数据等待发送
ResentBufS[ResentIn].Checked = RESENT_UNCHECKED;
ResentBufS[ResentIn].PFC = PFC & 0x0f; //取后四位1-16侦序号
PFC++;
ResentBufS[ResentIn].Interval = 0; //间隔时间清0
ResentBufS[ResentIn].Count = 3; //重发次数
ResentBufS[ResentIn].Length = length; //长度
ResentIn++;
break;
} else {
ResentIn++;
}
}
if (ResentIn >= RESENT_BUF_NUM) {
ResentIn = 0;
}
}
/*
*****************************************************************************************************
*FUNC: 计算检验和
*NOTE:
*****************************************************************************************************
*/
unsigned char GetCheckSum(unsigned char *Source,unsigned int Length)
{
unsigned int i;
unsigned char CS=0;
for (i=0; i<Length; i++) {
CS += *(Source + i);
}
return CS;
}
/*
*****************************************************************************************************
*FUNC: 登陆包DL2004协议
*NOTE:
*****************************************************************************************************
*/
void LoginMsg2004(void)
{
LoginUnion xdata LoginU;
unsigned char High,Low;
RSBInit(); // 登陆时清重发各缓冲区
LoginU.LoginS.StartBit1 = 0x68;
LoginU.LoginS.L_High = 12; // L1 = 用户数据 + 8字节的头部数据 = 20字节
LoginU.LoginS.L_High <<= 2; // D15-D2
LoginU.LoginS.L_High += 1;
LoginU.LoginS.L_Low = LoginU.LoginS.L_High;
LoginU.LoginS.StartBit2 = 0x68;
LoginU.LoginS.Control = 0 | DIR | PRM | FUNCCODE_R_A; //控制域
LoginU.LoginS.Add[0] = AddBytes[1]; //0X20
LoginU.LoginS.Add[1] = AddBytes[0]; //0X90
LoginU.LoginS.Add[2] = AddBytes[3]; //0X34
LoginU.LoginS.Add[3] = AddBytes[2]; //0X12
LoginU.LoginS.Add[4] = 0;
LoginU.LoginS.AFN = 0X02; //AFN
LoginU.LoginS.SEQ = 0 | FIR | FIN | CON |(PFC & 0x0f); //侦序列域,计数器的低四位
LoginU.LoginS.DA1 = 0x0; //DA1=0 P0
LoginU.LoginS.DA2 = 0x0; //DA2=0
LoginU.LoginS.DT1 = 0x01; //DT1=1 F1
LoginU.LoginS.DT2 = 0x00; //DT2=0
LoginU.LoginS.CS = GetCheckSum(&LoginU.bytes[6],12);
LoginU.LoginS.EndBit = 0x16;
//对调长度高低字节 //1,2,3,4,
High = LoginU.bytes[1];
Low = LoginU.bytes[2];
LoginU.bytes[1] = Low;
LoginU.bytes[2] = High;
High = LoginU.bytes[3];
Low = LoginU.bytes[4];
LoginU.bytes[3] = Low;
LoginU.bytes[4] = High;
Push2Resent(LoginU.bytes,20);
}
/*
*****************************************************************************************************
*Func: 发送心跳包
*Note:
*****************************************************************************************************
*/
void SendHeart2004(void)
{
LoginUnion xdata LoginU;
unsigned char High,Low;
LoginU.LoginS.StartBit1 = 0x68;
LoginU.LoginS.L_High = 12; // L1 = 用户数据 + 8字节的头部数据 = 20字节
LoginU.LoginS.L_High <<= 2; // D15-D2
LoginU.LoginS.L_High += 1;
LoginU.LoginS.L_Low = LoginU.LoginS.L_High;
LoginU.LoginS.StartBit2 = 0x68;
LoginU.LoginS.Control = 0 | DIR | PRM | FUNCCODE_R_A; //控制域
LoginU.LoginS.Add[0] = AddBytes[1]; //0X20
LoginU.LoginS.Add[1] = AddBytes[0]; //0X90
LoginU.LoginS.Add[2] = AddBytes[3]; //0X34
LoginU.LoginS.Add[3] = AddBytes[2]; //0X12
LoginU.LoginS.Add[4] = 0;
LoginU.LoginS.AFN = 0X02; //AFN
LoginU.LoginS.SEQ = 0 | FIR | FIN | CON | (PFC & 0x0f); //侦序列域,计数器的低四位
LoginU.LoginS.DA1 = 0x0; //DA1=0 P0
LoginU.LoginS.DA2 = 0x0; //DA2=0
LoginU.LoginS.DT1 = 0x04; //DT1=1 F1
LoginU.LoginS.DT2 = 0x00; //DT2=0
LoginU.LoginS.CS = GetCheckSum(&LoginU.bytes[6],12);
LoginU.LoginS.EndBit = 0x16;
//对调长度高低字节 //1,2,3,4,
High = LoginU.bytes[1];
Low = LoginU.bytes[2];
LoginU.bytes[1] = Low;
LoginU.bytes[2] = High;
High = LoginU.bytes[3];
Low = LoginU.bytes[4];
LoginU.bytes[3] = Low;
LoginU.bytes[4] = High;
Push2Resent(LoginU.bytes,20);
if (SendHeartFlag == FALSE) {
SendHeartFlag = TRUE; // 置已发标志
TimerSec[T_SOCKET_TTL] = SOCKET_TTL_SEC; // 时间初始化2分钟
}
}
/*
*****************************************************************************************************
*FUNC: 根据DA1 DA2 取得 PN
*NOTE:
*****************************************************************************************************
*/
#define UNKONW_FN 0
#define UNKONW_PN 255
unsigned char GetPn(unsigned char DA1, unsigned char DA2)
{
unsigned char i,j;
unsigned char DA2_Bit1=0;
unsigned char DA1_Bit1=0;
if ((DA1 == 0) && (DA2 == 0)) {
return 0;
}
for (i=0; i<8; i++) {
if (DA2 == (1 << i)) {
DA2_Bit1 = i;
for (j=0; j<8; j++) {
if (DA1 == (1 << j)) {
DA1_Bit1 = j+1;
return(DA2_Bit1*8 + DA1_Bit1);
}
}
return UNKONW_PN;
}
}
return UNKONW_PN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -