private async Task Run()
        {
            _cancellationToken.ThrowIfCancellationRequested();
            YHTTPRequest yreq = new YHTTPRequest((YHTTPHub)_hub, "Notification of " + _hub.RootUrl);

            try {
                String notUrl;
                if (_notifyPos < 0)
                {
                    notUrl = "GET /not.byn";
                }
                else
                {
                    notUrl = string.Format("GET /not.byn?abs=%d", _notifyPos);
                }

                _fifo      = "";
                _connected = true;
                await yreq.RequestProgress(notUrl, ProgressCb);
            } catch (YAPI_Exception ex) {
                Debug.WriteLine(ex.Message);
                _notifRetryCount++;
                _hub._devListValidity = 500;
                _error_delay          = 100 << (_notifRetryCount > 4 ? 4 : _notifRetryCount);
            } catch (OperationCanceledException) {
                _connected = false;
                throw;
            } catch (Exception ex) {
                Debug.WriteLine(ex.Message);
            }

            _connected = false;
        }
        internal override async Task <int> ping(uint mstimeout)
        {
            // ping dot not use Notification handler but a one shot http request
            YHTTPRequest req = new YHTTPRequest(this, "ping");
            await req.RequestSync("GET /api/module/firmwareRelease.json", null, mstimeout);

            return(YAPI.SUCCESS);
        }
        internal override async Task devRequestAsync(YDevice device, string req_first_line, byte[] req_head_and_body, YGenericHub.RequestAsyncResult asyncResult, object asyncContext)
        {
            ulong start = YAPI.GetTickCount();

            if (!_httpReqByDev.ContainsKey(device))
            {
                _httpReqByDev[device] = new YHTTPRequest(_hub, "Device " + device.SerialNumber);
            }

            YHTTPRequest req = _httpReqByDev[device];
            await req.RequestAsync(req_first_line, req_head_and_body, asyncResult, asyncContext);

            ulong stop = YAPI.GetTickCount();
            //Debug.WriteLine(string.Format("ASyncRes on {0} took {1}ms", device.SerialNumber, stop - start));
        }
        internal override async Task <byte[]> devRequestSync(YDevice device, string req_first_line, byte[] req_head_and_body, uint mstimeout, YGenericHub.RequestProgress progress, object context)
        {
            ulong start = YAPI.GetTickCount();

            if (!_httpReqByDev.ContainsKey(device))
            {
                _httpReqByDev[device] = new YHTTPRequest(_hub, "Device " + device.SerialNumber);
            }

            YHTTPRequest req = _httpReqByDev[device];

            byte[] result = await req.RequestSync(req_first_line, req_head_and_body, mstimeout);

            ulong stop = YAPI.GetTickCount();

            //Debug.WriteLine(string.Format("SyncRes on {0} took {1}ms", device.SerialNumber, stop - start));

            return(result);
        }
        internal override async Task <byte[]> hubRequestSync(string req_first_line, byte[] req_head_and_body, uint mstimeout)
        {
            YHTTPRequest req = new YHTTPRequest(_hub, "request to " + _hub.Host);

            return(await req.RequestSync(req_first_line, req_head_and_body, mstimeout));
        }