private async Task <Response> SendReceiveCommand(UInt32 command, byte[] buffer) { await SendReceiveInitCommand((UInt32)(4 + buffer.Length)); await SendCommandWithBuffer(command, buffer); var receivedBuff = await ReceiveFrame(); // La risposta è composta da: // 1 - un marker (4 byte) // 2 - il codice di errore (4 byte) // 3 - un codice di risultato (4 byte) // 4 - se necessario un buffer // 5 - il crc del messaggio (4 byte) var result = new Response(); result.responseData = ArrConverter.GetUInt32FromBuffer(receivedBuff, 8); if (receivedBuff.Length > 16) { result.responseBuff = receivedBuff.Skip(12).Take(receivedBuff.Length - 16).ToArray(); } else { result.responseBuff = null; } return(result); }
private async Task <byte[]> ReceiveFrame() { const UInt32 waitCommand = 0x00040000; const UInt32 packetCommand = 0x3F3F3F3F; const UInt32 bigFileCommand = 0x3F3F0001; try { if (!_isConnected) { return(await Task.FromResult(new byte[0])); } else { bool isWaitCommand = false; do { await Task.Delay(100); await _analyzerChar.StopUpdatesAsync(); if (_responseFrame == null || _responseFrame.Length == 0) { throw new Exception("dimensione della risposta errata!"); } // Controllo il marker string marker = Encoding.ASCII.GetString(_responseFrame, 0, 4); if (marker != _frameMarker) { string tmp = ""; foreach (byte data in _responseFrame) { tmp += data.ToString("X2"); } throw new Exception("invalid marker, received: " + tmp); } // Controllo il crc UInt32 crcSent = ArrConverter.GetUInt32FromBuffer(_responseFrame, _responseFrame.Length - 4); UInt32 crcCalc = Crc32_STM.CalculateFromBuffer(_responseFrame, _responseFrame.Length - 4); if (crcSent != crcCalc) { throw new Exception("invalid crc"); } // Controllo se ho una risposta con codice di errore UInt32 errorCode = ArrConverter.GetUInt32FromBuffer(_responseFrame, 4); if (errorCode != 0) { throw new Exception(errorCode.ToString()); } if (_responseFrame.Length == 16) { if (ArrConverter.GetUInt32FromBuffer(_responseFrame, 8) == waitCommand) { isWaitCommand = true; } } else if (_responseFrame.Length == 20) { if (ArrConverter.GetUInt32FromBuffer(_responseFrame, 8) == packetCommand) { int totalSize = (int)ArrConverter.GetUInt32FromBuffer(_responseFrame, 12); int packetsNum = ((totalSize % 20) == 0) ? (totalSize / 20) : ((totalSize / 20) + 1); var fullResponse = new byte[totalSize]; // Il device cerca di trasmettere un pacchetto await _analyzerChar.StartUpdatesAsync(); await SendCommand(packetCommand); for (var packetIndex = 0; packetIndex < packetsNum; packetIndex++) { await Task.Delay(100); await _analyzerChar.StopUpdatesAsync(); if (_responseFrame == null || _responseFrame.Length == 0) { throw new Exception("dimensione della risposta errata!"); } _responseFrame.CopyTo(fullResponse, 20 * packetIndex); await _analyzerChar.StartUpdatesAsync(); await SendCommand(packetCommand); } return(await Task.FromResult(fullResponse)); } else if (ArrConverter.GetUInt32FromBuffer(_responseFrame, 8) == bigFileCommand) { int totalSize = (int)ArrConverter.GetUInt32FromBuffer(_responseFrame, 12); int receivedLength = 0; // Alloco un buffer per l'intero file e il preambolo // Per adesso ignoro il preambolo e copio soltanto il buffer contenente il file byte[] fullRespose = new byte[totalSize + 16]; // Il device cerca di trasmettere un pacchetto await _analyzerChar.StartUpdatesAsync(); await SendCommand(packetCommand); while (receivedLength < totalSize) { await Task.Delay(100); await _analyzerChar.StopUpdatesAsync(); if (_responseFrame == null || _responseFrame.Length == 0) { throw new Exception("dimensione della risposta errata!"); } // Copio partendo da 12 e poi in base alla dimensione dei pacchetti ricevuti Buffer.BlockCopy(_responseFrame, 0, fullRespose, receivedLength + 12, _responseFrame.Length); MessagingCenter.Send <IAnalyzerDevice, double>(this, "DownloadFileProgress", (double)receivedLength / totalSize); receivedLength += _responseFrame.Length; await _analyzerChar.StartUpdatesAsync(); await SendCommand(packetCommand); } return(await Task.FromResult(fullRespose)); } } await _analyzerChar.StartUpdatesAsync(); }while (isWaitCommand); } await _analyzerChar.StartUpdatesAsync(); return(await Task.FromResult(_responseFrame)); } catch (Exception ex) { await _analyzerChar.StartUpdatesAsync(); throw ex; } }