internal async Task Setup(uint pktVersion)
        {
            _currentTask = new TaskCompletionSource <bool>();

            // construct a HID output report to send to the device
            HidOutputReport outReport = Hid.CreateOutputReport();

            YUSBPkt.imm_FormatConfReset(outReport, pktVersion);
            // Send the output report asynchronously
            _devState = DevState.ResetSend;
            var u = await Hid.SendOutputReportAsync(outReport);

            if (u != 65)
            {
                _devState = DevState.IOError;
                throw new YAPI_Exception(YAPI.IO_ERROR, "Unable to send Reset PKT");
            }

            Task <bool> task     = _currentTask.Task;
            Task        taskDone = await Task.WhenAny(task, Task.Delay(1000));

            if (taskDone != task)
            {
                throw new YAPI_Exception(YAPI.IO_ERROR, "Device does not respond to reset");
            }
        }
        private async Task checkMetaUTC()
        {
            if (_lastMetaUTC + META_UTC_DELAY < YAPI.GetTickCount())
            {
                HidOutputReport outReport = Hid.CreateOutputReport();
                YUSBPkt.imm_FormatMetaUTC(outReport, true);
                var u = await Hid.SendOutputReportAsync(outReport);

                if (u != 65)
                {
                    _devState = DevState.IOError;
                    throw new YAPI_Exception(YAPI.IO_ERROR, "Unable to send Start PKT");
                }

                _lastMetaUTC = YAPI.GetTickCount();
            }
        }
        internal async Task Start(byte pktAckDelay)
        {
            // construct a HID output report to send to the device
            HidOutputReport outReport = Hid.CreateOutputReport();

            //("Activate USB pkt ack (%dms)\n", dev->pktAckDelay);
            YUSBPkt.imm_FormatConfStart(outReport, 1, pktAckDelay);
            // Send the output report asynchronously
            _devState = DevState.StartSend;
            var u = await Hid.SendOutputReportAsync(outReport);

            if (u != 65)
            {
                _devState = DevState.IOError;
                throw new YAPI_Exception(YAPI.IO_ERROR, "Unable to send Start PKT");
            }
        }
        private async Task sendRequest(byte[] request, YGenericHub.RequestAsyncResult asyncResult, object asyncContext)
        {
            int pos = 0;

            try {
                if (_currentRequest != null)
                {
                    await _currentRequest.GetResponse();
                }

                //Debug.WriteLine(string.Format("{0}:Check last request is sent", Environment.CurrentManagedThreadId));
                _currentRequest = new YRequest(request, asyncResult, asyncContext, 10000);
                while (pos < request.Length)
                {
                    // construct a HID output report to send to the device
                    HidOutputReport outReport = Hid.CreateOutputReport();
                    int             size      = YUSBPkt.imm_FormatTCP(outReport, request, pos, true);
                    // Send the output report asynchronously
                    var u = await Hid.SendOutputReportAsync(outReport);

                    if (u != 65)
                    {
                        _devState = DevState.IOError;
                        _watcher.imm_removeUsableDevice(this);
                        return;
                    }

                    pos += size;
                }

                //Debug.WriteLine(string.Format("{0}:sent", Environment.CurrentManagedThreadId));
            } catch (Exception ex) {
                _devState       = DevState.IOError;
                _currentRequest = null;
                throw new YAPI_Exception(YAPI.IO_ERROR, ex.Message);
            }
        }
        internal async Task streamHandler(List <YPktStreamHead> streams)
        {
            foreach (YPktStreamHead s in streams)
            {
                uint streamType = s.StreamType;
                switch (streamType)
                {
                case YGenericHub.YSTREAM_NOTICE:
                case YGenericHub.YSTREAM_NOTICE_V2:
                    imm_handleNotifcation(s);
                    break;

                case YGenericHub.YSTREAM_TCP_CLOSE:
                case YGenericHub.YSTREAM_TCP:
                    if (_devState != DevState.StreamReadyReceived || _currentRequest == null)
                    {
                        continue;
                    }

                    _currentRequest.imm_AddIncommingData(s);
                    if (streamType == YGenericHub.YSTREAM_TCP_CLOSE)
                    {
                        // construct a HID output report to send to the device
                        HidOutputReport outReport = Hid.CreateOutputReport();
                        YUSBPkt.imm_FormatTCP(outReport, null, 0, true);
                        // Send the output report asynchronously
                        var u = await Hid.SendOutputReportAsync(outReport);

                        if (u != 65)
                        {
                            _devState = DevState.IOError;
                            _watcher.imm_removeUsableDevice(this);
                            return;
                        }

                        _currentRequest.imm_Close();
                    }

                    break;

                case YGenericHub.YSTREAM_EMPTY:
                    break;

                case YGenericHub.YSTREAM_REPORT:
                    if (_devState == DevState.StreamReadyReceived)
                    {
                        imm_handleTimedNotification(s);
                    }

                    break;

                case YGenericHub.YSTREAM_REPORT_V2:
                    if (_devState == DevState.StreamReadyReceived)
                    {
                        handleTimedNotificationV2(s);
                    }

                    break;

                default:
                    _yctx._Log("drop unknown ystream:" + s);
                    break;
                }
            }
        }