예제 #1
0
        public static BaseMessageParser BuildParser(SPPMessage msg)
        {
            BaseMessageParser b = null;

            for (int i = 0; i < RegisteredParsers.Length; i++)
            {
                var act = (object)Activator.CreateInstance(RegisteredParsers[i]);
                if (act.GetType() == RegisteredParsers[i])
                {
                    BaseMessageParser parser = (BaseMessageParser)act;
                    if (parser.HandledType == msg.Id)
                    {
                        SentrySdk.ConfigureScope(scope =>
                        {
                            scope.SetTag("msg-data-available", "true");
                            scope.SetExtra("msg-type", msg.Type.ToString());
                            scope.SetExtra("msg-id", msg.Id);
                            scope.SetExtra("msg-size", msg.Size);
                            scope.SetExtra("msg-total-size", msg.TotalPacketSize);
                            scope.SetExtra("msg-crc16", msg.CRC16);
                            scope.SetExtra("msg-payload", Hex.Dump(msg.Payload, 512, false, false, false));
                        });

                        parser.ParseMessage(msg);
                        b = parser;
                        break;
                    }
                }
            }
            return(b);
        }
예제 #2
0
        /**
         * Static "constructors"
         */
        public static SPPMessage DecodeMessage(byte[] raw)
        {
            SPPMessage draft = new SPPMessage();

            if (raw.Length < 6)
            {
                throw new InvalidDataException("Message too small");
            }

            if (raw[0] != (byte)Constants.SOM)
            {
                throw new InvalidDataException("Invalid SOM");
            }

            draft.Type = (MsgType)Convert.ToInt32(raw[1]);
            draft.Id   = (MessageIds)Convert.ToInt32(raw[3]);
            int size = Convert.ToInt32(raw[2]);

            //Substract Id and CRC from size
            int rawPayloadSize = size - 3;

            byte[] payload = new byte[rawPayloadSize];

            byte[] crcData = new byte[size];
            crcData[0] = raw[3]; //Msg ID

            for (int i = 0; i < rawPayloadSize; i++)
            {
                //Start to read at byte 4
                payload[i]     = raw[i + 4];
                crcData[i + 1] = raw[i + 4];
            }

            byte crc1 = raw[4 + rawPayloadSize];
            byte crc2 = raw[4 + rawPayloadSize + 1];

            crcData[crcData.Length - 2] = crc2;
            crcData[crcData.Length - 1] = crc1;

            draft.Payload = payload;
            draft.CRC16   = util.CRC16.crc16_ccitt(crcData);

            if (size != draft.Size)
            {
                throw new InvalidDataException("Payload size mismatch");
            }

            if (raw[4 + rawPayloadSize + 2] != (byte)Constants.EOM)
            {
                throw new InvalidDataException("Invalid EOM");
            }

            return(draft);
        }
        public static BaseMessageParser BuildParser(SPPMessage msg)
        {
            BaseMessageParser b = null;

            for (int i = 0; i < RegisteredParsers.Length; i++)
            {
                var act = (object)Activator.CreateInstance(RegisteredParsers[i]);
                if (act.GetType() == RegisteredParsers[i])
                {
                    BaseMessageParser parser = (BaseMessageParser)act;
                    if (parser.HandledType == msg.Id)
                    {
                        parser.ParseMessage(msg);
                        b = parser;
                        break;
                    }
                }
            }
            return(b);
        }
예제 #4
0
        /**
         * Static "constructors"
         */
        public static SPPMessage DecodeMessage(byte[] raw)
        {
            SPPMessage draft = new SPPMessage();

            if (raw.Length < 6)
            {
                throw new InvalidDataException(Loc.GetString("sppmsg_too_small"));
            }

            if (raw[0] != (byte)Constants.SOM && BluetoothService.Instance.ActiveModel == Model.Buds)
            {
                throw new InvalidDataException(Loc.GetString("sppmsg_invalid_som"));
            }
            else if (raw[0] != (byte)Constants.SOMPlus && BluetoothService.Instance.ActiveModel == Model.BudsPlus)
            {
                throw new InvalidDataException(Loc.GetString("sppmsg_invalid_som"));
            }

            draft.Id = (MessageIds)Convert.ToInt32(raw[3]);
            int size;

            if (BluetoothService.Instance.ActiveModel == Model.BudsPlus)
            {
                size       = raw[1] & 1023;
                draft.Type = (raw[2] & 16) == 0 ? MsgType.Request : MsgType.Response;
            }
            else
            {
                draft.Type = (MsgType)Convert.ToInt32(raw[1]);
                size       = Convert.ToInt32(raw[2]);
            }

            //Substract Id and CRC from size
            int rawPayloadSize = size - 3;

            byte[] payload = new byte[rawPayloadSize];

            byte[] crcData = new byte[size];
            crcData[0] = raw[3]; //Msg ID

            for (int i = 0; i < rawPayloadSize; i++)
            {
                //Start to read at byte 4
                payload[i]     = raw[i + 4];
                crcData[i + 1] = raw[i + 4];
            }

            byte crc1 = raw[4 + rawPayloadSize];
            byte crc2 = raw[4 + rawPayloadSize + 1];

            crcData[crcData.Length - 2] = crc2;
            crcData[crcData.Length - 1] = crc1;

            draft.Payload = payload;
            draft.CRC16   = util.CRC16.crc16_ccitt(crcData);

            if (size != draft.Size)
            {
                throw new InvalidDataException(Loc.GetString("sppmsg_size_mismatch"));
            }

            if (raw[4 + rawPayloadSize + 2] != (byte)Constants.EOM && BluetoothService.Instance.ActiveModel == Model.Buds)
            {
                throw new InvalidDataException(Loc.GetString("sppmsg_invalid_eom"));
            }
            else if (raw[4 + rawPayloadSize + 2] != (byte)Constants.EOMPlus && BluetoothService.Instance.ActiveModel == Model.BudsPlus)
            {
                throw new InvalidDataException(Loc.GetString("sppmsg_invalid_eom"));
            }

            return(draft);
        }
예제 #5
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;
            }
        }
예제 #6
0
        /**
         * Static "constructors"
         */
        public static SPPMessage DecodeMessage(byte[] raw)
        {
            SPPMessage draft = new SPPMessage();

            if (raw.Length < 6)
            {
                Sentry.SentrySdk.AddBreadcrumb($"Message too small (Length: {raw.Length})", "spp", level: Sentry.Protocol.BreadcrumbLevel.Warning);
                throw new InvalidDataException(Loc.GetString("sppmsg_too_small"));
            }

            if ((raw[0] != (byte)Constants.SOM && BluetoothService.Instance.ActiveModel == Model.Buds) ||
                (raw[0] != (byte)Constants.SOMPlus && BluetoothService.Instance.ActiveModel != Model.Buds))
            {
                Sentry.SentrySdk.AddBreadcrumb($"Invalid SOM (Received: {raw[0]})", "spp", level: Sentry.Protocol.BreadcrumbLevel.Warning);
                throw new InvalidDataException(Loc.GetString("sppmsg_invalid_som"));
            }

            draft.Id = (MessageIds)Convert.ToInt32(raw[3]);
            int size;

            if (BluetoothService.Instance.ActiveModel != Model.Buds)
            {
                size       = raw[1] & 1023;
                draft.Type = (raw[2] & 16) == 0 ? MsgType.Request : MsgType.Response;
            }
            else
            {
                draft.Type = (MsgType)Convert.ToInt32(raw[1]);
                size       = Convert.ToInt32(raw[2]);
            }

            //Substract Id and CRC from size
            int rawPayloadSize = size - 3;

            byte[] payload = new byte[rawPayloadSize];

            byte[] crcData = new byte[size];
            crcData[0] = raw[3]; //Msg ID

            for (int i = 0; i < rawPayloadSize; i++)
            {
                //Start to read at byte 4
                payload[i]     = raw[i + 4];
                crcData[i + 1] = raw[i + 4];
            }

            byte crc1 = raw[4 + rawPayloadSize];
            byte crc2 = raw[4 + rawPayloadSize + 1];

            crcData[crcData.Length - 2] = crc2;
            crcData[crcData.Length - 1] = crc1;

            draft.Payload = payload;
            draft.CRC16   = util.CRC16.crc16_ccitt(crcData);

            if (size != draft.Size)
            {
                Sentry.SentrySdk.AddBreadcrumb($"Invalid size (Reported: {size}, Calculated: {draft.Size})", "spp", level: Sentry.Protocol.BreadcrumbLevel.Warning);
                throw new InvalidDataException(Loc.GetString("sppmsg_size_mismatch"));
            }

            if (draft.CRC16 != 0)
            {
                Sentry.SentrySdk.AddBreadcrumb($"CRC checksum failed (ID: {draft.Id}, Size: {draft.Size})", "spp", level: Sentry.Protocol.BreadcrumbLevel.Warning);
            }

            if (raw[4 + rawPayloadSize + 2] != (byte)Constants.EOM && BluetoothService.Instance.ActiveModel == Model.Buds)
            {
                Sentry.SentrySdk.AddBreadcrumb($"Invalid EOM (Received: {raw[4 + rawPayloadSize + 2]})", "spp", level: Sentry.Protocol.BreadcrumbLevel.Warning);
                throw new InvalidDataException(Loc.GetString("sppmsg_invalid_eom"));
            }
            else if (raw[4 + rawPayloadSize + 2] != (byte)Constants.EOMPlus && BluetoothService.Instance.ActiveModel != Model.Buds)
            {
                Sentry.SentrySdk.AddBreadcrumb($"Invalid EOM (Received: {raw[4 + rawPayloadSize + 2]})", "spp", level: Sentry.Protocol.BreadcrumbLevel.Warning);
                throw new InvalidDataException(Loc.GetString("sppmsg_invalid_eom"));
            }

            return(draft);
        }