Matter support for large atribute responses (#19252)

Support for responses (arrays) that do not fit in a single UDP packer
Do not remove children fabrics
This commit is contained in:
s-hadinger 2023-08-03 18:28:25 +02:00 committed by GitHub
parent 39643611d4
commit b6129f2ab7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 2760 additions and 2561 deletions

View File

@ -29,6 +29,7 @@ All notable changes to this project will be documented in this file.
- Zero cross dimmer minimum interrupt time (#19211)
- Fade would fail when the difference between start and target would be too small (#19248)
- Inverted shutter (#19243)
- Matter support for large atribute responses
### Removed

View File

@ -176,18 +176,24 @@ class Matter_Device
#####################################################################
# Remove a fabric and clean all corresponding values and mDNS entries
def remove_fabric(fabric_parent)
var sub_fabrics = self.sessions.find_children_fabrics(fabric_parent.get_fabric_index())
if sub_fabrics == nil return end
for fabric_index : sub_fabrics
var fabric = self.sessions.find_fabric_by_index(fabric_index)
def remove_fabric(fabric)
if fabric != nil
tasmota.log("MTR: removing fabric " + fabric.get_fabric_id().copy().reverse().tohex(), 2)
self.message_handler.im.subs_shop.remove_by_fabric(fabric)
self.mdns_remove_op_discovery(fabric)
self.sessions.remove_fabric(fabric)
end
end
# var sub_fabrics = self.sessions.find_children_fabrics(fabric_parent.get_fabric_index())
# if sub_fabrics == nil return end
# for fabric_index : sub_fabrics
# var fabric = self.sessions.find_fabric_by_index(fabric_index)
# if fabric != nil
# tasmota.log("MTR: removing fabric " + fabric.get_fabric_id().copy().reverse().tohex(), 2)
# self.message_handler.im.subs_shop.remove_by_fabric(fabric)
# self.mdns_remove_op_discovery(fabric)
# self.sessions.remove_fabric(fabric)
# end
# end
self.sessions.save_fabrics()
end

View File

@ -225,7 +225,7 @@ class Matter_IM
# Inner code shared between read_attributes and subscribe_request
#
# query: `ReadRequestMessage` or `SubscribeRequestMessage`
def _inner_process_read_request(session, query, no_log)
def _inner_process_read_request(session, query, msg, no_log)
### Inner function to be iterated upon
# ret is the ReportDataMessage list to send back
@ -243,22 +243,47 @@ class Matter_IM
# Special case to report unsupported item, if pi==nil
var res = (pi != nil) ? pi.read_attribute(session, ctx, self.tlv_solo) : nil
var found = true # stop expansion since we have a value
var a1_raw # this is the bytes() block we need to add to response (or nil)
var a1_raw_or_list # contains either a bytes() buffer to append, or a list of bytes(), or nil
if res != nil
var res_str = res.to_str_val() # get the value with anonymous tag before it is tagged, for logging
var res_str = ""
if !no_log
res_str = res.to_str_val() # get the value with anonymous tag before it is tagged, for logging
end
# check if too big to encode as a single packet
if (res.is_list || res.is_array) && res.encode_len() > matter.IM_ReportData.MAX_MESSAGE
# tasmota.log(f"MTR: >>>>>> long response", 3)
a1_raw_or_list = [] # we return a list of block
var a1_raw = bytes(48)
var empty_list = TLV.Matter_TLV_array()
self.attributedata2raw(a1_raw, ctx, empty_list, false)
a1_raw_or_list.push(a1_raw)
# tasmota.log(f"MTR: >>>>>> long response global DELETE {a1_raw.tohex()}", 3)
for elt:res.val
a1_raw = bytes(48)
# var list_item = TLV.Matter_TLV_array()
# list_item.val.push(elt)
self.attributedata2raw(a1_raw, ctx, elt, true #- add ListIndex:null -#)
# tasmota.log(f"MTR: >>>>>> long response global ADD {a1_raw.tohex()}", 3)
a1_raw_or_list.push(a1_raw)
end
# tasmota.log(f"MTR: >>>>>> long response global {a1_raw_or_list}", 3)
else
# normal encoding
# encode directly raw bytes()
a1_raw = bytes(48) # pre-reserve 48 bytes
self.attributedata2raw(a1_raw, ctx, res)
a1_raw_or_list = bytes(48) # pre-reserve 48 bytes
self.attributedata2raw(a1_raw_or_list, ctx, res)
end
if !no_log
tasmota.log(format("MTR: >Read_Attr (%6i) %s%s - %s", session.local_session_id, str(ctx), attr_name, res_str), 3)
tasmota.log(f"MTR: >Read_Attr ({session.local_session_id:6i}) {ctx}{attr_name} - {res_str}", 3)
end
elif ctx.status != nil
if direct # we report an error only if a concrete direct read, not with wildcards
# encode directly raw bytes()
a1_raw = bytes(48) # pre-reserve 48 bytes
self.attributestatus2raw(a1_raw, ctx, ctx.status)
a1_raw_or_list = bytes(48) # pre-reserve 48 bytes
self.attributestatus2raw(a1_raw_or_list, ctx, ctx.status)
if tasmota.loglevel(3)
tasmota.log(format("MTR: >Read_Attr (%6i) %s%s - STATUS: 0x%02X %s", session.local_session_id, str(ctx), attr_name, ctx.status, ctx.status == matter.UNSUPPORTED_ATTRIBUTE ? "UNSUPPORTED_ATTRIBUTE" : ""), 3)
@ -270,27 +295,55 @@ class Matter_IM
found = false
end
# check if we still have enough room in last block
if a1_raw # do we have bytes to add, and it's not zero size
# a1_raw_or_list if either nil, bytes(), of list(bytes())
var idx = isinstance(a1_raw_or_list, list) ? 0 : nil # index in list, or nil if non-list
while a1_raw_or_list != nil
var elt = (idx == nil) ? a1_raw_or_list : a1_raw_or_list[idx] # dereference
if size(ret.attribute_reports) == 0
ret.attribute_reports.push(a1_raw) # push raw binary instead of a TLV
ret.attribute_reports.push(elt) # push raw binary instead of a TLV
else # already blocks present, see if we can add to the latest, or need to create a new block
var last_block = ret.attribute_reports[-1]
if size(last_block) + size(a1_raw) <= matter.IM_ReportData.MAX_MESSAGE
if size(last_block) + size(elt) <= matter.IM_ReportData.MAX_MESSAGE
# add to last block
last_block .. a1_raw
last_block .. elt
else
ret.attribute_reports.push(a1_raw) # push raw binary instead of a TLV
ret.attribute_reports.push(elt) # push raw binary instead of a TLV
end
end
if idx == nil
a1_raw_or_list = nil # stop loop
else
idx += 1
if idx >= size(a1_raw_or_list)
a1_raw_or_list = nil # stop loop
end
end
end
# check if we still have enough room in last block
# if a1_raw_or_list # do we have bytes to add, and it's not zero size
# if size(ret.attribute_reports) == 0
# ret.attribute_reports.push(a1_raw_or_list) # push raw binary instead of a TLV
# else # already blocks present, see if we can add to the latest, or need to create a new block
# var last_block = ret.attribute_reports[-1]
# if size(last_block) + size(a1_raw_or_list) <= matter.IM_ReportData.MAX_MESSAGE
# # add to last block
# last_block .. a1_raw_or_list
# else
# ret.attribute_reports.push(a1_raw_or_list) # push raw binary instead of a TLV
# end
# end
# end
return found # return true if we had a match
end
var endpoints = self.device.get_active_endpoints()
# structure is `ReadRequestMessage` 10.6.2 p.558
var ctx = matter.Path()
ctx.msg = msg
# prepare the response
var ret = matter.ReportDataMessage()
@ -347,8 +400,10 @@ class Matter_IM
# 2402 01 2 = 1U (U1)
# 2403 39 3 = 0x39U (U1)
# 2404 11 4 = 0x11U (U1)
# [OPTIONAL ListIndex]
# 3405 5 = NULL
# 18
def path2raw(raw, ctx, sub_tag)
def path2raw(raw, ctx, sub_tag, list_index_null)
# open struct
raw.add(0x37, 1) # add 37
raw.add(sub_tag, 1) # add sub_tag
@ -382,6 +437,11 @@ class Matter_IM
raw.add(0x2604, -2) # add 2604
raw.add(ctx.attribute, 4)
end
# do we add ListIndex: null
if list_index_null
raw.add(0x3405, -2) # add 3405
end
# close
raw.add(0x18, 1) # add 18
end
@ -418,15 +478,18 @@ class Matter_IM
# 2402 01 2 = 1U (U1)
# 2403 39 3 = 0x39U (U1)
# 2404 11 4 = 0x11U (U1)
# [OPTIONAL ListIndex]
# 3405 5 = NULL
#
# 18
# 2902 2 = True
# 18
# 18
def attributedata2raw(raw, ctx, val)
def attributedata2raw(raw, ctx, val, list_index_null)
raw.add(0x15350124, -4) # add 15350124
raw.add(0x0001, -2) # add 0001
self.path2raw(raw, ctx, 0x01)
self.path2raw(raw, ctx, 0x01, list_index_null)
# add value with tag 2
val.tag_sub = 2
@ -615,7 +678,7 @@ class Matter_IM
var query = matter.ReadRequestMessage().from_TLV(val)
# matter.profiler.log(str(query))
if query.attributes_requests != nil
var ret = self._inner_process_read_request(msg.session, query)
var ret = self._inner_process_read_request(msg.session, query, msg)
self.send_report_data(msg, ret)
end
@ -629,15 +692,10 @@ class Matter_IM
# returns `true` if processed, `false` if silently ignored,
# or raises an exception
def process_read_request_solo(msg, ctx)
# matter.profiler.log("read_request_solo start")
# matter.profiler.log(str(val))
# var query = matter.ReadRequestMessage().from_TLV(val)
# matter.profiler.log("read_request_start-TLV")
# prepare fallback error
ctx.status = matter.INVALID_ACTION
ctx.msg = msg
# TODO
# find pi for this endpoint/cluster/attribute
var pi = self.device.process_attribute_read_solo(ctx)
var res = nil
@ -653,6 +711,15 @@ class Matter_IM
if res != nil
# check if the payload is a complex structure and too long to fit in a single response packet
if (res.is_list || res.is_array) && res.encode_len() > matter.IM_ReportData.MAX_MESSAGE
# revert to standard
# the attribute will be read again, but it's hard to avoid it
res = nil # indicated to GC that we don't need it again
tasmota.log(f"MTR: Response to big, revert to non-solo", 3)
var val = matter.TLV.parse(msg.raw, msg.app_payload_idx)
return self.process_read_request(msg, val)
end
# encode directly raw bytes()
raw = bytes(48) # pre-reserve 48 bytes
@ -665,8 +732,6 @@ class Matter_IM
raw.add(0x1824FF01, -4) # add 1824FF01
raw.add(0x18, 1) # add 18
# matter.profiler.log("read_request_solo raw done")
elif ctx.status != nil
# encode directly raw bytes()
@ -686,31 +751,14 @@ class Matter_IM
return false
end
# matter.profiler.log("read_request_solo res ready")
# tasmota.log(f"MTR: process_read_request_solo {raw=}")
# send packet
# self.send_report_data_solo(msg, ret)
# var report_solo = matter.IM_ReportData_solo(msg, ret)
var resp = msg.build_response(0x05 #-Report Data-#, true)
# super(self).reset(msg, 0x05 #-Report Data-#, true)
# matter.profiler.log("read_request_solo report_solo")
# send_im()
# report_solo.send_im(self.device.message_handler)
var responder = self.device.message_handler
# matter.profiler.log("read_request_solo send_im-1")
# if tasmota.loglevel(3) # TODO remove before flight
# tasmota.log(f">>>: data_raw={raw.tohex()}", 3)
# end
# matter.profiler.log("read_request_solo send_im-2")
var msg_raw = msg.raw
msg_raw.clear()
resp.encode_frame(raw, msg_raw) # payload in cleartext
# matter.profiler.log("read_request_solo send_im-3")
resp.encrypt()
# matter.profiler.log("read_request_solo send_im-encrypted")
if tasmota.loglevel(4)
tasmota.log(format("MTR: <snd (%6i) id=%i exch=%i rack=%s", resp.session.local_session_id, resp.message_counter, resp.exchange_id, resp.ack_message_counter), 4)
end
@ -779,7 +827,7 @@ class Matter_IM
tasmota.log(f"MTR: >Subscribe (%6i) event_requests_size={size(query.event_requests)}", 3)
end
var ret = self._inner_process_read_request(msg.session, query, true #-no_log-#)
var ret = self._inner_process_read_request(msg.session, query, msg, true #-no_log-#)
# ret is of type `Matter_ReportDataMessage`
ret.subscription_id = sub.subscription_id # enrich with subscription id TODO
self.send_subscribe_response(msg, ret, sub)
@ -853,11 +901,7 @@ class Matter_IM
end
end
# tasmota.log("MTR: invoke_responses="+str(ret.invoke_responses), 4)
if size(ret.invoke_responses) > 0
# tasmota.log("MTR: InvokeResponse=" + str(ret), 4)
# tasmota.log("MTR: InvokeResponseTLV=" + str(ret.to_TLV()), 3)
self.send_invoke_response(msg, ret)
else
return false # we don't send anything, hence the responder sends a simple packet ack
@ -1009,6 +1053,7 @@ class Matter_IM
# structure is `ReadRequestMessage` 10.6.2 p.558
# tasmota.log("MTR: IM:write_request processing start", 4)
var ctx = matter.Path()
ctx.msg = msg
if query.write_requests != nil
# prepare the response
@ -1112,7 +1157,7 @@ class Matter_IM
tasmota.log(format("MTR: <Sub_Data (%6i) sub=%i", session.local_session_id, sub.subscription_id), 3)
sub.is_keep_alive = false # sending an actual data update
var ret = self._inner_process_read_request(session, fake_read)
var ret = self._inner_process_read_request(session, fake_read, nil #-no msg-#)
ret.suppress_response = false
ret.subscription_id = sub.subscription_id

View File

@ -64,9 +64,13 @@ class Matter_Plugin
end
# proxy for the same method in IM
def send_ack_now(msg)
def ack_request(ctx)
var msg = ctx.msg
if msg != nil
self.device.message_handler.im.send_ack_now(msg)
end
ctx.msg = nil
end
#############################################################
# parse_configuration

View File

@ -151,7 +151,7 @@ class Matter_Plugin_Root : Matter_Plugin
# ====================================================================================================
elif cluster == 0x003E # ========== Node Operational Credentials Cluster 11.17 p.704 ==========
self.send_ack_now(ctx.msg) # long operation, send Ack first
self.ack_request(ctx) # long operation, send Ack first
if attribute == 0x0000 # ---------- NOCs / list[NOCStruct] ----------
var nocl = TLV.Matter_TLV_array() # NOCs, p.711
@ -217,7 +217,7 @@ class Matter_Plugin_Root : Matter_Plugin
# ====================================================================================================
elif cluster == 0x0028 # ========== Basic Information Cluster cluster 11.1 p.565 ==========
self.send_ack_now(ctx.msg) # long operation, send Ack first
self.ack_request(ctx) # long operation, send Ack first
if attribute == 0x0000 # ---------- DataModelRevision / CommissioningWindowStatus ----------
return tlv_solo.set(TLV.U2, 1)
@ -374,7 +374,7 @@ class Matter_Plugin_Root : Matter_Plugin
return srcr
elif command == 0x0004 # ---------- CommissioningComplete p.636 ----------
self.send_ack_now(ctx.msg) # long operation, send Ack first
self.ack_request(ctx) # long operation, send Ack first
# no data
if session._fabric
session._breadcrumb = 0 # clear breadcrumb
@ -442,7 +442,7 @@ class Matter_Plugin_Root : Matter_Plugin
return ar
elif command == 0x0004 # ---------- CSRRequest ----------
self.send_ack_now(ctx.msg) # long operation, send Ack first
self.ack_request(ctx) # long operation, send Ack first
var CSRNonce = val.findsubval(0) # octstr 32
if size(CSRNonce) != 32 return nil end # check size on nonce
var IsForUpdateNOC = val.findsubval(1, false) # bool

View File

@ -94,6 +94,9 @@ class Matter_TLV
static class Matter_TLV_item
# we keep a shortcut reference to the Matter_TLV class
static var TLV = Matter_TLV
static var is_list = false
static var is_array = false
static var is_struct = false
# parent tag to inherit vendor/profile/tag
var parent
var next_idx # next idx in buffer (when parsing)
@ -607,7 +610,10 @@ class Matter_TLV
# class Matter_TLV_struct var _ end
static class Matter_TLV_list : Matter_TLV_item
static var is_struct = false
# inherited
static var is_list = true
# static var is_array = false
# static var is_struct = false
#################################################################################
def init(parent)
@ -825,6 +831,8 @@ class Matter_TLV
# Matter_TLV_struct class
#################################################################################
static class Matter_TLV_struct : Matter_TLV_list
static var is_list = false
# static var is_array = false
static var is_struct = true
def init(parent)
@ -843,6 +851,10 @@ class Matter_TLV
# Matter_TLV_array class
#################################################################################
static class Matter_TLV_array : Matter_TLV_list
static var is_list = false
static var is_array = true
# static var is_struct = false
def init(parent)
super(self).init(parent)
self.typ = self.TLV.ARRAY

View File

@ -5507,7 +5507,7 @@ be_local_closure(Matter_Device_autoconf_device, /* name */
********************************************************************/
be_local_closure(Matter_Device_remove_fabric, /* name */
be_nested_proto(
10, /* nstack */
6, /* nstack */
2, /* argc */
2, /* varg */
0, /* has upvals */
@ -5515,87 +5515,60 @@ be_local_closure(Matter_Device_remove_fabric, /* name */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[20]) { /* constants */
/* K0 */ be_nested_str_weak(sessions),
/* K1 */ be_nested_str_weak(find_children_fabrics),
/* K2 */ be_nested_str_weak(get_fabric_index),
/* K3 */ be_nested_str_weak(find_fabric_by_index),
/* K4 */ be_nested_str_weak(tasmota),
/* K5 */ be_nested_str_weak(log),
/* K6 */ be_nested_str_weak(MTR_X3A_X20removing_X20fabric_X20),
/* K7 */ be_nested_str_weak(get_fabric_id),
/* K8 */ be_nested_str_weak(copy),
/* K9 */ be_nested_str_weak(reverse),
/* K10 */ be_nested_str_weak(tohex),
/* K11 */ be_const_int(2),
/* K12 */ be_nested_str_weak(message_handler),
/* K13 */ be_nested_str_weak(im),
/* K14 */ be_nested_str_weak(subs_shop),
/* K15 */ be_nested_str_weak(remove_by_fabric),
/* K16 */ be_nested_str_weak(mdns_remove_op_discovery),
/* K17 */ be_nested_str_weak(remove_fabric),
/* K18 */ be_nested_str_weak(stop_iteration),
/* K19 */ be_nested_str_weak(save_fabrics),
( &(const bvalue[16]) { /* constants */
/* K0 */ be_nested_str_weak(tasmota),
/* K1 */ be_nested_str_weak(log),
/* K2 */ be_nested_str_weak(MTR_X3A_X20removing_X20fabric_X20),
/* K3 */ be_nested_str_weak(get_fabric_id),
/* K4 */ be_nested_str_weak(copy),
/* K5 */ be_nested_str_weak(reverse),
/* K6 */ be_nested_str_weak(tohex),
/* K7 */ be_const_int(2),
/* K8 */ be_nested_str_weak(message_handler),
/* K9 */ be_nested_str_weak(im),
/* K10 */ be_nested_str_weak(subs_shop),
/* K11 */ be_nested_str_weak(remove_by_fabric),
/* K12 */ be_nested_str_weak(mdns_remove_op_discovery),
/* K13 */ be_nested_str_weak(sessions),
/* K14 */ be_nested_str_weak(remove_fabric),
/* K15 */ be_nested_str_weak(save_fabrics),
}),
be_str_weak(remove_fabric),
&be_const_str_solidified,
( &(const binstruction[56]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0
0x8C080501, // 0001 GETMET R2 R2 K1
0x8C100302, // 0002 GETMET R4 R1 K2
0x7C100200, // 0003 CALL R4 1
0x7C080400, // 0004 CALL R2 2
0x4C0C0000, // 0005 LDNIL R3
0x1C0C0403, // 0006 EQ R3 R2 R3
0x780E0000, // 0007 JMPF R3 #0009
0x80000600, // 0008 RET 0
0x600C0010, // 0009 GETGBL R3 G16
0x5C100400, // 000A MOVE R4 R2
0x7C0C0200, // 000B CALL R3 1
0xA8020023, // 000C EXBLK 0 #0031
0x5C100600, // 000D MOVE R4 R3
0x7C100000, // 000E CALL R4 0
0x88140100, // 000F GETMBR R5 R0 K0
0x8C140B03, // 0010 GETMET R5 R5 K3
0x5C1C0800, // 0011 MOVE R7 R4
0x7C140400, // 0012 CALL R5 2
0x4C180000, // 0013 LDNIL R6
0x20180A06, // 0014 NE R6 R5 R6
0x781A0019, // 0015 JMPF R6 #0030
0xB81A0800, // 0016 GETNGBL R6 K4
0x8C180D05, // 0017 GETMET R6 R6 K5
0x8C200B07, // 0018 GETMET R8 R5 K7
0x7C200200, // 0019 CALL R8 1
0x8C201108, // 001A GETMET R8 R8 K8
0x7C200200, // 001B CALL R8 1
0x8C201109, // 001C GETMET R8 R8 K9
0x7C200200, // 001D CALL R8 1
0x8C20110A, // 001E GETMET R8 R8 K10
0x7C200200, // 001F CALL R8 1
0x00220C08, // 0020 ADD R8 K6 R8
0x5824000B, // 0021 LDCONST R9 K11
0x7C180600, // 0022 CALL R6 3
0x8818010C, // 0023 GETMBR R6 R0 K12
0x88180D0D, // 0024 GETMBR R6 R6 K13
0x88180D0E, // 0025 GETMBR R6 R6 K14
0x8C180D0F, // 0026 GETMET R6 R6 K15
0x5C200A00, // 0027 MOVE R8 R5
0x7C180400, // 0028 CALL R6 2
0x8C180110, // 0029 GETMET R6 R0 K16
0x5C200A00, // 002A MOVE R8 R5
0x7C180400, // 002B CALL R6 2
0x88180100, // 002C GETMBR R6 R0 K0
0x8C180D11, // 002D GETMET R6 R6 K17
0x5C200A00, // 002E MOVE R8 R5
0x7C180400, // 002F CALL R6 2
0x7001FFDB, // 0030 JMP #000D
0x580C0012, // 0031 LDCONST R3 K18
0xAC0C0200, // 0032 CATCH R3 1 0
0xB0080000, // 0033 RAISE 2 R0 R0
0x880C0100, // 0034 GETMBR R3 R0 K0
0x8C0C0713, // 0035 GETMET R3 R3 K19
0x7C0C0200, // 0036 CALL R3 1
0x80000000, // 0037 RET 0
( &(const binstruction[33]) { /* code */
0x4C080000, // 0000 LDNIL R2
0x20080202, // 0001 NE R2 R1 R2
0x780A0019, // 0002 JMPF R2 #001D
0xB80A0000, // 0003 GETNGBL R2 K0
0x8C080501, // 0004 GETMET R2 R2 K1
0x8C100303, // 0005 GETMET R4 R1 K3
0x7C100200, // 0006 CALL R4 1
0x8C100904, // 0007 GETMET R4 R4 K4
0x7C100200, // 0008 CALL R4 1
0x8C100905, // 0009 GETMET R4 R4 K5
0x7C100200, // 000A CALL R4 1
0x8C100906, // 000B GETMET R4 R4 K6
0x7C100200, // 000C CALL R4 1
0x00120404, // 000D ADD R4 K2 R4
0x58140007, // 000E LDCONST R5 K7
0x7C080600, // 000F CALL R2 3
0x88080108, // 0010 GETMBR R2 R0 K8
0x88080509, // 0011 GETMBR R2 R2 K9
0x8808050A, // 0012 GETMBR R2 R2 K10
0x8C08050B, // 0013 GETMET R2 R2 K11
0x5C100200, // 0014 MOVE R4 R1
0x7C080400, // 0015 CALL R2 2
0x8C08010C, // 0016 GETMET R2 R0 K12
0x5C100200, // 0017 MOVE R4 R1
0x7C080400, // 0018 CALL R2 2
0x8808010D, // 0019 GETMBR R2 R0 K13
0x8C08050E, // 001A GETMET R2 R2 K14
0x5C100200, // 001B MOVE R4 R1
0x7C080400, // 001C CALL R2 2
0x8808010D, // 001D GETMBR R2 R0 K13
0x8C08050F, // 001E GETMET R2 R2 K15
0x7C080200, // 001F CALL R2 1
0x80000000, // 0020 RET 0
})
)
);

File diff suppressed because it is too large Load Diff

View File

@ -295,6 +295,49 @@ be_local_closure(Matter_Plugin_parse_sensors, /* name */
/*******************************************************************/
/********************************************************************
** Solidified function: has
********************************************************************/
be_local_closure(Matter_Plugin_has, /* name */
be_nested_proto(
6, /* nstack */
3, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 4]) { /* constants */
/* K0 */ be_nested_str_weak(clusters),
/* K1 */ be_nested_str_weak(contains),
/* K2 */ be_nested_str_weak(endpoints),
/* K3 */ be_nested_str_weak(find),
}),
be_str_weak(has),
&be_const_str_solidified,
( &(const binstruction[15]) { /* code */
0x880C0100, // 0000 GETMBR R3 R0 K0
0x8C0C0701, // 0001 GETMET R3 R3 K1
0x5C140200, // 0002 MOVE R5 R1
0x7C0C0400, // 0003 CALL R3 2
0x780E0006, // 0004 JMPF R3 #000C
0x880C0102, // 0005 GETMBR R3 R0 K2
0x8C0C0703, // 0006 GETMET R3 R3 K3
0x5C140400, // 0007 MOVE R5 R2
0x7C0C0400, // 0008 CALL R3 2
0x4C100000, // 0009 LDNIL R4
0x200C0604, // 000A NE R3 R3 R4
0x740E0000, // 000B JMPT R3 #000D
0x500C0001, // 000C LDBOOL R3 0 1
0x500C0200, // 000D LDBOOL R3 1 0
0x80040600, // 000E RET 1 R3
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: parse_configuration
********************************************************************/
@ -382,69 +425,41 @@ be_local_closure(Matter_Plugin_subscribe_attribute, /* name */
/********************************************************************
** Solidified function: has
** Solidified function: ack_request
********************************************************************/
be_local_closure(Matter_Plugin_has, /* name */
be_local_closure(Matter_Plugin_ack_request, /* name */
be_nested_proto(
6, /* nstack */
3, /* argc */
2, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 4]) { /* constants */
/* K0 */ be_nested_str_weak(clusters),
/* K1 */ be_nested_str_weak(contains),
/* K2 */ be_nested_str_weak(endpoints),
/* K3 */ be_nested_str_weak(find),
( &(const bvalue[ 5]) { /* constants */
/* K0 */ be_nested_str_weak(msg),
/* K1 */ be_nested_str_weak(device),
/* K2 */ be_nested_str_weak(message_handler),
/* K3 */ be_nested_str_weak(im),
/* K4 */ be_nested_str_weak(send_ack_now),
}),
be_str_weak(has),
be_str_weak(ack_request),
&be_const_str_solidified,
( &(const binstruction[15]) { /* code */
0x880C0100, // 0000 GETMBR R3 R0 K0
0x8C0C0701, // 0001 GETMET R3 R3 K1
0x5C140200, // 0002 MOVE R5 R1
0x7C0C0400, // 0003 CALL R3 2
0x780E0006, // 0004 JMPF R3 #000C
0x880C0102, // 0005 GETMBR R3 R0 K2
0x8C0C0703, // 0006 GETMET R3 R3 K3
0x5C140400, // 0007 MOVE R5 R2
0x7C0C0400, // 0008 CALL R3 2
0x4C100000, // 0009 LDNIL R4
0x200C0604, // 000A NE R3 R3 R4
0x740E0000, // 000B JMPT R3 #000D
0x500C0001, // 000C LDBOOL R3 0 1
0x500C0200, // 000D LDBOOL R3 1 0
0x80040600, // 000E RET 1 R3
})
)
);
/*******************************************************************/
/********************************************************************
** Solidified function: get_endpoint
********************************************************************/
be_local_closure(Matter_Plugin_get_endpoint, /* name */
be_nested_proto(
2, /* nstack */
1, /* argc */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_nested_str_weak(endpoint),
}),
be_str_weak(get_endpoint),
&be_const_str_solidified,
( &(const binstruction[ 2]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
0x80040200, // 0001 RET 1 R1
( &(const binstruction[13]) { /* code */
0x88080300, // 0000 GETMBR R2 R1 K0
0x4C0C0000, // 0001 LDNIL R3
0x200C0403, // 0002 NE R3 R2 R3
0x780E0005, // 0003 JMPF R3 #000A
0x880C0101, // 0004 GETMBR R3 R0 K1
0x880C0702, // 0005 GETMBR R3 R3 K2
0x880C0703, // 0006 GETMBR R3 R3 K3
0x8C0C0704, // 0007 GETMET R3 R3 K4
0x5C140400, // 0008 MOVE R5 R2
0x7C0C0400, // 0009 CALL R3 2
0x4C0C0000, // 000A LDNIL R3
0x90060003, // 000B SETMBR R1 K0 R3
0x80000000, // 000C RET 0
})
)
);
@ -687,34 +702,26 @@ be_local_closure(Matter_Plugin_contains_cluster, /* name */
/********************************************************************
** Solidified function: send_ack_now
** Solidified function: <lambda>
********************************************************************/
be_local_closure(Matter_Plugin_send_ack_now, /* name */
be_local_closure(Matter_Plugin__X3Clambda_X3E, /* name */
be_nested_proto(
5, /* nstack */
2, /* argc */
2, /* varg */
3, /* nstack */
1, /* argc */
0, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
1, /* has constants */
( &(const bvalue[ 4]) { /* constants */
/* K0 */ be_nested_str_weak(device),
/* K1 */ be_nested_str_weak(message_handler),
/* K2 */ be_nested_str_weak(im),
/* K3 */ be_nested_str_weak(send_ack_now),
}),
be_str_weak(send_ack_now),
0, /* has constants */
NULL, /* no const */
be_str_weak(_X3Clambda_X3E),
&be_const_str_solidified,
( &(const binstruction[ 7]) { /* code */
0x88080100, // 0000 GETMBR R2 R0 K0
0x88080501, // 0001 GETMBR R2 R2 K1
0x88080502, // 0002 GETMBR R2 R2 K2
0x8C080503, // 0003 GETMET R2 R2 K3
0x5C100200, // 0004 MOVE R4 R1
0x7C080400, // 0005 CALL R2 2
0x80000000, // 0006 RET 0
( &(const binstruction[ 4]) { /* code */
0x60040008, // 0000 GETGBL R1 G8
0x5C080000, // 0001 MOVE R2 R0
0x7C040200, // 0002 CALL R1 1
0x80040200, // 0003 RET 1 R1
})
)
);
@ -820,26 +827,26 @@ be_local_closure(Matter_Plugin_update_shadow_lazy, /* name */
/********************************************************************
** Solidified function: <lambda>
** Solidified function: get_endpoint
********************************************************************/
be_local_closure(Matter_Plugin__X3Clambda_X3E, /* name */
be_local_closure(Matter_Plugin_get_endpoint, /* name */
be_nested_proto(
3, /* nstack */
2, /* nstack */
1, /* argc */
0, /* varg */
2, /* varg */
0, /* has upvals */
NULL, /* no upvals */
0, /* has sup protos */
NULL, /* no sub protos */
0, /* has constants */
NULL, /* no const */
be_str_weak(_X3Clambda_X3E),
1, /* has constants */
( &(const bvalue[ 1]) { /* constants */
/* K0 */ be_nested_str_weak(endpoint),
}),
be_str_weak(get_endpoint),
&be_const_str_solidified,
( &(const binstruction[ 4]) { /* code */
0x60040008, // 0000 GETGBL R1 G8
0x5C080000, // 0001 MOVE R2 R0
0x7C040200, // 0002 CALL R1 1
0x80040200, // 0003 RET 1 R1
( &(const binstruction[ 2]) { /* code */
0x88040100, // 0000 GETMBR R1 R0 K0
0x80040200, // 0001 RET 1 R1
})
)
);
@ -1071,13 +1078,16 @@ be_local_class(Matter_Plugin,
be_nested_map(37,
( (struct bmapnode*) &(const bmapnode[]) {
{ be_const_key_weak(init, -1), be_const_closure(Matter_Plugin_init_closure) },
{ be_const_key_weak(read_event, 8), be_const_closure(Matter_Plugin_read_event_closure) },
{ be_const_key_weak(read_event, 11), be_const_closure(Matter_Plugin_read_event_closure) },
{ be_const_key_weak(tick, -1), be_const_var(4) },
{ be_const_key_weak(is_local_device, 18), be_const_closure(Matter_Plugin_is_local_device_closure) },
{ be_const_key_weak(UPDATE_TIME, -1), be_const_int(5000) },
{ be_const_key_weak(get_attribute_list, -1), be_const_closure(Matter_Plugin_get_attribute_list_closure) },
{ be_const_key_weak(ui_conf_to_string, 28), be_const_static_closure(Matter_Plugin_ui_conf_to_string_closure) },
{ be_const_key_weak(ui_conf_to_string, 26), be_const_static_closure(Matter_Plugin_ui_conf_to_string_closure) },
{ be_const_key_weak(every_250ms, -1), be_const_closure(Matter_Plugin_every_250ms_closure) },
{ be_const_key_weak(ack_request, -1), be_const_closure(Matter_Plugin_ack_request_closure) },
{ be_const_key_weak(NAME, -1), be_nested_str_weak() },
{ be_const_key_weak(parse_sensors, -1), be_const_closure(Matter_Plugin_parse_sensors_closure) },
{ be_const_key_weak(CLUSTERS, 36), be_const_simple_instance(be_nested_simple_instance(&be_class_map, {
be_const_map( * be_nested_map(2,
( (struct bmapnode*) &(const bmapnode[]) {
@ -1097,28 +1107,25 @@ be_local_class(Matter_Plugin,
be_const_int(17),
})) ) } )) },
})) ) } )) },
{ be_const_key_weak(NAME, -1), be_nested_str_weak() },
{ be_const_key_weak(parse_sensors, -1), be_const_closure(Matter_Plugin_parse_sensors_closure) },
{ be_const_key_weak(get_endpoint, -1), be_const_closure(Matter_Plugin_get_endpoint_closure) },
{ be_const_key_weak(parse_configuration, -1), be_const_closure(Matter_Plugin_parse_configuration_closure) },
{ be_const_key_weak(ui_string_to_conf, -1), be_const_static_closure(Matter_Plugin_ui_string_to_conf_closure) },
{ be_const_key_weak(contains_cluster, -1), be_const_closure(Matter_Plugin_contains_cluster_closure) },
{ be_const_key_weak(attribute_updated, 11), be_const_closure(Matter_Plugin_attribute_updated_closure) },
{ be_const_key_weak(has, -1), be_const_closure(Matter_Plugin_has_closure) },
{ be_const_key_weak(ARG_TYPE, -1), be_const_static_closure(Matter_Plugin__X3Clambda_X3E_closure) },
{ be_const_key_weak(has, 8), be_const_closure(Matter_Plugin_has_closure) },
{ be_const_key_weak(device, 4), be_const_var(1) },
{ be_const_key_weak(timed_request, -1), be_const_closure(Matter_Plugin_timed_request_closure) },
{ be_const_key_weak(get_cluster_list, -1), be_const_closure(Matter_Plugin_get_cluster_list_closure) },
{ be_const_key_weak(read_attribute, -1), be_const_closure(Matter_Plugin_read_attribute_closure) },
{ be_const_key_weak(ARG, 14), be_nested_str_weak() },
{ be_const_key_weak(send_ack_now, -1), be_const_closure(Matter_Plugin_send_ack_now_closure) },
{ be_const_key_weak(subscribe_attribute, 26), be_const_closure(Matter_Plugin_subscribe_attribute_closure) },
{ be_const_key_weak(clusters, -1), be_const_var(3) },
{ be_const_key_weak(write_attribute, 24), be_const_closure(Matter_Plugin_write_attribute_closure) },
{ be_const_key_weak(ARG_TYPE, 15), be_const_static_closure(Matter_Plugin__X3Clambda_X3E_closure) },
{ be_const_key_weak(invoke_request, -1), be_const_closure(Matter_Plugin_invoke_request_closure) },
{ be_const_key_weak(subscribe_attribute, 24), be_const_closure(Matter_Plugin_subscribe_attribute_closure) },
{ be_const_key_weak(get_endpoint, 30), be_const_closure(Matter_Plugin_get_endpoint_closure) },
{ be_const_key_weak(write_attribute, 28), be_const_closure(Matter_Plugin_write_attribute_closure) },
{ be_const_key_weak(ARG_HINT, 22), be_nested_str_weak(_Not_X20used_) },
{ be_const_key_weak(update_shadow_lazy, -1), be_const_closure(Matter_Plugin_update_shadow_lazy_closure) },
{ be_const_key_weak(invoke_request, 30), be_const_closure(Matter_Plugin_invoke_request_closure) },
{ be_const_key_weak(clusters, -1), be_const_var(3) },
{ be_const_key_weak(endpoint, -1), be_const_var(2) },
{ be_const_key_weak(ARG_HINT, -1), be_nested_str_weak(_Not_X20used_) },
{ be_const_key_weak(attribute_updated, 15), be_const_closure(Matter_Plugin_attribute_updated_closure) },
{ be_const_key_weak(subscribe_event, -1), be_const_closure(Matter_Plugin_subscribe_event_closure) },
{ be_const_key_weak(update_shadow, -1), be_const_closure(Matter_Plugin_update_shadow_closure) },
{ be_const_key_weak(consolidate_clusters, -1), be_const_closure(Matter_Plugin_consolidate_clusters_closure) },

File diff suppressed because it is too large Load Diff