• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 use std::convert::{TryFrom, TryInto};
16 
17 use log::error;
18 
19 use crate::error::{Error, Result};
20 use crate::params::uci_packets::{
21     AndroidRadarConfigResponse, AppConfigTlv, CapTlv, CoreSetConfigResponse, DeviceConfigTlv,
22     GetDeviceInfoResponse, PowerStats, RadarConfigTlv, RawUciMessage, RfTestConfigResponse,
23     SessionHandle, SessionState, SessionUpdateControllerMulticastListRspV1Payload,
24     SessionUpdateControllerMulticastListRspV2Payload, SessionUpdateControllerMulticastResponse,
25     SessionUpdateDtTagRangingRoundsResponse, SetAppConfigResponse, StatusCode, UCIMajorVersion,
26     UciControlPacket,
27 };
28 use crate::uci::error::status_code_to_result;
29 
30 #[derive(Debug, Clone, PartialEq)]
31 pub(super) enum UciResponse {
32     SetLoggerMode,
33     SetNotification,
34     OpenHal,
35     CloseHal,
36     DeviceReset(Result<()>),
37     CoreGetDeviceInfo(Result<GetDeviceInfoResponse>),
38     CoreGetCapsInfo(Result<Vec<CapTlv>>),
39     CoreSetConfig(CoreSetConfigResponse),
40     CoreGetConfig(Result<Vec<DeviceConfigTlv>>),
41     CoreQueryTimeStamp(Result<u64>),
42     SessionInit(Result<Option<SessionHandle>>),
43     SessionDeinit(Result<()>),
44     SessionSetAppConfig(SetAppConfigResponse),
45     SessionGetAppConfig(Result<Vec<AppConfigTlv>>),
46     SessionGetCount(Result<u8>),
47     SessionGetState(Result<SessionState>),
48     SessionUpdateControllerMulticastList(Result<SessionUpdateControllerMulticastResponse>),
49     SessionUpdateDtTagRangingRounds(Result<SessionUpdateDtTagRangingRoundsResponse>),
50     SessionQueryMaxDataSize(Result<u16>),
51     SessionStart(Result<()>),
52     SessionStop(Result<()>),
53     SessionGetRangingCount(Result<usize>),
54     AndroidSetCountryCode(Result<()>),
55     AndroidGetPowerStats(Result<PowerStats>),
56     AndroidSetRadarConfig(AndroidRadarConfigResponse),
57     AndroidGetRadarConfig(Result<Vec<RadarConfigTlv>>),
58     RawUciCmd(Result<RawUciMessage>),
59     SendUciData(Result<()>),
60     SessionSetHybridControllerConfig(Result<()>),
61     SessionSetHybridControleeConfig(Result<()>),
62     SessionDataTransferPhaseConfig(Result<()>),
63     SessionSetRfTestConfig(RfTestConfigResponse),
64     RfTest(Result<()>),
65 }
66 
67 impl UciResponse {
need_retry(&self) -> bool68     pub fn need_retry(&self) -> bool {
69         match self {
70             Self::SetNotification | Self::OpenHal | Self::CloseHal | Self::SetLoggerMode => false,
71             Self::DeviceReset(result) => Self::matches_result_retry(result),
72             Self::CoreGetDeviceInfo(result) => Self::matches_result_retry(result),
73             Self::CoreGetCapsInfo(result) => Self::matches_result_retry(result),
74             Self::CoreGetConfig(result) => Self::matches_result_retry(result),
75             Self::CoreQueryTimeStamp(result) => Self::matches_result_retry(result),
76             Self::SessionInit(result) => Self::matches_result_retry(result),
77             Self::SessionDeinit(result) => Self::matches_result_retry(result),
78             Self::SessionGetAppConfig(result) => Self::matches_result_retry(result),
79             Self::SessionGetCount(result) => Self::matches_result_retry(result),
80             Self::SessionGetState(result) => Self::matches_result_retry(result),
81             Self::SessionUpdateControllerMulticastList(result) => {
82                 Self::matches_result_retry(result)
83             }
84             Self::SessionUpdateDtTagRangingRounds(result) => Self::matches_result_retry(result),
85             Self::SessionStart(result) => Self::matches_result_retry(result),
86             Self::SessionStop(result) => Self::matches_result_retry(result),
87             Self::SessionGetRangingCount(result) => Self::matches_result_retry(result),
88             Self::AndroidSetCountryCode(result) => Self::matches_result_retry(result),
89             Self::AndroidGetPowerStats(result) => Self::matches_result_retry(result),
90             Self::AndroidGetRadarConfig(result) => Self::matches_result_retry(result),
91             Self::AndroidSetRadarConfig(resp) => Self::matches_status_retry(&resp.status),
92             Self::RawUciCmd(result) => Self::matches_result_retry(result),
93             Self::SessionSetHybridControllerConfig(result) => Self::matches_result_retry(result),
94             Self::SessionSetHybridControleeConfig(result) => Self::matches_result_retry(result),
95             Self::SessionDataTransferPhaseConfig(result) => Self::matches_result_retry(result),
96             Self::CoreSetConfig(resp) => Self::matches_status_retry(&resp.status),
97             Self::SessionSetAppConfig(resp) => Self::matches_status_retry(&resp.status),
98 
99             Self::SessionQueryMaxDataSize(result) => Self::matches_result_retry(result),
100             Self::SessionSetRfTestConfig(resp) => Self::matches_status_retry(&resp.status),
101             Self::RfTest(result) => Self::matches_result_retry(result),
102             // TODO(b/273376343): Implement retry logic for Data packet send.
103             Self::SendUciData(_result) => false,
104         }
105     }
106 
matches_result_retry<T>(result: &Result<T>) -> bool107     fn matches_result_retry<T>(result: &Result<T>) -> bool {
108         matches!(result, Err(Error::CommandRetry))
109     }
matches_status_retry(status: &StatusCode) -> bool110     fn matches_status_retry(status: &StatusCode) -> bool {
111         matches!(status, StatusCode::UciStatusCommandRetry)
112     }
113 }
114 
115 impl TryFrom<(uwb_uci_packets::UciResponse, UCIMajorVersion, bool)> for UciResponse {
116     type Error = Error;
try_from( pair: (uwb_uci_packets::UciResponse, UCIMajorVersion, bool), ) -> std::result::Result<Self, Self::Error>117     fn try_from(
118         pair: (uwb_uci_packets::UciResponse, UCIMajorVersion, bool),
119     ) -> std::result::Result<Self, Self::Error> {
120         let evt = pair.0;
121         let uci_fira_major_ver = pair.1;
122         let is_multicast_list_rsp_v2_supported = pair.2;
123         use uwb_uci_packets::UciResponseChild;
124         match evt.specialize() {
125             UciResponseChild::CoreResponse(evt) => evt.try_into(),
126             UciResponseChild::SessionConfigResponse(evt) => {
127                 (evt, uci_fira_major_ver, is_multicast_list_rsp_v2_supported).try_into()
128             }
129             UciResponseChild::SessionControlResponse(evt) => evt.try_into(),
130             UciResponseChild::AndroidResponse(evt) => evt.try_into(),
131             UciResponseChild::TestResponse(evt) => evt.try_into(),
132             UciResponseChild::UciVendor_9_Response(evt) => raw_response(evt.into()),
133             UciResponseChild::UciVendor_A_Response(evt) => raw_response(evt.into()),
134             UciResponseChild::UciVendor_B_Response(evt) => raw_response(evt.into()),
135             UciResponseChild::UciVendor_E_Response(evt) => raw_response(evt.into()),
136             UciResponseChild::UciVendor_F_Response(evt) => raw_response(evt.into()),
137             _ => Err(Error::Unknown),
138         }
139     }
140 }
141 
142 impl TryFrom<uwb_uci_packets::CoreResponse> for UciResponse {
143     type Error = Error;
try_from(evt: uwb_uci_packets::CoreResponse) -> std::result::Result<Self, Self::Error>144     fn try_from(evt: uwb_uci_packets::CoreResponse) -> std::result::Result<Self, Self::Error> {
145         use uwb_uci_packets::CoreResponseChild;
146         match evt.specialize() {
147             CoreResponseChild::GetDeviceInfoRsp(evt) => Ok(UciResponse::CoreGetDeviceInfo(
148                 status_code_to_result(evt.get_status()).map(|_| GetDeviceInfoResponse {
149                     status: evt.get_status(),
150                     uci_version: evt.get_uci_version(),
151                     mac_version: evt.get_mac_version(),
152                     phy_version: evt.get_phy_version(),
153                     uci_test_version: evt.get_uci_test_version(),
154                     vendor_spec_info: evt.get_vendor_spec_info().clone(),
155                 }),
156             )),
157             CoreResponseChild::GetCapsInfoRsp(evt) => Ok(UciResponse::CoreGetCapsInfo(
158                 status_code_to_result(evt.get_status()).map(|_| evt.get_tlvs().clone()),
159             )),
160             CoreResponseChild::DeviceResetRsp(evt) => {
161                 Ok(UciResponse::DeviceReset(status_code_to_result(evt.get_status())))
162             }
163             CoreResponseChild::SetConfigRsp(evt) => {
164                 Ok(UciResponse::CoreSetConfig(CoreSetConfigResponse {
165                     status: evt.get_status(),
166                     config_status: evt.get_cfg_status().clone(),
167                 }))
168             }
169 
170             CoreResponseChild::GetConfigRsp(evt) => Ok(UciResponse::CoreGetConfig(
171                 status_code_to_result(evt.get_status()).map(|_| evt.get_tlvs().clone()),
172             )),
173             CoreResponseChild::CoreQueryTimeStampRsp(evt) => Ok(UciResponse::CoreQueryTimeStamp(
174                 status_code_to_result(evt.get_status()).map(|_| evt.get_timeStamp()),
175             )),
176             _ => Err(Error::Unknown),
177         }
178     }
179 }
180 
181 impl TryFrom<(uwb_uci_packets::SessionConfigResponse, UCIMajorVersion, bool)> for UciResponse {
182     type Error = Error;
try_from( pair: (uwb_uci_packets::SessionConfigResponse, UCIMajorVersion, bool), ) -> std::result::Result<Self, Self::Error>183     fn try_from(
184         pair: (uwb_uci_packets::SessionConfigResponse, UCIMajorVersion, bool),
185     ) -> std::result::Result<Self, Self::Error> {
186         use uwb_uci_packets::SessionConfigResponseChild;
187         let evt = pair.0;
188         let uci_fira_major_ver = pair.1;
189         let is_multicast_list_rsp_v2_supported = pair.2;
190         match evt.specialize() {
191             SessionConfigResponseChild::SessionInitRsp(evt) => {
192                 Ok(UciResponse::SessionInit(status_code_to_result(evt.get_status()).map(|_| None)))
193             }
194             SessionConfigResponseChild::SessionInitRsp_V2(evt) => Ok(UciResponse::SessionInit(
195                 status_code_to_result(evt.get_status()).map(|_| Some(evt.get_session_handle())),
196             )),
197             SessionConfigResponseChild::SessionDeinitRsp(evt) => {
198                 Ok(UciResponse::SessionDeinit(status_code_to_result(evt.get_status())))
199             }
200             SessionConfigResponseChild::SessionGetCountRsp(evt) => {
201                 Ok(UciResponse::SessionGetCount(
202                     status_code_to_result(evt.get_status()).map(|_| evt.get_session_count()),
203                 ))
204             }
205             SessionConfigResponseChild::SessionGetStateRsp(evt) => {
206                 Ok(UciResponse::SessionGetState(
207                     status_code_to_result(evt.get_status()).map(|_| evt.get_session_state()),
208                 ))
209             }
210             SessionConfigResponseChild::SessionUpdateControllerMulticastListRsp(evt)
211                 if uci_fira_major_ver == UCIMajorVersion::V1
212                     || !is_multicast_list_rsp_v2_supported =>
213             {
214                 error!(
215                     "Tryfrom: SessionConfigResponse:: SessionUpdateControllerMulticastListRspV1 "
216                 );
217                 let payload = evt.get_payload();
218                 let multicast_update_list_rsp_payload_v1 =
219                     SessionUpdateControllerMulticastListRspV1Payload::parse(payload).map_err(
220                         |e| {
221                             error!(
222                                 "Failed to parse Multicast list rsp v1 {:?}, payload: {:?}",
223                                 e, &payload
224                             );
225                             Error::BadParameters
226                         },
227                     )?;
228 
229                 Ok(UciResponse::SessionUpdateControllerMulticastList(Ok(
230                     SessionUpdateControllerMulticastResponse {
231                         status: multicast_update_list_rsp_payload_v1.status,
232                         status_list: vec![],
233                     },
234                 )))
235             }
236             SessionConfigResponseChild::SessionUpdateControllerMulticastListRsp(evt)
237                 if uci_fira_major_ver >= UCIMajorVersion::V2 =>
238             {
239                 error!(
240                     "Tryfrom: SessionConfigResponse:: SessionUpdateControllerMulticastListRspV2 "
241                 );
242                 let payload = evt.get_payload();
243                 let multicast_update_list_rsp_payload_v2 =
244                     SessionUpdateControllerMulticastListRspV2Payload::parse(payload).map_err(
245                         |e| {
246                             error!(
247                                 "Failed to parse Multicast list rsp v2 {:?}, payload: {:?}",
248                                 e, &payload
249                             );
250                             Error::BadParameters
251                         },
252                     )?;
253                 Ok(UciResponse::SessionUpdateControllerMulticastList(Ok(
254                     SessionUpdateControllerMulticastResponse {
255                         status: multicast_update_list_rsp_payload_v2.status,
256                         status_list: multicast_update_list_rsp_payload_v2.controlee_status,
257                     },
258                 )))
259             }
260             SessionConfigResponseChild::SessionUpdateDtTagRangingRoundsRsp(evt) => {
261                 Ok(UciResponse::SessionUpdateDtTagRangingRounds(Ok(
262                     SessionUpdateDtTagRangingRoundsResponse {
263                         status: evt.get_status(),
264                         ranging_round_indexes: evt.get_ranging_round_indexes().to_vec(),
265                     },
266                 )))
267             }
268             SessionConfigResponseChild::SessionSetAppConfigRsp(evt) => {
269                 Ok(UciResponse::SessionSetAppConfig(SetAppConfigResponse {
270                     status: evt.get_status(),
271                     config_status: evt.get_cfg_status().clone(),
272                 }))
273             }
274             SessionConfigResponseChild::SessionGetAppConfigRsp(evt) => {
275                 Ok(UciResponse::SessionGetAppConfig(
276                     status_code_to_result(evt.get_status()).map(|_| {
277                         evt.get_tlvs().clone().into_iter().map(|tlv| tlv.into()).collect()
278                     }),
279                 ))
280             }
281             SessionConfigResponseChild::SessionQueryMaxDataSizeRsp(evt) => {
282                 Ok(UciResponse::SessionQueryMaxDataSize(
283                     status_code_to_result(evt.get_status()).map(|_| evt.get_max_data_size()),
284                 ))
285             }
286             SessionConfigResponseChild::SessionSetHybridControllerConfigRsp(evt) => {
287                 Ok(UciResponse::SessionSetHybridControllerConfig(status_code_to_result(
288                     evt.get_status(),
289                 )))
290             }
291             SessionConfigResponseChild::SessionSetHybridControleeConfigRsp(evt) => {
292                 Ok(UciResponse::SessionSetHybridControleeConfig(status_code_to_result(
293                     evt.get_status(),
294                 )))
295             }
296             SessionConfigResponseChild::SessionDataTransferPhaseConfigRsp(evt) => {
297                 Ok(UciResponse::SessionDataTransferPhaseConfig(status_code_to_result(
298                     evt.get_status(),
299                 )))
300             }
301             _ => Err(Error::Unknown),
302         }
303     }
304 }
305 
306 impl TryFrom<uwb_uci_packets::SessionControlResponse> for UciResponse {
307     type Error = Error;
try_from( evt: uwb_uci_packets::SessionControlResponse, ) -> std::result::Result<Self, Self::Error>308     fn try_from(
309         evt: uwb_uci_packets::SessionControlResponse,
310     ) -> std::result::Result<Self, Self::Error> {
311         use uwb_uci_packets::SessionControlResponseChild;
312         match evt.specialize() {
313             SessionControlResponseChild::SessionStartRsp(evt) => {
314                 Ok(UciResponse::SessionStart(status_code_to_result(evt.get_status())))
315             }
316             SessionControlResponseChild::SessionStopRsp(evt) => {
317                 Ok(UciResponse::SessionStop(status_code_to_result(evt.get_status())))
318             }
319             SessionControlResponseChild::SessionGetRangingCountRsp(evt) => {
320                 Ok(UciResponse::SessionGetRangingCount(
321                     status_code_to_result(evt.get_status()).map(|_| evt.get_count() as usize),
322                 ))
323             }
324             _ => Err(Error::Unknown),
325         }
326     }
327 }
328 
329 impl TryFrom<uwb_uci_packets::AndroidResponse> for UciResponse {
330     type Error = Error;
try_from(evt: uwb_uci_packets::AndroidResponse) -> std::result::Result<Self, Self::Error>331     fn try_from(evt: uwb_uci_packets::AndroidResponse) -> std::result::Result<Self, Self::Error> {
332         use uwb_uci_packets::AndroidResponseChild;
333         match evt.specialize() {
334             AndroidResponseChild::AndroidSetCountryCodeRsp(evt) => {
335                 Ok(UciResponse::AndroidSetCountryCode(status_code_to_result(evt.get_status())))
336             }
337             AndroidResponseChild::AndroidGetPowerStatsRsp(evt) => {
338                 Ok(UciResponse::AndroidGetPowerStats(
339                     status_code_to_result(evt.get_stats().status).map(|_| evt.get_stats().clone()),
340                 ))
341             }
342             AndroidResponseChild::AndroidSetRadarConfigRsp(evt) => {
343                 Ok(UciResponse::AndroidSetRadarConfig(AndroidRadarConfigResponse {
344                     status: evt.get_status(),
345                     config_status: evt.get_cfg_status().clone(),
346                 }))
347             }
348             AndroidResponseChild::AndroidGetRadarConfigRsp(evt) => {
349                 Ok(UciResponse::AndroidGetRadarConfig(
350                     status_code_to_result(evt.get_status()).map(|_| evt.get_tlvs().clone()),
351                 ))
352             }
353             _ => Err(Error::Unknown),
354         }
355     }
356 }
357 
358 impl TryFrom<uwb_uci_packets::TestResponse> for UciResponse {
359     type Error = Error;
try_from(evt: uwb_uci_packets::TestResponse) -> std::result::Result<Self, Self::Error>360     fn try_from(evt: uwb_uci_packets::TestResponse) -> std::result::Result<Self, Self::Error> {
361         use uwb_uci_packets::TestResponseChild;
362         match evt.specialize() {
363             TestResponseChild::SessionSetRfTestConfigRsp(evt) => {
364                 Ok(UciResponse::SessionSetRfTestConfig(RfTestConfigResponse {
365                     status: evt.get_status(),
366                     config_status: evt.get_cfg_status().clone(),
367                 }))
368             }
369             TestResponseChild::TestPeriodicTxRsp(evt) => {
370                 Ok(UciResponse::RfTest(status_code_to_result(evt.get_status())))
371             }
372             TestResponseChild::TestPerRxRsp(evt) => {
373                 Ok(UciResponse::RfTest(status_code_to_result(evt.get_status())))
374             }
375             TestResponseChild::StopRfTestRsp(evt) => {
376                 Ok(UciResponse::RfTest(status_code_to_result(evt.get_status())))
377             }
378             _ => Err(Error::Unknown),
379         }
380     }
381 }
382 
raw_response(evt: uwb_uci_packets::UciResponse) -> Result<UciResponse>383 fn raw_response(evt: uwb_uci_packets::UciResponse) -> Result<UciResponse> {
384     let gid: u32 = evt.get_group_id().into();
385     let oid: u32 = evt.get_opcode().into();
386     let packet: UciControlPacket = evt.into();
387     Ok(UciResponse::RawUciCmd(Ok(RawUciMessage { gid, oid, payload: packet.to_raw_payload() })))
388 }
389 
390 #[cfg(test)]
391 mod tests {
392     use super::*;
393 
394     #[test]
test_uci_response_casting_from_uci_vendor_response_packet()395     fn test_uci_response_casting_from_uci_vendor_response_packet() {
396         let mut uci_vendor_rsp_packet = uwb_uci_packets::UciResponse::try_from(
397             uwb_uci_packets::UciVendor_9_ResponseBuilder {
398                 opcode: 0x00,
399                 payload: Some(vec![0x0, 0x1, 0x2, 0x3].into()),
400             }
401             .build(),
402         )
403         .unwrap();
404         let uci_fira_major_version = UCIMajorVersion::V1;
405         let mut uci_response = UciResponse::try_from((
406             uci_vendor_rsp_packet.clone(),
407             uci_fira_major_version.clone(),
408             false,
409         ))
410         .unwrap();
411         assert_eq!(
412             uci_response,
413             UciResponse::RawUciCmd(Ok(RawUciMessage {
414                 gid: 0x9,
415                 oid: 0x0,
416                 payload: vec![0x0, 0x1, 0x2, 0x3],
417             }))
418         );
419 
420         uci_vendor_rsp_packet = uwb_uci_packets::UciResponse::try_from(
421             uwb_uci_packets::UciVendor_A_ResponseBuilder {
422                 opcode: 0x00,
423                 payload: Some(vec![0x0, 0x1, 0x2, 0x3].into()),
424             }
425             .build(),
426         )
427         .unwrap();
428         uci_response = UciResponse::try_from((
429             uci_vendor_rsp_packet.clone(),
430             uci_fira_major_version.clone(),
431             false,
432         ))
433         .unwrap();
434         assert_eq!(
435             uci_response,
436             UciResponse::RawUciCmd(Ok(RawUciMessage {
437                 gid: 0xA,
438                 oid: 0x0,
439                 payload: vec![0x0, 0x1, 0x2, 0x3],
440             }))
441         );
442 
443         uci_vendor_rsp_packet = uwb_uci_packets::UciResponse::try_from(
444             uwb_uci_packets::UciVendor_B_ResponseBuilder {
445                 opcode: 0x00,
446                 payload: Some(vec![0x0, 0x1, 0x2, 0x3].into()),
447             }
448             .build(),
449         )
450         .unwrap();
451         uci_response = UciResponse::try_from((
452             uci_vendor_rsp_packet.clone(),
453             uci_fira_major_version.clone(),
454             false,
455         ))
456         .unwrap();
457         assert_eq!(
458             uci_response,
459             UciResponse::RawUciCmd(Ok(RawUciMessage {
460                 gid: 0xB,
461                 oid: 0x0,
462                 payload: vec![0x0, 0x1, 0x2, 0x3],
463             }))
464         );
465 
466         uci_vendor_rsp_packet = uwb_uci_packets::UciResponse::try_from(
467             uwb_uci_packets::UciVendor_E_ResponseBuilder {
468                 opcode: 0x00,
469                 payload: Some(vec![0x0, 0x1, 0x2, 0x3].into()),
470             }
471             .build(),
472         )
473         .unwrap();
474         uci_response = UciResponse::try_from((
475             uci_vendor_rsp_packet.clone(),
476             uci_fira_major_version.clone(),
477             false,
478         ))
479         .unwrap();
480         assert_eq!(
481             uci_response,
482             UciResponse::RawUciCmd(Ok(RawUciMessage {
483                 gid: 0xE,
484                 oid: 0x0,
485                 payload: vec![0x0, 0x1, 0x2, 0x3],
486             }))
487         );
488 
489         uci_vendor_rsp_packet = uwb_uci_packets::UciResponse::try_from(
490             uwb_uci_packets::UciVendor_F_ResponseBuilder {
491                 opcode: 0x00,
492                 payload: Some(vec![0x0, 0x1, 0x2, 0x3].into()),
493             }
494             .build(),
495         )
496         .unwrap();
497         uci_response = UciResponse::try_from((
498             uci_vendor_rsp_packet.clone(),
499             uci_fira_major_version.clone(),
500             false,
501         ))
502         .unwrap();
503         assert_eq!(
504             uci_response,
505             UciResponse::RawUciCmd(Ok(RawUciMessage {
506                 gid: 0xF,
507                 oid: 0x0,
508                 payload: vec![0x0, 0x1, 0x2, 0x3],
509             }))
510         );
511     }
512 }
513