104规约文章很长,很难理解,对于初学的人员来说比较难理解,其实104规约主要理解一下报头部分的控制报文。
- //设置遥测APCI
- void CMainFrame::SetYCAPCI()
- {
- memset(byteAPDUYC,0,sizeof(byteAPDUYC));//初始化
- //计算报头字节
- //////////////////APCI//////////////////////////////////////////////////////
- byteAPDUYC[0] = 0x68;//报头字
- byteAPDUYC[1] = 0xFA;//APDU长度,最大253 计算**
-
- byteAPDUYC[2] = 0x12;//1 8位控制域 低位 00000010
- byteAPDUYC[3] = 0x00;//2 8位控制域 高位 00000000
- // 0000000000000010 I格式发送帧计数
- byteAPDUYC[4] = 0x02;//3 8位控制域 低位 00000010
- byteAPDUYC[5] = 0x00;//4 8位控制域 高位 00000000
- // 0000000000000010 I格式接收帧计数
- /////////////////////ASDU////////////////////////////////////////////////
- byteAPDUYC[6] = 0x15;//标识符 遥测
- //可变帧限定词 10111100 第一位1表示连续,如果为0表示非连续
- byteAPDUYC[7] = 0xBC;//计算** 0111100 60个数据
- //传送原因
- byteAPDUYC[8] = 0x14;//响应总召唤 传送原因
- byteAPDUYC[9] = 0x00;//响应总召唤 传送原因
- }
理解了报头就知道了,我们在组包的时候就需要将数据加上,要计算数据的长度。
- //发送遥信数据
- void CMainFrame::SendYXData()
- {
- //总遥信个数
- int iYXByteCout = dbm.yxsum;
- //APDU个数
- int iAPDUCout = 0;
- //最后一帧APDU字节数
- int iLastAPDUCout = 0;
- //最大遥信字节数
- int iMaxYx = 127;
- //得到APDU个数
- iAPDUCout = iYXByteCout / iMaxYx;
- //得到最后一帧APDU字节数
- iLastAPDUCout = iYXByteCout % iMaxYx;
- //循环组APDU
- for(int w=0;w<iAPDUCout;w++)
- {
- SetYXAPCI();
- //计算公共地址 ASDU地址
- BYTE *pXXTDZ = new byte[2];
- memcpy(pXXTDZ, &dbm.r_yx[w*iMaxYx].NU, 2);
- //给公共地址赋值
- byteAPDU[10] =pXXTDZ[0]; //ASDU地址 可能要累加计算** (低位在前,高位在后)2A 75
- byteAPDU[11] =pXXTDZ[1];
- //释放临存公共地址的空间
- free(pXXTDZ);
- //信息体
- //如果SQ=0,表示非连续数据,一个三字节信息地址,一个一字节遥信数据
- //如果SQ=1,表示连续数据,用公用地址,然后连续一个字节遥信数据
- int iIndex = 0;//累加号
- for(int i=(w*iMaxYx);i<((w+1)*iMaxYx);i++)
- {
- byteAPDU[12+iIndex] = (BYTE)dbm.r_yx[i].val;
- iIndex++;
- }
- //校验和CS
- byteAPDU[12+iIndex] = 0x89;
- //结束标识
- byteAPDU[13+iIndex] = 0x16;
- //发送
- if(m_pMListenSocket->CheckpClientSocket(m_pMListenSocket->m_pClientSocket))
- {
- //SetSendBufData(byteAPDU,sizeof(byteAPDU));
- m_pMListenSocket->m_pClientSocket->SendTo(byteAPDU,141,atoi(strPort),strIP);
- Sleep(100);
- }
- }
- //最后一个APDU组包
- SetYXAPCI();
- //计算APDU长度
- int ilastLen = iLastAPDUCout+10;
- BYTE *pAPDULEN = new byte[1];
- memcpy(pAPDULEN, &ilastLen, 1);
- byteAPDU[1] = pAPDULEN[0];
- //计算可变帧限定词
- BYTE *pAPDULENKB = new byte[1];
- memcpy(pAPDULENKB, &iLastAPDUCout, 1);
- byteAPDU[7] =(pAPDULENKB[0]|0x80);//高位补1
- free(pAPDULENKB);
- //计算公共地址 ASDU地址
- BYTE *pXXTDZ = new byte[2];
- memcpy(pXXTDZ, &dbm.r_yx[iAPDUCout*iMaxYx].NU, 2);
- //给公共地址赋值
- byteAPDU[10] =pXXTDZ[0]; //ASDU地址 可能要累加计算** (低位在前,高位在后)2A 75
- byteAPDU[11] =pXXTDZ[1];
- //释放临存公共地址的空间
- free(pXXTDZ);
- int iIndex = 0;//顺序号
- for(int i=(iAPDUCout*iMaxYx);i<iYXByteCout;i++)
- {
- byteAPDU[12+iIndex] = (BYTE)dbm.r_yx[i].val;
- iIndex++;
- }
- //校验和CS
- byteAPDU[12+iIndex] = pAPDULEN[0];//CS校验和
- free(pAPDULEN);
- //结束标识
- byteAPDU[13+iIndex] =0x16;
- //发送
- if(m_pMListenSocket->CheckpClientSocket(m_pMListenSocket->m_pClientSocket))
- {
- //SetSendBufData(byteAPDU,sizeof(byteAPDU));
- m_pMListenSocket->m_pClientSocket->SendTo(byteAPDU,sizeof(byteAPDU),atoi(strPort),strIP);
- Sleep(100);
- }
- }
阅读(11253) | 评论(0) | 转发(0) |