feat: add application controller handling and DALI control device commands
Signed-off-by: Tony <tonylu@tony-cloud.com>
This commit is contained in:
@@ -22,6 +22,7 @@ Dali_msg_t dali_msg_new_generic(uint8_t bit_length, uint8_t address, uint8_t cmd
|
||||
|
||||
// create standard DALI message: 16,24,32 bits
|
||||
Dali_msg_t dali_msg_new(uint8_t address, uint8_t cmd1);
|
||||
Dali_msg_t dali_msg_new_1B(uint8_t data);
|
||||
Dali_msg_t dali_msg_new_3B(uint8_t address, uint8_t cmd1, uint8_t cmd2);
|
||||
Dali_msg_t dali_msg_new_4B(uint8_t address, uint8_t cmd1, uint8_t cmd2, uint8_t cmd3);
|
||||
|
||||
@@ -86,4 +87,3 @@ void dali_change_short_address(int addr1, int addr2);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -140,6 +140,11 @@ class DaliDomainService {
|
||||
bool sendRaw(uint8_t gateway_id, uint8_t raw_addr, uint8_t command) const;
|
||||
bool sendExtRaw(uint8_t gateway_id, uint8_t raw_addr, uint8_t command) const;
|
||||
std::optional<uint8_t> queryRaw(uint8_t gateway_id, uint8_t raw_addr, uint8_t command) const;
|
||||
bool sendControlDeviceRaw(uint8_t gateway_id, uint8_t byte0, uint8_t byte1, uint8_t byte2,
|
||||
bool send_twice = false) const;
|
||||
std::optional<uint8_t> queryControlDeviceRaw(uint8_t gateway_id, uint8_t byte0,
|
||||
uint8_t byte1, uint8_t byte2) const;
|
||||
bool sendBackwardFrame(uint8_t gateway_id, uint8_t value) const;
|
||||
std::optional<DaliDomainSnapshot> discoverDeviceTypes(
|
||||
uint8_t gateway_id, int short_address, const std::vector<int>& fallback_types = {},
|
||||
int max_next_types = 16) const;
|
||||
|
||||
@@ -25,6 +25,9 @@ namespace {
|
||||
constexpr size_t kSerialRxPacketMaxBytes = 8;
|
||||
constexpr UBaseType_t kSerialRxQueueDepth = 8;
|
||||
constexpr uint32_t kHardwareQueryRawPostSuppressMs = 10;
|
||||
constexpr uint8_t kControlDeviceSendOpcode = 0x60;
|
||||
constexpr uint8_t kControlDeviceSendTwiceOpcode = 0x61;
|
||||
constexpr uint8_t kControlDeviceQueryOpcode = 0x62;
|
||||
|
||||
portMUX_TYPE s_query_raw_suppress_lock = portMUX_INITIALIZER_UNLOCKED;
|
||||
uint8_t s_query_raw_suppress_inflight[DALI_PHY_COUNT] = {};
|
||||
@@ -146,6 +149,13 @@ std::vector<uint8_t> LegacyQueryResponse(uint8_t status, uint8_t value = 0x00) {
|
||||
return {status, value};
|
||||
}
|
||||
|
||||
std::optional<uint8_t> ParseLegacyQueryValue(const std::vector<uint8_t>& packet) {
|
||||
if (packet.size() >= 2 && packet[0] == 0xFF) {
|
||||
return packet[1];
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
void LogQueryRxPacket(const char* transport, int id, const std::vector<uint8_t>& packet,
|
||||
const char* note = nullptr) {
|
||||
const unsigned first = packet.size() > 0 ? packet[0] : 0;
|
||||
@@ -156,11 +166,80 @@ void LogQueryRxPacket(const char* transport, int id, const std::vector<uint8_t>&
|
||||
note == nullptr ? "" : " note=", note == nullptr ? "" : note);
|
||||
}
|
||||
|
||||
bool SendHardwareFrame(uint8_t bus_id, const uint8_t* data, size_t len) {
|
||||
bool SendHardwareControlDeviceFrame(uint8_t bus_id, const uint8_t* data, size_t len,
|
||||
bool send_twice) {
|
||||
if (data == nullptr || len != 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Dali_msg_t tx = dali_msg_new_3B(data[0], data[1], data[2]);
|
||||
tx.id = bus_id;
|
||||
ESP_LOGD(TAG, "sending hardware control-device frame for bus=%u data=%02x %02x %02x",
|
||||
bus_id, data[0], data[1], data[2]);
|
||||
if (send_twice) {
|
||||
dali_send_double(&tx);
|
||||
} else {
|
||||
dali_send(&tx);
|
||||
}
|
||||
return tx.status == DALI_FRAME_OK;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> TransactHardwareControlDeviceFrame(uint8_t bus_id, const uint8_t* data,
|
||||
size_t len) {
|
||||
if (data == nullptr || len != 3) {
|
||||
const auto packet = LegacyQueryResponse(0xFD);
|
||||
LogQueryRxPacket("hardware-cd", bus_id, packet, "invalid-query-len");
|
||||
return packet;
|
||||
}
|
||||
|
||||
Dali_msg_t tx = dali_msg_new_3B(data[0], data[1], data[2]);
|
||||
tx.id = bus_id;
|
||||
Dali_msg_t rx = {};
|
||||
ESP_LOGD(TAG, "received hardware control-device query for bus=%u data=%02x %02x %02x",
|
||||
bus_id, data[0], data[1], data[2]);
|
||||
BeginHardwareQueryRawSuppress(bus_id);
|
||||
if (dali_query(&tx, &rx) == pdTRUE) {
|
||||
ClearHardwareQueryRawSuppress(bus_id);
|
||||
if (rx.status != DALI_FRAME_OK || rx.length != 8) {
|
||||
ESP_LOGW(TAG, "hardware control-device query response for bus=%u has invalid status or length",
|
||||
bus_id);
|
||||
const auto packet = LegacyQueryResponse(0xFD);
|
||||
LogQueryRxPacket("hardware-cd", bus_id, packet, "invalid-status-or-length");
|
||||
return packet;
|
||||
}
|
||||
const std::vector<uint8_t> packet{0xFF, rx.data[0]};
|
||||
LogQueryRxPacket("hardware-cd", bus_id, packet, "ok");
|
||||
return packet;
|
||||
}
|
||||
ClearHardwareQueryRawSuppress(bus_id);
|
||||
const auto packet = LegacyQueryResponse(0xFE);
|
||||
LogQueryRxPacket("hardware-cd", bus_id, packet, "no-response");
|
||||
return packet;
|
||||
}
|
||||
|
||||
bool SendHardwareBackwardFrame(uint8_t bus_id, uint8_t value) {
|
||||
Dali_msg_t tx = dali_msg_new_1B(value);
|
||||
tx.id = bus_id;
|
||||
ESP_LOGD(TAG, "sending hardware backward frame for bus=%u data=%02x", bus_id, value);
|
||||
dali_send(&tx);
|
||||
return tx.status == DALI_FRAME_OK;
|
||||
}
|
||||
|
||||
bool SendHardwareFrame(uint8_t bus_id, const uint8_t* data, size_t len) {
|
||||
if (data == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (len == 4 && (data[0] == kControlDeviceSendOpcode ||
|
||||
data[0] == kControlDeviceSendTwiceOpcode)) {
|
||||
return SendHardwareControlDeviceFrame(bus_id, data + 1, 3,
|
||||
data[0] == kControlDeviceSendTwiceOpcode);
|
||||
}
|
||||
|
||||
if (len != 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data[0] == 0x00) {
|
||||
return true;
|
||||
}
|
||||
@@ -186,6 +265,9 @@ std::vector<uint8_t> TransactHardwareFrame(uint8_t bus_id, const uint8_t* data,
|
||||
if (data == nullptr) {
|
||||
return {};
|
||||
}
|
||||
if (len == 4 && data[0] == kControlDeviceQueryOpcode) {
|
||||
return TransactHardwareControlDeviceFrame(bus_id, data + 1, 3);
|
||||
}
|
||||
if (len != 3) {
|
||||
if (len > 0 && data[0] == 0x12) {
|
||||
const auto packet = LegacyQueryResponse(0xFD);
|
||||
@@ -276,12 +358,14 @@ std::vector<uint8_t> TransactSerialFrame(int uart_port, QueueHandle_t queue,
|
||||
LogQueryRxPacket("serial", uart_port, packet, "empty-query");
|
||||
return packet;
|
||||
}
|
||||
if (data[0] == 0x12 && len != 3) {
|
||||
const bool query_frame = data[0] == 0x12 || data[0] == kControlDeviceQueryOpcode;
|
||||
const size_t expected_query_len = data[0] == kControlDeviceQueryOpcode ? 4 : 3;
|
||||
if (query_frame && len != expected_query_len) {
|
||||
const auto packet = LegacyQueryResponse(0xFD);
|
||||
LogQueryRxPacket("serial", uart_port, packet, "invalid-query-len");
|
||||
return packet;
|
||||
}
|
||||
if (data != nullptr && len > 0 && data[0] == 0x12) {
|
||||
if (query_frame) {
|
||||
DrainSerialQueue(queue);
|
||||
}
|
||||
if (!WriteSerialFrame(uart_port, data, len)) {
|
||||
@@ -289,7 +373,7 @@ std::vector<uint8_t> TransactSerialFrame(int uart_port, QueueHandle_t queue,
|
||||
LogQueryRxPacket("serial", uart_port, packet, "write-failed");
|
||||
return packet;
|
||||
}
|
||||
if (data[0] != 0x12) {
|
||||
if (!query_frame) {
|
||||
return {0xFF};
|
||||
}
|
||||
|
||||
@@ -721,6 +805,70 @@ std::optional<uint8_t> DaliDomainService::queryRaw(uint8_t gateway_id, uint8_t r
|
||||
return channel->comm->queryRawNew(raw_addr, command);
|
||||
}
|
||||
|
||||
bool DaliDomainService::sendControlDeviceRaw(uint8_t gateway_id, uint8_t byte0, uint8_t byte1,
|
||||
uint8_t byte2, bool send_twice) const {
|
||||
const auto* channel = findChannelByGateway(gateway_id);
|
||||
if (channel == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t frame[3] = {byte0, byte1, byte2};
|
||||
markHostActivity(gateway_id);
|
||||
markBusActivity(gateway_id);
|
||||
if (channel->hardware_bus.has_value()) {
|
||||
return SendHardwareControlDeviceFrame(channel->hardware_bus->bus_id, frame, sizeof(frame),
|
||||
send_twice);
|
||||
}
|
||||
if (!channel->hooks.send) {
|
||||
return false;
|
||||
}
|
||||
const uint8_t bridge_frame[4] = {
|
||||
static_cast<uint8_t>(send_twice ? kControlDeviceSendTwiceOpcode : kControlDeviceSendOpcode),
|
||||
byte0,
|
||||
byte1,
|
||||
byte2,
|
||||
};
|
||||
return channel->hooks.send(bridge_frame, sizeof(bridge_frame));
|
||||
}
|
||||
|
||||
std::optional<uint8_t> DaliDomainService::queryControlDeviceRaw(uint8_t gateway_id, uint8_t byte0,
|
||||
uint8_t byte1,
|
||||
uint8_t byte2) const {
|
||||
const auto* channel = findChannelByGateway(gateway_id);
|
||||
if (channel == nullptr) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const uint8_t frame[3] = {byte0, byte1, byte2};
|
||||
markHostActivity(gateway_id);
|
||||
markBusActivity(gateway_id);
|
||||
if (channel->hardware_bus.has_value()) {
|
||||
return ParseLegacyQueryValue(
|
||||
TransactHardwareControlDeviceFrame(channel->hardware_bus->bus_id, frame, sizeof(frame)));
|
||||
}
|
||||
if (!channel->hooks.transact) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const uint8_t bridge_frame[4] = {kControlDeviceQueryOpcode, byte0, byte1, byte2};
|
||||
return ParseLegacyQueryValue(channel->hooks.transact(bridge_frame, sizeof(bridge_frame)));
|
||||
}
|
||||
|
||||
bool DaliDomainService::sendBackwardFrame(uint8_t gateway_id, uint8_t value) const {
|
||||
const auto* channel = findChannelByGateway(gateway_id);
|
||||
if (channel == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
markBusActivity(gateway_id);
|
||||
if (channel->hardware_bus.has_value()) {
|
||||
return SendHardwareBackwardFrame(channel->hardware_bus->bus_id, value);
|
||||
}
|
||||
if (!channel->hooks.send) {
|
||||
return false;
|
||||
}
|
||||
return channel->hooks.send(&value, 1);
|
||||
}
|
||||
|
||||
std::optional<DaliDomainSnapshot> DaliDomainService::discoverDeviceTypes(
|
||||
uint8_t gateway_id, int short_address, const std::vector<int>& fallback_types,
|
||||
int max_next_types) const {
|
||||
|
||||
@@ -144,6 +144,9 @@ class GatewayController {
|
||||
void publishPayload(uint8_t gateway_id, const std::vector<uint8_t>& payload);
|
||||
void publishFrame(const std::vector<uint8_t>& frame);
|
||||
void handleDaliRawFrame(const DaliRawFrame& frame);
|
||||
bool handleApplicationControllerFrame(const DaliRawFrame& frame);
|
||||
std::optional<uint8_t> applicationControllerResponse(uint8_t gateway_id, uint8_t first,
|
||||
uint8_t instance, uint8_t opcode) const;
|
||||
|
||||
bool sendRawAndMirror(uint8_t gateway_id, uint8_t raw_addr, uint8_t command);
|
||||
bool sendExtRawAndMirror(uint8_t gateway_id, uint8_t raw_addr, uint8_t command);
|
||||
@@ -207,6 +210,14 @@ class GatewayController {
|
||||
bool ble_enabled_{false};
|
||||
bool wifi_enabled_{false};
|
||||
bool ip_router_enabled_{true};
|
||||
bool application_controller_enabled_{true};
|
||||
bool application_controller_power_cycle_notification_{true};
|
||||
bool application_controller_power_cycle_seen_{true};
|
||||
bool application_controller_reset_state_{false};
|
||||
uint8_t application_controller_operating_mode_{0};
|
||||
uint8_t application_controller_dtr0_{0};
|
||||
uint8_t application_controller_dtr1_{0};
|
||||
uint8_t application_controller_dtr2_{0};
|
||||
};
|
||||
|
||||
} // namespace gateway
|
||||
|
||||
@@ -28,6 +28,12 @@ constexpr uint8_t kBridgeTransportRequestOpcode = 0xB0;
|
||||
constexpr uint8_t kBridgeTransportResponseOpcode = 0xB1;
|
||||
constexpr uint8_t kBridgeTransportVersion = 1;
|
||||
constexpr size_t kBridgeTransportMaxChunkBytes = 120;
|
||||
constexpr uint8_t kDali103SendOpcode = 0x60;
|
||||
constexpr uint8_t kDali103SendTwiceOpcode = 0x61;
|
||||
constexpr uint8_t kDali103QueryOpcode = 0x62;
|
||||
constexpr uint8_t kDali103QueryResponseOpcode = 0x63;
|
||||
constexpr uint8_t kDali103NoResponseOpcode = 0x64;
|
||||
constexpr uint8_t kDali103RawFrameOpcode = 0x65;
|
||||
constexpr uint8_t kGatewayFeatureCache = 0x40;
|
||||
constexpr uint8_t kGatewayCacheOpcode = 0x39;
|
||||
constexpr uint8_t kGatewayCacheProtocolVersion = 1;
|
||||
@@ -106,6 +112,9 @@ bool IsDaliHostCommandOpcode(uint8_t opcode) {
|
||||
case 0x32:
|
||||
case 0x37:
|
||||
case 0x38:
|
||||
case kDali103SendOpcode:
|
||||
case kDali103SendTwiceOpcode:
|
||||
case kDali103QueryOpcode:
|
||||
case 0xA0:
|
||||
case 0xA2:
|
||||
case kBridgeTransportRequestOpcode:
|
||||
@@ -933,6 +942,24 @@ void GatewayController::dispatchCommand(const std::vector<uint8_t>& command) {
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kDali103SendOpcode:
|
||||
case kDali103SendTwiceOpcode:
|
||||
if (command.size() >= 8) {
|
||||
dali_domain_.sendControlDeviceRaw(gateway_id, command[4], command[5], command[6],
|
||||
opcode == kDali103SendTwiceOpcode);
|
||||
}
|
||||
break;
|
||||
case kDali103QueryOpcode:
|
||||
if (command.size() >= 8) {
|
||||
const auto result =
|
||||
dali_domain_.queryControlDeviceRaw(gateway_id, command[4], command[5], command[6]);
|
||||
if (result.has_value()) {
|
||||
publishPayload(gateway_id, {kDali103QueryResponseOpcode, gateway_id, result.value()});
|
||||
} else {
|
||||
publishPayload(gateway_id, {kDali103NoResponseOpcode, gateway_id, 0x00});
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kGatewayCacheOpcode:
|
||||
handleGatewayCacheCommand(gateway_id, command);
|
||||
break;
|
||||
@@ -1036,6 +1063,160 @@ void GatewayController::publishFrame(const std::vector<uint8_t>& frame) {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<uint8_t> GatewayController::applicationControllerResponse(
|
||||
uint8_t gateway_id, uint8_t first, uint8_t instance, uint8_t opcode) const {
|
||||
const uint8_t gateway_short =
|
||||
static_cast<uint8_t>(((gateway_id & 0x3F) << 1) | 0x01);
|
||||
const bool addressed_to_gateway = first == 0xFF || first == gateway_short;
|
||||
if (!addressed_to_gateway || instance != 0xFE) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
switch (opcode) {
|
||||
case 0x30: {
|
||||
uint8_t status = 0;
|
||||
if (application_controller_enabled_) {
|
||||
status |= 0x08;
|
||||
}
|
||||
if (application_controller_power_cycle_seen_) {
|
||||
status |= 0x20;
|
||||
}
|
||||
if (application_controller_reset_state_) {
|
||||
status |= 0x40;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
case 0x31:
|
||||
case 0x32:
|
||||
case 0x33:
|
||||
return 0x00;
|
||||
case 0x34:
|
||||
return 0x02;
|
||||
case 0x35:
|
||||
return 0x00;
|
||||
case 0x36:
|
||||
return application_controller_dtr0_;
|
||||
case 0x37:
|
||||
return application_controller_dtr1_;
|
||||
case 0x38:
|
||||
return application_controller_dtr2_;
|
||||
case 0x39:
|
||||
case 0x3A:
|
||||
case 0x3B:
|
||||
return 0x00;
|
||||
case 0x3C:
|
||||
return 0xFF;
|
||||
case 0x3D:
|
||||
return static_cast<uint8_t>(application_controller_enabled_ ? 1 : 0);
|
||||
case 0x3E:
|
||||
return application_controller_operating_mode_;
|
||||
case 0x3F:
|
||||
case 0x40:
|
||||
case 0x41:
|
||||
case 0x42:
|
||||
case 0x43:
|
||||
case 0x44:
|
||||
return 0x00;
|
||||
case 0x45:
|
||||
return static_cast<uint8_t>(application_controller_power_cycle_notification_ ? 1 : 0);
|
||||
case 0x46:
|
||||
return 0x01;
|
||||
case 0x47:
|
||||
return 0x01;
|
||||
case 0x48:
|
||||
return static_cast<uint8_t>(application_controller_reset_state_ ? 1 : 0);
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
bool GatewayController::handleApplicationControllerFrame(const DaliRawFrame& frame) {
|
||||
if (frame.data.size() != 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t first = frame.data[0];
|
||||
const uint8_t instance = frame.data[1];
|
||||
const uint8_t opcode = frame.data[2];
|
||||
|
||||
if (first == 0xC1) {
|
||||
switch (instance) {
|
||||
case 0x30:
|
||||
application_controller_dtr0_ = opcode;
|
||||
break;
|
||||
case 0x31:
|
||||
application_controller_dtr1_ = opcode;
|
||||
break;
|
||||
case 0x32:
|
||||
application_controller_dtr2_ = opcode;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((first & 0x01) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const uint8_t gateway_short =
|
||||
static_cast<uint8_t>(((frame.gateway_id & 0x3F) << 1) | 0x01);
|
||||
if (first != 0xFF && first != gateway_short) {
|
||||
return false;
|
||||
}
|
||||
if (instance != 0xFE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (opcode) {
|
||||
case 0x01:
|
||||
application_controller_power_cycle_seen_ = false;
|
||||
application_controller_reset_state_ = false;
|
||||
break;
|
||||
case 0x10:
|
||||
application_controller_enabled_ = true;
|
||||
application_controller_power_cycle_notification_ = true;
|
||||
application_controller_reset_state_ = true;
|
||||
application_controller_operating_mode_ = 0;
|
||||
application_controller_dtr0_ = 0;
|
||||
application_controller_dtr1_ = 0;
|
||||
application_controller_dtr2_ = 0;
|
||||
break;
|
||||
case 0x16:
|
||||
application_controller_enabled_ = true;
|
||||
application_controller_reset_state_ = false;
|
||||
break;
|
||||
case 0x17:
|
||||
application_controller_enabled_ = false;
|
||||
application_controller_reset_state_ = false;
|
||||
break;
|
||||
case 0x18:
|
||||
application_controller_operating_mode_ = application_controller_dtr0_;
|
||||
application_controller_reset_state_ = false;
|
||||
break;
|
||||
case 0x1F:
|
||||
application_controller_power_cycle_notification_ = true;
|
||||
application_controller_reset_state_ = false;
|
||||
break;
|
||||
case 0x20:
|
||||
application_controller_power_cycle_notification_ = false;
|
||||
application_controller_reset_state_ = false;
|
||||
break;
|
||||
case 0x21:
|
||||
application_controller_reset_state_ = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const auto response = applicationControllerResponse(frame.gateway_id, first, instance, opcode);
|
||||
if (!response.has_value()) {
|
||||
return false;
|
||||
}
|
||||
return dali_domain_.sendBackwardFrame(frame.gateway_id, response.value());
|
||||
}
|
||||
|
||||
void GatewayController::handleBridgeTransportCommand(uint8_t gateway_id,
|
||||
const std::vector<uint8_t>& command) {
|
||||
const uint8_t version = command.size() > 4 ? command[4] : kBridgeTransportVersion;
|
||||
@@ -1119,6 +1300,20 @@ void GatewayController::handleDaliRawFrame(const DaliRawFrame& frame) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (frame.data.size() == 3 &&
|
||||
(((frame.data[0] & 0x01) != 0) || frame.data[0] == 0xC1)) {
|
||||
handleApplicationControllerFrame(frame);
|
||||
const bool maintenance_activity = maintenance_activity_gateway_.load() == frame.gateway_id;
|
||||
if (setup_mode_ || dali_domain_.isAllocAddr(frame.gateway_id) || maintenance_activity ||
|
||||
runtime_.hasActiveQueryCommand(frame.gateway_id)) {
|
||||
return;
|
||||
}
|
||||
publishPayload(frame.gateway_id,
|
||||
{kDali103RawFrameOpcode, frame.gateway_id, frame.data[0], frame.data[1],
|
||||
frame.data[2]});
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t addr = 0;
|
||||
uint8_t data = 0;
|
||||
if (frame.data.size() == 2) {
|
||||
|
||||
@@ -324,7 +324,7 @@ GatewayRuntime::CommandPriority GatewayRuntime::classifyCommandPriority(
|
||||
if (opcode == 0x00 || opcode == 0x01 || opcode == 0x03 || opcode == 0x04 || opcode == 0x07 ||
|
||||
opcode == 0x08 || opcode == 0x10 || opcode == 0x11 || opcode == 0x12 || opcode == 0x13 ||
|
||||
opcode == 0x17 || opcode == 0x18 || opcode == 0x37 || opcode == 0x38 ||
|
||||
(opcode == 0x30 && addr == 0)) {
|
||||
opcode == 0x60 || opcode == 0x61 || opcode == 0x62 || (opcode == 0x30 && addr == 0)) {
|
||||
return CommandPriority::kControl;
|
||||
}
|
||||
return CommandPriority::kNormal;
|
||||
@@ -597,8 +597,8 @@ std::string GatewayRuntime::defaultBleGatewayName() const {
|
||||
}
|
||||
|
||||
bool GatewayRuntime::isQueryCommand(const std::vector<uint8_t>& command) const {
|
||||
return command.size() >= 6 && isGatewayCommandFrame(command) && command[3] >= 0x14 &&
|
||||
command[3] <= 0x16;
|
||||
return command.size() >= 6 && isGatewayCommandFrame(command) &&
|
||||
((command[3] >= 0x14 && command[3] <= 0x16) || command[3] == 0x62);
|
||||
}
|
||||
|
||||
size_t GatewayRuntime::pendingCommandCountLocked() const {
|
||||
@@ -639,6 +639,15 @@ std::optional<std::string> GatewayRuntime::queryCommandKey(
|
||||
|
||||
const auto gw = command[2];
|
||||
const auto cmd = command[3];
|
||||
if (cmd == 0x62) {
|
||||
if (command.size() < 8) {
|
||||
return std::nullopt;
|
||||
}
|
||||
char key[40] = {0};
|
||||
std::snprintf(key, sizeof(key), "%u:%u:%u:%u:%u", gw, cmd, command[4], command[5],
|
||||
command[6]);
|
||||
return std::string(key);
|
||||
}
|
||||
if (cmd == 0x16) {
|
||||
char key[16] = {0};
|
||||
std::snprintf(key, sizeof(key), "%u:%u", gw, cmd);
|
||||
|
||||
Reference in New Issue
Block a user