private async Task <bool> SendFrame(byte[] frame) { if (!_isConnected) { return(await Task.FromResult(false)); } else { if (_analyzerChar != null) { _responseFrame = null; byte[] frameToSend = new byte[8 + frame.Length]; // Imposto l'header Encoding.ASCII.GetBytes(_frameMarker).CopyTo(frameToSend, 0); // Imposto il frame da inviare frame.CopyTo(frameToSend, 4); // Calcolo e imposto il crc UInt32 crc = Crc32_STM.CalculateFromBuffer(frameToSend, frameToSend.Length - 4); ArrConverter.SetBufferFromUInt32(crc, frameToSend, frameToSend.Length - 4); await _analyzerChar.WriteAsync(frameToSend); } else { return(await Task.FromResult(false)); } } return(await Task.FromResult(true)); }
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; } }