wiliot-certificate 1.3.0a1__py3-none-any.whl → 1.4.0a2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. brg_certificate/__init__.py +0 -0
  2. brg_certificate/ag/energous_v0_defines.py +925 -0
  3. brg_certificate/ag/energous_v1_defines.py +931 -0
  4. brg_certificate/ag/energous_v2_defines.py +925 -0
  5. brg_certificate/ag/energous_v3_defines.py +925 -0
  6. brg_certificate/ag/energous_v4_defines.py +925 -0
  7. brg_certificate/ag/fanstel_lan_v0_defines.py +925 -0
  8. brg_certificate/ag/fanstel_lte_v0_defines.py +925 -0
  9. brg_certificate/ag/fanstel_wifi_v0_defines.py +925 -0
  10. brg_certificate/ag/minew_lte_v0_defines.py +925 -0
  11. brg_certificate/ag/wlt_cmd_if.html +102 -0
  12. brg_certificate/ag/wlt_types.html +6114 -0
  13. brg_certificate/ag/wlt_types_ag.py +7840 -0
  14. brg_certificate/ag/wlt_types_ag_jsons/brg2brg_ota.json +142 -0
  15. brg_certificate/ag/wlt_types_ag_jsons/brg2gw_hb.json +785 -0
  16. brg_certificate/ag/wlt_types_ag_jsons/brg2gw_hb_sleep.json +139 -0
  17. brg_certificate/ag/wlt_types_ag_jsons/calibration.json +394 -0
  18. brg_certificate/ag/wlt_types_ag_jsons/custom.json +515 -0
  19. brg_certificate/ag/wlt_types_ag_jsons/datapath.json +672 -0
  20. brg_certificate/ag/wlt_types_ag_jsons/energy2400.json +550 -0
  21. brg_certificate/ag/wlt_types_ag_jsons/energySub1g.json +595 -0
  22. brg_certificate/ag/wlt_types_ag_jsons/externalSensor.json +598 -0
  23. brg_certificate/ag/wlt_types_ag_jsons/interface.json +938 -0
  24. brg_certificate/ag/wlt_types_ag_jsons/powerManagement.json +1234 -0
  25. brg_certificate/ag/wlt_types_ag_jsons/side_info_sensor.json +105 -0
  26. brg_certificate/ag/wlt_types_ag_jsons/signal_indicator_data.json +77 -0
  27. brg_certificate/ag/wlt_types_ag_jsons/unified_echo_ext_pkt.json +61 -0
  28. brg_certificate/ag/wlt_types_ag_jsons/unified_echo_pkt.json +110 -0
  29. brg_certificate/brg_certificate.py +191 -0
  30. brg_certificate/brg_certificate_cli.py +47 -0
  31. brg_certificate/cert_common.py +828 -0
  32. brg_certificate/cert_config.py +395 -0
  33. brg_certificate/cert_data_sim.py +188 -0
  34. brg_certificate/cert_defines.py +337 -0
  35. brg_certificate/cert_gw_sim.py +285 -0
  36. brg_certificate/cert_mqtt.py +373 -0
  37. brg_certificate/cert_prints.py +181 -0
  38. brg_certificate/cert_protobuf.py +88 -0
  39. brg_certificate/cert_results.py +300 -0
  40. brg_certificate/cert_utils.py +358 -0
  41. brg_certificate/certificate_sanity_test_list.txt +36 -0
  42. brg_certificate/certificate_test_list.txt +43 -0
  43. brg_certificate/config/eclipse.json +10 -0
  44. brg_certificate/config/hivemq.json +10 -0
  45. brg_certificate/config/mosquitto.json +10 -0
  46. brg_certificate/config/mosquitto.md +95 -0
  47. brg_certificate/config/wiliot-dev.json +10 -0
  48. brg_certificate/restore_brg.py +59 -0
  49. brg_certificate/tests/calibration/interval_test/interval_test.json +13 -0
  50. brg_certificate/tests/calibration/interval_test/interval_test.py +28 -0
  51. brg_certificate/tests/calibration/output_power_test/output_power_test.json +13 -0
  52. brg_certificate/tests/calibration/output_power_test/output_power_test.py +28 -0
  53. brg_certificate/tests/calibration/pattern_test/pattern_test.json +13 -0
  54. brg_certificate/tests/calibration/pattern_test/pattern_test.py +70 -0
  55. brg_certificate/tests/datapath/adaptive_pacer_algo_test/adaptive_pacer_algo_test.json +13 -0
  56. brg_certificate/tests/datapath/adaptive_pacer_algo_test/adaptive_pacer_algo_test.py +76 -0
  57. brg_certificate/tests/datapath/num_of_tags_test/num_of_tags_test.json +13 -0
  58. brg_certificate/tests/datapath/num_of_tags_test/num_of_tags_test.py +83 -0
  59. brg_certificate/tests/datapath/output_power_test/output_power_test.json +13 -0
  60. brg_certificate/tests/datapath/output_power_test/output_power_test.py +27 -0
  61. brg_certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.json +13 -0
  62. brg_certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.py +43 -0
  63. brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.json +13 -0
  64. brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.py +63 -0
  65. brg_certificate/tests/datapath/pacer_interval_test/pacer_interval_test.json +13 -0
  66. brg_certificate/tests/datapath/pacer_interval_test/pacer_interval_test.py +50 -0
  67. brg_certificate/tests/datapath/pattern_test/pattern_test.json +13 -0
  68. brg_certificate/tests/datapath/pattern_test/pattern_test.py +28 -0
  69. brg_certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.json +13 -0
  70. brg_certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.py +51 -0
  71. brg_certificate/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.json +13 -0
  72. brg_certificate/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.py +54 -0
  73. brg_certificate/tests/datapath/pkt_filter_test/pkt_filter_test.json +13 -0
  74. brg_certificate/tests/datapath/pkt_filter_test/pkt_filter_test.py +55 -0
  75. brg_certificate/tests/datapath/rssi_threshold_test/rssi_threshold_test.json +13 -0
  76. brg_certificate/tests/datapath/rssi_threshold_test/rssi_threshold_test.py +73 -0
  77. brg_certificate/tests/datapath/rx_channel_test/rx_channel_test.json +13 -0
  78. brg_certificate/tests/datapath/rx_channel_test/rx_channel_test.py +41 -0
  79. brg_certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.json +21 -0
  80. brg_certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.py +184 -0
  81. brg_certificate/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.json +21 -0
  82. brg_certificate/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.py +210 -0
  83. brg_certificate/tests/datapath/stress_gen3_test/stress_gen3_test.json +30 -0
  84. brg_certificate/tests/datapath/stress_gen3_test/stress_gen3_test.py +203 -0
  85. brg_certificate/tests/datapath/stress_test/stress_test.json +30 -0
  86. brg_certificate/tests/datapath/stress_test/stress_test.py +210 -0
  87. brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.json +13 -0
  88. brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.py +113 -0
  89. brg_certificate/tests/datapath/tx_repetition_test/tx_repetition_test.json +13 -0
  90. brg_certificate/tests/datapath/tx_repetition_test/tx_repetition_test.py +79 -0
  91. brg_certificate/tests/edge_mgmt/actions_test/actions_test.json +13 -0
  92. brg_certificate/tests/edge_mgmt/actions_test/actions_test.py +432 -0
  93. brg_certificate/tests/edge_mgmt/brg2brg_ota_ble5_test/brg2brg_ota_ble5_test.json +13 -0
  94. brg_certificate/tests/edge_mgmt/brg2brg_ota_ble5_test/brg2brg_ota_ble5_test.py +94 -0
  95. brg_certificate/tests/edge_mgmt/brg2brg_ota_test/brg2brg_ota_test.json +13 -0
  96. brg_certificate/tests/edge_mgmt/brg2brg_ota_test/brg2brg_ota_test.py +87 -0
  97. brg_certificate/tests/edge_mgmt/leds_test/leds_test.json +13 -0
  98. brg_certificate/tests/edge_mgmt/leds_test/leds_test.py +210 -0
  99. brg_certificate/tests/edge_mgmt/ota_test/ota_test.json +13 -0
  100. brg_certificate/tests/edge_mgmt/ota_test/ota_test.py +83 -0
  101. brg_certificate/tests/edge_mgmt/stat_test/stat_test.json +13 -0
  102. brg_certificate/tests/edge_mgmt/stat_test/stat_test.py +48 -0
  103. brg_certificate/tests/energy2400/duty_cycle_test/duty_cycle_test.json +13 -0
  104. brg_certificate/tests/energy2400/duty_cycle_test/duty_cycle_test.py +26 -0
  105. brg_certificate/tests/energy2400/output_power_test/output_power_test.json +13 -0
  106. brg_certificate/tests/energy2400/output_power_test/output_power_test.py +27 -0
  107. brg_certificate/tests/energy2400/pattern_test/pattern_test.json +13 -0
  108. brg_certificate/tests/energy2400/pattern_test/pattern_test.py +28 -0
  109. brg_certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.json +13 -0
  110. brg_certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.py +398 -0
  111. brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.json +13 -0
  112. brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.py +153 -0
  113. brg_certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.json +13 -0
  114. brg_certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.py +264 -0
  115. brg_certificate/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.json +13 -0
  116. brg_certificate/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.py +27 -0
  117. brg_certificate/tests/energy_sub1g/pattern_test/pattern_test.json +13 -0
  118. brg_certificate/tests/energy_sub1g/pattern_test/pattern_test.py +26 -0
  119. brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.json +13 -0
  120. brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.py +397 -0
  121. brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.json +13 -0
  122. brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.py +27 -0
  123. brg_certificate/wltPb_pb2.py +72 -0
  124. brg_certificate/wltPb_pb2.pyi +227 -0
  125. brg_certificate/wlt_types.py +114 -0
  126. gw_certificate/api/extended_api.py +7 -1531
  127. gw_certificate/api_if/200/data.json +106 -0
  128. gw_certificate/api_if/200/logs.json +12 -0
  129. gw_certificate/api_if/200/status.json +47 -0
  130. gw_certificate/api_if/201/data.json +98 -0
  131. gw_certificate/api_if/201/logs.json +12 -0
  132. gw_certificate/api_if/201/status.json +53 -0
  133. gw_certificate/api_if/202/data.json +83 -0
  134. gw_certificate/api_if/202/logs.json +12 -0
  135. gw_certificate/api_if/202/status.json +60 -0
  136. gw_certificate/api_if/203/data.json +85 -0
  137. gw_certificate/api_if/203/logs.json +12 -0
  138. gw_certificate/api_if/203/status.json +63 -0
  139. gw_certificate/api_if/204/data.json +85 -0
  140. gw_certificate/api_if/204/logs.json +12 -0
  141. gw_certificate/api_if/204/status.json +63 -0
  142. gw_certificate/api_if/205/data.json +85 -0
  143. gw_certificate/api_if/205/logs.json +12 -0
  144. gw_certificate/api_if/205/status.json +63 -0
  145. gw_certificate/api_if/api_validation.py +0 -2
  146. gw_certificate/common/analysis_data_bricks.py +18 -1413
  147. gw_certificate/common/debug.py +0 -21
  148. gw_certificate/common/utils.py +1 -212
  149. gw_certificate/common/utils_defines.py +0 -87
  150. gw_certificate/gw_certificate.py +9 -7
  151. gw_certificate/gw_certificate_cli.py +39 -23
  152. gw_certificate/interface/4.4.52_app.zip +0 -0
  153. gw_certificate/interface/4.4.52_sd_bl_app.zip +0 -0
  154. gw_certificate/interface/ble_simulator.py +0 -32
  155. gw_certificate/interface/if_defines.py +1 -0
  156. gw_certificate/interface/mqtt.py +96 -19
  157. gw_certificate/interface/nrfutil-linux +0 -0
  158. gw_certificate/interface/nrfutil-mac +0 -0
  159. gw_certificate/interface/nrfutil.exe +0 -0
  160. gw_certificate/interface/pkt_generator.py +0 -82
  161. gw_certificate/interface/uart_if.py +73 -43
  162. gw_certificate/templates/results.html +1 -1
  163. gw_certificate/tests/__init__.py +1 -2
  164. gw_certificate/tests/actions.py +134 -9
  165. gw_certificate/tests/connection.py +10 -5
  166. gw_certificate/tests/downlink.py +2 -4
  167. gw_certificate/tests/generic.py +62 -12
  168. gw_certificate/tests/registration.py +78 -27
  169. gw_certificate/tests/static/generated_packet_table.py +12 -48
  170. gw_certificate/tests/static/packet_table.csv +10048 -10048
  171. gw_certificate/tests/static/references.py +2 -1
  172. gw_certificate/tests/static/uplink_defines.py +0 -7
  173. gw_certificate/tests/throughput.py +7 -12
  174. gw_certificate/tests/uplink.py +83 -43
  175. {wiliot_certificate-1.3.0a1.dist-info → wiliot_certificate-1.4.0a2.dist-info}/METADATA +59 -8
  176. wiliot_certificate-1.4.0a2.dist-info/RECORD +198 -0
  177. {wiliot_certificate-1.3.0a1.dist-info → wiliot_certificate-1.4.0a2.dist-info}/WHEEL +1 -1
  178. wiliot_certificate-1.4.0a2.dist-info/entry_points.txt +3 -0
  179. wiliot_certificate-1.4.0a2.dist-info/top_level.txt +2 -0
  180. gw_certificate/interface/packet_error.py +0 -22
  181. wiliot_certificate-1.3.0a1.dist-info/RECORD +0 -51
  182. wiliot_certificate-1.3.0a1.dist-info/entry_points.txt +0 -2
  183. wiliot_certificate-1.3.0a1.dist-info/top_level.txt +0 -1
  184. {wiliot_certificate-1.3.0a1.dist-info → wiliot_certificate-1.4.0a2.dist-info}/LICENSE +0 -0
@@ -0,0 +1,395 @@
1
+ from brg_certificate.cert_defines import *
2
+ from brg_certificate.cert_prints import *
3
+ from brg_certificate.wlt_types import *
4
+ import brg_certificate.cert_common as cert_common
5
+ import brg_certificate.cert_protobuf as cert_protobuf
6
+ import datetime, string, json, random
7
+
8
+ BLE5_MAX_DURATION = ag.BLE5_PARAM_PRIMARY_CHANNEL_SCAN_CYCLE + 1000 # In MS
9
+ BLE5_MAX_RETRIES = BLE5_MAX_DURATION//20
10
+
11
+ #################################
12
+ # GW
13
+ #################################
14
+
15
+ def gw_configure(test, cfg={}, version="", extended_cfg={}, ret_pkt=False, wait=False, serialization_change=False):
16
+ cfg = cfg if cfg else get_default_gw_dict(test)
17
+ if test.gw_lan:
18
+ cfg[GW_MODE] = BLE_LAN
19
+ gw_config = create_gw_config(test, cfg, version)
20
+ gw_config[GW_CONF][ADDITIONAL].update(extended_cfg)
21
+ gw_config[GW_CONF].update(extended_cfg)
22
+ if test.protobuf:
23
+ payload = cert_protobuf.downlink_to_pb(gw_config)
24
+ utPrint(f"Configuring GW with cfg pkt:\n{payload}", "BLUE")
25
+ else:
26
+ if not serialization_change:
27
+ gw_config[GW_CONF][ADDITIONAL][SERIALIZATION_FORMAT] = JSON
28
+ payload = json.dumps(gw_config)
29
+ utPrint(f"Configuring GW with cfg pkt:\n{payload}", "BLUE")
30
+ test.mqttc.flush_pkts()
31
+ test.mqttc.publish(test.mqttc.update_topic, payload=payload, qos=1)
32
+ if wait:
33
+ # Search for update packet
34
+ start_time = datetime.datetime.now()
35
+ while (datetime.datetime.now() - start_time).seconds < DEFAULT_GW_FIELD_UPDATE_TIMEOUT:
36
+ for p in test.mqttc._userdata["pkts"].status:
37
+ if GW_CONF in p.body or GW_STATUS in p.body:
38
+ print_pkt(p.body)
39
+ utPrint("SUCCESS: Found GW cfg", "GREEN")
40
+ cert_common.wait_time_n_print(5)
41
+ if ret_pkt:
42
+ return test, p.body
43
+ else:
44
+ return test, DONE
45
+ print_update_wait()
46
+ test.rc = TEST_FAILED
47
+ test.add_reason(f"FAILURE: GW cfg not found after {DEFAULT_GW_FIELD_UPDATE_TIMEOUT} seconds!")
48
+ return test, NO_RESPONSE
49
+ else:
50
+ utPrint("Sent GW cfg, Wait is set to False", "BLUE")
51
+ return test, DONE
52
+
53
+ def create_gw_config(test, cfg, version=""):
54
+ if version:
55
+ return dict({GW_CONF:{LAT: GW_LATITUDE_DEFAULT, LNG: GW_LONGITUDE_DEFAULT, WIFI_VERSION: version[WIFI_VERSION],
56
+ BLE_VERSION: version[BLE_VERSION], GW_API_VERSION: GW_API_VER_OLD, ADDITIONAL:dict(cfg)}})
57
+ elif test.gw_orig_versions:
58
+ return dict({GW_CONF:{LAT: GW_LATITUDE_DEFAULT, LNG: GW_LONGITUDE_DEFAULT, WIFI_VERSION: test.gw_orig_versions[WIFI_VERSION],
59
+ BLE_VERSION: test.gw_orig_versions[BLE_VERSION], GW_API_VERSION: GW_API_VER_OLD, ADDITIONAL:dict(cfg)}})
60
+ # Protection for FDM gw config
61
+ else:
62
+ return dict({GW_CONF:{LAT: GW_LATITUDE_DEFAULT, LNG: GW_LONGITUDE_DEFAULT, GW_API_VERSION: GW_API_VER_OLD,
63
+ ADDITIONAL:dict(cfg)}})
64
+
65
+ def gw_downlink(test, raw_tx_data="", is_ota=False, version="", max_duration=100, max_retries=8):
66
+ pkt = create_gw_downlink_pkt(test, raw_tx_data, is_ota, version=version, max_duration=max_duration, max_retries=max_retries)
67
+ print("GW Downlink:", pkt)
68
+ payload = cert_protobuf.downlink_to_pb(pkt) if test.protobuf else json.dumps(pkt)
69
+ test.mqttc.publish(test.mqttc.update_topic, payload=payload, qos=1)
70
+
71
+ def create_gw_downlink_pkt(test, raw_tx_data="", is_ota=False, version="", max_duration=100, max_retries=8):
72
+ ret = dict({TX_PKT: raw_tx_data,
73
+ TX_MAX_DURATION_MS: max_duration,
74
+ TX_MAX_RETRIES: max_retries})
75
+ if is_ota == False:
76
+ ret[ACTION] = 0
77
+ else:
78
+ ret[ACTION] = 1
79
+ ret[GW_ID] = str(test.gw)
80
+ ret[BRIDGE_ID] = test.active_brg.id_str
81
+ ret[IMG_DIR_URL] = f"https://api.us-east-2.prod.wiliot.cloud/v1/bridge/type/{test.active_brg.board_type}/version/{version}/binary/"
82
+ # Using a random uuid to force file download on the GW side
83
+ ret[VER_UUID_STR] = ''.join(random.choices(string.digits, k=VER_MAX_LEN))
84
+ ret[UPGRADE_BLSD] = False
85
+ ret[TX_MAX_DURATION_MS] = 150
86
+ return ret
87
+
88
+ def get_default_gw_dict(test=None):
89
+ return dict({WLT_SERVER: test.server if test else PROD, GW_MODE: BLE_WIFI, USE_STAT_LOC: False,
90
+ SERIALIZATION_FORMAT: PROTOBUF})
91
+
92
+ def config_gw_defaults(test, version=""):
93
+ utPrint(f"Configuring gateway {test.gw} to defaults", "BLUE")
94
+ return gw_configure(test, get_default_gw_dict(test), wait=True, version=version)
95
+
96
+ def config_gw_version(test, version):
97
+ utPrint(f"Updating GW versions to {version[WIFI_VERSION]} , {version[BLE_VERSION]}", "BLUE")
98
+ if version == VERSIONS["3.16.3"]:
99
+ gw_configure(test,
100
+ dict({WLT_SERVER: test.server if test else PROD, OUTPUT_POWER_2_4: 8, GW_MODE: BLE_WIFI, TX_PERIOD: 3,
101
+ USE_STAT_LOC: False, GW_DATA_MODE: TAGS_AND_BRGS, PACER_INTERVAL: 60, GW_ENERGY_PATTERN: 17, RX_TX_PERIOD: 100}),
102
+ version)
103
+ if version == VERSIONS["4.1.0"] or version == VERSIONS["4.1.2"]:
104
+ gw_configure(test,
105
+ dict({WLT_SERVER: test.server if test else PROD, GW_MODE: BLE_WIFI,
106
+ USE_STAT_LOC: False}),
107
+ version)
108
+ else:
109
+ gw_configure(test, get_default_gw_dict(test), version)
110
+
111
+ def gw_info_action(test):
112
+ pkt = {ACTION: GET_INFO_ACTION}
113
+ payload = cert_protobuf.downlink_to_pb(pkt) if test.protobuf else json.dumps(pkt)
114
+ test.mqttc.publish(test.mqttc.update_topic, payload=payload, qos=1)
115
+
116
+ def gw_reboot_action(test):
117
+ pkt = {ACTION: REBOOT_GW_ACTION}
118
+ payload = cert_protobuf.downlink_to_pb(pkt) if test.protobuf else json.dumps(pkt)
119
+ test.mqttc.publish(test.mqttc.update_topic, payload=payload, qos=1)
120
+
121
+ def gw_action(test, action):
122
+ pkt = {ACTION: action}
123
+ payload = cert_protobuf.downlink_to_pb(pkt) if test.protobuf else json.dumps(pkt)
124
+ test.mqttc.publish(test.mqttc.update_topic, payload=payload, qos=1)
125
+
126
+ def gw_log_period_action(test, period):
127
+ pkt = {ACTION: f"{LOG_PERIOD_ACTION} {period}"}
128
+ payload = cert_protobuf.downlink_to_pb(pkt) if test.protobuf else json.dumps(pkt)
129
+ test.mqttc.publish(test.mqttc.update_topic, payload=payload, qos=1)
130
+
131
+ def gw_logs_action(test):
132
+ pkt = {ACTION: GET_LOGS}
133
+ payload = cert_protobuf.downlink_to_pb(pkt) if test.protobuf else json.dumps(pkt)
134
+ test.mqttc.publish(test.mqttc.update_topic, payload=payload, qos=1)
135
+
136
+ def gw_status_wait(test, cond, str, time_limit): #cond gatewayLogs str test type
137
+ test.mqttc.flush_pkts()
138
+ start_time = datetime.datetime.now()
139
+ while (datetime.datetime.now() - start_time).seconds < time_limit:
140
+ for p in test.mqttc._userdata["pkts"].status:
141
+ if cond in p.body:
142
+ if str in p.body[cond]:
143
+ print_pkt(p.body)
144
+ return
145
+ print_update_wait()
146
+
147
+ #################################
148
+ # BRG
149
+ #################################
150
+
151
+ get_brg_id_int = lambda test, brg_mac : brg_mac if brg_mac != 0 else test.active_brg.id_int
152
+
153
+ def fields_n_vals_dict_get(fields, values):
154
+ # initiate fields and values
155
+ fields_and_values = {}
156
+ for field, value in zip(fields, values):
157
+ fields_and_values[field] = int(value)
158
+ # functionality run print
159
+ print_string = generate_print_string(fields_and_values)
160
+ functionality_run_print(print_string)
161
+ return fields_and_values
162
+
163
+ def brg_configure(test, cfg_pkt=None, module=None, fields=None, values=None, wait=True, ret_cfg_pkt=False):
164
+ retries = 3
165
+ if not cfg_pkt:
166
+ fields_n_vals = fields_n_vals_dict_get(fields, values)
167
+ cfg_pkt = get_default_brg_pkt(test, pkt_type=module, **fields_n_vals)
168
+ # Search for update packet
169
+ test.mqttc.flush_pkts()
170
+ if not wait:
171
+ gw_downlink(test=test, raw_tx_data=cfg_pkt.dump())
172
+ utPrint("Wait is set to False, not waiting for Bridge cfg ACK", "CYAN")
173
+ return test, DONE
174
+
175
+ for retry in range(retries):
176
+ gw_downlink(test=test, raw_tx_data=cfg_pkt.dump())
177
+ pkts_found = False
178
+ seq_ids = []
179
+ wlt_pkt = WltPkt()
180
+ start_time = datetime.datetime.now()
181
+ while (datetime.datetime.now() - start_time).seconds < DEFAULT_BRG_FIELD_UPDATE_TIMEOUT:
182
+ pkts = cert_common.get_brg_cfg_pkts(test=test)
183
+ if pkts:
184
+ pkts_found = True
185
+ for p in pkts:
186
+ wlt_pkt = WltPkt(p)
187
+ if seq_ids == [] or wlt_pkt.pkt.seq_id not in seq_ids:
188
+ print(wlt_pkt.pkt)
189
+ if cfg_pkt.pkt == wlt_pkt.pkt:
190
+ utPrint("SUCCESS: Bridge cfg", "GREEN")
191
+ return (test, DONE) if not ret_cfg_pkt else (test, wlt_pkt)
192
+ seq_ids.append(wlt_pkt.pkt.seq_id)
193
+ print_update_wait()
194
+ utPrint(f"brg_configure: No pkts found retry={retry}!", "WARNING")
195
+ if not pkts_found:
196
+ utPrint(f"brg_configure: No pkts found retry={retry}!", "RED")
197
+ test.add_reason(f"brg_configure: No pkts found. retry={retry}")
198
+ test.rc = TEST_FAILED
199
+ if wlt_pkt.pkt:
200
+ # In case of failure, we want to see if it's api version issue
201
+ test.active_brg.api_version = wlt_pkt.pkt.api_version
202
+ print(f"-->> api_version:{test.active_brg.api_version}\nFailed brg_configure with pkt ({cfg_pkt.pkt.__dict__})")
203
+ test.add_reason(f"Failed brg_configure")
204
+ return test, NO_RESPONSE
205
+
206
+ def brg_configure_ble5(test, cfg_pkt=None, module=None, fields=None, values=None, ret_cfg_pkt=False, wait=True):
207
+ if not cfg_pkt:
208
+ fields_n_vals = fields_n_vals_dict_get(fields, values)
209
+ cfg_pkt = get_default_brg_pkt(test, pkt_type=module, **fields_n_vals)
210
+ # Search for update packet
211
+ test.mqttc.flush_pkts()
212
+
213
+ num_of_tries = 0
214
+ pkts_found = False
215
+ seq_ids = []
216
+ wlt_pkt = WltPkt()
217
+ start_time = datetime.datetime.now()
218
+ gw_downlink(test=test, raw_tx_data=cfg_pkt.dump(), max_duration=BLE5_MAX_DURATION, max_retries=BLE5_MAX_RETRIES)
219
+ while not pkts_found and wait:
220
+ if ((datetime.datetime.now() - start_time).seconds > ((ag.BLE5_PARAM_PRIMARY_CHANNEL_SCAN_CYCLE/1000)+1)):
221
+ if num_of_tries < 3:
222
+ num_of_tries += 1
223
+ start_time = datetime.datetime.now()
224
+ gw_downlink(test=test, raw_tx_data=cfg_pkt.dump(), max_duration=BLE5_MAX_DURATION, max_retries=BLE5_MAX_RETRIES)
225
+ print(f"Brg configure - BLE5 mode : No pkts found after {(ag.BLE5_PARAM_PRIMARY_CHANNEL_SCAN_CYCLE/1000)+1} seconds, in try number {num_of_tries}")
226
+ else:
227
+ test.add_reason(f"Brg configure - BLE5 mode : No pkts found after {BLE5_MAX_DURATION} seconds, in 3 tries")
228
+ test.rc = TEST_FAILED
229
+ time.sleep(1)
230
+ test.mqttc.flush_pkts()
231
+ return test, NO_RESPONSE
232
+ pkts = cert_common.get_brg_cfg_pkts(test=test)
233
+ if pkts:
234
+ for p in pkts:
235
+ wlt_pkt = WltPkt(p)
236
+ if seq_ids == [] or wlt_pkt.pkt.seq_id not in seq_ids:
237
+ print(wlt_pkt.pkt)
238
+ if cfg_pkt.pkt == wlt_pkt.pkt:
239
+ utPrint("SUCCESS: Bridge cfg", "GREEN")
240
+ time.sleep(15)
241
+ test.mqttc.flush_pkts()
242
+ return (test, DONE) if not ret_cfg_pkt else (test, wlt_pkt)
243
+ seq_ids.append(wlt_pkt.pkt.seq_id)
244
+ print_update_wait()
245
+
246
+ def brg1_configure(test, cfg_pkt=None, module=None, fields=None, values=None, wait=True, ret_cfg_pkt=False, ble5=False):
247
+ test.active_brg = test.brg1
248
+ if ble5:
249
+ test, res = brg_configure_ble5(test, cfg_pkt, module, fields, values, ret_cfg_pkt)
250
+ else:
251
+ test, res = brg_configure(test, cfg_pkt, module, fields, values, wait, ret_cfg_pkt)
252
+ test.active_brg = test.brg0
253
+ return test, res
254
+
255
+ def internal_brg_configure(test, cfg_pkt=None, module=None, fields=None, values=None, wait=True, ret_cfg_pkt=False):
256
+ test.active_brg = test.internal_brg_obj
257
+ if not cfg_pkt:
258
+ fields_n_vals = fields_n_vals_dict_get(fields, values) if fields and values else {}
259
+ cfg_pkt = get_default_brg_pkt(test, pkt_type=module, **fields_n_vals)
260
+ test, res = brg_configure(test, cfg_pkt, module, fields, values, wait, ret_cfg_pkt)
261
+ test.active_brg = test.brg0
262
+ return test, res
263
+
264
+ def send_brg_action(test, action_id, **kwargs):
265
+ print(f"\nSending {ag.ACTIONS_DICT[action_id]}{test.active_brg.api_version} with parameters={kwargs if kwargs else None}")
266
+ test.mqttc.flush_pkts()
267
+ action_pkt = get_default_brg_pkt(test, pkt_type=eval_pkt(f'{ag.ACTIONS_DICT[action_id]}{test.active_brg.api_version}'), **kwargs)
268
+ gw_downlink(test, raw_tx_data=action_pkt.dump())
269
+
270
+ def get_default_brg_pkt(test, pkt_type, group_id=ag.GROUP_ID_GW2BRG, seq_id=0, **kwargs):
271
+ seq_id = test.get_seq_id() if seq_id == 0 else seq_id
272
+ # Bypass from default sub1g ep cfg of 0 (no energizing)
273
+ if "ModuleEnergySub1G" in pkt_type.__name__ and BRG_PATTERN not in kwargs:
274
+ # TODO - Remove on next api_version update - this is a patch for parameter name change from api version 11 to 12
275
+ brg_pattern = "sub1g_energy_" + BRG_PATTERN if test.active_brg.api_version < ag.API_VERSION_V12 else BRG_PATTERN
276
+ kwargs.update({brg_pattern: ag.SUB1G_ENERGY_PATTERN_ISRAEL})
277
+ brg_pkt = WltPkt(hdr=ag.Hdr(group_id=group_id), pkt=pkt_type(brg_mac=test.active_brg.id_int if test.active_brg else 0, seq_id=seq_id, **kwargs))
278
+ return brg_pkt
279
+
280
+ def config_brg_defaults(test, modules=[], ble5=False):
281
+ failed_cfg = False
282
+ modules = test.active_brg.modules if not modules else modules
283
+ for module in modules:
284
+ utPrint(f"Configuring {module.__name__} to defaults. board type[{test.active_brg.board_type}] api version[{test.active_brg.api_version}]", "BLUE")
285
+ cfg_pkt = get_default_brg_pkt(test, module)
286
+ if ble5:
287
+ test, res = brg_configure_ble5(test=test, cfg_pkt=cfg_pkt)
288
+ else:
289
+ test, res = brg_configure(test=test, cfg_pkt=cfg_pkt)
290
+ if res == NO_RESPONSE:
291
+ utPrint(f"FAILURE: {module.__name__} not configured to defaults", "RED")
292
+ failed_cfg = True
293
+ else:
294
+ utPrint(f"SUCCESS: {module.__name__} configured to defaults", "GREEN")
295
+ return (test, DONE) if not failed_cfg else (test, NO_RESPONSE)
296
+
297
+ def config_brg1_defaults(test, modules=[], ble5=False):
298
+ test.active_brg = test.brg1
299
+ test, res = config_brg_defaults(test, modules, ble5)
300
+ test.active_brg = test.brg0
301
+ return test, res
302
+
303
+ def print_cur_modules(test, modules):
304
+ start_time = datetime.datetime.now()
305
+ # Print all pkts
306
+ for module in modules:
307
+ pkts = cert_mqtt.get_brg2gw_mgmt_pkts(test.mqttc, test, mgmt_types=[module])
308
+ if pkts:
309
+ print("\nGot {} packet after {} sec!".format(module, (datetime.datetime.now() - start_time).seconds))
310
+ print(pkts[-1][MGMT_PKT].pkt)
311
+
312
+ return test
313
+
314
+ def brg_ota(test, gw_ble_version=None, search_ack=True):
315
+ if not gw_ble_version:
316
+ gw_ble_version = cert_common.get_gw_versions(test)[BLE_VERSION]
317
+ if not gw_ble_version:
318
+ test.rc = TEST_FAILED
319
+ test.add_reason("Couldn't get GW versions!")
320
+ return test
321
+
322
+ if gw_ble_version != test.active_brg.version:
323
+ utPrint(f"Updating BRG version to {gw_ble_version}", "BLUE")
324
+ ota_updates = [f"Starting OTA to BRG WLT_{test.active_brg.id_str}",
325
+ f"BRG OTA finished with status 0 for bridge {test.active_brg.id_str}"]
326
+ functionality_run_print(f"OTA for brg: {test.active_brg.id_str}")
327
+ action_pkt = get_default_brg_pkt(test=test, pkt_type=eval_pkt(f'ActionGenericV{test.active_brg.api_version}'), action_id=ag.ACTION_REBOOT)
328
+ # BRG OTA - Flash pkts ONLY before starting to avoid deletion of needed GW Logs which are in the status topic
329
+ test.mqttc.flush_status_pkts()
330
+ gw_downlink(test, raw_tx_data=action_pkt.dump(), is_ota=True, version=gw_ble_version)
331
+ # expected_hash=1 due to different cfgs and versions between builds
332
+ test = cert_common.reboot_config_analysis(test=test, expected_hash=1, ble_version=gw_ble_version, timeout=VER_UPDATE_TIMEOUT)
333
+
334
+ # for debug - print all logs to see failure reason
335
+ cert_common.get_gw_logs_packets(test, print_log=True)
336
+ if test.rc == TEST_FAILED and test.exit_on_param_failure:
337
+ return test
338
+ elif search_ack:
339
+ test = cert_common.gw_logs_search(test, ota_updates)
340
+ if test.rc == TEST_FAILED and test.exit_on_param_failure:
341
+ return test
342
+ test = cert_common.gw_action_status_search(test, ag.BRG_MGMT_MSG_TYPE_OTA_UPDATE, 0)
343
+ if test.rc == TEST_FAILED and test.exit_on_param_failure:
344
+ return test
345
+ else:
346
+ test.add_reason(WANTED_VER_SAME)
347
+ test.active_brg.version = gw_ble_version
348
+ test.active_brg.update_modules()
349
+ return test
350
+
351
+ def update_versions(test, versions, update_gw=True, update_brg=True):
352
+ #update gw versions
353
+ if update_gw:
354
+ config_gw_version(test, versions)
355
+ # Search for update packet
356
+ start_time = datetime.datetime.now()
357
+ found = {BLE_VERSION: False, WIFI_VERSION: False}
358
+ # First pkt received is GW "cfg ack"
359
+ tries = 0
360
+ while not all([found[version] for version in found]):
361
+ for p in test.mqttc._userdata["pkts"].status:
362
+ if GW_CONF in p.body or GW_STATUS in p.body:
363
+ print("\nConfig pkts:")
364
+ print_pkt(p.body)
365
+ bkv = BLE_VERSION.replace('Chip', '') if test.protobuf else BLE_VERSION
366
+ wkv = WIFI_VERSION.replace('Chip', '') if test.protobuf else WIFI_VERSION
367
+ ckv = GW_STATUS if test.protobuf else GW_CONF
368
+ if p.body[ckv][bkv] == versions[BLE_VERSION]:
369
+ found[BLE_VERSION] = True
370
+ if p.body[ckv][wkv] == versions[WIFI_VERSION]:
371
+ found[WIFI_VERSION] = True
372
+ if not all([found[version] for version in found]):
373
+ # WIFI configured, need to configure again for BLE
374
+ if tries > 0:
375
+ # First pkt received is GW "cfg ack"
376
+ print(f"\nVersions Update Status:\n{found}\nTries: {tries}\nUpdate Time: {(datetime.datetime.now() - start_time).seconds} seconds")
377
+ config_gw_version(test, versions)
378
+ tries += 1
379
+ test.mqttc.flush_pkts()
380
+ print_update_wait()
381
+ if (datetime.datetime.now() - start_time).seconds > VER_UPDATE_TIMEOUT:
382
+ test.rc = TEST_FAILED
383
+ failed_versions = " & ".join([f"{k}={v}" for k,v in versions.items() if not found[k]])
384
+ test.add_reason(f"{failed_versions} not found after {VER_UPDATE_TIMEOUT} seconds in {tries} tries!")
385
+ print(f"\n{test.reason}")
386
+ break
387
+ cert_common.wait_time_n_print(10)
388
+ if not test.rc:
389
+ if update_gw:
390
+ print(f"\nGW versions updated successfully in {tries if tries > 0 else 1} tries!\n")
391
+ # update brg version if test is not an internal_brg test
392
+ if update_brg and not test.internal_brg:
393
+ test = brg_ota(test, gw_ble_version=versions[BLE_VERSION], search_ack=False)
394
+
395
+ return test
@@ -0,0 +1,188 @@
1
+ # from http import client
2
+ import time
3
+ import os
4
+ import json
5
+ from brg_certificate.cert_prints import *
6
+ from brg_certificate.cert_defines import *
7
+ from brg_certificate.wlt_types import *
8
+ import brg_certificate.cert_protobuf as cert_protobuf
9
+ import threading
10
+
11
+ # gw_sim defines
12
+ TAG_ID_OFFSET = -16
13
+ TAG_ID_FROM_ADVA_LENGTH = 8
14
+ TAG_ID_FROM_ADVA_OFFSET = 2
15
+ HDR_BLE5_DEFAULT_PKT_SIZE = 0x26
16
+ PIXEL_SIM_INDICATOR = "ABCDEF"
17
+ PIXEL_SIM_MIN_CYCLE = 20 # 20 is the CYCLE_PERIOD_MS_DEFAULT
18
+
19
+ def init_adva(flow_version_major=0x4, flow_version_minor=0x34):
20
+ return "{0:02X}".format(flow_version_major) + os.urandom(4).hex().upper() + "{0:02X}".format(flow_version_minor)
21
+
22
+ random_bytes = lambda n: int.from_bytes(os.urandom(n), "big")
23
+
24
+ def write_to_data_sim_log_file(txt):
25
+ f = open(os.path.join(BASE_DIR, DATA_SIM_LOG_FILE), "a")
26
+ f.write(txt)
27
+ f.close()
28
+
29
+ class WiliotPixelGen2:
30
+ """Represents 1 Wiliot Gen2 BLE4 Pixel"""
31
+ def __init__(self, pixel_sim_indicator=PIXEL_SIM_INDICATOR):
32
+ self.adva = init_adva(flow_version_major=0x4, flow_version_minor=0x34)
33
+ self.hdr = ag.DataHdr(uuid_msb=ag.HDR_DEFAULT_TAG_UUID_MSB, uuid_lsb=ag.HDR_DEFAULT_TAG_UUID_LSB, group_id_minor=0x0300)
34
+ self.pixel_sim_indicator = pixel_sim_indicator
35
+ self.payload0 = "010203040506070809"
36
+ self.payload1 = "0A0B0C0D"
37
+ self.pkt_id = 0
38
+
39
+ def __repr__(self) -> str:
40
+ return f'TagID: {self.get_tag_id()} PktID: {self.get_pkt_id()} PktType: {self.hdr.pkt_type} RawPkt: {self.get_pkt()}'
41
+
42
+ def get_tag_id(self):
43
+ return self.adva[TAG_ID_FROM_ADVA_OFFSET:TAG_ID_FROM_ADVA_OFFSET + TAG_ID_FROM_ADVA_LENGTH]
44
+
45
+ def set_pkt_type(self, pkt_type):
46
+ assert pkt_type in [0, 1, 2], "Packet type Must be 0, 1 or 2!"
47
+ self.hdr.pkt_type = pkt_type
48
+
49
+ def randomize_pkt_id(self):
50
+ self.pkt_id = random_bytes(4)
51
+
52
+ def randomize_payload1(self):
53
+ self.payload1 = f"{random_bytes(4):08X}"
54
+
55
+ def get_pkt_id(self):
56
+ return "{0:08X}".format(self.pkt_id)
57
+
58
+ def get_pkt(self):
59
+ """Get current packet from generator (hex string)
60
+ adva-6 hdr-7 sim_indicator-3 payload-13 tag_id-4 pkt_id-4 """
61
+ return self.adva + self.hdr.dump() + self.get_pkt_id() + self.pixel_sim_indicator + self.payload0 + self.get_tag_id() + self.payload1
62
+
63
+ class WiliotPixelGen3:
64
+ """Represents 1 Wiliot Gen3 BLE4 Pixel"""
65
+ def __init__(self, pixel_sim_indicator=PIXEL_SIM_INDICATOR):
66
+ self.adva = init_adva(flow_version_major=0x6, flow_version_minor=0x34) # 0x6 is the flow version for Gen3 (GEN3_FLOW_VER_MAJOR_MIN_VAL)
67
+ self.hdr = ag.DataHdr(uuid_msb=ag.HDR_DEFAULT_TAG_UUID_MSB, uuid_lsb=ag.HDR_DEFAULT_TAG_UUID_LSB, group_id_minor=0x0500)
68
+ self.pixel_sim_indicator = pixel_sim_indicator
69
+ self.payload0 = "010203040506070809"
70
+ self.payload1 = "0A0B0C0D"
71
+ self.pkt_id = 0
72
+
73
+ def __repr__(self) -> str:
74
+ return f'TagID: {self.get_tag_id()} PktID: {self.get_pkt_id()} PktType: {self.hdr.pkt_type} RawPkt: {self.get_pkt()}'
75
+
76
+ def get_tag_id(self):
77
+ return self.adva[TAG_ID_FROM_ADVA_OFFSET:TAG_ID_FROM_ADVA_OFFSET + TAG_ID_FROM_ADVA_LENGTH]
78
+
79
+ def set_pkt_type(self, pkt_type):
80
+ assert pkt_type in [0, 1], "Packet type Must be 0 or 1!"
81
+ self.hdr.pkt_type = pkt_type
82
+
83
+ def randomize_pkt_id(self):
84
+ self.pkt_id = random_bytes(4)
85
+
86
+ def randomize_payload1(self):
87
+ self.payload1 = f"{random_bytes(4):08X}"
88
+
89
+ def get_pkt_id(self):
90
+ return "{0:08X}".format(self.pkt_id)
91
+
92
+ def get_pkt(self):
93
+ """Get current packet from generator (hex string)
94
+ adva-6 hdr-7 nonce/pkt_id-4 sim_indicator-3 payload0-9 tag_id-4 payload1-4 """
95
+ return self.adva + self.hdr.dump() + self.get_pkt_id() + self.pixel_sim_indicator + self.payload0 + self.get_tag_id() + self.payload1
96
+ class WiliotPixelGen3Extended:
97
+ """Represents 1 Wiliot Gen3 BLE4 Pixel"""
98
+ def __init__(self, pixel_sim_indicator=PIXEL_SIM_INDICATOR):
99
+ self.adi = '0000'
100
+ self.adva = init_adva(flow_version_major=0x6, flow_version_minor=0x34) # 0x6 is the flow version for Gen3 (GEN3_FLOW_VER_MAJOR_MIN_VAL)
101
+ self.hdr = ag.DataHdr(pkt_size=HDR_BLE5_DEFAULT_PKT_SIZE, uuid_msb=ag.HDR_DEFAULT_TAG_UUID_MSB, uuid_lsb=ag.HDR_DEFAULT_TAG_UUID_LSB, group_id_minor=0x0500)
102
+ self.uid = "010203040506" # 6 bytes UID
103
+ self.mic = pixel_sim_indicator + pixel_sim_indicator # 6 bytes MIC (mico and mic1 are set to the sim indicator)
104
+ self.payload0 = self.get_tag_id() + f"{random_bytes(4):08X}" # 8 bytes payload. We will use first 4 bytes for the tag_id to keep the same location as in Gen2 and Gen3 BLE4
105
+ self.payload1 = self.get_tag_id() + f"{random_bytes(4):08X}" # 8 bytes payload. We will use first 4 bytes for the tag_id to keep the same location as in Gen2 and Gen3 BLE4
106
+ self.pkt_id = 0
107
+
108
+ def __repr__(self) -> str:
109
+ return f'TagID: {self.get_tag_id()} PktID: {self.get_pkt_id()} RawPkt: {self.get_pkt()}'
110
+
111
+ def get_tag_id(self):
112
+ return self.adva[TAG_ID_FROM_ADVA_OFFSET:TAG_ID_FROM_ADVA_OFFSET + TAG_ID_FROM_ADVA_LENGTH]
113
+
114
+ def set_pkt_type(self, pkt_type):
115
+ assert pkt_type in [2, 3], "Packet type Must be 2 or 3!"
116
+ self.hdr.pkt_type = pkt_type
117
+
118
+ def randomize_pkt_id(self):
119
+ self.pkt_id = random_bytes(4)
120
+
121
+ def get_pkt_id(self):
122
+ return "{0:08X}".format(self.pkt_id)
123
+
124
+ def get_pkt(self):
125
+ """ Get current packet from generator (hex string) - 47 bytes
126
+ adva-6 adi-2 hdr-7 nonce/pkt_id-4 uid-6 mic-6 payload0-8 payload1-8 """
127
+ return self.adva + self.adi + self.hdr.dump() + self.get_pkt_id() + self.uid + self.mic + self.payload0 + self.payload1
128
+
129
+ class DataSimThread(threading.Thread):
130
+ def __init__(self, test, num_of_pixels, duplicates, delay, pkt_types, pixels_type=GEN2):
131
+ super().__init__()
132
+ self.test = test
133
+ self.num_of_pixels = num_of_pixels
134
+ # Create pixels list
135
+ if pixels_type == GEN2:
136
+ self.pixels = [WiliotPixelGen2() for _ in range(self.num_of_pixels)]
137
+ elif pixels_type == GEN3:
138
+ self.pixels = [WiliotPixelGen3() for _ in range(self.num_of_pixels)]
139
+ elif pixels_type == GEN3_EXTENDED:
140
+ self.pixels = [WiliotPixelGen3Extended() for _ in range(self.num_of_pixels)]
141
+ else:
142
+ print(f"Didn't define pixels type")
143
+ self.duplicates = duplicates
144
+ self.delay = delay
145
+ self.pkt_types = pkt_types
146
+ self._stop_event = threading.Event()
147
+ self.daemon = True
148
+
149
+ def run(self):
150
+ write_to_data_sim_log_file(f"num_of_pixels={self.num_of_pixels} duplicates={self.duplicates} delay={self.delay} pkt_types={self.pkt_types}\n")
151
+ # Run pixel_sim loop
152
+ while not self._stop_event.is_set():
153
+ for i in range(self.num_of_pixels):
154
+ for pkt_type in self.pkt_types:
155
+ pkt = self.pixels[i]
156
+ pkt.set_pkt_type(pkt_type)
157
+ # Set pkt_id, in Gen3 pkt_type_1 has pkt_id_0+1
158
+ if type(pkt) == WiliotPixelGen3:
159
+ if pkt_type == 1:
160
+ if self.pkt_types == [0,1]:
161
+ pkt.pkt_id += 1
162
+ else:
163
+ pkt.randomize_pkt_id()
164
+ pkt.randomize_payload1() # In the FW we assume data is random at the place gen2 pkt id was (4 last bytes)
165
+ else:
166
+ # pkt type 0
167
+ pkt.randomize_pkt_id()
168
+ pkt.randomize_payload1() # In the FW we assume data is random at the 4 last bytes
169
+ else:
170
+ pkt.randomize_pkt_id()
171
+ if type(pkt) == WiliotPixelGen2:
172
+ pkt.randomize_payload1() # In the FW we assume data is random at the 4 last bytes
173
+ # Publish pkt to MQTT
174
+ msg = {TX_PKT: pkt.get_pkt(),
175
+ TX_MAX_RETRIES: self.duplicates,
176
+ TX_MAX_DURATION_MS: 100,
177
+ ACTION: 0}
178
+ if self.test.protobuf == True:
179
+ payload = cert_protobuf.downlink_to_pb(msg)
180
+ else:
181
+ payload = json.dumps(msg)
182
+ self.test.mqttc.publish(self.test.mqttc.update_topic, payload=payload)
183
+ write_to_data_sim_log_file(f"{pkt}" + " {}\n".format(datetime.datetime.now().strftime("%d/%m,%H:%M:%S.%f")[:-4]))
184
+ actual_delay = max(self.delay, self.duplicates*(PIXEL_SIM_MIN_CYCLE))
185
+ time.sleep(actual_delay/1000)
186
+
187
+ def stop(self):
188
+ self._stop_event.set()