Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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;
            }
        }