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