public Task NewConnectionAsync(ObjectPath device, CloseSafeHandle fileDescriptor, IDictionary <string, object> properties) { SocketState = SocketStates.Connected; _fileDescriptor = fileDescriptor; Log.Debug("Linux.BluetoothSocket: Connected to profile"); Stream = new UnixStream(fileDescriptor.DangerousGetHandle().ToInt32()); Task.Run(() => NewConnection?.Invoke(device, _fileDescriptor, properties)); return(Task.CompletedTask); }
public async Task <Message> ReceiveMessageAsync() { try { int bytesRead = await ReadCountAsync(_headerReadBuffer, 0, 16, _fileDescriptors).ConfigureAwait(false); if (bytesRead == 0) { return(null); } if (bytesRead != 16) { throw new ProtocolException("Header read length mismatch: " + bytesRead + " of expected " + "16"); } EndianFlag endianness = (EndianFlag)_headerReadBuffer[0]; MessageReader reader = new MessageReader(endianness, new ArraySegment <byte>(_headerReadBuffer)); //discard endian byte, message type and flags, which we don't care about here reader.Seek(3); byte version = reader.ReadByte(); if (version != ProtocolInformation.Version) { throw new NotSupportedException("Protocol version '" + version.ToString() + "' is not supported"); } uint bodyLength = reader.ReadUInt32(); //discard _methodSerial reader.ReadUInt32(); uint headerLength = reader.ReadUInt32(); int bodyLen = (int)bodyLength; int toRead = (int)headerLength; //we fixup to include the padding following the header toRead = ProtocolInformation.Padded(toRead, 8); long msgLength = toRead + bodyLen; if (msgLength > ProtocolInformation.MaxMessageLength) { throw new ProtocolException("Message length " + msgLength + " exceeds maximum allowed " + ProtocolInformation.MaxMessageLength + " bytes"); } byte[] header = new byte[16 + toRead]; Array.Copy(_headerReadBuffer, header, 16); bytesRead = await ReadCountAsync(header, 16, toRead, _fileDescriptors).ConfigureAwait(false); if (bytesRead != toRead) { throw new ProtocolException("Message header length mismatch: " + bytesRead + " of expected " + toRead); } var messageHeader = Header.FromBytes(new ArraySegment <byte>(header)); byte[] body = null; //read the body if (bodyLen != 0) { body = new byte[bodyLen]; bytesRead = await ReadCountAsync(body, 0, bodyLen, _fileDescriptors).ConfigureAwait(false); if (bytesRead != bodyLen) { throw new ProtocolException("Message body length mismatch: " + bytesRead + " of expected " + bodyLen); } } if (_fileDescriptors.Count < messageHeader.NumberOfFds) { throw new ProtocolException("File descriptor length mismatch: " + _fileDescriptors.Count + " of expected " + messageHeader.NumberOfFds); } Message msg = new Message( messageHeader, body, messageHeader.NumberOfFds == 0 ? null : _fileDescriptors.Count == messageHeader.NumberOfFds ? _fileDescriptors.ToArray() : _fileDescriptors.Take((int)messageHeader.NumberOfFds).ToArray() ); _fileDescriptors.RemoveRange(0, (int)messageHeader.NumberOfFds); return(msg); } catch { foreach (var fd in _fileDescriptors) { CloseSafeHandle.close(fd.Handle); } throw; } }