wiliot-certificate 4.4.2__py3-none-any.whl → 4.5.0__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.
- {brg_certificate → certificate}/ag/wlt_cmd_if.html +10 -4
- {brg_certificate → certificate}/ag/wlt_types_ag.py +1878 -519
- certificate/cert_common.py +1488 -0
- certificate/cert_config.py +480 -0
- {brg_certificate → certificate}/cert_data_sim.py +134 -46
- {brg_certificate → certificate}/cert_defines.py +129 -128
- {brg_certificate → certificate}/cert_gw_sim.py +183 -53
- {brg_certificate → certificate}/cert_mqtt.py +179 -64
- {brg_certificate → certificate}/cert_prints.py +35 -33
- {brg_certificate → certificate}/cert_protobuf.py +15 -6
- {brg_certificate → certificate}/cert_results.py +240 -64
- certificate/cert_utils.py +634 -0
- certificate/certificate.py +205 -0
- certificate/certificate_cli.py +76 -0
- certificate/certificate_eth_test_list.txt +76 -0
- certificate/certificate_sanity_test_list.txt +66 -0
- certificate/certificate_test_list.txt +76 -0
- {brg_certificate → certificate}/tests/calibration/interval_test/interval_test.json +3 -2
- {brg_certificate → certificate}/tests/calibration/interval_test/interval_test.py +7 -6
- certificate/tests/calibration/output_power_test/output_power_test.json +23 -0
- certificate/tests/calibration/output_power_test/output_power_test.py +39 -0
- {brg_certificate → certificate}/tests/calibration/pattern_test/pattern_test.json +2 -1
- {brg_certificate → certificate}/tests/calibration/pattern_test/pattern_test.py +20 -15
- certificate/tests/cloud_connectivity/acl_ext_adv_test/acl_ext_adv_test.json +15 -0
- certificate/tests/cloud_connectivity/acl_ext_adv_test/acl_ext_adv_test.py +140 -0
- certificate/tests/cloud_connectivity/acl_test/acl_test.json +15 -0
- certificate/tests/cloud_connectivity/acl_test/acl_test.py +96 -0
- certificate/tests/cloud_connectivity/brg_ota_test/brg_ota_test.json +19 -0
- certificate/tests/cloud_connectivity/brg_ota_test/brg_ota_test.py +41 -0
- certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.json +19 -0
- certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.py +215 -0
- certificate/tests/cloud_connectivity/connection_test/connection_test.json +18 -0
- certificate/tests/cloud_connectivity/connection_test/connection_test.py +67 -0
- certificate/tests/cloud_connectivity/deduplication_test/deduplication_test.json +15 -0
- certificate/tests/cloud_connectivity/deduplication_test/deduplication_test.py +80 -0
- certificate/tests/cloud_connectivity/downlink_test/downlink_test.json +21 -0
- certificate/tests/cloud_connectivity/downlink_test/downlink_test.py +201 -0
- certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.json +17 -0
- certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.py +104 -0
- certificate/tests/cloud_connectivity/reboot_test/reboot_test.json +18 -0
- certificate/tests/cloud_connectivity/reboot_test/reboot_test.py +59 -0
- certificate/tests/cloud_connectivity/registration_test/registration_test.json +20 -0
- certificate/tests/cloud_connectivity/registration_test/registration_test.py +384 -0
- certificate/tests/cloud_connectivity/registration_test/registration_test_cli.py +90 -0
- certificate/tests/cloud_connectivity/stress_test/stress_test.json +17 -0
- certificate/tests/cloud_connectivity/stress_test/stress_test.py +101 -0
- certificate/tests/cloud_connectivity/uplink_ext_adv_test/uplink_ext_adv_test.json +25 -0
- certificate/tests/cloud_connectivity/uplink_ext_adv_test/uplink_ext_adv_test.py +92 -0
- certificate/tests/cloud_connectivity/uplink_test/uplink_test.json +20 -0
- certificate/tests/cloud_connectivity/uplink_test/uplink_test.py +169 -0
- {brg_certificate → certificate}/tests/datapath/aging_test/aging_test.json +2 -1
- certificate/tests/datapath/aging_test/aging_test.py +142 -0
- certificate/tests/datapath/event_ble5_test/event_ble5_test.json +17 -0
- certificate/tests/datapath/event_ble5_test/event_ble5_test.py +89 -0
- certificate/tests/datapath/event_test/event_test.json +17 -0
- certificate/tests/datapath/event_test/event_test.py +80 -0
- {brg_certificate → certificate}/tests/datapath/num_of_tags_test/num_of_tags_test.json +4 -3
- {brg_certificate → certificate}/tests/datapath/num_of_tags_test/num_of_tags_test.py +19 -13
- certificate/tests/datapath/output_power_test/output_power_test.json +23 -0
- {brg_certificate → certificate}/tests/datapath/output_power_test/output_power_test.py +17 -6
- {brg_certificate → certificate}/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.json +2 -1
- {brg_certificate → certificate}/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.py +13 -11
- {brg_certificate → certificate}/tests/datapath/pacer_interval_test/pacer_interval_test.json +2 -1
- {brg_certificate → certificate}/tests/datapath/pacer_interval_test/pacer_interval_test.py +9 -7
- {brg_certificate → certificate}/tests/datapath/pattern_test/pattern_test.json +3 -2
- {brg_certificate → certificate}/tests/datapath/pattern_test/pattern_test.py +18 -6
- certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.json +20 -0
- certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.py +61 -0
- {brg_certificate → certificate}/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.json +2 -1
- {brg_certificate → certificate}/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.py +15 -14
- certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.json +19 -0
- certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.py +85 -0
- {brg_certificate → certificate}/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.json +2 -1
- {brg_certificate → certificate}/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.py +10 -9
- {brg_certificate → certificate}/tests/datapath/pkt_filter_test/pkt_filter_test.json +2 -1
- {brg_certificate → certificate}/tests/datapath/pkt_filter_test/pkt_filter_test.py +10 -9
- {brg_certificate → certificate}/tests/datapath/rssi_threshold_test/rssi_threshold_test.json +3 -2
- {brg_certificate → certificate}/tests/datapath/rssi_threshold_test/rssi_threshold_test.py +9 -8
- brg_certificate/tests/datapath/output_power_test/output_power_test.json → certificate/tests/datapath/rx_channel_hopping_test/rx_channel_hopping_test.json +6 -4
- certificate/tests/datapath/rx_channel_hopping_test/rx_channel_hopping_test.py +77 -0
- {brg_certificate → certificate}/tests/datapath/rx_channel_test/rx_channel_test.json +3 -2
- {brg_certificate → certificate}/tests/datapath/rx_channel_test/rx_channel_test.py +7 -6
- {brg_certificate → certificate}/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.json +8 -7
- {brg_certificate → certificate}/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.py +113 -73
- {brg_certificate → certificate}/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.json +8 -7
- {brg_certificate → certificate}/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.py +112 -72
- {brg_certificate → certificate}/tests/datapath/stress_gen3_test/stress_gen3_test.json +4 -3
- {brg_certificate → certificate}/tests/datapath/stress_gen3_test/stress_gen3_test.py +15 -11
- {brg_certificate → certificate}/tests/datapath/stress_test/stress_test.json +4 -3
- {brg_certificate → certificate}/tests/datapath/stress_test/stress_test.py +15 -11
- {brg_certificate → certificate}/tests/datapath/tx_repetition_test/tx_repetition_test.json +3 -1
- {brg_certificate → certificate}/tests/datapath/tx_repetition_test/tx_repetition_test.py +14 -13
- certificate/tests/edge_mgmt/action_blink_test/action_blink_test.json +15 -0
- certificate/tests/edge_mgmt/action_blink_test/action_blink_test.py +24 -0
- certificate/tests/edge_mgmt/action_get_battery_sensor_test/action_get_battery_sensor_test.json +15 -0
- certificate/tests/edge_mgmt/action_get_battery_sensor_test/action_get_battery_sensor_test.py +43 -0
- certificate/tests/edge_mgmt/action_get_module_test/action_get_module_test.json +15 -0
- certificate/tests/edge_mgmt/action_get_module_test/action_get_module_test.py +42 -0
- certificate/tests/edge_mgmt/action_get_pof_data_test/action_get_pof_data_test.json +15 -0
- certificate/tests/edge_mgmt/action_get_pof_data_test/action_get_pof_data_test.py +44 -0
- certificate/tests/edge_mgmt/action_gw_hb_test/action_gw_hb_test.json +16 -0
- certificate/tests/edge_mgmt/action_gw_hb_test/action_gw_hb_test.py +42 -0
- certificate/tests/edge_mgmt/action_reboot_test/action_reboot_test.json +15 -0
- certificate/tests/edge_mgmt/action_reboot_test/action_reboot_test.py +49 -0
- certificate/tests/edge_mgmt/action_restore_defaults_test/action_restore_defaults_test.json +15 -0
- certificate/tests/edge_mgmt/action_restore_defaults_test/action_restore_defaults_test.py +102 -0
- certificate/tests/edge_mgmt/action_send_hb_test/action_send_hb_test.json +15 -0
- certificate/tests/edge_mgmt/action_send_hb_test/action_send_hb_test.py +45 -0
- {brg_certificate → certificate}/tests/edge_mgmt/periodic_msgs_test/periodic_msgs_test.json +3 -2
- {brg_certificate → certificate}/tests/edge_mgmt/periodic_msgs_test/periodic_msgs_test.py +22 -11
- {brg_certificate → certificate}/tests/energy2400/duty_cycle_test/duty_cycle_test.json +2 -1
- {brg_certificate → certificate}/tests/energy2400/duty_cycle_test/duty_cycle_test.py +7 -6
- certificate/tests/energy2400/output_power_test/output_power_test.json +23 -0
- {brg_certificate → certificate}/tests/energy2400/output_power_test/output_power_test.py +17 -6
- {brg_certificate → certificate}/tests/energy2400/pattern_test/pattern_test.json +2 -1
- {brg_certificate → certificate}/tests/energy2400/pattern_test/pattern_test.py +7 -6
- certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.json +26 -0
- certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.py +379 -0
- certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.json +20 -0
- certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.py +173 -0
- certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.json +24 -0
- certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.py +350 -0
- {brg_certificate → certificate}/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.json +2 -1
- {brg_certificate → certificate}/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.py +7 -6
- {brg_certificate → certificate}/tests/energy_sub1g/pattern_test/pattern_test.json +2 -1
- {brg_certificate → certificate}/tests/energy_sub1g/pattern_test/pattern_test.py +7 -6
- {brg_certificate → certificate}/tests/pwr_mgmt/pwr_mgmt_test/pwr_mgmt_test.json +2 -1
- {brg_certificate → certificate}/tests/pwr_mgmt/pwr_mgmt_test/pwr_mgmt_test.py +10 -10
- {brg_certificate → certificate}/tests/sensors/ext_sensor_test/ext_sensor_test.json +5 -4
- certificate/tests/sensors/ext_sensor_test/ext_sensor_test.py +450 -0
- certificate/wlt_types.py +122 -0
- {gw_certificate → common}/api_if/202/status.json +6 -0
- {gw_certificate → common}/api_if/203/status.json +6 -0
- {gw_certificate → common}/api_if/204/status.json +6 -0
- common/api_if/206/data.json +85 -0
- common/api_if/206/status.json +69 -0
- common/api_if/api_validation.py +91 -0
- common/web/templates/generator.html +210 -0
- common/web/templates/index.html +20 -0
- common/web/templates/menu.html +54 -0
- common/web/templates/parser.html +53 -0
- {brg_certificate/ag → common/web/templates}/wlt_types.html +1216 -191
- common/web/web_utils.py +399 -0
- {brg_certificate → common}/wltPb_pb2.py +14 -12
- {gw_certificate/common → common}/wltPb_pb2.pyi +16 -2
- gui_certificate/gui_certificate_cli.py +14 -0
- gui_certificate/server.py +1267 -0
- gui_certificate/templates/cert_run.html +1273 -0
- wiliot_certificate-4.5.0.dist-info/METADATA +99 -0
- wiliot_certificate-4.5.0.dist-info/RECORD +168 -0
- {wiliot_certificate-4.4.2.dist-info → wiliot_certificate-4.5.0.dist-info}/WHEEL +1 -1
- wiliot_certificate-4.5.0.dist-info/entry_points.txt +5 -0
- wiliot_certificate-4.5.0.dist-info/top_level.txt +3 -0
- brg_certificate/ag/energous_v0_defines.py +0 -925
- brg_certificate/ag/energous_v1_defines.py +0 -931
- brg_certificate/ag/energous_v2_defines.py +0 -925
- brg_certificate/ag/energous_v3_defines.py +0 -925
- brg_certificate/ag/energous_v4_defines.py +0 -925
- brg_certificate/ag/fanstel_lan_v0_defines.py +0 -925
- brg_certificate/ag/fanstel_lte_v0_defines.py +0 -925
- brg_certificate/ag/fanstel_wifi_v0_defines.py +0 -925
- brg_certificate/ag/minew_lte_v0_defines.py +0 -925
- brg_certificate/ag/wlt_types_ag_jsons/brg2brg_ota.json +0 -142
- brg_certificate/ag/wlt_types_ag_jsons/brg2gw_hb.json +0 -785
- brg_certificate/ag/wlt_types_ag_jsons/brg2gw_hb_sleep.json +0 -139
- brg_certificate/ag/wlt_types_ag_jsons/calibration.json +0 -394
- brg_certificate/ag/wlt_types_ag_jsons/custom.json +0 -515
- brg_certificate/ag/wlt_types_ag_jsons/datapath.json +0 -672
- brg_certificate/ag/wlt_types_ag_jsons/energy2400.json +0 -550
- brg_certificate/ag/wlt_types_ag_jsons/energySub1g.json +0 -595
- brg_certificate/ag/wlt_types_ag_jsons/externalSensor.json +0 -598
- brg_certificate/ag/wlt_types_ag_jsons/interface.json +0 -938
- brg_certificate/ag/wlt_types_ag_jsons/powerManagement.json +0 -1234
- brg_certificate/ag/wlt_types_ag_jsons/side_info_sensor.json +0 -105
- brg_certificate/ag/wlt_types_ag_jsons/signal_indicator_data.json +0 -77
- brg_certificate/ag/wlt_types_ag_jsons/unified_echo_ext_pkt.json +0 -61
- brg_certificate/ag/wlt_types_ag_jsons/unified_echo_pkt.json +0 -110
- brg_certificate/brg_certificate.py +0 -225
- brg_certificate/brg_certificate_cli.py +0 -63
- brg_certificate/cert_common.py +0 -923
- brg_certificate/cert_config.py +0 -402
- brg_certificate/cert_utils.py +0 -362
- brg_certificate/certificate_bcc_sanity_test_list.txt +0 -40
- brg_certificate/certificate_bcc_test_list.txt +0 -48
- brg_certificate/certificate_sanity_test_list.txt +0 -43
- brg_certificate/certificate_test_list.txt +0 -53
- brg_certificate/config/eclipse.json +0 -10
- brg_certificate/config/hivemq.json +0 -10
- brg_certificate/config/mosquitto.json +0 -10
- brg_certificate/config/mosquitto.md +0 -95
- brg_certificate/config/wiliot-dev.json +0 -10
- brg_certificate/restore_brg.py +0 -61
- brg_certificate/tests/calibration/output_power_test/output_power_test.json +0 -16
- brg_certificate/tests/calibration/output_power_test/output_power_test.py +0 -28
- brg_certificate/tests/datapath/aging_test/aging_test.py +0 -143
- brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.json +0 -16
- brg_certificate/tests/datapath/pacer_interval_tags_count_test/pacer_interval_tags_count_test.py +0 -73
- brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.json +0 -17
- brg_certificate/tests/datapath/tx_repetition_algo_test/tx_repetition_algo_test.py +0 -118
- brg_certificate/tests/edge_mgmt/actions_test/actions_test.json +0 -14
- brg_certificate/tests/edge_mgmt/actions_test/actions_test.py +0 -396
- brg_certificate/tests/edge_mgmt/brg2brg_ota_ble5_test/brg2brg_ota_ble5_test.json +0 -20
- brg_certificate/tests/edge_mgmt/brg2brg_ota_ble5_test/brg2brg_ota_ble5_test.py +0 -94
- brg_certificate/tests/edge_mgmt/brg2brg_ota_test/brg2brg_ota_test.json +0 -19
- brg_certificate/tests/edge_mgmt/brg2brg_ota_test/brg2brg_ota_test.py +0 -87
- brg_certificate/tests/edge_mgmt/leds_test/leds_test.json +0 -17
- brg_certificate/tests/edge_mgmt/leds_test/leds_test.py +0 -223
- brg_certificate/tests/edge_mgmt/ota_test/ota_test.json +0 -17
- brg_certificate/tests/edge_mgmt/ota_test/ota_test.py +0 -128
- brg_certificate/tests/energy2400/output_power_test/output_power_test.json +0 -16
- brg_certificate/tests/energy2400/signal_indicator_ble5_10_250k_test/signal_indicator_ble5_10_250k_test.json +0 -20
- brg_certificate/tests/energy2400/signal_indicator_ble5_10_250k_test/signal_indicator_ble5_10_250k_test.py +0 -321
- brg_certificate/tests/energy2400/signal_indicator_ble5_10_500k_test/signal_indicator_ble5_10_500k_test.json +0 -20
- brg_certificate/tests/energy2400/signal_indicator_ble5_10_500k_test/signal_indicator_ble5_10_500k_test.py +0 -321
- brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.json +0 -20
- brg_certificate/tests/energy2400/signal_indicator_sub1g_2_4_test/signal_indicator_sub1g_2_4_test.py +0 -141
- brg_certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.json +0 -20
- brg_certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.py +0 -276
- brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.json +0 -20
- brg_certificate/tests/energy_sub1g/signal_indicator_functionality_test/signal_indicator_functionality_test.py +0 -390
- brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.json +0 -16
- brg_certificate/tests/energy_sub1g/signal_indicator_test/signal_indicator_test.py +0 -28
- brg_certificate/tests/sensors/ext_sensor_test/ext_sensor_test.py +0 -305
- brg_certificate/wltPb_pb2.pyi +0 -234
- brg_certificate/wlt_types.py +0 -113
- gw_certificate/ag/ut_defines.py +0 -364
- gw_certificate/ag/wlt_types.py +0 -85
- gw_certificate/ag/wlt_types_ag.py +0 -5310
- gw_certificate/ag/wlt_types_data.py +0 -64
- gw_certificate/api/extended_api.py +0 -23
- gw_certificate/api_if/200/data.json +0 -106
- gw_certificate/api_if/200/status.json +0 -47
- gw_certificate/api_if/201/data.json +0 -98
- gw_certificate/api_if/201/status.json +0 -53
- gw_certificate/api_if/205/logs.json +0 -12
- gw_certificate/api_if/api_validation.py +0 -38
- gw_certificate/api_if/gw_capabilities.py +0 -54
- gw_certificate/cert_results.py +0 -145
- gw_certificate/common/analysis_data_bricks.py +0 -60
- gw_certificate/common/debug.py +0 -42
- gw_certificate/common/serialization_formatter.py +0 -93
- gw_certificate/common/utils.py +0 -8
- gw_certificate/common/utils_defines.py +0 -15
- gw_certificate/common/wltPb_pb2.py +0 -84
- gw_certificate/gw_certificate.py +0 -154
- gw_certificate/gw_certificate_cli.py +0 -87
- gw_certificate/interface/4.4.91_app.zip +0 -0
- gw_certificate/interface/4.4.91_sd_bl_app.zip +0 -0
- gw_certificate/interface/ble_simulator.py +0 -61
- gw_certificate/interface/ble_sniffer.py +0 -189
- gw_certificate/interface/flash_fw.py +0 -90
- gw_certificate/interface/if_defines.py +0 -36
- gw_certificate/interface/mqtt.py +0 -563
- gw_certificate/interface/nrfutil-linux +0 -0
- gw_certificate/interface/nrfutil-mac +0 -0
- gw_certificate/interface/nrfutil.exe +0 -0
- gw_certificate/interface/pkt_generator.py +0 -594
- gw_certificate/interface/uart_if.py +0 -236
- gw_certificate/interface/uart_ports.py +0 -20
- gw_certificate/templates/results.html +0 -241
- gw_certificate/templates/stage.html +0 -22
- gw_certificate/templates/table.html +0 -6
- gw_certificate/templates/test.html +0 -38
- gw_certificate/tests/__init__.py +0 -10
- gw_certificate/tests/actions.py +0 -289
- gw_certificate/tests/bad_crc_to_PER_quantization.csv +0 -51
- gw_certificate/tests/connection.py +0 -188
- gw_certificate/tests/downlink.py +0 -172
- gw_certificate/tests/generic.py +0 -238
- gw_certificate/tests/registration.py +0 -340
- gw_certificate/tests/static/__init__.py +0 -0
- gw_certificate/tests/static/connection_defines.py +0 -9
- gw_certificate/tests/static/downlink_defines.py +0 -9
- gw_certificate/tests/static/generated_packet_table.py +0 -195
- gw_certificate/tests/static/packet_table.csv +0 -10067
- gw_certificate/tests/static/references.py +0 -5
- gw_certificate/tests/static/uplink_defines.py +0 -14
- gw_certificate/tests/throughput.py +0 -240
- gw_certificate/tests/uplink.py +0 -853
- wiliot_certificate-4.4.2.dist-info/METADATA +0 -211
- wiliot_certificate-4.4.2.dist-info/RECORD +0 -210
- wiliot_certificate-4.4.2.dist-info/entry_points.txt +0 -3
- wiliot_certificate-4.4.2.dist-info/top_level.txt +0 -3
- {brg_certificate → certificate}/__init__.py +0 -0
- {gw_certificate → common}/api_if/202/data.json +0 -0
- {gw_certificate/api_if/200 → common/api_if/202}/logs.json +0 -0
- {gw_certificate → common}/api_if/203/data.json +0 -0
- {gw_certificate/api_if/201 → common/api_if/203}/logs.json +0 -0
- {gw_certificate → common}/api_if/204/data.json +0 -0
- {gw_certificate/api_if/202 → common/api_if/204}/logs.json +0 -0
- {gw_certificate → common}/api_if/205/data.json +0 -0
- {gw_certificate/api_if/203 → common/api_if/205}/logs.json +0 -0
- {gw_certificate → common}/api_if/205/status.json +0 -0
- {gw_certificate/api_if/204 → common/api_if/206}/logs.json +0 -0
- {gw_certificate → common/api_if}/__init__.py +0 -0
- {gw_certificate/api_if → gui_certificate}/__init__.py +0 -0
- {wiliot_certificate-4.4.2.dist-info → wiliot_certificate-4.5.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
from
|
|
2
|
-
from
|
|
3
|
-
from
|
|
4
|
-
import
|
|
5
|
-
import
|
|
1
|
+
from certificate.cert_prints import *
|
|
2
|
+
from certificate.cert_defines import *
|
|
3
|
+
from certificate.wlt_types import *
|
|
4
|
+
import certificate.cert_data_sim as cert_data_sim
|
|
5
|
+
import certificate.cert_mqtt as cert_mqtt
|
|
6
|
+
import certificate.cert_common as cert_common
|
|
7
|
+
import certificate.cert_config as cert_config
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
def run(test):
|
|
@@ -17,10 +19,13 @@ def run(test):
|
|
|
17
19
|
|
|
18
20
|
for param in test.params:
|
|
19
21
|
# A special verification for 38_38_39, which is irrelevant for bridge with cloud connectivity
|
|
20
|
-
if param.value == ag.CALIBRATION_PATTERN_38_38_39 and not
|
|
22
|
+
if param.value == ag.CALIBRATION_PATTERN_38_38_39 and not test.dut_is_combo():
|
|
21
23
|
utPrint("\nCALIBRATION_PATTERN_38_38_39 was configured - checking the GW doesn't receive tag packets", "BLUE")
|
|
22
|
-
# Config
|
|
23
|
-
test = cert_config.
|
|
24
|
+
# Config tester's rx_channel to CHANNEL_37
|
|
25
|
+
test = cert_config.brg_configure(test, fields=[BRG_RX_CHANNEL],
|
|
26
|
+
values=[ag.RX_CHANNEL_37],
|
|
27
|
+
module=test.tester.internal_brg.datapath,
|
|
28
|
+
target=TESTER)[0]
|
|
24
29
|
if test.rc != TEST_FAILED:
|
|
25
30
|
# Configure the BRG, wait=False
|
|
26
31
|
test = cert_config.brg_configure(test, fields=[BRG_PATTERN, BRG_CALIB_INTERVAL],
|
|
@@ -31,7 +36,7 @@ def run(test):
|
|
|
31
36
|
else:
|
|
32
37
|
test.reset_result() # reset result
|
|
33
38
|
continue # skip the current phase and continue to next param
|
|
34
|
-
|
|
39
|
+
wait_time_n_print(CLEAR_DATA_PATH_TIMEOUT)
|
|
35
40
|
# MQTT scan
|
|
36
41
|
if test.data == DATA_SIMULATION:
|
|
37
42
|
# start generating pkts and send them using data simulator
|
|
@@ -44,16 +49,16 @@ def run(test):
|
|
|
44
49
|
time.sleep(5)
|
|
45
50
|
|
|
46
51
|
# Analyze pass/fail
|
|
47
|
-
gw_tags_pkts = len(df.query('src_id ==
|
|
48
|
-
brg_tags_pkts = len(df.query('src_id !=
|
|
52
|
+
gw_tags_pkts = len(df.query(f'src_id == {GW_ID}'))
|
|
53
|
+
brg_tags_pkts = len(df.query(f'src_id != {GW_ID}'))
|
|
49
54
|
print(f"Found gw_tags_pkts={gw_tags_pkts}, brg_tags_pkts={brg_tags_pkts}")
|
|
50
55
|
if (gw_tags_pkts == 0 and test.data == DATA_REAL_TAGS) or brg_tags_pkts != 0:
|
|
51
56
|
test.rc = TEST_FAILED
|
|
52
57
|
test.add_reason(f"gw_tags_pkts={gw_tags_pkts} brg_tags_pkts={brg_tags_pkts} for BRG 38,38,39 calibration, "
|
|
53
58
|
"and GW scanning on ch 37")
|
|
54
|
-
# Revert
|
|
55
|
-
test = cert_config.
|
|
56
|
-
generate_log_file(test, param.name)
|
|
59
|
+
# Revert tester
|
|
60
|
+
test = cert_config.brg_configure(test, module=test.tester.internal_brg.datapath, target=TESTER)[0]
|
|
61
|
+
cert_mqtt.generate_log_file(test, param.name)
|
|
57
62
|
field_functionality_pass_fail_print(test, fields[0], value=param.name)
|
|
58
63
|
test.set_phase_rc(param.name, test.rc)
|
|
59
64
|
test.add_phase_reason(param.name, test.reason)
|
|
@@ -63,7 +68,7 @@ def run(test):
|
|
|
63
68
|
test.reset_result() # reset result and continue to next param
|
|
64
69
|
else:
|
|
65
70
|
test = cert_config.brg_configure(test, fields=fields, values=[param.value], module=calib_module)[0]
|
|
66
|
-
generate_log_file(test, param.name)
|
|
71
|
+
cert_mqtt.generate_log_file(test, param.name)
|
|
67
72
|
field_functionality_pass_fail_print(test, fields[0], value=param.name)
|
|
68
73
|
test.set_phase_rc(param.name, test.rc)
|
|
69
74
|
test.add_phase_reason(param.name, test.reason)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Access Control List using Extended Advertising",
|
|
3
|
+
"module": "Cloud Connectivity",
|
|
4
|
+
"purpose": "Test the access control list (ACL) functionality, configure allow list and deny list and test the behavior, while the Bridge is transmitting in extended advertising",
|
|
5
|
+
"documentation": "https://community.wiliot.com/customers/s/article/Wiliot-Network---Gateway-Extended-Advertising-Implementation",
|
|
6
|
+
"initialCondition": "Gateway configured to defaults",
|
|
7
|
+
"procedure": ["Test prolog", "configure the brg to be on the deny list", "configure the brg to be on the allow list", "Test epilog"],
|
|
8
|
+
"expectedOutcome": "For the deny list - no unified packets are found, for the allow list - unified packets are found",
|
|
9
|
+
"mandatory": 0,
|
|
10
|
+
"multiBridgeTest": 0,
|
|
11
|
+
"gwOnlyTest": 1,
|
|
12
|
+
"dataSimOnlyTest": 1,
|
|
13
|
+
"SupportedFromApiVersion": 206,
|
|
14
|
+
"allSupportedValues": ["deny", "allow"]
|
|
15
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
from certificate.cert_prints import *
|
|
2
|
+
from certificate.cert_defines import *
|
|
3
|
+
from certificate.wlt_types import *
|
|
4
|
+
import certificate.cert_mqtt as cert_mqtt
|
|
5
|
+
import certificate.cert_common as cert_common
|
|
6
|
+
import certificate.cert_config as cert_config
|
|
7
|
+
import certificate.cert_data_sim as cert_data_sim
|
|
8
|
+
from certificate.ag.wlt_types_ag import *
|
|
9
|
+
import certificate.cert_gw_sim as cert_gw_sim
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# DEFINES
|
|
13
|
+
DUPLICATES = 5
|
|
14
|
+
DELAY = 20
|
|
15
|
+
test_indicator = cert_data_sim.PIXEL_SIM_INDICATOR
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def generate_expected_pkts(acl_bridge_ids, non_acl_bridge_id, pixels_pkts, mgmt_pkts):
|
|
19
|
+
expected_pkts_allow, expected_pkts_deny = [], []
|
|
20
|
+
# This payload is hardcoded in !ble_sim_ext_adv when adding extra data packets after mgmt packets
|
|
21
|
+
extra_data_payload = "1E16C6FC000039019F8BB88B5EE6CB0F5760B70AA55C87A494776400000000" * 5
|
|
22
|
+
|
|
23
|
+
for pkt in pixels_pkts:
|
|
24
|
+
brg_id = cert_common.change_endianness(pkt.adva)
|
|
25
|
+
(expected_pkts_allow if brg_id in acl_bridge_ids else expected_pkts_deny).append(brg_id + pkt.payload * 7)
|
|
26
|
+
for pkt in mgmt_pkts:
|
|
27
|
+
brg_id = cert_common.change_endianness(pkt.adva)
|
|
28
|
+
if brg_id in acl_bridge_ids:
|
|
29
|
+
expected_pkts_allow.append(brg_id + pkt.payload * 2 + extra_data_payload)
|
|
30
|
+
expected_pkts_deny.append(brg_id + pkt.payload * 2)
|
|
31
|
+
elif brg_id == non_acl_bridge_id:
|
|
32
|
+
expected_pkts_allow.append(brg_id + pkt.payload * 2)
|
|
33
|
+
expected_pkts_deny.append(brg_id + pkt.payload * 2 + extra_data_payload)
|
|
34
|
+
return expected_pkts_allow, expected_pkts_deny
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def run(test):
|
|
38
|
+
|
|
39
|
+
test = cert_common.test_prolog(test)
|
|
40
|
+
if test.rc == TEST_FAILED:
|
|
41
|
+
return cert_common.test_epilog(test)
|
|
42
|
+
|
|
43
|
+
cert_config.gw_action(test, f'{cert_gw_sim.BLE_SIM_INIT} 1', TESTER)
|
|
44
|
+
|
|
45
|
+
# Generate management and data packets
|
|
46
|
+
pixels_pkts, bridge_ids = cert_data_sim.brg_pkt_gen(num_of_pkts_per_brg=100, num_of_brgs=4,
|
|
47
|
+
pkt_type=PIXELS_PKT, indicator=test_indicator)
|
|
48
|
+
mgmt_pkts, _ = cert_data_sim.brg_pkt_gen(num_of_pkts_per_brg=100, num_of_brgs=4, brgs_list=bridge_ids,
|
|
49
|
+
pkt_type=MGMT_PKT, indicator=test_indicator)
|
|
50
|
+
|
|
51
|
+
# Use first 3 bridges for ACL, 4th bridge is not in ACL
|
|
52
|
+
acl_bridge_ids = bridge_ids[:3]
|
|
53
|
+
non_acl_bridge_id = bridge_ids[3]
|
|
54
|
+
|
|
55
|
+
expected_pkts_allow, expected_pkts_deny = generate_expected_pkts(acl_bridge_ids, non_acl_bridge_id, pixels_pkts, mgmt_pkts)
|
|
56
|
+
|
|
57
|
+
for param in test.params:
|
|
58
|
+
phase_run_print(f"ACL Extended Advertising Test - Mode: {param.value}")
|
|
59
|
+
|
|
60
|
+
cfg = cert_config.get_default_gw_dict(test)
|
|
61
|
+
cfg[ACL][ACL_BRIDGE_IDS] = acl_bridge_ids
|
|
62
|
+
cfg[ACL][ACL_MODE] = param.value
|
|
63
|
+
test, ret = cert_config.gw_configure(test, cfg=cfg, wait=True)
|
|
64
|
+
print_update_wait(1)
|
|
65
|
+
|
|
66
|
+
test.get_mqttc_by_target(DUT).flush_pkts()
|
|
67
|
+
|
|
68
|
+
# We provide the tester with the first pkt only. It concatenates the packets to an aggregated packet.
|
|
69
|
+
for pkt in mgmt_pkts:
|
|
70
|
+
# Here the aggregated packet is 2 mgmt pkts and 5 hardcoded data pkts
|
|
71
|
+
cert_config.gw_action(test, f'{cert_gw_sim.BLE_SIM_EXT_ADV} {pkt.get_pkt()} {DUPLICATES} '
|
|
72
|
+
f'{OUTPUT_POWER_2_4_MAX} {DELAY} {1} {1}', TESTER)
|
|
73
|
+
print_update_wait(0.1)
|
|
74
|
+
for pkt in pixels_pkts:
|
|
75
|
+
cert_config.gw_action(test, f'{cert_gw_sim.BLE_SIM_EXT_ADV} {pkt.get_pkt()} {DUPLICATES} '
|
|
76
|
+
f'{OUTPUT_POWER_2_4_MAX} {DELAY}', TESTER)
|
|
77
|
+
print_update_wait(0.1)
|
|
78
|
+
print_update_wait(1)
|
|
79
|
+
|
|
80
|
+
cert_mqtt.dump_pkts(test, log=param.name)
|
|
81
|
+
|
|
82
|
+
# Analyze pass/fail
|
|
83
|
+
# Get all received aggregated packets with the test indicator
|
|
84
|
+
received_pkts = cert_mqtt.get_all_aggregated_data_pkts(test.get_mqttc_by_target(DUT), indicator=test_indicator)
|
|
85
|
+
|
|
86
|
+
# Validate that received packets match expected packets
|
|
87
|
+
expected_pkts = set(expected_pkts_deny if param.value == ACL_DENY else expected_pkts_allow)
|
|
88
|
+
for p in received_pkts:
|
|
89
|
+
pkt = p[ALIAS_BRIDGE_ID] + p[AGGREGATED_PAYLOAD]
|
|
90
|
+
if pkt not in expected_pkts:
|
|
91
|
+
test.rc = TEST_FAILED
|
|
92
|
+
test.add_reason(f"Phase failed! Received unexpected packet from brg {p[ALIAS_BRIDGE_ID]} in {param.value} mode")
|
|
93
|
+
break
|
|
94
|
+
|
|
95
|
+
# Filter packets by bridge IDs in ACL list
|
|
96
|
+
received_data_pkts = [pkt for pkt in received_pkts if MGMT_PKT not in pkt]
|
|
97
|
+
acl_bridge_pkts = [pkt for pkt in received_data_pkts if pkt[ALIAS_BRIDGE_ID] in acl_bridge_ids]
|
|
98
|
+
non_acl_bridge_pkts = [pkt for pkt in received_data_pkts if pkt[ALIAS_BRIDGE_ID] == non_acl_bridge_id]
|
|
99
|
+
|
|
100
|
+
# In deny mode - we want to make sure bridges in ACL list are filtered
|
|
101
|
+
if param.value == ACL_DENY:
|
|
102
|
+
if len(non_acl_bridge_pkts) == 0:
|
|
103
|
+
test.rc = TEST_FAILED
|
|
104
|
+
test.add_reason(f"Phase failed! Bridge {non_acl_bridge_id} was not in the deny list "
|
|
105
|
+
f"and packets were not found from it")
|
|
106
|
+
if len(acl_bridge_pkts) != 0:
|
|
107
|
+
test.rc = TEST_FAILED
|
|
108
|
+
test.add_reason("Phase failed! Received packets from bridges that were on the deny list")
|
|
109
|
+
|
|
110
|
+
# In allow mode - we want to make sure only bridges in ACL list are not filtered
|
|
111
|
+
if param.value == ACL_ALLOW:
|
|
112
|
+
if len(non_acl_bridge_pkts) != 0:
|
|
113
|
+
test.rc = TEST_FAILED
|
|
114
|
+
test.add_reason(f"Phase failed! Bridge {non_acl_bridge_id} was not on the allow list "
|
|
115
|
+
f"and {len(non_acl_bridge_pkts)} packets were found from it")
|
|
116
|
+
# Check that we received packets from all expected bridges
|
|
117
|
+
received_bridge_ids = set([pkt[ALIAS_BRIDGE_ID] for pkt in acl_bridge_pkts])
|
|
118
|
+
if received_bridge_ids != set(acl_bridge_ids):
|
|
119
|
+
test.rc = TEST_FAILED
|
|
120
|
+
test.add_reason("Phase failed! Didn't receive packets from all bridges that were on the allow list")
|
|
121
|
+
|
|
122
|
+
# Check that management packets are received from all bridges (ACL doesn't filter mgmt packets)
|
|
123
|
+
all_mgmt_pkts = cert_mqtt.get_all_mgmt_pkts(test.get_mqttc_by_target(DUT), indicator=test_indicator)
|
|
124
|
+
mgmt_bridge_ids = set([pkt[ALIAS_BRIDGE_ID] for pkt in all_mgmt_pkts])
|
|
125
|
+
if not set(bridge_ids).issubset(mgmt_bridge_ids):
|
|
126
|
+
test.rc = TEST_FAILED
|
|
127
|
+
missing_bridges = set(bridge_ids) - mgmt_bridge_ids
|
|
128
|
+
test.add_reason(f"Phase failed! Expected management packets from all bridges, "
|
|
129
|
+
f"whether they are on the ACL or not, but missing from BRG {missing_bridges}")
|
|
130
|
+
|
|
131
|
+
field_functionality_pass_fail_print(test, "ACL", value=param.value)
|
|
132
|
+
test.set_phase_rc(param.name, test.rc)
|
|
133
|
+
test.add_phase_reason(param.name, test.reason)
|
|
134
|
+
if test.rc == TEST_FAILED and test.exit_on_param_failure:
|
|
135
|
+
break
|
|
136
|
+
else:
|
|
137
|
+
test.reset_result()
|
|
138
|
+
|
|
139
|
+
cert_config.gw_action(test, f'{cert_gw_sim.BLE_SIM_INIT} 0', TESTER)
|
|
140
|
+
return cert_common.test_epilog(test, revert_gws=True)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Access Control List",
|
|
3
|
+
"module": "Cloud Connectivity",
|
|
4
|
+
"purpose": "Test the access control list (ACL) functionality, configure allow list and deny list and test the behavior",
|
|
5
|
+
"documentation": "https://community.wiliot.com/customers/s/article/Access-Control-List",
|
|
6
|
+
"initialCondition": "Gateway configured to defaults",
|
|
7
|
+
"procedure": ["Test prolog", "configure the brg to be on the deny list", "configure the brg to be on the allow list", "Test epilog"],
|
|
8
|
+
"expectedOutcome": "For the deny list - no unified packets are found, for the allow list - unified packets are found",
|
|
9
|
+
"mandatory": 0,
|
|
10
|
+
"multiBridgeTest": 0,
|
|
11
|
+
"gwOnlyTest": 1,
|
|
12
|
+
"dataSimOnlyTest": 1,
|
|
13
|
+
"SupportedFromApiVersion": 205,
|
|
14
|
+
"allSupportedValues": ["deny", "allow"]
|
|
15
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from certificate.cert_prints import *
|
|
2
|
+
from certificate.cert_defines import *
|
|
3
|
+
from certificate.wlt_types import *
|
|
4
|
+
import certificate.cert_mqtt as cert_mqtt
|
|
5
|
+
import certificate.cert_common as cert_common
|
|
6
|
+
import certificate.cert_config as cert_config
|
|
7
|
+
import certificate.cert_data_sim as cert_data_sim
|
|
8
|
+
from certificate.ag.wlt_types_ag import *
|
|
9
|
+
|
|
10
|
+
SCAN_TIMEOUT = 30
|
|
11
|
+
NUM_OF_BRGS = 4
|
|
12
|
+
# DEFINES
|
|
13
|
+
test_indicator = cert_data_sim.PIXEL_SIM_INDICATOR
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def run(test):
|
|
17
|
+
|
|
18
|
+
test = cert_common.test_prolog(test)
|
|
19
|
+
if test.rc == TEST_FAILED:
|
|
20
|
+
return cert_common.test_epilog(test)
|
|
21
|
+
|
|
22
|
+
# Generate management and data packets
|
|
23
|
+
bridge_ids = [cert_common.hex2alias_id_get(get_random_hex_str(12)) for _ in range(NUM_OF_BRGS)]
|
|
24
|
+
pixels_pkts, _ = cert_data_sim.brg_pkt_gen(num_of_pkts_per_brg=20, num_of_brgs=NUM_OF_BRGS, brgs_list=bridge_ids,
|
|
25
|
+
pkt_type=PIXELS_PKT, indicator=test_indicator)
|
|
26
|
+
|
|
27
|
+
mgmt_pkts, _ = cert_data_sim.brg_pkt_gen(num_of_pkts_per_brg=10, num_of_brgs=NUM_OF_BRGS, brgs_list=bridge_ids,
|
|
28
|
+
pkt_type=MGMT_PKT, indicator=test_indicator)
|
|
29
|
+
# Use first 3 bridges for ACL, 4th bridge is not in ACL
|
|
30
|
+
acl_bridge_ids = bridge_ids[:3]
|
|
31
|
+
non_acl_bridge_id = bridge_ids[3]
|
|
32
|
+
pkts = pixels_pkts + mgmt_pkts
|
|
33
|
+
|
|
34
|
+
sim_thread = cert_data_sim.GenericSimThread(test=test, pkts=pkts)
|
|
35
|
+
sim_thread.start()
|
|
36
|
+
|
|
37
|
+
for param in test.params:
|
|
38
|
+
phase_run_print(f"ACL Test - Mode: {param.value}")
|
|
39
|
+
test.flush_all_mqtt_packets()
|
|
40
|
+
|
|
41
|
+
cfg = cert_config.get_default_gw_dict(test)
|
|
42
|
+
cfg[ACL][ACL_BRIDGE_IDS] = acl_bridge_ids
|
|
43
|
+
cfg[ACL][ACL_MODE] = param.value
|
|
44
|
+
test, _ = cert_config.gw_configure(test, cfg=cfg, wait=True)
|
|
45
|
+
print_update_wait(1)
|
|
46
|
+
|
|
47
|
+
test.get_mqttc_by_target(DUT).flush_pkts()
|
|
48
|
+
mqtt_scan_wait(test, SCAN_TIMEOUT)
|
|
49
|
+
cert_mqtt.dump_pkts(test, log=param.name)
|
|
50
|
+
|
|
51
|
+
# Analyze pass/fail
|
|
52
|
+
# Get all received packets with the test indicator and filter packets by bridge IDs in ACL list
|
|
53
|
+
received_pkts = cert_mqtt.get_unified_data_pkts(test, only_active_brg=False, indicator=test_indicator)
|
|
54
|
+
acl_bridge_pkts = [pkt for pkt in received_pkts if any([id in pkt[PAYLOAD] for id in acl_bridge_ids])]
|
|
55
|
+
non_acl_bridge_pkts = [pkt for pkt in received_pkts if non_acl_bridge_id in pkt[PAYLOAD]]
|
|
56
|
+
|
|
57
|
+
# In deny mode - we want to make sure bridges in ACL list are filtered
|
|
58
|
+
if param.value == ACL_DENY:
|
|
59
|
+
if len(non_acl_bridge_pkts) == 0:
|
|
60
|
+
test.rc = TEST_FAILED
|
|
61
|
+
test.add_reason(f"Phase failed! Bridge {non_acl_bridge_id} was not in the deny list "
|
|
62
|
+
f"and packets were not found from it")
|
|
63
|
+
if len(acl_bridge_pkts) != 0:
|
|
64
|
+
test.rc = TEST_FAILED
|
|
65
|
+
test.add_reason("Phase failed! Received packets from bridges that were on the deny list")
|
|
66
|
+
|
|
67
|
+
# In allow mode - we want to make sure only bridges in ACL list are not filtered
|
|
68
|
+
if param.value == ACL_ALLOW:
|
|
69
|
+
if len(non_acl_bridge_pkts) != 0:
|
|
70
|
+
test.rc = TEST_FAILED
|
|
71
|
+
test.add_reason(f"Phase failed! Bridge {non_acl_bridge_id} was not on the allow list "
|
|
72
|
+
f"and {len(non_acl_bridge_pkts)} packets were found from it")
|
|
73
|
+
# Check that we received packets from all expected bridges
|
|
74
|
+
received_alias_bridge_ids = set([pkt[ALIAS_BRIDGE_ID] for pkt in acl_bridge_pkts])
|
|
75
|
+
if len(received_alias_bridge_ids) != len(acl_bridge_ids):
|
|
76
|
+
test.rc = TEST_FAILED
|
|
77
|
+
test.add_reason("Phase failed! Didn't receive packets from all bridges that were on the allow list")
|
|
78
|
+
|
|
79
|
+
# Check that management packets are received from all bridges (ACL doesn't filter mgmt packets)
|
|
80
|
+
all_mgmt_pkts = cert_mqtt.get_all_mgmt_pkts(test.get_mqttc_by_target(DUT), indicator=test_indicator)
|
|
81
|
+
mgmt_alias_bridge_ids = set([pkt[ALIAS_BRIDGE_ID] for pkt in all_mgmt_pkts])
|
|
82
|
+
|
|
83
|
+
if len(mgmt_alias_bridge_ids) != NUM_OF_BRGS:
|
|
84
|
+
test.rc = TEST_FAILED
|
|
85
|
+
test.add_reason("Phase failed! Didn't receive management packets from all bridges")
|
|
86
|
+
|
|
87
|
+
field_functionality_pass_fail_print(test, "ACL", value=param.value)
|
|
88
|
+
test.set_phase_rc(param.name, test.rc)
|
|
89
|
+
test.add_phase_reason(param.name, test.reason)
|
|
90
|
+
if test.rc == TEST_FAILED and test.exit_on_param_failure:
|
|
91
|
+
break
|
|
92
|
+
else:
|
|
93
|
+
test.reset_result()
|
|
94
|
+
|
|
95
|
+
sim_thread.stop()
|
|
96
|
+
return cert_common.test_epilog(test, revert_gws=True, modules=[])
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Bridge OTA",
|
|
3
|
+
"module": "Cloud Connectivity",
|
|
4
|
+
"purpose": "Verify the device can perform bridge firmware upgrade over the air",
|
|
5
|
+
"documentation": ["https://community.wiliot.com/customers/s/article/Bridge-OTA"],
|
|
6
|
+
"initialCondition": "Gateway online, with bridgeOtaUpgradeSupported and in current latest version",
|
|
7
|
+
"procedure": ["Test prolog",
|
|
8
|
+
"Publish an OTA action to the gateway",
|
|
9
|
+
"Analyze if bridge was upgraded and action status message was uploaded",
|
|
10
|
+
"Test epilog"],
|
|
11
|
+
"expectedOutcome": "Tester brg advertises ModuleIF packet with the new version and DUT Gateway publish an actionStatus message indicating success and within timeout",
|
|
12
|
+
"mandatory": 0,
|
|
13
|
+
"multiBridgeTest": 0,
|
|
14
|
+
"gwOnlyTest": 1,
|
|
15
|
+
"internalBridge": 1,
|
|
16
|
+
"SupportedFromApiVersion": 203,
|
|
17
|
+
"allSupportedValues": []
|
|
18
|
+
|
|
19
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
from certificate.cert_prints import *
|
|
3
|
+
from certificate.cert_defines import *
|
|
4
|
+
from certificate.wlt_types import *
|
|
5
|
+
from certificate.cert_utils import TESTER_FW_VERSIONS
|
|
6
|
+
import certificate.cert_gw_sim as cert_gw_sim
|
|
7
|
+
import certificate.cert_common as cert_common
|
|
8
|
+
import certificate.cert_config as cert_config
|
|
9
|
+
import certificate.cert_mqtt as cert_mqtt
|
|
10
|
+
|
|
11
|
+
BRG_OTA_HIGH_TIMEOUT = (60 * 10)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def run(test):
|
|
15
|
+
test = cert_common.test_prolog(test)
|
|
16
|
+
if test.rc == TEST_FAILED:
|
|
17
|
+
return cert_common.test_epilog(test)
|
|
18
|
+
|
|
19
|
+
phase_run_print("BRG OTA started")
|
|
20
|
+
utPrint("Important: For the gateway to be able to download the file, it must use a valid token in the HTTP GET request.", "WARNING")
|
|
21
|
+
utPrint("Meaning It must be registered under an owner, and the certificate '-env' should correspond to that owner.", "WARNING")
|
|
22
|
+
test.flush_all_mqtt_packets()
|
|
23
|
+
target_brg = test.tester.internal_brg
|
|
24
|
+
desired_ver = TESTER_FW_VERSIONS[0] if target_brg.version != TESTER_FW_VERSIONS[0] else TESTER_FW_VERSIONS[1]
|
|
25
|
+
|
|
26
|
+
# Initiate action
|
|
27
|
+
utPrint(f"Publishing OTA action to DUT: {test.dut.mqttc.update_topic}. Awaiting OTA.. (timeout is {BRG_OTA_HIGH_TIMEOUT} seconds)")
|
|
28
|
+
# Set active_brg to be the tester, for reboot_config_analysis within brg_ota
|
|
29
|
+
test.active_brg = target_brg
|
|
30
|
+
test = cert_config.brg_ota(test, ble_version=desired_ver, search_ack=True, target=TESTER, upgrader=DUT, timeout=BRG_OTA_HIGH_TIMEOUT)
|
|
31
|
+
|
|
32
|
+
# Stop advertising on tester in case it just rebooted after getting OTA. So it is ready for next tests
|
|
33
|
+
cert_config.gw_action(test, cert_gw_sim.STOP_ADVERTISING, target=TESTER)
|
|
34
|
+
|
|
35
|
+
cert_mqtt.generate_log_file(test, "brg_ota")
|
|
36
|
+
|
|
37
|
+
if test.rc == TEST_PASSED and cert_gw_sim.GW_SIM_RESET_TS is not None:
|
|
38
|
+
reboot_pkt_time = int((cert_gw_sim.GW_SIM_RESET_TS - test.start_time).total_seconds())
|
|
39
|
+
test.reason = f"Reboot pkt received after {reboot_pkt_time} seconds"
|
|
40
|
+
|
|
41
|
+
return cert_common.test_epilog(test)
|
certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Gateway Channel behavior",
|
|
3
|
+
"module": "Cloud Connectivity",
|
|
4
|
+
"purpose": "Test gateway's channel scanning time cycles on all main channels",
|
|
5
|
+
"documentation": "",
|
|
6
|
+
"initialCondition": "Gateway configured with default settings",
|
|
7
|
+
"procedure": ["Test prolog",
|
|
8
|
+
"Send packets as close as possible to continuously on all 3 channels, with a unique channel identifier",
|
|
9
|
+
"Scan for packets and identify scanning behaviour",
|
|
10
|
+
"Test epilog"],
|
|
11
|
+
"expectedOutcome": "There is no expected outcome from the GW (Only behaviour analysis)",
|
|
12
|
+
"mandatory": 1,
|
|
13
|
+
"multiBridgeTest": 0,
|
|
14
|
+
"gwOnlyTest": 1,
|
|
15
|
+
"dataSimOnlyTest": 1,
|
|
16
|
+
"internalBridge": 1,
|
|
17
|
+
"SupportedFromApiVersion": 203,
|
|
18
|
+
"allSupportedValues": []
|
|
19
|
+
}
|
certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.py
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
from certificate.cert_prints import *
|
|
2
|
+
from certificate.cert_defines import *
|
|
3
|
+
from certificate.wlt_types import *
|
|
4
|
+
from certificate.ag.wlt_types_ag import OUTPUT_POWER_2_4_MAX
|
|
5
|
+
import certificate.cert_common as cert_common
|
|
6
|
+
import certificate.cert_mqtt as cert_mqtt
|
|
7
|
+
import certificate.cert_config as cert_config
|
|
8
|
+
import certificate.cert_gw_sim as cert_gw_sim
|
|
9
|
+
import os
|
|
10
|
+
import math
|
|
11
|
+
import pandas as pd
|
|
12
|
+
import plotly.express as px
|
|
13
|
+
import time
|
|
14
|
+
from collections import defaultdict
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# DEFINES
|
|
18
|
+
CHANNELS = [37, 38, 39] # channel to check in DUT
|
|
19
|
+
DEFAULT_WAIT_TIME = 5 # How much extra time to wait after the transmition is over
|
|
20
|
+
SCAN_TEST_INDICATOR = get_random_hex_str(6) # Unique identifier for the pkt sent
|
|
21
|
+
ADV_DURATION = 20 # How long to transmit to the DUT
|
|
22
|
+
# cmd_ble_sm defines
|
|
23
|
+
BLE_SIM_RADIO_1MBPS = 1
|
|
24
|
+
BLE_SIM_SINGLE_UNIQUE_PKT = 1
|
|
25
|
+
SCAN_DUPLICATES = 1
|
|
26
|
+
BLE_SIM_ADV_37_38_39 = 0
|
|
27
|
+
UNIQUE_CONTENT = 1
|
|
28
|
+
PPS = 20
|
|
29
|
+
|
|
30
|
+
# HELPER FUNCTIONS
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def interpolation(payload, next_payload, channel_pkt_counter):
|
|
34
|
+
cur_pkt_num = int.from_bytes(bytes.fromhex(payload[-8:]), byteorder="little")
|
|
35
|
+
next_pkt_num = int.from_bytes(bytes.fromhex(next_payload[-8:]), byteorder="little")
|
|
36
|
+
diff = next_pkt_num - cur_pkt_num
|
|
37
|
+
if diff > 1:
|
|
38
|
+
channel_pkt_counter += diff - 1
|
|
39
|
+
return channel_pkt_counter
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def compute_channels_windows(timeline_df):
|
|
43
|
+
"""
|
|
44
|
+
Build contiguous channel windows: for each run of the same channel, return (channel, start_ts, end_ts).
|
|
45
|
+
The result is and array of these windows. For exmaple: [(37, 0.004), (38, 0.038), .....]
|
|
46
|
+
"""
|
|
47
|
+
windows = []
|
|
48
|
+
current_ch = timeline_df.iloc[0]['channel']
|
|
49
|
+
start_ts = timeline_df.iloc[0]['timestamp_ms']
|
|
50
|
+
|
|
51
|
+
for _, row in timeline_df.iloc[1:].iterrows():
|
|
52
|
+
if row['channel'] != current_ch:
|
|
53
|
+
windows.append((current_ch, start_ts))
|
|
54
|
+
current_ch = row['channel']
|
|
55
|
+
start_ts = row['timestamp_ms']
|
|
56
|
+
|
|
57
|
+
windows.append((current_ch, start_ts))
|
|
58
|
+
return windows
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def compute_listening_stats(windows):
|
|
62
|
+
per_channel_starts = defaultdict(list)
|
|
63
|
+
avg_start_to_start_ms = {}
|
|
64
|
+
|
|
65
|
+
for ch, start_ts in windows:
|
|
66
|
+
per_channel_starts[ch].append(start_ts)
|
|
67
|
+
|
|
68
|
+
# Calculating the avg for each channel of the compelte cycle it does (that inclues all channels listend to)
|
|
69
|
+
for ch in CHANNELS:
|
|
70
|
+
starts = sorted(per_channel_starts.get(ch, []))
|
|
71
|
+
start_gaps = [curr - prev for prev, curr in zip(starts, starts[1:])]
|
|
72
|
+
avg_start_to_start_ms[ch] = sum(start_gaps) / len(start_gaps) if start_gaps else 0
|
|
73
|
+
|
|
74
|
+
return avg_start_to_start_ms
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def analyze_listening_timeline(test, all_pkts_received_from_tester, num_of_sent_pkts, start_timestamp_ms):
|
|
78
|
+
"""
|
|
79
|
+
Build a timeline graph and print channel listening percentages.
|
|
80
|
+
"""
|
|
81
|
+
timeline_entries = []
|
|
82
|
+
channel_pkt_counter = defaultdict(int)
|
|
83
|
+
channel_cards = []
|
|
84
|
+
|
|
85
|
+
# Parse data into {ts, channel pairs} - X and Y axis
|
|
86
|
+
all_pkts_received_from_tester = sorted(all_pkts_received_from_tester, key=lambda pkt: float(pkt.get(TIMESTAMP)))
|
|
87
|
+
for idx, pkt in enumerate(all_pkts_received_from_tester):
|
|
88
|
+
payload = pkt.get(PAYLOAD)
|
|
89
|
+
channel = int(payload[-10:-8], 16)
|
|
90
|
+
time_stamp = float(pkt.get(TIMESTAMP))
|
|
91
|
+
|
|
92
|
+
# Add dropped packts in the middle of listening windows to neglect it from not scanning window
|
|
93
|
+
# Those complitions will not apear in the graph, only on % calculations
|
|
94
|
+
# If there are packets dropped at the ed of a window - it can not detect that
|
|
95
|
+
if idx < len(all_pkts_received_from_tester) - 1:
|
|
96
|
+
next_pkt = all_pkts_received_from_tester[idx + 1]
|
|
97
|
+
next_channel = int(next_pkt.get(PAYLOAD)[-10:-8], 16)
|
|
98
|
+
if next_channel == channel:
|
|
99
|
+
next_payload = next_pkt.get(PAYLOAD)
|
|
100
|
+
channel_pkt_counter[channel] = interpolation(payload, next_payload, channel_pkt_counter[channel])
|
|
101
|
+
|
|
102
|
+
timeline_entries.append({'timestamp_ms': time_stamp, 'channel': channel})
|
|
103
|
+
channel_pkt_counter[channel] += 1
|
|
104
|
+
|
|
105
|
+
if not timeline_entries or not channel_pkt_counter:
|
|
106
|
+
utPrint("No packets were received; skipping timeline graph", "RED")
|
|
107
|
+
test.rc = TEST_FAILED
|
|
108
|
+
test.reason = "No packets were received in all channels"
|
|
109
|
+
return
|
|
110
|
+
|
|
111
|
+
# Create graph
|
|
112
|
+
timeline_df = pd.DataFrame(timeline_entries).sort_values('timestamp_ms')
|
|
113
|
+
timeline_df['relative_time_s'] = (timeline_df['timestamp_ms'] - start_timestamp_ms) / 1000
|
|
114
|
+
timeline_path = os.path.join(ARTIFACTS_DIR, test.dir, 'channel_scan_behavior.html')
|
|
115
|
+
color_map = {37: "#1f77b4", 38: "#ff7f0e", 39: "#2ca02c"}
|
|
116
|
+
timeline_fig = px.scatter(timeline_df, x='relative_time_s', y='channel', color='channel', color_discrete_map=color_map,
|
|
117
|
+
title='Channel scanning timeline',
|
|
118
|
+
labels={'relative_time_s': 'Time (s)', 'channel': 'Scanning Channel'})
|
|
119
|
+
timeline_fig.update_layout(height=350, yaxis=dict(tickmode='array', tickvals=CHANNELS, ticktext=[str(ch) for ch in CHANNELS],
|
|
120
|
+
range=[min(CHANNELS) - 0.5, max(CHANNELS) + 0.5]))
|
|
121
|
+
timeline_fig.update_coloraxes(showscale=False)
|
|
122
|
+
|
|
123
|
+
# Build contiguous channel windows and compute averages
|
|
124
|
+
windows = compute_channels_windows(timeline_df[['timestamp_ms', 'channel']])
|
|
125
|
+
avg_start_to_start_ms = compute_listening_stats(windows)
|
|
126
|
+
positive_start_gaps = [v for v in avg_start_to_start_ms.values() if v > 0]
|
|
127
|
+
avg_cycle_from_starts_ms = sum(positive_start_gaps) / len(positive_start_gaps) if positive_start_gaps else None
|
|
128
|
+
|
|
129
|
+
# Build per-channel cards for the HTML summary
|
|
130
|
+
for ch in CHANNELS:
|
|
131
|
+
pct_recievied_vs_sent = channel_pkt_counter[ch] * 100 / num_of_sent_pkts
|
|
132
|
+
cycle_ms = int(avg_start_to_start_ms[ch]) if int(avg_start_to_start_ms[ch]) != 0 else None
|
|
133
|
+
duration_ms = int(pct_recievied_vs_sent * cycle_ms / 100) if cycle_ms else None
|
|
134
|
+
# pct_recievied_vs_sent: packets on this channel / sent; cycle_ms: avg start-to-start; duration_ms: pct_recievied_vs_sent * cycle
|
|
135
|
+
channel_cards.append({"title": f"Channel {ch}",
|
|
136
|
+
"pct_recievied_vs_sent": round(pct_recievied_vs_sent, 4),
|
|
137
|
+
"cycle_ms": cycle_ms,
|
|
138
|
+
"duration_ms": duration_ms})
|
|
139
|
+
|
|
140
|
+
# Not‑scanning stats are the residual to 100% after the three channels
|
|
141
|
+
# Interpolation smooths dropouts so this reflects actual not-scannning time
|
|
142
|
+
observed_pct_recievied_vs_sent = sum(card["pct_recievied_vs_sent"] for card in channel_cards)
|
|
143
|
+
channel_cards.append({"title": "Not scanning",
|
|
144
|
+
"pct_recievied_vs_sent": max(0, round(100 - observed_pct_recievied_vs_sent, 2)),
|
|
145
|
+
"cycle_ms": int(avg_cycle_from_starts_ms) if avg_cycle_from_starts_ms else None,
|
|
146
|
+
"duration_ms": int((max(0, round(100 - observed_pct_recievied_vs_sent, 2)) *
|
|
147
|
+
(int(avg_cycle_from_starts_ms) if avg_cycle_from_starts_ms else 0)) / 100)
|
|
148
|
+
if avg_cycle_from_starts_ms else None})
|
|
149
|
+
|
|
150
|
+
# Embed summary text into the HTML alongside the plot
|
|
151
|
+
cards_html = "".join([
|
|
152
|
+
(
|
|
153
|
+
"<div style='flex:1; min-width:200px; border:1px solid #ddd; border-radius:8px; padding:12px; background:#fafafa;'>"
|
|
154
|
+
f"<div style='font-weight:700; margin-bottom:8px;'>{card['title']}</div>"
|
|
155
|
+
f"<div>% scanning: {card['pct_recievied_vs_sent']}% </div>"
|
|
156
|
+
f"<div>Scan cycle: {card['cycle_ms']} ms </div>"
|
|
157
|
+
f"<div>Scan duration: {card['duration_ms']} ms </div>"
|
|
158
|
+
"</div>"
|
|
159
|
+
)
|
|
160
|
+
for card in channel_cards
|
|
161
|
+
])
|
|
162
|
+
summary_html = (
|
|
163
|
+
"<div style=\"font-family: Arial, sans-serif; font-size:16px; line-height:1.5; margin-bottom:16px;\">"
|
|
164
|
+
f"<h3 style=\"margin:0 0 8px 0;\">Scan Summary</h3>"
|
|
165
|
+
f"<div style='display:flex; gap:12px; margin-top:12px; flex-wrap:wrap;'>{cards_html}</div>"
|
|
166
|
+
"</div>"
|
|
167
|
+
)
|
|
168
|
+
full_html = f"<html><head></head><body>{summary_html}{timeline_fig.to_html(full_html=False, include_plotlyjs='cdn')}</body></html>"
|
|
169
|
+
with open(timeline_path, "w") as f:
|
|
170
|
+
f.write(full_html)
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def run(test):
|
|
174
|
+
test = cert_common.test_prolog(test)
|
|
175
|
+
if test.rc == TEST_FAILED:
|
|
176
|
+
return cert_common.test_epilog(test)
|
|
177
|
+
|
|
178
|
+
# Setup
|
|
179
|
+
phase_run_print("Running scan channel behavior")
|
|
180
|
+
all_messages_in_test = []
|
|
181
|
+
all_data_pkts = []
|
|
182
|
+
all_data_pkts_from_tester = []
|
|
183
|
+
|
|
184
|
+
# Prepairation for advertisment
|
|
185
|
+
cert_config.gw_action(test, f'{cert_gw_sim.BLE_SIM_INIT} 1', TESTER) # Move BLE to sim mode
|
|
186
|
+
delay = math.floor(1000 / PPS)
|
|
187
|
+
upload_wait_time = test.dut.upload_wait_time + DEFAULT_WAIT_TIME
|
|
188
|
+
payload = cert_common.generate_adv_payload(SCAN_TEST_INDICATOR, unique_pkt=True)
|
|
189
|
+
|
|
190
|
+
# Transmitting packets on all channels
|
|
191
|
+
utPrint(f"Transmitting in parallel on all 3 main channels for {ADV_DURATION} seconds", "WARNING")
|
|
192
|
+
num_of_sent_pkts = ADV_DURATION * PPS
|
|
193
|
+
strat_trans_time_ms = time.time() * 1000
|
|
194
|
+
|
|
195
|
+
cert_config.gw_action(test, f'{cert_gw_sim.BLE_SIM} '
|
|
196
|
+
f'{payload} {SCAN_DUPLICATES} {OUTPUT_POWER_2_4_MAX} '
|
|
197
|
+
f'{BLE_SIM_ADV_37_38_39} {delay} {BLE_SIM_RADIO_1MBPS} {num_of_sent_pkts} {BLE_SIM_SINGLE_UNIQUE_PKT}',
|
|
198
|
+
TESTER)
|
|
199
|
+
mqtt_scan_wait(test, ADV_DURATION + upload_wait_time)
|
|
200
|
+
|
|
201
|
+
all_data_pkts_from_tester.extend(cert_mqtt.get_all_data_pkts(test.get_mqttc_by_target(DUT), indicator=SCAN_TEST_INDICATOR))
|
|
202
|
+
all_data_pkts.extend(cert_mqtt.get_all_data_pkts(test.get_mqttc_by_target(DUT)))
|
|
203
|
+
all_messages_in_test.extend(test.get_mqttc_by_target(DUT)._userdata[PKTS].data)
|
|
204
|
+
|
|
205
|
+
cert_config.gw_action(test, f'{cert_gw_sim.BLE_SIM_INIT} 0', TESTER)
|
|
206
|
+
time.sleep(1) # To allow all packets to show in the log
|
|
207
|
+
|
|
208
|
+
cert_mqtt.generate_log_file(test, 'channel_scan', target=DUT)
|
|
209
|
+
cert_mqtt.generate_log_file(test, 'channel_scan_tester', target=TESTER)
|
|
210
|
+
|
|
211
|
+
analyze_listening_timeline(test, all_data_pkts_from_tester, num_of_sent_pkts, strat_trans_time_ms)
|
|
212
|
+
|
|
213
|
+
test = cert_common.wiliot_pkts_validation(test, all_messages_in_test, all_data_pkts)
|
|
214
|
+
|
|
215
|
+
return cert_common.test_epilog(test)
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Gateway Connection",
|
|
3
|
+
"module": "Cloud Connectivity",
|
|
4
|
+
"purpose": "Verify that the device uploads its status message to the MQTT status topic upon connecting to the MQTT, after manual disconnect",
|
|
5
|
+
"documentation": ["https://community.wiliot.com/customers/s/article/Sending-Wiliot-Packets-to-the-Wiliot-Cloud"],
|
|
6
|
+
"initialCondition": "Device is connected to MQTT and ready at hand to be manually turned off",
|
|
7
|
+
"procedure": ["Test prolog",
|
|
8
|
+
"Disconnect sequence - Device gets powered off and then on according to the instructions",
|
|
9
|
+
"Wait for device to connect to MQTT by verifying a status message or fail when timeout occurs",
|
|
10
|
+
"Test epilog"],
|
|
11
|
+
"expectedOutcome": "Device reconnects and publishes its configuration to the MQTT status topic before timeout",
|
|
12
|
+
"mandatory": 1,
|
|
13
|
+
"multiBridgeTest": 0,
|
|
14
|
+
"gwOnlyTest": 1,
|
|
15
|
+
"SupportedFromApiVersion": 203,
|
|
16
|
+
"allSupportedValues": []
|
|
17
|
+
|
|
18
|
+
}
|