📄 serialcomm.cpp
字号:
// SerialComm.cpp : Defines the entry point for the DLL application.
//
//History
//*Data *Name *comments.
//2008-Feb-03 Rock Li Initialization
#include "stdafx.h"
#include "SerialComm.h"
#include "SerialBase.h"
//Added the command by Rock Li
// New Key word. It should be well-arranged in the future.
#define CMD_DOWN_SEND_UNACK_DATA_TO_TN 0xD0 // SendUnackDataToTN
#define CMD_DOWN_SEND_ACK_DATA_TO_TN 0xD1 // SendAckDataToTN
#define CMD_ACK_SEND_ACK_DATA_TO_TN 0xD2 // SendAckDataToTN
#define CMD_DOWN_DOWNLOAD_UID 0xEF //DownloadUID
#define CMD_DOWN_RUN_NET_BUILD 0xEE //RunNetBuild
#define MAX_UID 8 //DownloadUID
//End of adding by Rock Li
#define UNIQUE_NODE_ID_LEN 6
#define MAX_ROUTE_NODE_NUM 8 //最多路由中继数
#define MAX_CONF_NODE_NUM 6 //记录相邻的已配置节点数
#define __LITTLE_ENDIAN_BITFIELD 1
#pragma pack(1)
typedef struct
{
unsigned char comand; //CMD_DOWN_0 EF
unsigned char trans_length;
unsigned char reserved; //sometimes it is used for check sum
}UartHead; //head of Uart
#pragma pack()
typedef struct
{
UartHead head;
unsigned char UID[MAX_UID][6];
}UartDownloadUID; //上位机对下层传的UID download命令格式。
typedef unsigned char Byte;
typedef unsigned char uint8;
typedef unsigned char Bits;
typedef struct
{
uint8 subnetID;
#if defined(__LITTLE_ENDIAN_BITFIELD)
Bits node : 7;
Bits : 1;
#elif defined(__BIG_ENDIAN_BITFIELD)
Bits : 1;
Bits node : 7;
#else
////#error "ENDIAN_BITFIELD not specified"
#endif
} SubnetNodeAddr; //记录一个节点的逻辑地址
typedef struct
{
#if defined(__LITTLE_ENDIAN_BITFIELD)
Bits routeNodeNum :4; //保存路由节点的个数
Bits pollFailTimes :2; //状态查询失败的次数
Bits unused :2;
#elif defined(__BIG_ENDIAN_BITFIELD)
Bits unused :2;
Bits pollFailTimes :2; //状态查询失败的次数
Bits routeNodeNum :4; //保存路由节点的个数
#else
////#error "ENDIAN_BITFIELD not specified"
#endif
SubnetNodeAddr routeNode[MAX_ROUTE_NODE_NUM]; //路由节点的逻辑地址
Byte statusWord;
}DownlinkPath; //CC到终端的下行路径
typedef struct
{
SubnetNodeAddr subnetNodeAddr; //分配给终端的逻辑地址
#if defined(__LITTLE_ENDIAN_BITFIELD)
Bits valueofQ :4; //通信质量
Bits level :4; //该节点到CC的路由级数
#elif defined(__BIG_ENDIAN_BITFIELD)
Bits level :4; //该节点到CC的路由级数
Bits valueofQ :4; //通信质量
#else
#error "ENDIAN_BITFIELD not specified"
#endif
uint8 generalQ; //记录广义的Q值,该值只记录,不保存,在掉电后再上电初始化的时候,重新由Q和路由级数计算
}ConfiguredNode;
typedef struct
{
ConfiguredNode configuredList[MAX_CONF_NODE_NUM]; //已配置邻居节点列表
unsigned char confNodeCnt; //已配置邻居节点列表中节点的个数
// UnConfiguredNode unconfiguredList[MAX_UNCONF_NODE_NUM]; //未配置邻居节点列表
// unsigned char unconfNodeCnt; //未配置邻居节点列表中节点的个数
}NeighborNode;
typedef struct
{
#if defined(__LITTLE_ENDIAN_BITFIELD)
Bits ifConfigued :1; //是否被配置
Bits bValid :1; //表示该节点的信息是否有效
Bits currPath :1; //0:表示主路径;1:表示辅路径
Bits needConfig :1; // 1:表示需要配置,0:不需要配置
Bits pathNum :2; //表示路径条数
Bits unused :2;
#elif defined(__BIG_ENDIAN_BITFIELD)
Bits unused :2;
Bits pathNum :2; //表示路径条数
Bits needConfig :1; // 1:表示需要配置,0:不需要配置
Bits currPath :1; //0:表示主路径;1:表示辅路径
Bits bValid :1; //表示该节点的信息是否有效
Bits ifConfigued :1; //是否被配置
#else
////#error "ENDIAN_BITFIELD not specified"
#endif
DownlinkPath priPath; //主路径
DownlinkPath secPath; //辅路径
Byte uniqueNodeId[UNIQUE_NODE_ID_LEN]; //终端节点地址
SubnetNodeAddr subnetNodeAddr; //分配给终端的逻辑地址
NeighborNode neiborList; //相邻节点信息
uint8 Qvalue; //记录Q值
SubnetNodeAddr priUplinkNode; //上行的主节点
SubnetNodeAddr secUplinkNode; //上行的第二个节点
uint8 CCQvalue;
}NodeInfo; //一条路由通道信息
#define MAX_TERMINAL_NUM 36 //最多终端数
#define MAX_ROUTE_NODE_NUM 8 //最多路由中继数
#define MAX_CONF_NODE_NUM 6 //记录相邻的已配置节点数
#define MAX_UNCONF_NODE_NUM 4 //记录相邻的未配置节点数
#define UNIQUE_NODE_ID_LEN 6
#define cmd_1 0xFF // 组网期间的信息上传
#define cmd_2 0xFE // 组网完成后的信息上传
#define cmd_3 0xFD // 收到数据包的信息
#define cmd_4 0xFC // UID下载是否成功的CC回执给上位机的信息
#define cmd_5 0xFB // (手动组网模式)集中器返回握手信息,表示可以接收命令
#define cmd_6 0xFA //(手动组网模式)集中器APP返回下载UID校验正确的信息
#define CMD_DOWN_0 0xEF //Load UID ,命令
#define CMD_DOWN_1 0xEE //组网命令
#define CMD_DOWN_2 0xEC //开灯关灯命令
#define CMD_DOWN_3 0xEA //(自动组网模式中)自动轮询和按键轮询的命令,,CC图标的右键菜单下达
#define CMD_DOWN_4 0xE9 //设置轮询方式
#define CMD_DOWN_5 0xE8 //增加一个节点,输入的都是uid
#define CMD_DOWN_6 0xE7 //删除一个节点,根据节点的uid删除一个节点
#define CMD_DOWN_7 0xE6 //查询一个或多个节点,输入的都是uid
#define CMD_DOWN_8 0xE5 //配置一个或多个节点,输入的都是uid
#define CMD_DOWN_9 0xE4 //(手动组网模式中)上位机下达命令前的握手命令,察看集中器是否忙
#define CMD_DOWN_10 0xE3 //手动自动都用的设置组网参数
#define CMD_DOWN_11 0xE2 //指定路由信息的命令
#define CMD_DOWN_15 0xDE //手动组网,利用某点查结点间的Q值,节点到节点的Q值查询
#define PC_REV_CMD_LEN 0x4E
//Added by Rock 2008-Feb-01
#define MAX_NUM_TN 100;
typedef struct
{
unsigned char uniqueNodeId[UNIQUE_NODE_ID_LEN];
}UID;
typedef struct tag_TN_Info
{
unsigned char nodecnt; //225
UID uid; //UID information
SubnetNodeAddr la; //Logic Address
}TN_Info;
static TN_Info m_tnInfo[100];
static unsigned char m_AckCmd[] = {
cmd_1,
cmd_2,
cmd_3,
cmd_4,
cmd_5,
cmd_6,
CMD_ACK_SEND_ACK_DATA_TO_TN
}; //the name should be adjusted
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
SERIALCOMM_API bool DownloadUID(unsigned char *p_TermUID, int NumOfNodes)
{
//CMD_DOWN_DOWNLOAD_UID
//To make the check sum
if(NumOfNodes>MAX_UID)
{
return false;
}
UartDownloadUID package;
memset((void*)&package,0,sizeof(package));
unsigned char checkSum = 0;
for(int i=0; i < NumOfNodes * 6; i++)
{
checkSum += p_TermUID[i];
}
package.head.comand = CMD_DOWN_DOWNLOAD_UID;
package.head.trans_length = NumOfNodes * 6 + 3;
package.head.reserved = checkSum;
memcpy(package.UID,p_TermUID,NumOfNodes*6);
// bool WriteComm(unsigned char* lpBuffer, const DWORD dwBytesToWrite)
if(!WriteComm((unsigned char*)&package, package.head.trans_length))
{
return false;
}
pMsgQue ackMsg = NULL;
bool bRet = GetAckMessage(&ackMsg);
if(bRet)
{
if(ackMsg != NULL)
{
UartHead* headMsg = (UartHead*)ackMsg;
if(headMsg->comand == cmd_4) //this command should be adjusted.
{
if(headMsg->reserved == 0x01)
{
return true;
}
else
{
return false;
}
}
else
{
//it is impossible; program error
return false;
}
}
}
else
{
return false;
}
return true;
}
SERIALCOMM_API bool DllInit(HANDLE hProExit, char szComName[])
{
//bool Init(HANDLE hProExit, unsigned char uploadCmd[],char szComName[])
return Init(hProExit, m_AckCmd,szComName);
// return true;
}
SERIALCOMM_API bool DllCleanUp()
{
return CleanUp();
}
SERIALCOMM_API bool RunNetBuild(void)
{
//CMD_DOWN_DOWNLOAD_UID
//To make the check sum
UartHead rxDataHead;
memset((void*)&rxDataHead, 0, sizeof(rxDataHead));
rxDataHead.comand = CMD_DOWN_RUN_NET_BUILD;
rxDataHead.trans_length = 0x3;
rxDataHead.reserved = 0x00;
if(!WriteComm((unsigned char*)&rxDataHead,rxDataHead.trans_length))
{
return false;
}
/*
pMsgQue ackMsg = NULL;
bool bRet = GetAckMessage(&ackMsg);
if(bRet)
{
if(ackMsg != NULL)
{
UartHead* headMsg = (UartHead*)ackMsg;
if(headMsg->comand == cmd_4) //this command should be adjusted.
{
if(headMsg->reserved == 0x01)
{
return true;
}
else
{
return false;
}
}
else
{
//it is impossible; program error
return false;
}
}
}
else
{
return false;
}
*/
return true;
}
//Purpose: To sends unacknowledged data to a TN.
//Arguments description:
//p_TermUID --> An pointer to UID of one terminal Node
//p_InDataBuf -->An pointer to the Data to be sent
//inDataLen -->the length of the data
//return value: true for success and false for failure
//comments: inDataLen should be less than 200. Or it will return false.
SERIALCOMM_API bool SendUnAckDataToTN ( unsigned char *p_TermUID,
unsigned char *p_InDataBuf,
unsigned char inDataLen)
{
#pragma pack(1)
struct tag_UserData
{
UartHead head;
unsigned char data[256];
} txUserData;
#pragma pack()
if(inDataLen >200)
{
return false;
}
memset((void*)&txUserData, 0, sizeof(txUserData));
txUserData.head.comand = CMD_DOWN_SEND_UNACK_DATA_TO_TN;
txUserData.head.trans_length = 0x3 + 6 + inDataLen;
txUserData.head.reserved = 0x00;
memcpy(&txUserData.data, p_TermUID ,6);
memcpy( (char*)&txUserData.data + 6, (void*)p_InDataBuf ,inDataLen);
//we should use sizeof function to check the length of data, To ensure that align =1
if(!WriteComm((unsigned char*)&txUserData,txUserData.head.trans_length))
{
return false;
}
return true;
}
//Purpose: To sends unacknowledged data to a TN.
//Arguments description:
//p_TermUID --> An pointer to UID of one terminal Node
//p_InDataBuf -->An pointer to the Data to be sent
//inDataLen -->the length of the data
//return value: true for success and false for failure
//comments: inDataLen should be less than 200. Or it will return false.
SERIALCOMM_API bool SendAckDataToTN ( unsigned char *p_TermUID,
unsigned char *p_InDataBuf,
unsigned char inDataLen,
unsigned char *p_RespData,
unsigned char *p_RespDataLen)
{
#pragma pack(1)
struct tag_UserData
{
UartHead head;
unsigned char data[256];
} txUserData;
#pragma pack()
if(inDataLen >200)
{
return false;
}
memset((void*)&txUserData, 0, sizeof(txUserData));
txUserData.head.comand = CMD_DOWN_SEND_ACK_DATA_TO_TN;
txUserData.head.trans_length = 0x3 + 6 + inDataLen;
txUserData.head.reserved = 0x00;
memcpy(&txUserData.data, p_TermUID ,6);
memcpy( (char*)&txUserData.data + 6, p_InDataBuf ,inDataLen);
//we should use sizeof function to check the length of data, To ensure that align =1
if(!WriteComm((unsigned char*)&txUserData,txUserData.head.trans_length))
{
return false;
}
pMsgQue ackMsg = NULL;
bool bRet = GetAckMessage(&ackMsg);
if(bRet)
{
if(ackMsg != NULL)
{
UartHead* headMsg = (UartHead*)ackMsg;
if(headMsg->comand == CMD_ACK_SEND_ACK_DATA_TO_TN) //this command should be adjusted.
{
if(headMsg->reserved == 0x01)
{
return true;
}
else
{
return false;
}
}
else
{
//it is impossible; program error
return false;
}
}
}
else
{
return false;
}
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -