123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- // 协议栈模块
- // 秒寻科技
- // zt 2024-09-15
- package ap
- import (
- "encoding/binary"
- "errors"
- "ipsomc/module/ps/psmodel"
- )
- type Ap struct {
- }
- // 全局变量
- var (
- s_crc_table = [16]uint16{0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef}
- )
- // AP层上行处理单元
- func (obj *Ap) ApUl(dataList []byte, dataListLen *int) (*psmodel.PS_HEAD_T, *psmodel.PS_TAIL_T, error) {
- newLen := *dataListLen
- var wCrc uint16 = 0
- var psCrc uint16 = 0
- var psHeadModel *psmodel.PS_HEAD_T
- var psTailModel *psmodel.PS_TAIL_T
- var wStopIndex uint16 = 0
- //长度容错检查
- if newLen < psmodel.PS_FRAME_MIN_LEN {
- return nil, nil, errors.New("帧长度不合法")
- }
- //帧头帧尾检查
- if dataList[0] != psmodel.PS_AP_END_FLAG || dataList[newLen-1] != psmodel.PS_AP_END_FLAG {
- return nil, nil, errors.New("数据错误")
- }
- //逆向转义处理
- if err := obj.ApTransferReverse(dataList, &newLen); err != nil {
- return nil, nil, err
- }
- *dataListLen = newLen
- //解析数据到结构(协议头,协议尾)
- psHeadModel, psTailModel = obj.ApParseSlicToStruct(dataList, int32(newLen))
- //CRC校验
- psCrc = psTailModel.Crc //数据报文中的CRC校验码
- wStopIndex = uint16(newLen - 3)
- wCrc = obj.ApGenCrc16(dataList[1:wStopIndex], uint16(newLen), 0) //基于数据报文生成CRC校验码
- if wCrc != psCrc {
- return psHeadModel, psTailModel, errors.New("CRC校验错误")
- }
- return psHeadModel, psTailModel, nil
- }
- // 对输入数据实施逆向转义处理
- // byData:待逆转义数据,返回参数
- // pdwLen:数据长度,返回参数
- func (obj *Ap) ApTransferReverse(byData []byte, pdwLen *int) error {
- outData := make([]byte, 0)
- wCounter := 0
- // 逆向转义处理
- for i := 1; i < (*pdwLen - 1); i++ {
- //处理0x5E和0x5D两个连续字符
- if byData[i] == 0x5E && byData[i+1] == 0x5D {
- outData = append(outData, 0x5E)
- i++
- wCounter++
- } else if byData[i] == 0x5E && byData[i+1] == 0x7D { //处理0x5E和0x7D两个连续字符
- outData = append(outData, 0x7E)
- i++
- wCounter++
- } else { //处理其它字符
- outData = append(outData, byData[i])
- wCounter++
- }
- }
- // 将临时数据拷贝回byData切片中
- byData = byData[:0] //清空切片
- byData = append(byData, 0x7E) //保存帧头
- byData = append(byData, outData...) //保存数据
- byData = append(byData, 0x7E) //保存帧尾
- *pdwLen = wCounter + 2
- return nil
- }
- // 将切片数据解析到结构体中
- // dataList:数据切片
- func (obj *Ap) ApParseSlicToStruct(dataList []byte, dwLen int32) (*psmodel.PS_HEAD_T, *psmodel.PS_TAIL_T) {
- var psHeadModel psmodel.PS_HEAD_T
- var psTailModel psmodel.PS_TAIL_T
- var wTailIndex uint16 = 0
- var wStopIndex uint16 = 0
- //AP层
- psHeadModel.StApHead.StartFlag = dataList[0] //协议头
- //VP层
- psHeadModel.StVpHead.ProjectID = int(binary.LittleEndian.Uint32(dataList[1:5])) //项目编号 //项目编号
- psHeadModel.StVpHead.PacketNo = dataList[5] //协议包号
- psHeadModel.StVpHead.DeviceID = int(binary.LittleEndian.Uint32(dataList[6:10])) //设备编号
- psHeadModel.StVpHead.VpFlag = dataList[10] //VP层标识符
- psHeadModel.StVpHead.McpType = dataList[11] //MCP层协议类型
- //MCP层
- psHeadModel.StMcpHead.Comd = dataList[12] //MCP命令标识符
- psHeadModel.StMcpHead.Resp = dataList[13] //MCP响应标识符
- ////帧尾
- wTailIndex = uint16(dwLen - 3)
- wStopIndex = uint16(dwLen - 1)
- psTailModel.Crc = uint16(binary.LittleEndian.Uint16(dataList[wTailIndex:wStopIndex])) //CRC校验码
- psTailModel.StopFlag = dataList[wStopIndex] //结束标识符
- return &psHeadModel, &psTailModel
- }
- // 生成CRC16校验码
- // data:数据
- // len:数据长度
- // def_crc
- func (obj *Ap) ApGenCrc16(data []byte, len uint16, def_crc uint16) uint16 {
- var crc uint16 = def_crc
- var crc_h4 uint8 = 0
- for _, v := range data {
- crc_h4 = (uint8)(crc >> 12)
- crc <<= 4
- crc ^= s_crc_table[crc_h4^(v>>4)]
- crc_h4 = (uint8)(crc >> 12)
- crc <<= 4
- crc ^= s_crc_table[crc_h4^(v&0x0f)]
- }
- return crc
- }
- // AP层下行处理单元
- func (obj *Ap) ApDl(dataList []byte, dataListLen int) ([]byte, int, error) {
- newLen := dataListLen
- //长度容错检查
- if newLen < psmodel.PS_FRAME_MIN_LEN {
- return nil, 0, errors.New("帧长度不合法")
- }
- //帧头帧尾检查
- if dataList[0] != psmodel.PS_AP_END_FLAG || dataList[newLen-1] != psmodel.PS_AP_END_FLAG {
- return nil, 0, errors.New("数据错误")
- }
- //转义处理
- apFrame, err := obj.ApTransfer(dataList, &newLen)
- if err != nil {
- return nil, 0, err
- }
- return apFrame, newLen, nil
- }
- // 对输入数据实施转义处理
- // byData:待逆转义数据,返回参数
- // pdwLen:数据长度,返回参数
- func (obj *Ap) ApTransfer(byData []byte, pdwLen *int) ([]byte, error) {
- outData := make([]byte, 0)
- //帧头
- outData = append(outData, 0x7E)
- // 转义处理
- for i := 1; i < (*pdwLen - 1); i++ {
- if byData[i] == 0x5E { //将0x5E转义成0x5E,0x5D
- outData = append(outData, 0x5E)
- outData = append(outData, 0x5D)
- } else if byData[i] == 0x7E { //将0x7E转义成0x5E,0x7D
- outData = append(outData, 0x5E)
- outData = append(outData, 0x7D)
- } else { //其它字符
- outData = append(outData, byData[i])
- }
- }
- //帧尾
- outData = append(outData, 0x7E) //保存帧头
- *pdwLen = len(byData) //队列长度
- return outData, nil
- }
|