예제 #1
0
        private void MessageLoop()
        {
            var packet        = new List <byte>();
            var messageOpcode = 0x0;

            using (var messageBuffer = new MemoryStream())
            {
                while (_client.Connected)
                {
                    packet.Clear();

                    var ab = _client.Available;
                    if (ab == 0)
                    {
                        continue;
                    }

                    packet.Add((byte)_clientStream.ReadByte());
                    var fin  = (packet[0] & (1 << 7)) != 0;
                    var rsv1 = (packet[0] & (1 << 6)) != 0;
                    var rsv2 = (packet[0] & (1 << 5)) != 0;
                    var rsv3 = (packet[0] & (1 << 4)) != 0;

                    // Must error if is set.
                    //if (rsv1 || rsv2 || rsv3)
                    //    return;

                    var opcode = packet[0] & ((1 << 4) - 1);

                    switch (opcode)
                    {
                    case 0x0:     // Continuation Frame
                        break;

                    case 0x1:     // Text
                    case 0x2:     // Binary
                    case 0x8:     // Connection Close
                        messageOpcode = opcode;
                        break;

                    case 0x9:
                        continue;     // Ping

                    case 0xA:
                        continue;     // Pong

                    default:
                        continue;     // Reserved
                    }

                    packet.Add((byte)_clientStream.ReadByte());
                    var masked       = IsMasking = (packet[1] & (1 << 7)) != 0;
                    var pseudoLength = packet[1] - (masked ? 128 : 0);

                    ulong actualLength = 0;
                    if (pseudoLength > 0 && pseudoLength < 125)
                    {
                        actualLength = (ulong)pseudoLength;
                    }
                    else if (pseudoLength == 126)
                    {
                        var length = new byte[2];
                        _clientStream.Read(length, 0, length.Length);
                        packet.AddRange(length);
                        Array.Reverse(length);
                        actualLength = BitConverter.ToUInt16(length, 0);
                    }
                    else if (pseudoLength == 127)
                    {
                        var length = new byte[8];
                        _clientStream.Read(length, 0, length.Length);
                        packet.AddRange(length);
                        Array.Reverse(length);
                        actualLength = BitConverter.ToUInt64(length, 0);
                    }

                    var mask = new byte[4];
                    if (masked)
                    {
                        _clientStream.Read(mask, 0, mask.Length);
                        packet.AddRange(mask);
                    }

                    if (actualLength > 0)
                    {
                        var data = new byte[actualLength];
                        _clientStream.Read(data, 0, data.Length);
                        packet.AddRange(data);

                        if (masked)
                        {
                            data = ApplyMask(data, mask);
                        }

                        messageBuffer.Write(data, 0, data.Length);
                    }

                    LogRequest?.Invoke(this, new LogEventArgs($@"RECV: {BitConverter.ToString(packet.ToArray())}"));

                    if (!fin)
                    {
                        continue;
                    }
                    var message = messageBuffer.ToArray();

                    switch (messageOpcode)
                    {
                    case 0x1:
                        AnyMessageReceived?.Invoke(this, message);
                        TextMessageReceived?.Invoke(this, Encoding.UTF8.GetString(message));
                        break;

                    case 0x2:
                        AnyMessageReceived?.Invoke(this, message);
                        BinaryMessageReceived?.Invoke(this, Encoding.UTF8.GetString(message));
                        break;

                    case 0x8:
                        Close();
                        break;

                    default:
                        throw new Exception("Invalid opcode: " + messageOpcode);
                    }

                    messageBuffer.SetLength(0);
                }
            }
        }
예제 #2
0
        private void MessageLoop()
        {
            WebSocketSession session = this;
            TcpClient        client  = session.Client;
            Stream           stream  = session.ClientStream;

            List <byte> packet = new List <byte>();

            int messageOpcode = 0x0;

            using (MemoryStream messageBuffer = new MemoryStream())
                while (client.Connected)
                {
                    packet.Clear();

                    int ab = client.Available;
                    if (ab == 0)
                    {
                        continue;
                    }

                    packet.Add((byte)stream.ReadByte());
                    bool fin  = (packet[0] & (1 << 7)) != 0;
                    bool rsv1 = (packet[0] & (1 << 6)) != 0;
                    bool rsv2 = (packet[0] & (1 << 5)) != 0;
                    bool rsv3 = (packet[0] & (1 << 4)) != 0;

                    // Must error if is set.
                    //if (rsv1 || rsv2 || rsv3)
                    //    return;

                    int opcode = packet[0] & ((1 << 4) - 1);

                    switch (opcode)
                    {
                    case 0x0:     // Continuation Frame
                        break;

                    case 0x1:     // Text
                    case 0x2:     // Binary
                    case 0x8:     // Connection Close
                        messageOpcode = opcode;
                        break;

                    case 0x9:
                        continue;     // Ping

                    case 0xA:
                        continue;     // Pong

                    default:
                        continue;     // Reserved
                    }

                    packet.Add((byte)stream.ReadByte());
                    bool masked       = (packet[1] & (1 << 7)) != 0;
                    int  pseudoLength = packet[1] - (masked ? 128 : 0);

                    ulong actualLength = 0;
                    if (pseudoLength > 0 && pseudoLength < 125)
                    {
                        actualLength = (ulong)pseudoLength;
                    }
                    else if (pseudoLength == 126)
                    {
                        byte[] length = new byte[2];
                        stream.Read(length, 0, length.Length);
                        packet.AddRange(length);
                        Array.Reverse(length);
                        actualLength = BitConverter.ToUInt16(length, 0);
                    }
                    else if (pseudoLength == 127)
                    {
                        byte[] length = new byte[8];
                        stream.Read(length, 0, length.Length);
                        packet.AddRange(length);
                        Array.Reverse(length);
                        actualLength = BitConverter.ToUInt64(length, 0);
                    }

                    byte[] mask = new byte[4];
                    if (masked)
                    {
                        stream.Read(mask, 0, mask.Length);
                        packet.AddRange(mask);
                    }

                    if (actualLength > 0)
                    {
                        byte[] data = new byte[actualLength];
                        stream.Read(data, 0, data.Length);
                        packet.AddRange(data);

                        if (masked)
                        {
                            data = ApplyMask(data, mask);
                        }

                        messageBuffer.Write(data, 0, data.Length);
                    }

                    Console.WriteLine($@"RECV: {BitConverter.ToString(packet.ToArray())}");

                    if (!fin)
                    {
                        continue;
                    }
                    byte[] message = messageBuffer.ToArray();

                    switch (messageOpcode)
                    {
                    case 0x1:
                        AnyMessageReceived?.Invoke(session, message);
                        TextMessageReceived?.Invoke(session, Encoding.UTF8.GetString(message));
                        break;

                    case 0x2:
                        AnyMessageReceived?.Invoke(session, message);
                        BinaryMessageReceived?.Invoke(session, Encoding.UTF8.GetString(message));
                        break;

                    case 0x8:
                        Close();
                        break;

                    default:
                        throw new Exception("Invalid opcode: " + messageOpcode);
                    }

                    messageBuffer.SetLength(0);
                }
        }
예제 #3
0
        public void MessageReceiver(object sender, SPPMessage e)
        {
            BaseMessageParser parser = SPPMessageParserFactory.BuildParser(e);

            AnyMessageReceived?.Invoke(this, parser);
            switch (e.Id)
            {
            case SPPMessage.MessageIds.MSG_ID_RESET:
                ResetResponse?.Invoke(this, ((ResetResponseParser)parser).ResultCode);
                break;

            case SPPMessage.MessageIds.MSG_ID_FOTA_DEVICE_INFO_SW_VERSION:
                SwVersionResponse?.Invoke(this, ((SoftwareVersionOTAParser)parser).SoftwareVersion);
                break;

            case SPPMessage.MessageIds.MSG_ID_BATTERY_TYPE:
                BatteryTypeResponse?.Invoke(this, (BatteryTypeParser)parser);
                break;

            case SPPMessage.MessageIds.MSG_ID_AMBIENT_MODE_UPDATED:
                AmbientEnabledUpdateResponse?.Invoke(this, ((AmbientModeUpdateParser)parser).Enabled);
                break;

            case SPPMessage.MessageIds.MSG_ID_DEBUG_BUILD_INFO:
                BuildStringResponse?.Invoke(this, ((DebugBuildInfoParser)parser).BuildString);
                break;

            case SPPMessage.MessageIds.MSG_ID_DEBUG_GET_ALL_DATA:
                GetAllDataResponse?.Invoke(this, (DebugGetAllDataParser)parser);
                break;

            case SPPMessage.MessageIds.MSG_ID_DEBUG_SERIAL_NUMBER:
                SerialNumberResponse?.Invoke(this, (DebugSerialNumberParser)parser);
                break;

            case SPPMessage.MessageIds.MSG_ID_EXTENDED_STATUS_UPDATED:
                ExtendedStatusUpdate?.Invoke(this, (ExtendedStatusUpdateParser)parser);
                break;

            case SPPMessage.MessageIds.MSG_ID_FIND_MY_EARBUDS_STOP:
                FindMyGearStopped?.Invoke(this, null);
                break;

            case SPPMessage.MessageIds.MSG_ID_RESP:
                GenericResponse?.Invoke(this, (GenericResponseParser)parser);
                break;

            case SPPMessage.MessageIds.MSG_ID_SELF_TEST:
                SelfTestResponse?.Invoke(this, (SelfTestParser)parser);
                break;

            case SPPMessage.MessageIds.MSG_ID_SET_TOUCHPAD_OTHER_OPTION:
                OtherOption?.Invoke(this, ((SetOtherOptionParser)parser).OptionType);
                break;

            case SPPMessage.MessageIds.MSG_ID_STATUS_UPDATED:
                StatusUpdate?.Invoke(this, (StatusUpdateParser)parser);
                break;

            case SPPMessage.MessageIds.MSG_ID_USAGE_REPORT:
                UsageReport?.Invoke(this, (UsageReportParser)parser);
                break;

            case SPPMessage.MessageIds.MSG_ID_MUTE_EARBUD_STATUS_UPDATED:
                FindMyGearMuteUpdate?.Invoke(this, (MuteUpdateParser)parser);
                break;

            case SPPMessage.MessageIds.MSG_ID_ANC_STATUS_UPDATED:
                NoiseCancellingUpdated?.Invoke(this, ((NoiseCancellingUpdatedParser)parser).Enabled);
                break;
            }
        }
예제 #4
0
        public void DispatchEvent(BaseMessageParser?parser, SPPMessage.MessageIds?ids = null)
        {
            AnyMessageReceived?.Invoke(this, parser);
            switch (ids ?? parser?.HandledType ?? 0)
            {
            case SPPMessage.MessageIds.RESET:
                ResetResponse?.Invoke(this, (parser as ResetResponseParser)?.ResultCode ?? -1);
                break;

            case SPPMessage.MessageIds.FOTA_DEVICE_INFO_SW_VERSION:
                SwVersionResponse?.Invoke(this, (parser as SoftwareVersionOTAParser)?.SoftwareVersion ?? "null");
                break;

            case SPPMessage.MessageIds.BATTERY_TYPE:
                BatteryTypeResponse?.Invoke(this, (parser as BatteryTypeParser) !);
                break;

            case SPPMessage.MessageIds.AMBIENT_MODE_UPDATED:
                AmbientEnabledUpdateResponse?.Invoke(this, (parser as AmbientModeUpdateParser)?.Enabled ?? false);
                break;

            case SPPMessage.MessageIds.DEBUG_BUILD_INFO:
                BuildStringResponse?.Invoke(this, (parser as DebugBuildInfoParser)?.BuildString ?? "null");
                break;

            case SPPMessage.MessageIds.DEBUG_GET_ALL_DATA:
                GetAllDataResponse?.Invoke(this, (parser as DebugGetAllDataParser) !);
                break;

            case SPPMessage.MessageIds.DEBUG_SERIAL_NUMBER:
                SerialNumberResponse?.Invoke(this, (parser as DebugSerialNumberParser) !);
                break;

            case SPPMessage.MessageIds.EXTENDED_STATUS_UPDATED:
                BaseUpdate?.Invoke(this, (parser as IBasicStatusUpdate) !);
                ExtendedStatusUpdate?.Invoke(this, (parser as ExtendedStatusUpdateParser) !);
                break;

            case SPPMessage.MessageIds.FIND_MY_EARBUDS_STOP:
                FindMyGearStopped?.Invoke(this, EventArgs.Empty);
                break;

            case SPPMessage.MessageIds.RESP:
                GenericResponse?.Invoke(this, (parser as GenericResponseParser) !);
                break;

            case SPPMessage.MessageIds.SELF_TEST:
                SelfTestResponse?.Invoke(this, (parser as SelfTestParser) !);
                break;

            case SPPMessage.MessageIds.SET_TOUCHPAD_OTHER_OPTION:
                OtherOption?.Invoke(this, (parser as SetOtherOptionParser) !.OptionType);
                break;

            case SPPMessage.MessageIds.STATUS_UPDATED:
                StatusUpdate?.Invoke(this, (parser as StatusUpdateParser) !);
                BaseUpdate?.Invoke(this, (parser as IBasicStatusUpdate) !);
                break;

            case SPPMessage.MessageIds.USAGE_REPORT:
                UsageReport?.Invoke(this, (parser as UsageReportParser) !);
                break;

            case SPPMessage.MessageIds.MUTE_EARBUD_STATUS_UPDATED:
                FindMyGearMuteUpdate?.Invoke(this, (parser as MuteUpdateParser) !);
                break;

            case SPPMessage.MessageIds.NOISE_REDUCTION_MODE_UPDATE:
                AncEnabledUpdateResponse?.Invoke(this,
                                                 (parser as NoiseReductionModeUpdateParser)?.Enabled ?? false);
                break;

            case SPPMessage.MessageIds.NOISE_CONTROLS_UPDATE:
                NoiseControlUpdateResponse?.Invoke(this,
                                                   (parser as NoiseControlUpdateParser)?.Mode ?? NoiseControlMode.Off);
                break;
            }
        }