예제 #1
0
        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;
        }
예제 #2
0
        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;
            }
        }