前面一节我们讲了固定帧:可变帧最大的区别在于数据不是连续的,都带地址信息,该地址信息就是点号。
//发送变化遥测数据,可变帧遥信
void CMainFrame::SendChangeYXData()
{
//总遥信个数
int iYXByteCout = dbm.yxcsum;
//APDU个数
int iAPDUCout = 0;
//最后一帧APDU字节数
int iLastAPDUCout = 0;
//最大遥信字节数
int iMaxYx = 60;
//得到APDU个数
iAPDUCout = iYXByteCout / iMaxYx;
//得到最后一帧APDU字节数
iLastAPDUCout = iYXByteCout % iMaxYx;
//循环组APDU
for(int w=0;w<iAPDUCout;w++)
{
memset(byteAPDUCYX,0,sizeof(byteAPDUCYX));//初始化
//计算报头字节
/APCI//
byteAPDUCYX[0] =0x68;//报头字
byteAPDUCYX[1] = 0xFA;//APDU长度250
byteAPDUCYX[2] =0x02;//1 8位控制域 低位 00000010
byteAPDUCYX[3] =0x00;//2 8位控制域 高位 00000000
// 0000000000000010 I格式发送帧计数
byteAPDUCYX[4] =0x02;//3 8位控制域 低位 00000010
byteAPDUCYX[5] =0x00;//4 8位控制域 高位 00000000
// 0000000000000010 I格式接收帧计数
/ASDU//
byteAPDUCYX[6] =0x01;//标识符 遥信
//可变帧限定词 01111111 第一位1表示连续,如果为0表示非连续
byteAPDUCYX[7] = 0x3C;//计算** 1111111 127个数据
//传送原因
byteAPDUCYX[8] =0x14;//响应总召唤 传送原因
byteAPDUCYX[9] =0x00;//响应总召唤 传送原因
//计算公共地址 ASDU地址
BYTE *pXXTDZ = new byte[2];
memcpy(pXXTDZ, &dbm.r_yxc[w*iMaxYx].NU, 2);
//给公共地址赋值
byteAPDUCYX[10] =pXXTDZ[0]; //ASDU地址 可能要累加计算** (低位在前,高位在后)2A 75
byteAPDUCYX[11] =pXXTDZ[1];
//释放临存公共地址的空间
free(pXXTDZ);
//信息体
//如果SQ=0,表示非连续数据,一个三字节信息地址,一个一字节遥信数据
//如果SQ=1,表示连续数据,用公用地址,然后连续一个字节遥信数据
int iIndex = 0;//累加号
for(int i=(w*iMaxYx);i<((w+1)*iMaxYx);i++)
{
BYTE *pXXTDZ1 = new byte[3];
memcpy(pXXTDZ1, &dbm.r_yxc[w*iMaxYx].NU, 3);
//给公共地址赋值
byteAPDUCYX[12+iIndex+0] =pXXTDZ1[0]; //ASDU地址 可能要累加计算** (低位在前,高位在后)2A 75
byteAPDUCYX[12+iIndex+1] =pXXTDZ1[1];
byteAPDUCYX[12+iIndex+2] =pXXTDZ1[2];
byteAPDUCYX[12+iIndex+3] = (BYTE)dbm.r_yxc[i].val;
free(pXXTDZ1);
iIndex = iIndex+4;
}
//校验和CS
byteAPDUCYX[12+iIndex] = 0xFA;
//结束标识
byteAPDUCYX[13+iIndex] = 0x16;
//发送
if(m_pMListenSocket->CheckpClientSocket(m_pMListenSocket->m_pClientSocket))
{
//SetSendBufData(byteAPDU,sizeof(byteAPDU));
m_pMListenSocket->m_pClientSocket->SendTo(byteAPDUCYX,sizeof(byteAPDUCYX),atoi(strPort),strIP);
Sleep(100);
}
}
//最后一个APDU组包
byteAPDUCYX[0] =0x68;//报头字
//计算APDU长度
int ilastLen = (iLastAPDUCout*4)+10;
BYTE *pAPDULEN = new byte[1];
memcpy(pAPDULEN, &ilastLen, 1);
byteAPDUCYX[1] = pAPDULEN[0];//APDU长度250
byteAPDUCYX[2] =0x02;//1 8位控制域 低位 00000010
byteAPDUCYX[3] =0x00;//2 8位控制域 高位 00000000
// 0000000000000010 I格式发送帧计数
byteAPDUCYX[4] =0x02;//3 8位控制域 低位 00000010
byteAPDUCYX[5] =0x00;//4 8位控制域 高位 00000000
// 0000000000000010 I格式接收帧计数
/ASDU//
byteAPDUCYX[6] =0x01;//标识符 遥信
//计算可变帧限定词
BYTE *pAPDULEN_ = new byte[1];
memcpy(pAPDULEN_, &iLastAPDUCout, 1);
//可变帧限定词 01111111 第一位1表示连续,如果为0表示非连续
byteAPDUCYX[7] = pAPDULEN_[0];//计算** 1111111 127个数据
free(pAPDULEN_);
//传送原因
byteAPDUCYX[8] =0x14;//响应总召唤 传送原因
byteAPDUCYX[9] =0x00;//响应总召唤 传送原因
//计算公共地址 ASDU地址
BYTE *pXXTDZ = new byte[2];
memcpy(pXXTDZ, &dbm.r_yxc[iAPDUCout*iMaxYx].NU, 2);
//给公共地址赋值
byteAPDUCYX[10] =pXXTDZ[0]; //ASDU地址 可能要累加计算** (低位在前,高位在后)2A 75
byteAPDUCYX[11] =pXXTDZ[1];
//释放临存公共地址的空间
free(pXXTDZ);
int iIndex = 0;//顺序号
for(int i=(iAPDUCout*iMaxYx);i<iYXByteCout;i++)
{
BYTE *pXXTDZ1 = new byte[3];
memcpy(pXXTDZ1, &dbm.r_yxc[w*iMaxYx].NU, 3);
//给公共地址赋值
byteAPDUCYX[12+iIndex+0] =pXXTDZ1[0]; //ASDU地址 可能要累加计算** (低位在前,高位在后)2A 75
byteAPDUCYX[12+iIndex+1] =pXXTDZ1[1];
byteAPDUCYX[12+iIndex+2] =pXXTDZ1[2];
byteAPDUCYX[12+iIndex+3] = (BYTE)dbm.r_yxc[i].val;
free(pXXTDZ1);
iIndex = iIndex+4;
}
//校验和CS
byteAPDUCYX[12+iIndex] = pAPDULEN[0];
free(pAPDULEN);
//结束标识
byteAPDUCYX[13+iIndex] =0x16;
//发送
if(m_pMListenSocket->CheckpClientSocket(m_pMListenSocket->m_pClientSocket))
{
//SetSendBufData(byteAPDU,sizeof(byteAPDU));
m_pMListenSocket->m_pClientSocket->SendTo(byteAPDUCYX,(14+iLastAPDUCout*4),atoi(strPort),strIP);
Sleep(100);
}
}