/// <summary> /// 进行会话初始化工作,即发送Hello报文 /// </summary> /// <returns>错误码</returns> public enErrCode InitiateConnect() { byte[] payload = new byte[3]; // 重置client sequence number m_u8TxPacketId = 0; // prepare hello packet payload[0] = API_VERSION; // version payload[1] = m_u8TxPacketId; // cliSeqNo payload[2] = 0; // mode // send hello packet sendRequestNoCheck(enCmd.CMID_HELLO, // cmdId false, // isAck false, // shouldBeAcked payload, // payload 3, // length null); // replyCb // remember state m_SerStatus = enSerStatus.SER_ST_HELLO_SENT; return(enErrCode.ERR_NONE); }
/// <summary> /// 会话状态变更回调函数,Serial层通过此函数通知Session层,当前会话状态变更 /// </summary> /// <param name="newStatus">新的会话状态</param> private void SessionStatusChanged(enSerStatus newStatus) { switch (newStatus) { case enSerStatus.SER_ST_DISCONNECTED: { Status = newStatus; CommStackLog.RecordInf(enLogLayer.eSession, "Disconnected!"); m_sigDisconnected.Set(); m_sigConnected.Reset(); m_sigSessionOK.Reset(); // 然后通知上层新的会话需求 if (SessionLost != null) { SessionLost(); } break; } case enSerStatus.SER_ST_CONNECTED: { Status = newStatus; CommStackLog.RecordInf(enLogLayer.eSession, "Connected!"); m_sigDisconnected.Reset(); // 新的会话构建完成,设置通知信号量 m_sigConnected.Set(); m_sigSessionOK.Set(); if (SessionBuilt != null) { SessionBuilt(); } break; } default: break; } }
/// <summary> /// 接受新的数据帧解析函数 /// </summary> /// <param name="rxFrame">帧数据及</param> /// <param name="rxFrameLen">帧长度</param> private void rxHdlcFrame(byte[] rxFrame, byte rxFrameLen) { if (rxFrame == null) { return; } if (isInvalidCmd(rxFrame[1])) { CommStackLog.RecordErr(enLogLayer.eSerial, "Err cmd(0x" + rxFrame[1].ToString("X2") + ")"); return; } bool isAck = false; bool shouldAck = false; bool isRepeatId = false; bool isNotifData = false; //接收报文的个数 m_i32RxFrameCnt++; // parse header m_u8RxControl = rxFrame[0]; m_RxCmdId = (enCmd)rxFrame[1]; m_u8RxSeqNum = rxFrame[2]; m_u8RxPyldLen = rxFrame[3]; enNotifyType notType = (enNotifyType)rxFrame[4]; if (m_RxCmdId == enCmd.CMDID_NOTIFICATION && (notType == enNotifyType.NOTIFID_NOTIFDATA || notType == enNotifyType.NOTIFID_NOTIFEVENT)) { isNotifData = true; } // 提取出HDLC帧中负载数据 Array.Copy(rxFrame, 4, m_u8aRxPayload, 0, m_u8RxPyldLen); // 解析接受到的HDLC帧是响应帧还是数据帧(请求帧) isAck = ((m_u8RxControl & FLAG_ACK) != 0); // 如果HDLC帧是数据帧解析接受到的HDLC帧是否需要应答 shouldAck = ((m_u8RxControl & FLAG_ACKNOWLEDGED) != 0); // 应答报文 if (isAck) { // 通知上层响应帧到达 if (m_u8RxPyldLen > 0) { // Kous: 是上层应用请求的响应报文,回调上层应用定义的响应通知函数 dispatchResponse(m_RxCmdId, m_u8aRxPayload, m_u8RxPyldLen); } } // 请求报文 else { // 非数据通知时才检测更新m_u8RxPacketId if (!isNotifData) { // 是否为重复请求报文 if (m_bRxPacketIdInit && m_u8RxSeqNum == m_u8RxPacketId) { CommStackLog.RecordInf(enLogLayer.eSerial, "SO(" + m_u8RxSeqNum.ToString() + ") repeats"); isRepeatId = true; } else { isRepeatId = false; m_bRxPacketIdInit = true; m_u8RxPacketId = m_u8RxSeqNum; // 记录接收到的报文序列号 } } // 如果报文是需要响应的报文,则在Ser层直接回应 if (shouldAck) { byte len = 1; byte[] payload = new byte[len]; payload[0] = (byte)eRC.RC_OK; //Thread.Sleep(20); output1Frame(FLAG_ACK | FLAG_ACKNOWLEDGED, (byte)m_RxCmdId, m_u8RxPacketId, len, payload, true); } switch (m_RxCmdId) { case enCmd.CMID_HELLO_RESPONSE: { if (m_u8RxPyldLen >= 5 && m_u8aRxPayload[HELLO_RESP_OFFS_RC] == 0 && m_u8aRxPayload[HELLO_RESP_OFFS_VERSION] == API_VERSION) { // change state m_SerStatus = enSerStatus.SER_ST_CONNECTED; // record manager sequence number m_bRxPacketIdInit = true; m_u8RxPacketId = m_u8aRxPayload[HELLO_RESP_OFFS_MGRSEQNO]; // 通知会话层新的会话已经建立 if (m_evStatusChanged != null) { m_evStatusChanged(m_SerStatus); } // 新的会话建立完成,则下发CLI命令 m_hdlcore.MoniterCli(); } ; break; } case enCmd.CMID_MGR_HELLO: { // 以下8行用于过滤短时间内收到的重复MgrHello报文 TimeSpan tsMgrHello = DateTime.Now - m_dtLastMgrHello; m_dtLastMgrHello = DateTime.Now; // 4秒内收到的MgrHello认为为重复 if (tsMgrHello.TotalMilliseconds < 2000) { CommStackLog.RecordInf(enLogLayer.eSerial, "Redundant MgrHello"); break; } // 以上8行用于过滤短时间内收到的重复MgrHello报文 if (m_u8RxPyldLen >= 2) { // change state m_SerStatus = enSerStatus.SER_ST_DISCONNECTED; // 通知会话层新的当前会话已经失效 if (m_evStatusChanged != null) { m_evStatusChanged(m_SerStatus); } } break; } default: { // dispatch //if (m_u8RxPyldLen > 0 && m_evRequestArrived != null && isRepeatId == false) // m_evRequestArrived(m_RxCmdId, m_u8RxControl, m_u8aRxPayload, m_u8RxPyldLen); if (m_u8RxPyldLen > 0 && m_evRequestArrived != null) { if (isNotifData) { m_evRequestArrived(m_RxCmdId, m_u8RxControl, m_u8aRxPayload, m_u8RxPyldLen); } else if (isRepeatId == false) { m_evRequestArrived(m_RxCmdId, m_u8RxControl, m_u8aRxPayload, m_u8RxPyldLen); } } break; } } // Kous: 清空接收负载缓存 Array.Clear(m_u8aRxPayload, 0, m_u8RxPyldLen); m_u8RxPyldLen = 0; } }