public async Task DevRequestAsync(string serial, byte[] request, YGenericHub.RequestAsyncResult asyncResult, object asyncContext)
        {
            if (_devState != DevState.StreamReadyReceived)
            {
                throw new YAPI_Exception(YAPI.IO_ERROR, "Device not ready");
            }

            await sendRequest(request, asyncResult, asyncContext);
        }
Esempio n. 2
0
        internal async Task DevRequestAsync(string serial, byte[] request, YGenericHub.RequestAsyncResult asyncResult, object asyncContext)
        {
            YUSBDevice d = imm_devFromSerial(serial);

            if (d == null)
            {
                throw new YAPI_Exception(YAPI.DEVICE_NOT_FOUND, "Device has been uplugged");
            }

            await d.DevRequestAsync(serial, request, asyncResult, asyncContext);
        }
Esempio n. 3
0
        private async Task sendRequest(byte[] request, YGenericHub.RequestAsyncResult asyncResult, object asyncContext)
        {
            int pos = 0;

            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)
            {
                if (_hid == null)
                {
                    _devState       = DevState.IOError;
                    _currentRequest = null;
                    throw new YAPI_Exception(YAPI.IO_ERROR, "USB device has been stopped");
                }

                // construct a HID output report to send to the device

                HidOutputReport outReport;
                try {
                    outReport = _hid.CreateOutputReport();
                } catch (Exception ex) {
                    _devState       = DevState.IOError;
                    _currentRequest = null;
                    throw new YAPI_Exception(YAPI.IO_ERROR, "Error during CreateOutputReport():" + ex.Message);
                }

                int size = YUSBPkt.imm_FormatTCP(outReport, request, pos, true);
                // Send the output report asynchronously
                uint u;
                try {
                    u = await _hid.SendOutputReportAsync(outReport);
                } catch (Exception ex) {
                    _devState       = DevState.IOError;
                    _currentRequest = null;
                    throw new YAPI_Exception(YAPI.IO_ERROR, "Error during SendOutputReportAsync():" + ex.Message);
                }

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

                pos += size;
            }

            //Debug.WriteLine(string.Format("{0}:sent", Environment.CurrentManagedThreadId));
        }
 internal WSRequest(string dbglabel, int tcpchanel, byte[] full_request, YGenericHub.RequestProgress progress, Object context)
 {
     _async         = false;
     _asyncId       = 0;
     _channel       = tcpchanel;
     _requestData   = full_request;
     _dbglabel      = dbglabel;
     _progressCb    = progress;
     _progressCtx   = context;
     _asyncResultCb = null;
     _asyncCtx      = null;
 }
 internal WSRequest(string dbglabel, int tcpchanel, byte asyncid, byte[] full_request, YGenericHub.RequestAsyncResult asyncResult, Object asyncContext)
 {
     _async         = true;
     _asyncId       = asyncid;
     _channel       = tcpchanel;
     _requestData   = full_request;
     _dbglabel      = dbglabel;
     _progressCb    = null;
     _progressCtx   = null;
     _asyncResultCb = asyncResult;
     _asyncCtx      = asyncContext;
 }
        public YRequest(byte[] requestBytes, YGenericHub.RequestAsyncResult asyncResult, object asyncContext, ulong maxTime)
        {
            _response      = new byte[1024];
            _response_size = 0;
            _isDone        = false;
            _debug_name    = YAPI.DefaultEncoding.GetString(requestBytes);
            int debug_pos = _debug_name.IndexOf('\r');

            if (debug_pos > 0)
            {
                _debug_name = _debug_name.Substring(0, debug_pos);
            }

            _asyncResult  = asyncResult;
            _asyncContext = asyncContext;
            _tm_start     = YAPI.GetTickCount();
            _timeout      = _tm_start + maxTime;
            _tcs          = new TaskCompletionSource <byte[]>();
        }
 internal virtual async Task requestHTTPAsync(string request, byte[] rest_of_request, YGenericHub.RequestAsyncResult asyncResult, object context)
 {
     string shortRequest = imm_formatRequest(request);
     await _hub.devRequestAsync(this, shortRequest, rest_of_request, asyncResult, context);
 }
        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));
        }
Esempio n. 9
0
        internal async Task RequestAsync(string req_first_line, byte[] req_head_and_body, YGenericHub.RequestAsyncResult callback, object context)
        {
            //log("STA_Async:" + req_first_line.TrimEnd());
            await EnsureLastRequestDone();

            _currentReq = doRequestTask(req_first_line, req_head_and_body, _hub._yctx._networkTimeoutMs, context, callback, null);
            //log("END_Aync:" + req_first_line.TrimEnd());
        }
Esempio n. 10
0
        internal async Task <byte[]> doRequestTask(string firstLine, byte[] rest_of_request, ulong mstimeout, object context, YGenericHub.RequestAsyncResult resultCallback, HandleIncommingData progressCb)
        {
            byte[] full_request;
            int    retrycount = 0;

            _context          = context;
            _resultCallback   = resultCallback;
            _requestTimeout   = mstimeout;
            _progressCallback = progressCb;

retry:
            if (retrycount++ == 2)
            {
                string msg = "too many retry";
                if (resultCallback != null)
                {
                    await resultCallback(context, null, YAPI.IO_ERROR, msg);

                    return(null);
                }
                else
                {
                    throw new YAPI_Exception(YAPI.IO_ERROR, msg);
                }
            }

            log(String.Format("Start({0}):{1}", _reuse_socket ? "reuse" : "new", firstLine));
            _startRequestTime = YAPI.GetTickCount();
            _header_found     = false;
            string persistent_tag = firstLine.Substring(firstLine.Length - 2);

            if (persistent_tag.Equals("&."))
            {
                firstLine += " \r\n";
            }
            else
            {
                firstLine += " \r\nConnection: close\r\n";
            }

            if (rest_of_request == null)
            {
                string str_request = firstLine + _hub.imm_getAuthorization(firstLine) + "\r\n";
                full_request = YAPI.DefaultEncoding.GetBytes(str_request);
            }
            else
            {
                string str_request = firstLine + _hub.imm_getAuthorization(firstLine);
                int    len         = str_request.Length;
                full_request = new byte[len + rest_of_request.Length];
                Array.Copy(YAPI.DefaultEncoding.GetBytes(str_request), 0, full_request, 0, len);
                Array.Copy(rest_of_request, 0, full_request, len, rest_of_request.Length);
            }

            _result.SetLength(0);
            _header.Length = 0;
            byte[]     buffer = new byte[1024];
            Task <int> readTask;

            try {
                if (!_reuse_socket)
                {
                    // Creates an unconnected socket
                    _socket = new StreamSocket();
                    // Connect the socket to the remote endpoint. Catch any errors.
                    HostName serverHost = new HostName(_hub._http_params.Host);
                    int      port       = _hub._http_params.Port;
                    _socket.Control.NoDelay = true;
                    string port_str = port.ToString();
                    await _socket.ConnectAsync(serverHost, port_str);

                    _out = _socket.OutputStream.AsStreamForWrite();
                    _in  = _socket.InputStream.AsStreamForRead();
                    log(String.Format(" - new socket ({0} / {1})", _socket.ToString(), _in.ToString()));
                }

                readTask = _in.ReadAsync(buffer, 0, buffer.Length);
                if (_reuse_socket)
                {
                    try {
                        Task task = await Task.WhenAny(readTask, Task.Delay(0));

                        if (task == readTask)
                        {
                            int read = readTask.Result;
                            if (read == 0)
                            {
                                //socket has been reseted
                                log(String.Format(" - reset socket {0} {1})", _socket.ToString(), read));
                                closeSocket();
                                goto retry;
                            }

                            string msg = "suspect data received before request. Reset the socket";
                            log(msg);
                            throw new Exception(msg);
                        }
                    } catch (Exception e) {
                        log("Reset socket connection:" + e.Message);
                        closeSocket();
                        goto retry;
                    }
                }
            } catch (Exception e) {
                log("Exception on socket connection:" + e.Message);
                closeSocket();
                if (resultCallback != null)
                {
                    await resultCallback(context, null, YAPI.IO_ERROR, e.Message);

                    return(null);
                }
                else
                {
                    throw new YAPI_Exception(YAPI.IO_ERROR, e.Message);
                }
            }

            // write request
            try {
                await _out.WriteAsync(full_request, 0, full_request.Length);

                await _out.FlushAsync();
            } catch (Exception e) {
                closeSocket();
                if (resultCallback != null)
                {
                    await resultCallback(context, null, YAPI.IO_ERROR, e.Message);

                    return(null);
                }
                else
                {
                    throw new YAPI_Exception(YAPI.IO_ERROR, e.Message);
                }
            }

            _reuse_socket = false;
            bool eof = false;

            do
            {
                int read;
                try {
                    int   waitms;
                    ulong now;
                    if (_requestTimeout > 0)
                    {
                        now = YAPI.GetTickCount();
                        ulong read_timeout = _startRequestTime + _requestTimeout;
                        if (read_timeout < now)
                        {
                            string msg = string.Format("Request took too long {0:D}ms", now - _startRequestTime);
                            if (resultCallback != null)
                            {
                                await resultCallback(context, null, YAPI.TIMEOUT, msg);

                                return(null);
                            }
                            else
                            {
                                throw new YAPI_Exception(YAPI.TIMEOUT, msg);
                            }
                        }

                        read_timeout -= now;
                        if (read_timeout > YIO_IDLE_TCP_TIMEOUT)
                        {
                            read_timeout = YIO_IDLE_TCP_TIMEOUT;
                        }

                        waitms = (int)read_timeout;
                    }
                    else
                    {
                        waitms = YIO_IDLE_TCP_TIMEOUT;
                    }

                    Task task = await Task.WhenAny(readTask, Task.Delay(waitms));

                    now = YAPI.GetTickCount();
                    if (task != readTask)
                    {
                        string msg = string.Format("Hub did not send data during {0:D}ms", waitms);
                        if (resultCallback != null)
                        {
                            await resultCallback(context, null, YAPI.IO_ERROR, msg);

                            return(null);
                        }
                        else
                        {
                            throw new YAPI_Exception(YAPI.TIMEOUT, msg);
                        }
                    }

                    read = readTask.Result;
                    log(String.Format("_requestProcesss read ={0:d} after{1}", read, now - _startRequestTime));
                } catch (IOException e) {
                    closeSocket();
                    if (resultCallback != null)
                    {
                        await resultCallback(context, null, YAPI.IO_ERROR, e.Message);

                        return(null);
                    }
                    else
                    {
                        throw new YAPI_Exception(YAPI.IO_ERROR, e.Message);
                    }
                }

                if (read <= 0)
                {
                    // end of connection
                    closeSocket();
                    log("end of connection " + _dbglabel);
                    eof = true;
                }
                else if (read > 0)
                {
                    if (imm_HandleIncommingData(buffer, read))
                    {
                        closeSocket();
                        goto retry;
                    }

                    if (_reuse_socket)
                    {
                        byte[] tmp = _result.ToArray();
                        if (tmp[tmp.Length - 1] == 10 && tmp[tmp.Length - 2] == 13)
                        {
                            log("end of request " + _dbglabel + " let the socket open for later");
                            eof = true;
                        }
                    }
                }

                if (!eof)
                {
                    readTask = _in.ReadAsync(buffer, 0, buffer.Length);
                }
            } while (!eof);

            if (_header.Length == 0 && _result.Length == 0)
            {
                log("Short request detected");
                closeSocket();
                goto retry;
            }


            byte[] final_res = _result.ToArray();
            if (resultCallback != null)
            {
                await resultCallback(context, final_res, YAPI.SUCCESS, "");
            }

            return(final_res);
        }
Esempio n. 11
0
 internal override async Task devRequestAsync(YDevice device, string req_first_line, byte[] req_head_and_body, YGenericHub.RequestAsyncResult asyncResult, object asyncContext)
 {
     WSRequest wsRequest = await sendRequest(req_first_line, req_head_and_body, DEVICE_TCP_CHANNEL, true, null, null);
 }
        internal async Task RequestAsync(string req_first_line, byte[] req_head_and_body, YGenericHub.RequestAsyncResult callback, object context)
        {
            //log("STA_Async:" + req_first_line.TrimEnd());
            await EnsureLastRequestDone();

            _currentReq = doRequestTask(req_first_line, req_head_and_body, YHTTPHub.YIO_DEFAULT_TCP_TIMEOUT, context, callback, null);
            //log("END_Aync:" + req_first_line.TrimEnd());
        }
Esempio n. 13
0
 /// <param name="device">            the device that will receive the request</param>
 /// <param name="req_first_line">    first line of request without space, HTTP1.1 or \r\n </param>
 /// <param name="req_head_and_body"> http headers with double \r\n followed by potential body </param>
 /// <param name="asyncResult">       the callback to call when the request is done </param>
 /// <param name="asyncContext">      a pointer to a context to pass for the asyncResutl </param>
 internal abstract Task devRequestAsync(YDevice device, string req_first_line, byte[] req_head_and_body, YGenericHub.RequestAsyncResult asyncResult, object asyncContext);
 internal async Task DevRequestAsync(string serial, byte[] request, YGenericHub.RequestAsyncResult asyncResult,
                                     object asyncContext)
 {
     YUSBDevice d = imm_devFromSerial(serial);
     await d.DevRequestAsync(serial, request, asyncResult, asyncContext);
 }
        private async Task <WSRequest> sendRequest(string req_first_line, byte[] req_head_and_body, int tcpchanel, bool async, YGenericHub.RequestProgress progress, Object context, YGenericHub.RequestAsyncResult asyncResult, Object asyncContext)
        {
            WSRequest request;
            string    debug = req_first_line.Trim();

            byte[] full_request;
            byte[] req_first_lineBytes;
            if (req_head_and_body == null)
            {
                req_first_line     += "\r\n\r\n";
                req_first_lineBytes = YAPI.DefaultEncoding.GetBytes(req_first_line);
                full_request        = req_first_lineBytes;
            }
            else
            {
                req_first_line     += "\r\n";
                req_first_lineBytes = YAPI.DefaultEncoding.GetBytes(req_first_line);
                full_request        = new byte[req_first_lineBytes.Length + req_head_and_body.Length];
                Array.Copy(req_first_lineBytes, 0, full_request, 0, req_first_lineBytes.Length);
                Array.Copy(req_head_and_body, 0, full_request, req_first_lineBytes.Length, req_head_and_body.Length);
            }

            ulong timeout = YAPI.GetTickCount() + WS_REQUEST_MAX_DURATION;

            while ((_connectionState != ConnectionState.CONNECTED && _connectionState != ConnectionState.DEAD))
            {
                if (timeout < YAPI.GetTickCount())
                {
                    if (_connectionState != ConnectionState.CONNECTED && _connectionState != ConnectionState.CONNECTING)
                    {
                        throw new YAPI_Exception(YAPI.IO_ERROR, "IO error with hub");
                    }
                    else
                    {
                        throw new YAPI_Exception(YAPI.TIMEOUT, "Last request did not finished correctly");
                    }
                }

                if (_connectionState == ConnectionState.DEAD)
                {
                    throw new YAPI_Exception(_session_errno, _session_error);
                }
            }

            if (async)
            {
                request = new WSRequest(debug, tcpchanel, _nextAsyncId++, full_request, asyncResult, asyncContext);
                if (_nextAsyncId >= 127)
                {
                    _nextAsyncId = 48;
                }
            }
            else
            {
                request = new WSRequest(debug, tcpchanel, full_request, progress, context);
            }

            try {
                WSRequest wsRequest = _workingRequests[tcpchanel].Peek();
                await wsRequest.WaitEnd();
            } catch (InvalidOperationException) {}

            _workingRequests[tcpchanel].Enqueue(request);

            //todo: handle timeout
            await processRequests(request);

            if (request.ErrorCode != YAPI.SUCCESS)
            {
                throw new YAPI_Exception(request.ErrorCode, request.ErrorMsg);
            }

            return(request);
        }