private void L2OnRcvData(object obj) { ByteBuffer queue = obj as ByteBuffer; if (l2State != L2State_E.WAIT_RESP_MODE) { l2State = L2State_E.RX_MODE; } byte u8Temp = 0; ByteBuffer fifo = obj as ByteBuffer; /*Split data to package*/ u8Temp = fifo.GetFirstByte(); if (u8Temp != L1Object.PREAMBLE) { do { /*Remove the first slot in fifo*/ fifo.RetriveByte(); if (fifo.GetLength() == 0) { return; } u8Temp = fifo.GetFirstByte(); } while ((fifo.GetLength() > 0) && (u8Temp != L1Object.PREAMBLE)); } if (fifo.GetLength() > 0) { /*Wait for getting full header data*/ if (fifo.GetLength() >= L1Object.HEADER_LENGTH) { if (bIsHeaderDetected != 1) { /*Get payload length*/ byte[] u8Header = fifo.GetNBytes(L1Object.HEADER_LENGTH); if (!L1Object.L1Object_CheckCRC(u8Header, 0, L1Object.HEADER_LENGTH)) { /*Wrong CRC Header*/ fifo.RetriveBytes(L1Object.HEADER_LENGTH); l2State = L2State_E.NORMAL_MODE; return; } u16PayloadLengthWaitting = (UInt16)((u8Header[L1Object.LEN_OFFSET] << 8) + u8Header[L1Object.LEN_OFFSET + 1]); bIsHeaderDetected = 1; } if (u16PayloadLengthWaitting > L1Object.MAX_PAYLOAD_LEN) { /*Length of payload is over defined maximum value*/ byte[] u8Buff = new byte[L1Object.HEADER_LENGTH]; fifo.RetriveBytes(L1Object.HEADER_LENGTH); bIsHeaderDetected = 0; l2State = L2State_E.NORMAL_MODE; return; } else { if (fifo.GetLength() < u16PayloadLengthWaitting + L1Object.HEADER_LENGTH + 1) { l2State = L2State_E.NORMAL_MODE; /*Do not enough data*/ return; } else { sL1Object_t L1Obj = new sL1Object_t(); //ASSERT(u8Pkg); byte[] u8Pkg = fifo.RetriveBytes(u16PayloadLengthWaitting + L1Object.HEADER_LENGTH + 1); bIsHeaderDetected = 0; /*Check CRC DATA and build package*/ if (L1Object.L1Object_ArrayToPkg(u8Pkg, u16PayloadLengthWaitting + L1Object.HEADER_LENGTH + 1, ref L1Obj) == 1) { /*Check received sequence and set the last sequence*/ if (IsValidSequence(L1Obj) == 1) { /*Check Minor CMD : ACK/NAK/DATA...*/ if (L1Object.L1Object_IsACKPkg(L1Obj)) { /*Post semaphore ACK signal*/ eACK = eACKType_t.ACK; ACKRespondEvent.Set(); } else if (L1Object.L1Object_IsNAKPkg(L1Obj)) { /*Post semaphore NAK signal*/ eACK = eACKType_t.NAK; ACKRespondEvent.Set(); } else if (L1Object.L1Object_IsPingPkg(L1Obj)) { /*NOTE Process PING pakage*/ /*Reset sequence and sync key*/ u8LastRecvSeq = 255; } else if (L1Object.L1Object_IsSetAesKeyPkg(L1Obj)) { /*Process SetAesKey pakage*/ //(u8AesKey, 0x00, L1Object.MAX_KEY_SIZE); /*NOTE :Decrypt data and save to Aes key*/ } else if (L1Object.L1Object_IsSyncKeyReqPkg(L1Obj)) { /*NOTE :Process SyncKey request pakage*/ /*Be ware that here is running in receiver interrupt*/ } else { /*Process data package*/ /*Call up to L3*/ if (callbackFunc != null) { callbackFunc(L1Obj.aPayLoad); } if (L1Obj.bIsNeedFeedBackACK != 0) { L2SendCMD((byte)PKG_TYPE.ACK_PKG); } } } else { Trace.WriteLine("Invalid sequence!\r\n"); if (L1Object.L1Object_IsPingPkg(L1Obj)) { /*NOTE Process PING package*/ /*Reset sequence and sync key*/ u8LastRecvSeq = 255; } else if (L1Obj.bIsNeedFeedBackACK != 0) { /*Get the same package, resend the last ACK/NAK package*/ L2ReSendLastCMD(); } else { /*Ignore*/ } }/*End of check valid sequence*/ } else { /*Data has wrong format*/ /*Send NAK if this is mode needing return ACK*/ if (L1Obj.bIsNeedFeedBackACK != 0) { L2SendCMD((byte)PKG_TYPE.NAK_PKG); } l2State = L2State_E.NORMAL_MODE; return; } /*End check CRC data*/ } /*End of build package*/ l2State = L2State_E.NORMAL_MODE; return; } /*End of check length of package*/ } /*End of check length of header*/ } /*End of Check preamble */ return; }
private void L2SendPkg(L2Pkg pkg) { if (pkg.isNeededACK) { int sendTimes = (int)pkg.resend + 1; bool respond = false; //Send data and wait respond do { l2State = L2State_E.TX_MODE; sL1Object_t obj = new sL1Object_t(); L1Object.L1Object_BuildFromData(this, pkg.data, pkg.MinorCmd, u8Seq, ref obj); byte[] temp = new byte[pkg.data.Length + 1 + L1Object.HEADER_LENGTH]; L1Object.L1Object_L1ObjectToArray(obj, ref temp); L1Handler.Send(temp); l2State = L2State_E.WAIT_RESP_MODE; //Wait respond event if (ACKRespondEvent.WaitOne(TIME_WAIT_DEV_RESPOND)) { respond = true; } else { Trace.WriteLine("L2:Resend " + sendTimes.ToString()); if (IsResetEn) { try { L1Handler.Close(); L1Handler.Open(); } catch (Exception ex) { l2State = L2State_E.ERROR; Trace.WriteLine(ex.Message); } } } ACKRespondEvent.Reset(); sendTimes--; } while (respond == false && sendTimes > 0); if (respond == false && sendTimes <= 0) { l2State = L2State_E.ERROR; } else { l2State = L2State_E.NORMAL_MODE; } } else { l2State = L2State_E.TX_MODE; sL1Object_t obj = new sL1Object_t(); L1Object.L1Object_BuildFromData(this, pkg.data, pkg.MinorCmd, u8Seq, ref obj); byte[] temp = new byte[pkg.data.Length + 1 + L1Object.HEADER_LENGTH]; L1Object.L1Object_L1ObjectToArray(obj, ref temp); L1Handler.Send(temp); l2State = L2State_E.NORMAL_MODE; } }