public BlockTransferManager(string resource, byte blockId, int version, CANClient client)
        {
            mResource     = resource;
            mBlockId      = blockId;
            mBlockVersion = version;
            mClient       = client;

            Uri uri = new Uri(resource);

            if (uri.Scheme != "file")
            {
                mResDownLoader = new ResumableResourceDownload(mResource);
            }

            // first get the device version
            mState = BlockTransferState.AquiringDeviceVersion;

            // subscribe to CAN frame events
            mClient.RaiseFrameReceivedEvent += FrameReceivedEventHandler;
            CNXLog.WarnFormat("Starting BlockTransferManager url {0}, Id {1}, ver {2}", resource, blockId, version);
            SendBlockRequest();

            // start time for cataloge and status reporting
            mBlockQueryTimer = new System.Threading.Timer(OnTimedEvent, null, 0, (2 * 60 * 1000));
        }
 /// <summary>
 /// Transferes the block regardless of device version.
 /// </summary>
 public void ForceTransfer()
 {
     if (mState == BlockTransferState.AquiringDeviceVersion || mState == BlockTransferState.None)
     {
         mState = BlockTransferState.AquiringDeviceVersion;
         BlockStateMachine(BlockEvent.AquireFailed);
     }
 }
 public StateChangedEventArgs(BlockTransferState state)
 {
     State = state;
 }
        private void BlockStateMachine(BlockEvent blockEvent)
        {
            BlockTransferState entryState = mState;

            switch (entryState)
            {
            case BlockTransferState.None:
                switch (blockEvent)
                {
                case BlockEvent.Timeout:
                    mState = BlockTransferState.AquiringDeviceVersion;
                    SendBlockRequest();
                    break;

                case BlockEvent.AquireFailed:
                    mState = BlockTransferState.AquiringResource;
                    BeginFetchingResource();
                    break;

                case BlockEvent.ServerVersion:
                case BlockEvent.Frame:
                    if (Synchronised)
                    {
                        mState = BlockTransferState.DeviceSynchronised;
                    }
                    else
                    {
                        mState = BlockTransferState.AquiringResource;
                        BeginFetchingResource();
                    }
                    break;

                case BlockEvent.AquireComplete:
                case BlockEvent.SendFailed:
                    mState = BlockTransferState.SynchronisingBlock;
                    BeginSendingBlock();
                    break;

                case BlockEvent.SendComplete:
                    mState = BlockTransferState.AquiringDeviceVersion;
                    SendBlockRequest();
                    break;
                }
                break;

            case BlockTransferState.AquiringDeviceVersion:
                switch (blockEvent)
                {
                case BlockEvent.Timeout:
                    mState = BlockTransferState.AquiringDeviceVersion;
                    SendBlockRequest();
                    break;

                case BlockEvent.AquireFailed:
                    mState = BlockTransferState.AquiringResource;
                    BeginFetchingResource();
                    break;

                case BlockEvent.ServerVersion:
                case BlockEvent.Frame:
                    if (Synchronised)
                    {
                        mState = BlockTransferState.DeviceSynchronised;
                    }
                    else
                    {
                        mState = BlockTransferState.AquiringResource;
                        BeginFetchingResource();
                    }
                    break;

                case BlockEvent.AquireComplete:
                case BlockEvent.SendFailed:
                    mState = BlockTransferState.SynchronisingBlock;
                    BeginSendingBlock();
                    break;

                case BlockEvent.SendComplete:
                    mState = BlockTransferState.AquiringDeviceVersion;
                    SendBlockRequest();
                    break;
                }
                break;

            case BlockTransferState.AquiringResource:
                switch (blockEvent)
                {
                case BlockEvent.Timeout:
                case BlockEvent.ServerVersion:
                case BlockEvent.Frame:
                    break;

                case BlockEvent.AquireFailed:
                    mState = BlockTransferState.AquiringResourceFailed;
                    break;

                case BlockEvent.AquireComplete:
                case BlockEvent.SendFailed:
                    mState = BlockTransferState.SynchronisingBlock;
                    BeginSendingBlock();
                    break;

                case BlockEvent.SendComplete:
                    mState = BlockTransferState.AquiringDeviceVersion;
                    SendBlockRequest();
                    break;
                }
                break;

            case BlockTransferState.AquiringResourceFailed:
                switch (blockEvent)
                {
                case BlockEvent.Timeout:
                case BlockEvent.ServerVersion:
                    mState = BlockTransferState.AquiringResource;
                    BeginFetchingResource();
                    break;

                case BlockEvent.AquireFailed:
                    break;

                case BlockEvent.Frame:
                    if (Synchronised)
                    {
                        mState = BlockTransferState.DeviceSynchronised;
                    }
                    break;

                case BlockEvent.AquireComplete:
                case BlockEvent.SendFailed:
                    mState = BlockTransferState.SynchronisingBlock;
                    BeginSendingBlock();
                    break;

                case BlockEvent.SendComplete:
                    mState = BlockTransferState.AquiringDeviceVersion;
                    SendBlockRequest();
                    break;
                }
                break;

            case BlockTransferState.SynchronisingBlock:
                switch (blockEvent)
                {
                case BlockEvent.Timeout:
                    break;

                case BlockEvent.ServerVersion:
                case BlockEvent.AquireFailed:
                    mState = BlockTransferState.AquiringResource;
                    BeginFetchingResource();
                    break;

                case BlockEvent.Frame:
                    if (Synchronised)
                    {
                        mState = BlockTransferState.DeviceSynchronised;
                    }
                    break;

                case BlockEvent.AquireComplete:
                case BlockEvent.SendFailed:
                    mState = BlockTransferState.SynchronisingBlock;
                    BeginSendingBlock();
                    break;

                case BlockEvent.SendComplete:
                    mState = BlockTransferState.AquiringDeviceVersion;
                    SendBlockRequest();
                    break;
                }
                break;

            case BlockTransferState.DeviceSynchronised:
                switch (blockEvent)
                {
                case BlockEvent.Timeout:
                    SendBlockRequest();
                    break;

                case BlockEvent.ServerVersion:
                case BlockEvent.Frame:
                    if (!Synchronised)
                    {
                        mState = BlockTransferState.AquiringResource;
                        BeginFetchingResource();
                    }
                    break;

                case BlockEvent.AquireComplete:
                case BlockEvent.SendComplete:
                    break;
                }
                break;

            default:
                mState = BlockTransferState.AquiringDeviceVersion;
                break;
            }

            if (entryState != mState)
            {
                CNXLog.InfoFormat("Block {0} transfer from {1} to {2}", mBlockId, entryState, mState);
                OnRaiseStateChangedEvent(new StateChangedEventArgs(mState));
            }
        }