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()); } }
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()); } }