/// <summary> /// Expects CBus message bytes with ETX and STX stripped and check sum already verified /// </summary> /// <param name="CommandBytes"></param> /// <param name="Command"></param> /// <returns></returns> public bool TryParseCommand(byte[] CommandBytes, int CommandLength, bool IsMonitoredSAL, bool IsShortFormMessage, out CBusSALCommand Command) { int dataPointer; byte CBusApplicationAddress; if (CBusSALCommand.TryParseApplicationId(CommandBytes, CommandLength, IsMonitoredSAL, IsShortFormMessage, out dataPointer, out CBusApplicationAddress)) { //var appAddress = IsShortFormMessage ? CommandBytes[1] : CommandBytes[2]; var maping = AddressMap.SingleOrDefault(m => m.Address == CBusApplicationAddress); if (maping != null) { switch (maping.ApplicationType) { case CBusProtcol.ApplicationTypes.LIGHTING: { CBusLightingCommand lightingCommand; if (CBusLightingCommand.TryParseReply(CommandBytes, CommandLength, IsShortFormMessage, CBusApplicationAddress, ref dataPointer, out lightingCommand)) { Command = lightingCommand; return(true); } break; } case CBusProtcol.ApplicationTypes.TRIGGER: { CBusTriggerCommand triggerCommand; if (CBusTriggerCommand.TryParse(CommandBytes, CommandLength, IsShortFormMessage, CBusApplicationAddress, ref dataPointer, out triggerCommand)) { Command = triggerCommand; return(true); } break; } default: break; } } else { //Valid message but unknown application type } } else { //Could not get application address } Command = null; return(false); }
/// <summary> /// When receiving a command from the wire parse using this method into a CBus Command /// </summary> /// <param name="CommandBytes"></param> /// <param name="Command"></param> /// <returns></returns> internal static bool TryParse(byte[] CommandBytes, int CommandLength, bool IsShortFormMessage, byte CBusApplicationAddress, ref int dataPointer, out CBusTriggerCommand Command) { Command = null; var triggerCommandList = new List <TriggerCommand>(); CBusHeader header; CBusHeader.TryParse(CommandBytes[0], out header); //As message length includes checksum, where as we just want the payload length var messagePayloadLenght = (CommandLength - 1); //Process Contained Commands while (dataPointer < messagePayloadLenght) { //Most Significant Bit indicates long or short format comamnd if ((CommandBytes[dataPointer] & 0x80) == 0) { //Short form command byte group = 0; var triggerCommandType = TriggerCommand.TriggerCommandId.UNKNOWN; if (!Enum.IsDefined(typeof(TriggerCommand.TriggerCommandId), CommandBytes[dataPointer])) { return(false); } //Lower 3 bites of command //var commandLength = (commandId & 0x07); triggerCommandType = (TriggerCommand.TriggerCommandId)CommandBytes[dataPointer++]; group = CommandBytes[dataPointer++]; //Add the command switch (triggerCommandType) { case TriggerCommand.TriggerCommandId.EVENT: { var triggerGroup = CommandBytes[dataPointer++]; var Action = CommandBytes[dataPointer++]; var cmd = new TriggerCommand(triggerGroup, Action); triggerCommandList.Add(cmd); break; } //Also contain level parameter case TriggerCommand.TriggerCommandId.TRIGGER_MIN: case TriggerCommand.TriggerCommandId.TRIGGER_MAX: case TriggerCommand.TriggerCommandId.TRIGGER_KILL: { var triggerGroup = CommandBytes[dataPointer++]; var cmd = new TriggerCommand(triggerCommandType, triggerGroup); triggerCommandList.Add(cmd); break; } case TriggerCommand.TriggerCommandId.UNKNOWN: default: return(false); } } else { //Long form command, not implemented break; } } Command = new CBusTriggerCommand(header, CBusApplicationAddress, triggerCommandList); return(true); }