15
15
* limitations under the License.
16
16
*/
17
17
18
- use core:: convert:: TryInto ;
18
+ use core:: { cell :: RefCell , convert:: TryInto } ;
19
19
20
20
use super :: objects:: * ;
21
- use crate :: { attribute_enum, error:: Error , utils:: rand:: Rand } ;
21
+ use crate :: {
22
+ attribute_enum,
23
+ error:: { Error , ErrorCode } ,
24
+ utils:: rand:: Rand ,
25
+ } ;
26
+ use heapless:: String ;
22
27
use strum:: FromRepr ;
23
28
24
29
pub const ID : u32 = 0x0028 ;
@@ -27,8 +32,11 @@ pub const ID: u32 = 0x0028;
27
32
#[ repr( u16 ) ]
28
33
pub enum Attributes {
29
34
DMRevision ( AttrType < u8 > ) = 0 ,
35
+ VendorName ( AttrUtfType ) = 1 ,
30
36
VendorId ( AttrType < u16 > ) = 2 ,
37
+ ProductName ( AttrUtfType ) = 3 ,
31
38
ProductId ( AttrType < u16 > ) = 4 ,
39
+ NodeLabel ( AttrUtfType ) = 5 ,
32
40
HwVer ( AttrType < u16 > ) = 7 ,
33
41
SwVer ( AttrType < u32 > ) = 9 ,
34
42
SwVerString ( AttrUtfType ) = 0xa ,
@@ -39,8 +47,11 @@ attribute_enum!(Attributes);
39
47
40
48
pub enum AttributesDiscriminants {
41
49
DMRevision = 0 ,
50
+ VendorName = 1 ,
42
51
VendorId = 2 ,
52
+ ProductName = 3 ,
43
53
ProductId = 4 ,
54
+ NodeLabel = 5 ,
44
55
HwVer = 7 ,
45
56
SwVer = 9 ,
46
57
SwVerString = 0xa ,
@@ -57,6 +68,8 @@ pub struct BasicInfoConfig<'a> {
57
68
pub serial_no : & ' a str ,
58
69
/// Device name; up to 32 characters
59
70
pub device_name : & ' a str ,
71
+ pub vendor_name : & ' a str ,
72
+ pub product_name : & ' a str ,
60
73
}
61
74
62
75
pub const CLUSTER : Cluster < ' static > = Cluster {
@@ -70,16 +83,31 @@ pub const CLUSTER: Cluster<'static> = Cluster {
70
83
Access :: RV ,
71
84
Quality :: FIXED ,
72
85
) ,
86
+ Attribute :: new (
87
+ AttributesDiscriminants :: VendorName as u16 ,
88
+ Access :: RV ,
89
+ Quality :: FIXED ,
90
+ ) ,
73
91
Attribute :: new (
74
92
AttributesDiscriminants :: VendorId as u16 ,
75
93
Access :: RV ,
76
94
Quality :: FIXED ,
77
95
) ,
96
+ Attribute :: new (
97
+ AttributesDiscriminants :: ProductName as u16 ,
98
+ Access :: RV ,
99
+ Quality :: FIXED ,
100
+ ) ,
78
101
Attribute :: new (
79
102
AttributesDiscriminants :: ProductId as u16 ,
80
103
Access :: RV ,
81
104
Quality :: FIXED ,
82
105
) ,
106
+ Attribute :: new (
107
+ AttributesDiscriminants :: NodeLabel as u16 ,
108
+ Access :: RWVM ,
109
+ Quality :: N ,
110
+ ) ,
83
111
Attribute :: new (
84
112
AttributesDiscriminants :: HwVer as u16 ,
85
113
Access :: RV ,
@@ -107,13 +135,16 @@ pub const CLUSTER: Cluster<'static> = Cluster {
107
135
pub struct BasicInfoCluster < ' a > {
108
136
data_ver : Dataver ,
109
137
cfg : & ' a BasicInfoConfig < ' a > ,
138
+ node_label : RefCell < String < 32 > > , // Max node-label as per the spec
110
139
}
111
140
112
141
impl < ' a > BasicInfoCluster < ' a > {
113
142
pub fn new ( cfg : & ' a BasicInfoConfig < ' a > , rand : Rand ) -> Self {
143
+ let node_label = RefCell :: new ( String :: from ( "" ) ) ;
114
144
Self {
115
145
data_ver : Dataver :: new ( rand) ,
116
146
cfg,
147
+ node_label,
117
148
}
118
149
}
119
150
@@ -124,8 +155,13 @@ impl<'a> BasicInfoCluster<'a> {
124
155
} else {
125
156
match attr. attr_id . try_into ( ) ? {
126
157
Attributes :: DMRevision ( codec) => codec. encode ( writer, 1 ) ,
158
+ Attributes :: VendorName ( codec) => codec. encode ( writer, self . cfg . vendor_name ) ,
127
159
Attributes :: VendorId ( codec) => codec. encode ( writer, self . cfg . vid ) ,
160
+ Attributes :: ProductName ( codec) => codec. encode ( writer, self . cfg . product_name ) ,
128
161
Attributes :: ProductId ( codec) => codec. encode ( writer, self . cfg . pid ) ,
162
+ Attributes :: NodeLabel ( codec) => {
163
+ codec. encode ( writer, self . node_label . borrow ( ) . as_str ( ) )
164
+ }
129
165
Attributes :: HwVer ( codec) => codec. encode ( writer, self . cfg . hw_ver ) ,
130
166
Attributes :: SwVer ( codec) => codec. encode ( writer, self . cfg . sw_ver ) ,
131
167
Attributes :: SwVerString ( codec) => codec. encode ( writer, self . cfg . sw_ver_str ) ,
@@ -136,12 +172,35 @@ impl<'a> BasicInfoCluster<'a> {
136
172
Ok ( ( ) )
137
173
}
138
174
}
175
+
176
+ pub fn write ( & self , attr : & AttrDetails , data : AttrData ) -> Result < ( ) , Error > {
177
+ let data = data. with_dataver ( self . data_ver . get ( ) ) ?;
178
+
179
+ match attr. attr_id . try_into ( ) ? {
180
+ Attributes :: NodeLabel ( codec) => {
181
+ * self . node_label . borrow_mut ( ) = String :: from (
182
+ codec
183
+ . decode ( data)
184
+ . map_err ( |_| Error :: new ( ErrorCode :: InvalidAction ) ) ?,
185
+ ) ;
186
+ }
187
+ _ => return Err ( Error :: new ( ErrorCode :: InvalidAction ) ) ,
188
+ }
189
+
190
+ self . data_ver . changed ( ) ;
191
+
192
+ Ok ( ( ) )
193
+ }
139
194
}
140
195
141
196
impl < ' a > Handler for BasicInfoCluster < ' a > {
142
197
fn read ( & self , attr : & AttrDetails , encoder : AttrDataEncoder ) -> Result < ( ) , Error > {
143
198
BasicInfoCluster :: read ( self , attr, encoder)
144
199
}
200
+
201
+ fn write ( & self , attr : & AttrDetails , data : AttrData ) -> Result < ( ) , Error > {
202
+ BasicInfoCluster :: write ( self , attr, data)
203
+ }
145
204
}
146
205
147
206
impl < ' a > NonBlockingHandler for BasicInfoCluster < ' a > { }
0 commit comments