/** * Static "constructors" */ public static SPPMessage DecodeMessage(byte[] raw) { try { SPPMessage draft = new SPPMessage(); if (raw.Length < 6) { SentrySdk.AddBreadcrumb($"Message too small (Length: {raw.Length})", "spp", level: BreadcrumbLevel.Warning); Log.Error($"Message too small (Length: {raw.Length})"); throw new InvalidPacketException(InvalidPacketException.ErrorCodes.TooSmall, Loc.Resolve("sppmsg_too_small")); } if ((raw[0] != (byte)Constants.SOM && BluetoothImpl.Instance.ActiveModel == Models.Buds) || (raw[0] != (byte)Constants.SOMPlus && BluetoothImpl.Instance.ActiveModel != Models.Buds)) { SentrySdk.AddBreadcrumb($"Invalid SOM (Received: {raw[0]})", "spp", level: BreadcrumbLevel.Warning); Log.Error($"Invalid SOM (Received: {raw[0]})"); throw new InvalidPacketException(InvalidPacketException.ErrorCodes.SOM, Loc.Resolve("sppmsg_invalid_som")); } draft.Id = (MessageIds)Convert.ToInt32(raw[3]); int size; if (BluetoothImpl.Instance.ActiveModel != Models.Buds) { var p1 = (raw[2] << 8); var p2 = raw[1] & 255; var header = p1 + p2; draft.IsFragment = (header & 8192) != 0; draft.Type = (header & 4096) != 0 ? MsgType.Request : MsgType.Response; size = header & 1023; } else { draft.Type = (MsgType)Convert.ToInt32(raw[1]); size = Convert.ToInt32(raw[2]); } //Subtract Id and CRC from size var rawPayloadSize = size - 3; byte[] payload = new byte[rawPayloadSize]; byte[] crcData = new byte[size]; crcData[0] = raw[3]; //Msg ID for (var i = 0; i < rawPayloadSize; i++) { //Start to read at byte 4 payload[i] = raw[i + 4]; crcData[i + 1] = raw[i + 4]; } var crc1 = raw[4 + rawPayloadSize]; var crc2 = raw[4 + rawPayloadSize + 1]; crcData[^ 2] = crc2;
public void MessageReceiver(object?sender, SPPMessage e) { Dispatcher.UIThread.InvokeAsync(() => { BaseMessageParser?parser = SPPMessageParserFactory.BuildParser(e); DispatchEvent(parser, e.Id); }, DispatcherPriority.DataBind); }
public static BaseMessageParser?BuildParser(SPPMessage msg) { BaseMessageParser?b = null; for (int i = 0; i < RegisteredParsers.Length; i++) { var act = 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", HexUtils.Dump(msg.Payload, 512, false, false, false)); }); parser.ParseMessage(msg); b = parser; break; } } } if (b != null) { foreach (var hook in ScriptManager.Instance.DecoderHooks) { hook?.OnDecoderCreated(msg, ref b); } } return(b); }
private async void OnMessageReceived(object?sender, SPPMessage e) { switch (e.Id) { #region SESSION case SPPMessage.MessageIds.LOG_SESSION_OPEN: _hasCompletedRoleSwitch = false; if (e.Payload[0] == 0) { await BluetoothImpl.Instance.SendRequestAsync(SPPMessage.MessageIds.LOG_TRACE_START, 0); } break; case SPPMessage.MessageIds.LOG_SESSION_CLOSE: break; #endregion #region TRACE case SPPMessage.MessageIds.LOG_TRACE_START: _traceContext = e.BuildParser() as LogTraceStartParser; _traceBuffer = new byte[_traceContext !.DataSize];