private void SendBlock(Object stateInfo)
        {
            bool sendComplete = false;

            try
            {
                // build a chunk 1 message
                CANFrame chunk1 = BuildChunk1(mBlockId, mBlockCRC, (uint)mBlockData.Length, mBlockVersion, 0);
                // send chunk 1
                mClient.Send(chunk1);

                // transfer the block
                CANFrame frame = new CANFrame();
                frame.MailboxId = (uint)CNXMsgIds.BlockChunkN + (uint)mBlockId;

                byte[] data = new byte[8];
                for (uint offset = 0; offset < mBlockData.Length; offset = mLastOffset > offset ? mLastOffset : offset + 4)
                //for (uint offset = 0; offset < mBlockData.Length; offset += 4)
                {
                    // set the offset
                    BitConverter.GetBytes(offset).CopyTo(data, 0);
                    if (!BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(data, 0, 4);
                    }
                    uint remainder = (uint)(mBlockData.LongLength - offset);
                    int  count     = (int)((remainder > 4) ? 4 : remainder);
                    Array.Copy(mBlockData, offset, data, 4, count);
                    frame.DataFromArray(data, 0, 4 + count);
                    int sent = mClient.Send(frame);
                    // pause to give CPC's time to commit to flash
                    // 40mS every 10 frames.
                    if (offset % 10 == 0)
                    {
                        Thread.Sleep(100);
                    }
                    Thread.Sleep(1);
                    for (int retry = 1; sent < 1 && retry < 10; ++retry)
                    {
                        Thread.Sleep(retry * 5);
                        sent = mClient.Send(frame);
                    }
                }
                // send chunk 1 for good luck
                Thread.Sleep(40);
                mClient.Send(chunk1);
                sendComplete = true;
                Thread.Sleep(40);
            }
            catch (Exception e)
            {
                CNXLog.ErrorFormat("SendBlock error - {0}", e.ToString());
            }
            BlockStateMachine(sendComplete ? BlockEvent.SendComplete : BlockEvent.SendFailed);
        }
        public static void SendBlock(object stateInfo)
        {
            if (stateInfo == null)
            {
                CNXLog.ErrorFormat("SendBlock - stateInfo NULL");
                return;
            }
            BlockInfo blockInfo = (BlockInfo)stateInfo;

            //CNXLog.InfoFormat("Running transfere for block {0}, CRC {1} {2}", blockInfo.mBlockId, blockInfo.mCrc, blockInfo.ToString());

            try
            {
                // build a chunk 1 message
                CANFrame chunk1 = BlockTransferManager.BuildChunk1(blockInfo.mBlockId, blockInfo.mCrc, (uint)blockInfo.mBlockData.Length, blockInfo.mVersion, 0);
                // send chunk 1
                //CNXLog.InfoFormat("Sending Block {0} Chunck 1 {1}.", blockInfo.mBlockId, chunk1.ToString());
                blockInfo.mClient.Send(chunk1);

                // transfer the block
                CANFrame frame = new CANFrame();
                frame.MailboxId = (uint)CNXMsgIds.BlockChunkN + (uint)blockInfo.mBlockId;

                byte[] data = new byte[8];
                for (uint offset = 0; offset < blockInfo.mBlockData.Length; offset += 4)
                {
                    // set the offset
                    BitConverter.GetBytes(offset).CopyTo(data, 0);
                    if (!BitConverter.IsLittleEndian)
                    {
                        Array.Reverse(data, 0, 4);
                    }
                    uint remainder = (uint)(blockInfo.mBlockData.LongLength - offset);
                    int  count     = (int)((remainder > 4) ? 4 : remainder);
                    Array.Copy(blockInfo.mBlockData, offset, data, 4, count);
                    frame.DataFromArray(data, 0, 4 + count);
                    int sent = blockInfo.mClient.Send(frame);
                    //CNXLog.InfoFormat("Sending Block {0} Chunck ({1}) {2}.", blockInfo.mBlockId, offset, frame.ToString());
                    Thread.Yield();
                    Thread.Sleep(10);
                    if (offset % 16 == 0)
                    {
                        //Console.WriteLine("Block pause.");
                        Thread.Yield();
                        Thread.Sleep(10);
                    }
                }
                // allow time for the block to be consumed
                Thread.Sleep(41);
                if (blockInfo.mRepeat != 0)
                {
                    frame.MailboxId = (uint)CNXMsgIds.BlockQuery + (uint)blockInfo.mBlockId;
                    frame.ClearData();
                    blockInfo.mClient.Send(frame);
                }
            }
            catch (ThreadAbortException)
            {
                // normal behaviour if the transfere is canceled
                CNXLog.WarnFormat("Block {0} transfere cancled.", (Block)blockInfo.mBlockId);
            }
            catch (Exception e)
            {
                CNXLog.ErrorFormat("SendBlock {0} {1}", (Block)blockInfo.mBlockId, e.ToString());
            }
        }
Exemple #3
0
        protected void OnDatagramReceivedEventHandler(object sender, DatagramReceivedEventArgs a)
        {
            CANFrame frame = new CANFrame();

            if (a.Datagram.Length < 4)
            {
                ServerMsgLog.WarnFormat("UDP out-of-range, length {0}", a.Datagram.Length);
                return;
            }

            uint msgId = 0;

            try
            {
                // work out what it all meens
                // first assume that the datgram is a CNX CAN message
                if (BitConverter.IsLittleEndian)
                {
                    Array.Reverse(a.Datagram, 0, 4);
                }
                msgId = BitConverter.ToUInt32(a.Datagram, 0);

                switch (msgId)
                {
                case (uint)CNXMsgIds.TripProgress:
                    frame.MailboxId = msgId;
                    frame.DataFromArray(a.Datagram, 4, a.Datagram.Length - 4);
                    TripProgressType msgType;
                    int pathId;
                    int position;
                    int?tripNo;
                    CNXCANMsgHelper.UnpackTripProgress(frame, out msgType, out pathId, out position, out tripNo);
                    object[] args = { msgType, pathId, position, tripNo };
                    ServerMsgLog.WarnFormat("UDP Trip Progress {0}, RouteTag {1}, Progress {2}, tripNo {3}.", args);
                    mCANClient.Send(frame);
                    break;

                case (uint)CNXMsgIds.DeviceCatalogue:
                    ServerMsgLog.WarnFormat("UDP Re-Cataloge message (0x101).");
                    // clear our catalogue
                    mCANServer.ClearDeviceCatalogue();
                    // put our self into the new catalogue
                    AddSelfToCatalogue();
                    // reset catalogues on all equipment.
                    frame.ClearData();
                    frame.MailboxId = (uint)CANLib.CNXMsgIds.DeviceCatalogue;
                    mCANClient.Send(frame);
                    mCANClient.Send(CNXCANMsgHelper.PackIdentifiers(mCommsServer.CommsAddress, mCommsServer.CompanyTag));
                    break;

                case (uint)CNXMsgIds.TripNone:
                case (uint)CNXMsgIds.TripOffRoute:
                    frame.MailboxId = msgId;
                    mCANClient.Send(frame);
                    ServerMsgLog.WarnFormat("UDP {0}.", (CNXMsgIds)msgId);
                    break;

                case (uint)CNXMsgIds.TripOnRoute:
                    frame.MailboxId = msgId;
                    frame.DataFromArray(a.Datagram, 4, a.Datagram.Length - 4);
                    ServerMsgLog.WarnFormat("UDP {0}.", frame.ToString());
                    mCANClient.Send(frame);
                    break;

                case (uint)RTTMesg.RTTInMsgIds.FirmwareBuildNos:
                    ServerMsgLog.WarnFormat("UDP firmware version (0x1001) length {0}\n{1}.", a.Datagram.Length, CommsServer.HexDump(a.Datagram, a.Datagram.Length));
                    if (a.Datagram.Length > 5)
                    {
                        StartFirmwareManagement(a.Datagram, 4);
                    }
                    break;

                case (uint)RTTMesg.RTTInMsgIds.ResourceBuildNos:
                    ServerMsgLog.WarnFormat("UDP configuration message (0x1002) length {0}\n{1}.", a.Datagram.Length, CommsServer.HexDump(a.Datagram, a.Datagram.Length));
                    if (a.Datagram.Length > 5)
                    {
                        byte[] versions = new byte[a.Datagram.Length - 4];
                        Array.Copy(a.Datagram, 4, versions, 0, versions.Length);
                        StartDeviceConfigurationManagement(versions);
                    }
                    break;

                case (uint)RTTMesg.RTTInMsgIds.CompanyTag:
                    mCommsServer.CompanyTag = a.Datagram[4];
                    ServerMsgLog.WarnFormat("UDP CompanyTag {0}", mCommsServer.CompanyTag);
                    mCANClient.Send(CNXCANMsgHelper.PackIdentifiers(mCommsServer.CommsAddress, mCommsServer.CompanyTag));
                    break;

                case (uint)RTTMesg.RTTInMsgIds.DriverLogonOK:
                    ServerMsgLog.WarnFormat("UDP {0}.", (RTTMesg.RTTInMsgIds)msgId);
                    frame.MailboxId = (uint)CNXMsgIds.LogonResult;
                    frame.Data      = new byte[1];
                    frame.Data[0]   = (byte)LogonState.LogonOK;
                    mCANClient.Send(frame);
                    break;

                case (uint)RTTMesg.RTTInMsgIds.DriverLogonFail:
                    ServerMsgLog.WarnFormat("UDP {0}.", (RTTMesg.RTTInMsgIds)msgId);
                    frame.MailboxId = (uint)CNXMsgIds.LogonResult;
                    frame.Data      = new byte[1];
                    frame.Data[0]   = (byte)LogonState.LogonFailed;
                    mCANClient.Send(frame);
                    break;

                case (uint)RTTMesg.RTTInMsgIds.DriverLogoff:
                    ServerMsgLog.WarnFormat("UDP {0}.", (RTTMesg.RTTInMsgIds)msgId);
                    BeginSendTransientBlock(Block.DriverLogon, new byte[] { 0 });
                    break;

                case (uint)RTTMesg.RTTInMsgIds.DriverMesg2:
                    ServerMsgLog.WarnFormat("UDP {0}\n{1}.", (RTTMesg.RTTInMsgIds)msgId, CommsServer.HexDump(a.Datagram, a.Datagram.Length));
                    //TransientBlock block = new TransientBlock(mCANClient, (byte)Block.MessageToDriver);
                    byte[] blockData = new byte[a.Datagram.Length - 4];
                    Array.Copy(a.Datagram, 4, blockData, 0, blockData.Length);
                    //block.Send(blockData, false);
                    BeginSendTransientBlock(Block.MessageToDriver, blockData);
                    break;

                case (uint)RTTMesg.RTTInMsgIds.VehicleInfo:
                    mCommsServer.CompanyTag = a.Datagram[4];
                    mCommsServer.VehicleId  = Encoding.ASCII.GetString(a.Datagram, 5, a.Datagram.Length - 5);
                    ServerMsgLog.WarnFormat("UDP VehicleInfo {0} {1}", mCommsServer.CompanyTag, mCommsServer.VehicleId);
                    mCANClient.Send(CNXCANMsgHelper.PackIdentifiers(mCommsServer.CommsAddress, mCommsServer.CompanyTag));
                    break;

                case (uint)RTTMesg.RTTInMsgIds.FlushData:
                    ServerMsgLog.WarnFormat("UDP Flush APC");
                    frame.MailboxId = (uint)CNXMsgIds.ResetLoading;
                    frame.DataFromArray(a.Datagram, 4, a.Datagram.Length - 4);
                    mApc.FrameReceivedEventHandler(null, new FrameReceivedEventArgs(frame));
                    mCANClient.Send(frame);
                    // force daily restart as requested by Iris
                    //if (mTracker.mIris != null)
                    //	mTracker.mIris.Restart();
                    break;

                default:
                    ServerMsgLog.WarnFormat("UDP Unknown id {0} length {1}\n{2}.", msgId, a.Datagram.Length, CommsServer.HexDump(a.Datagram, a.Datagram.Length));
                    break;
                }
            }
            catch (Exception e)
            {
                ServerMsgLog.ErrorFormat("Datagram {0} Handler Error : {1}", msgId, e.ToString());
            }
        }