wiliot-certificate 4.5.0__py3-none-any.whl → 4.5.0a1__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 (125) hide show
  1. certificate/ag/wlt_types_ag_jsons/brg2brg_ota.json +211 -0
  2. certificate/ag/wlt_types_ag_jsons/brg2gw_hb.json +894 -0
  3. certificate/ag/wlt_types_ag_jsons/brg2gw_hb_sleep.json +184 -0
  4. certificate/ag/wlt_types_ag_jsons/calibration.json +490 -0
  5. certificate/ag/wlt_types_ag_jsons/custom.json +614 -0
  6. certificate/ag/wlt_types_ag_jsons/datapath.json +900 -0
  7. certificate/ag/wlt_types_ag_jsons/energy2400.json +670 -0
  8. certificate/ag/wlt_types_ag_jsons/energySub1g.json +691 -0
  9. certificate/ag/wlt_types_ag_jsons/externalSensor.json +727 -0
  10. certificate/ag/wlt_types_ag_jsons/interface.json +1095 -0
  11. certificate/ag/wlt_types_ag_jsons/powerManagement.json +1439 -0
  12. certificate/ag/wlt_types_ag_jsons/side_info_sensor.json +105 -0
  13. certificate/ag/wlt_types_ag_jsons/signal_indicator_data.json +77 -0
  14. certificate/ag/wlt_types_ag_jsons/unified_echo_ext_pkt.json +126 -0
  15. certificate/ag/wlt_types_ag_jsons/unified_echo_pkt.json +175 -0
  16. certificate/ag/wlt_types_ag_jsons/unified_sensor_pkt.json +65 -0
  17. certificate/cert_common.py +46 -75
  18. certificate/cert_config.py +18 -43
  19. certificate/cert_data_sim.py +9 -12
  20. certificate/cert_defines.py +0 -9
  21. certificate/cert_gw_sim.py +7 -35
  22. certificate/cert_mqtt.py +5 -15
  23. certificate/cert_prints.py +0 -1
  24. certificate/cert_results.py +37 -56
  25. certificate/cert_utils.py +15 -27
  26. certificate/certificate.py +5 -12
  27. certificate/certificate_cli.py +13 -10
  28. certificate/certificate_eth_test_list.txt +4 -6
  29. certificate/certificate_sanity_test_list.txt +2 -3
  30. certificate/certificate_test_list.txt +4 -5
  31. certificate/tests/calibration/interval_test/interval_test.json +0 -1
  32. certificate/tests/calibration/output_power_test/output_power_test.json +0 -1
  33. certificate/tests/calibration/pattern_test/pattern_test.json +0 -1
  34. certificate/tests/cloud_connectivity/acl_ext_adv_test/acl_ext_adv_test.json +1 -2
  35. certificate/tests/cloud_connectivity/acl_test/acl_test.json +1 -2
  36. certificate/tests/cloud_connectivity/acl_test/acl_test.py +15 -13
  37. certificate/tests/cloud_connectivity/brg_ota_test/brg_ota_test.json +1 -2
  38. certificate/tests/cloud_connectivity/brg_ota_test/brg_ota_test.py +6 -8
  39. certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.json +1 -2
  40. certificate/tests/cloud_connectivity/channel_scan_behaviour_test/channel_scan_behaviour_test.py +3 -3
  41. certificate/tests/cloud_connectivity/connection_test/connection_test.json +0 -1
  42. certificate/tests/cloud_connectivity/connection_test/connection_test.py +13 -6
  43. certificate/tests/cloud_connectivity/downlink_test/downlink_test.json +0 -1
  44. certificate/tests/cloud_connectivity/downlink_test/downlink_test.py +4 -1
  45. certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.json +1 -2
  46. certificate/tests/cloud_connectivity/ext_adv_stress_test/ext_adv_stress_test.py +14 -20
  47. certificate/tests/cloud_connectivity/reboot_test/reboot_test.json +0 -1
  48. certificate/tests/cloud_connectivity/reboot_test/reboot_test.py +0 -2
  49. certificate/tests/cloud_connectivity/registration_test/registration_test.json +0 -1
  50. certificate/tests/cloud_connectivity/registration_test/registration_test_cli.py +1 -1
  51. certificate/tests/cloud_connectivity/stress_test/stress_test.json +1 -2
  52. certificate/tests/cloud_connectivity/stress_test/stress_test.py +16 -20
  53. certificate/tests/cloud_connectivity/uplink_ext_adv_test/uplink_ext_adv_test.json +0 -1
  54. certificate/tests/cloud_connectivity/uplink_ext_adv_test/uplink_ext_adv_test.py +2 -1
  55. certificate/tests/cloud_connectivity/uplink_test/uplink_test.json +0 -1
  56. certificate/tests/cloud_connectivity/uplink_test/uplink_test.py +20 -28
  57. certificate/tests/datapath/aging_test/aging_test.json +0 -1
  58. certificate/tests/datapath/aging_test/aging_test.py +3 -7
  59. certificate/tests/datapath/event_ble5_test/event_ble5_test.json +2 -3
  60. certificate/tests/datapath/event_ble5_test/event_ble5_test.py +13 -7
  61. certificate/tests/datapath/event_test/event_test.json +2 -3
  62. certificate/tests/datapath/event_test/event_test.py +10 -5
  63. certificate/tests/datapath/num_of_tags_test/num_of_tags_test.json +2 -3
  64. certificate/tests/datapath/num_of_tags_test/num_of_tags_test.py +5 -9
  65. certificate/tests/datapath/output_power_test/output_power_test.json +0 -1
  66. certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.json +0 -1
  67. certificate/tests/datapath/pacer_interval_ble5_test/pacer_interval_ble5_test.py +4 -4
  68. certificate/tests/datapath/pacer_interval_test/pacer_interval_test.json +0 -1
  69. certificate/tests/datapath/pattern_test/pattern_test.json +0 -1
  70. certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.json +0 -1
  71. certificate/tests/datapath/pkt_filter_ble5_chl21_test/pkt_filter_ble5_chl21_test.py +5 -5
  72. certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.json +0 -1
  73. certificate/tests/datapath/pkt_filter_ble5_test/pkt_filter_ble5_test.py +5 -5
  74. certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.json +0 -1
  75. certificate/tests/datapath/pkt_filter_brg2gw_ext_adv_test/pkt_filter_brg2gw_ext_adv_test.py +8 -10
  76. certificate/tests/datapath/pkt_filter_gen3_test/pkt_filter_gen3_test.json +0 -1
  77. certificate/tests/datapath/pkt_filter_test/pkt_filter_test.json +0 -1
  78. certificate/tests/datapath/rssi_threshold_test/rssi_threshold_test.json +1 -2
  79. certificate/tests/datapath/rx_channel_hopping_test/rx_channel_hopping_test.json +0 -1
  80. certificate/tests/datapath/rx_channel_test/rx_channel_test.json +0 -1
  81. certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.json +0 -1
  82. certificate/tests/datapath/rx_rate_gen2_test/rx_rate_gen2_test.py +1 -1
  83. certificate/tests/datapath/rx_rate_gen3_test/rx_rate_gen3_test.json +0 -1
  84. certificate/tests/datapath/stress_gen3_test/stress_gen3_test.json +0 -1
  85. certificate/tests/datapath/stress_gen3_test/stress_gen3_test.py +0 -3
  86. certificate/tests/datapath/stress_test/stress_test.json +0 -1
  87. certificate/tests/datapath/stress_test/stress_test.py +0 -3
  88. certificate/tests/datapath/tx_repetition_test/tx_repetition_test.json +0 -1
  89. certificate/tests/edge_mgmt/action_blink_test/action_blink_test.json +0 -1
  90. certificate/tests/edge_mgmt/action_get_battery_sensor_test/action_get_battery_sensor_test.json +0 -1
  91. certificate/tests/edge_mgmt/action_get_module_test/action_get_module_test.json +0 -1
  92. certificate/tests/edge_mgmt/action_get_pof_data_test/action_get_pof_data_test.json +0 -1
  93. certificate/tests/edge_mgmt/action_gw_hb_test/action_gw_hb_test.json +0 -1
  94. certificate/tests/edge_mgmt/action_reboot_test/action_reboot_test.json +0 -1
  95. certificate/tests/edge_mgmt/action_restore_defaults_test/action_restore_defaults_test.json +0 -1
  96. certificate/tests/edge_mgmt/action_send_hb_test/action_send_hb_test.json +0 -1
  97. certificate/tests/edge_mgmt/action_send_hb_test/action_send_hb_test.py +14 -18
  98. certificate/tests/edge_mgmt/periodic_msgs_test/periodic_msgs_test.json +0 -1
  99. certificate/tests/energy2400/duty_cycle_test/duty_cycle_test.json +0 -1
  100. certificate/tests/energy2400/output_power_test/output_power_test.json +0 -1
  101. certificate/tests/energy2400/pattern_test/pattern_test.json +0 -1
  102. certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.json +0 -1
  103. certificate/tests/energy2400/signal_indicator_ble5_test/signal_indicator_ble5_test.py +3 -4
  104. certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.json +9 -9
  105. certificate/tests/energy2400/signal_indicator_ext_adv_test/signal_indicator_ext_adv_test.py +271 -113
  106. certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.json +0 -1
  107. certificate/tests/energy2400/signal_indicator_test/signal_indicator_test.py +1 -1
  108. certificate/tests/energy_sub1g/duty_cycle_test/duty_cycle_test.json +0 -1
  109. certificate/tests/energy_sub1g/pattern_test/pattern_test.json +0 -1
  110. certificate/tests/pwr_mgmt/pwr_mgmt_test/pwr_mgmt_test.json +0 -1
  111. certificate/tests/sensors/ext_sensor_test/ext_sensor_test.json +0 -1
  112. certificate/tests/sensors/ext_sensor_test/ext_sensor_test.py +9 -4
  113. common/api_if/api_validation.py +2 -8
  114. common/web/templates/generator.html +79 -141
  115. common/web/web_utils.py +56 -78
  116. gui_certificate/server.py +78 -283
  117. gui_certificate/templates/cert_run.html +113 -179
  118. {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a1.dist-info}/METADATA +38 -27
  119. {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a1.dist-info}/RECORD +123 -109
  120. certificate/tests/cloud_connectivity/deduplication_test/deduplication_test.json +0 -15
  121. certificate/tests/cloud_connectivity/deduplication_test/deduplication_test.py +0 -80
  122. {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a1.dist-info}/WHEEL +0 -0
  123. {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a1.dist-info}/entry_points.txt +0 -0
  124. {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a1.dist-info}/licenses/LICENSE +0 -0
  125. {wiliot_certificate-4.5.0.dist-info → wiliot_certificate-4.5.0a1.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,8 @@
1
1
  from certificate.cert_prints import *
2
2
  from certificate.cert_defines import *
3
3
  from certificate.wlt_types import *
4
+ from certificate.cert_utils import Phase
5
+ from certificate.cert_utils import *
4
6
  import certificate.cert_utils as cert_utils
5
7
  import certificate.cert_config as cert_config
6
8
  import certificate.cert_mqtt as cert_mqtt
@@ -479,8 +481,8 @@ def pacing_analysis(test, pacer_interval, df, pkt_filter_cfg=ag.PKT_FILTER_RANDO
479
481
  # In non-sterile runs - rssi is less stable and can trigger more events
480
482
  max_count_threshold = float('inf')
481
483
  else:
482
- # In rssi movement events the alpha filter takes about 13 packets to stabilize
483
- max_count_threshold = 1 + (RSSI_EVENT_PKTS_TO_STABILIZE / expected_event_pkt_count)
484
+ # In rssi movement events the alpha filter takes about 10 packets to stabilize
485
+ max_count_threshold = 1 + (10 / expected_event_pkt_count)
484
486
  else:
485
487
  max_count_threshold = PACER_INTERVAL_CEIL_THRESHOLD
486
488
 
@@ -490,14 +492,12 @@ def pacing_analysis(test, pacer_interval, df, pkt_filter_cfg=ag.PKT_FILTER_RANDO
490
492
 
491
493
  if not (PACER_INTERVAL_THRESHOLD <= len(event_pkts) / expected_event_pkt_count <= max_count_threshold):
492
494
  test.rc = TEST_FAILED
493
- msg = f"Packet count for dynamic tag {tag} is wrong! expected_event_pkt_count = {expected_event_pkt_count}, received pkt count = {len(event_pkts)}"
494
- test.add_reason(msg)
495
- utPrint(msg, "RED")
495
+ test.add_reason(f"Packet count for dynamic tag {tag} is wrong!")
496
+ print(f"expected_event_pkt_count = {expected_event_pkt_count}, received pkt count = {len(event_pkts)}")
496
497
  if not (PACER_INTERVAL_THRESHOLD <= avg_event_pacer / event_pacing <= PACER_INTERVAL_CEIL_THRESHOLD):
497
498
  test.rc = TEST_FAILED
498
- msg = f"Tag {tag} has a wrong avg time diff. diff_time {list(event_pkts.timestamp.diff().div(1000))}, avg_event_pacer={avg_event_pacer} exceeds threshold!"
499
- test.add_reason(msg)
500
- utPrint(msg, "RED")
499
+ print(f"Tag {tag} with diff_time {list(event_pkts.timestamp.diff().div(1000))}, avg_event_pacer={avg_event_pacer} exceeds threshold!")
500
+ test.add_reason(f"Tag {tag} has a wrong avg time diff")
501
501
 
502
502
  # Verify the tags pacer interval (without event)
503
503
  failed_tags = 0
@@ -512,9 +512,8 @@ def pacing_analysis(test, pacer_interval, df, pkt_filter_cfg=ag.PKT_FILTER_RANDO
512
512
  if ((avg_pacer / pacer_interval) < PACER_INTERVAL_THRESHOLD_HIGH and (pacer_interval - avg_pacer) > 1):
513
513
  failed_tags += 1
514
514
  test.rc = TEST_FAILED
515
- msg = f"Tag {tag} with diff_time {list(pkts.timestamp.diff().div(1000))}, avg_pacer={avg_pacer} exceeds {PACER_INTERVAL_THRESHOLD_HIGH} minimum threshold!"
516
- utPrint(msg, "RED")
517
- test.add_reason(msg)
515
+ print(f"Tag {tag} with diff_time {list(pkts.timestamp.diff().div(1000))}, avg_pacer={avg_pacer} exceeds {PACER_INTERVAL_THRESHOLD_HIGH} minimum threshold!")
516
+ test.add_reason(f"{failed_tags}/{tags_count} tags with wrong time diff")
518
517
  # Pass the test with real tags when less than 5% tag failed
519
518
  if test.data != DATA_SIMULATION and failed_tags / tags_count < 0.05:
520
519
  test.rc = TEST_PASSED
@@ -523,9 +522,7 @@ def pacing_analysis(test, pacer_interval, df, pkt_filter_cfg=ag.PKT_FILTER_RANDO
523
522
  if max_received_pkts == len(pkts):
524
523
  # we fail the tag only if it received all expected pkts and pacer caluculation is valid
525
524
  failed_tags += 1
526
- msg = f"Tag {tag} with diff_time {list(pkts.timestamp.diff().div(1000))}, avg_pacer={avg_pacer} exceeds {PACER_INTERVAL_CEIL_THRESHOLD} maximum threshold!"
527
- utPrint(msg, "RED")
528
- test.add_reason(msg)
525
+ print(f"Tag {tag} with diff_time {list(pkts.timestamp.diff().div(1000))}, avg_pacer={avg_pacer} exceeds {PACER_INTERVAL_CEIL_THRESHOLD} maximum threshold!")
529
526
  else:
530
527
  print(f"Tag {tag} received only {len(pkts)} pkts out of {max_received_pkts}, avg_pacer failed but skipping pacer ceil validation")
531
528
  if failed_tags / tags_count > 0.2: # Fail the test on ceil threshold only when more than 20% tag failed
@@ -605,13 +602,12 @@ def run_event_test_phase(test, phase, datapath_module, values, scan_time, event_
605
602
  scan_time_multiplier = 1
606
603
  delay = DATA_SIM_EVENT_TESTING_DELAY_MS
607
604
  if "rssi" in phase:
608
- test.sterile_run = is_quiet_setup_running()
609
605
  delay = DATA_SIM_RSSI_EVENT_TESTING_DELAY_MS
610
606
  scan_time_multiplier = (1 / 3)
611
607
  fields += [BRG_RSSI_MOVEMENT_THRESHOLD]
612
608
 
613
- ble5 = ble5_test and test.dut_is_bridge() # ble5 only for bridge dut (with combo we don't need to wait)
614
- test = cert_config.brg_configure(test, fields=fields, values=values, module=datapath_module, ble5=ble5)[0]
609
+ test = (cert_config.brg_configure_ble5(test, fields=fields, values=values, module=datapath_module)[0] if ble5_test
610
+ else cert_config.brg_configure(test, fields=fields, values=values, module=datapath_module)[0])
615
611
  test.set_phase_rc(phase, test.rc)
616
612
  test.add_phase_reason(phase, test.reason)
617
613
  if test.rc == TEST_FAILED and test.exit_on_param_failure:
@@ -748,9 +744,7 @@ def scan_for_mgmt_pkts(test, mgmt_type, target=DUT):
748
744
  break
749
745
  if not found:
750
746
  test.rc = TEST_FAILED
751
- error = f"Didn't receive {mgmt_type[0].__name__} pkt after {DEFAULT_BRG_FIELD_UPDATE_TIMEOUT} seconds!"
752
- test.add_reason(error)
753
- utPrint(error, "RED")
747
+ test.add_reason(f"Didn't receive {mgmt_type[0].__name__} pkt after {DEFAULT_BRG_FIELD_UPDATE_TIMEOUT} seconds!")
754
748
  return test, ret_pkts
755
749
 
756
750
  # Actions test functions
@@ -782,7 +776,8 @@ def scan_for_modules(test, modules=[]):
782
776
 
783
777
 
784
778
  def search_action_ack(test, action_id, **kwargs):
785
- test, mgmt_pkts = scan_for_mgmt_pkts(test, mgmt_type=[eval_pkt(f'{ag.ACTIONS_DICT[action_id]}{test.active_brg.api_version}')])
779
+ test, mgmt_pkts = cert_common.scan_for_mgmt_pkts(test,
780
+ mgmt_type=[eval_pkt(f'{ag.ACTIONS_DICT[action_id]}{test.active_brg.api_version}')])
786
781
  if test.rc == TEST_FAILED:
787
782
  return test
788
783
  print("\nReceived ACK pkts:")
@@ -1056,24 +1051,14 @@ def get_gw_type(mqttc):
1056
1051
 
1057
1052
  def get_module_if_pkt(test):
1058
1053
  cert_config.send_brg_action(test, ag.ACTION_GET_MODULE, interface=1)
1059
- mgmt_type = [m for m in ag.MODULES_LIST if "ModuleIf" in m.__name__]
1060
- test, pkts = scan_for_mgmt_pkts(test, mgmt_type=mgmt_type)
1061
-
1054
+ test, pkts = scan_for_mgmt_pkts(test, mgmt_type=[eval_pkt(f'ModuleIfV{test.active_brg.api_version}'),
1055
+ eval_pkt(f'ModuleIfV{test.active_brg.api_version - 1}'),])
1062
1056
  if test.rc == TEST_FAILED:
1063
1057
  return test, NO_RESPONSE
1064
1058
  else:
1065
1059
  print(pkts[-1][MGMT_PKT].pkt)
1066
1060
  return test, pkts[-1][MGMT_PKT].pkt
1067
1061
 
1068
- def get_gw_api_version(mqttc):
1069
- messages = cert_mqtt.get_all_status_pkts(mqttc)
1070
- for msg in messages:
1071
- if GW_CONF in msg: # JSON
1072
- return msg[GW_CONF][GW_API_VERSION]
1073
- if GW_STATUS in msg: # protobuf
1074
- return msg[GW_STATUS][GW_API_VERSION]
1075
- return None
1076
-
1077
1062
  def get_cfg_hash(test):
1078
1063
  utPrint(f"Fetching BRG cfg hash for BRG {test.active_brg.id_str}", "BLUE")
1079
1064
  test, module_if_pkt = get_module_if_pkt(test)
@@ -1289,27 +1274,10 @@ def output_power_supported(board_type, output_power):
1289
1274
  return output_power in ag.OUTPUT_POWER_2_4_SUPPORTED_VALUES
1290
1275
 
1291
1276
 
1292
- def validate_received_packets(pkts_array):
1293
- for pkt in pkts_array:
1294
- # Check all required fields are present
1295
- if TIMESTAMP not in pkt:
1296
- return False, "timestamp field is missing in some of the packets"
1297
- if ALIAS_BRIDGE_ID not in pkt:
1298
- return False, "alias_bridge_id field is missing in some of the packets"
1299
- if PAYLOAD not in pkt:
1300
- return False, "payload field is missing in some of the packets"
1301
- if SEQUENCE_ID not in pkt:
1302
- return False, "sequence_id field is missing in some of the packets"
1303
- # Check that the payload length is either 62 or 74 hex characters (equevelnt to 31 or 37 bytes)
1304
- if len(pkt[PAYLOAD]) != 62 and len(pkt[PAYLOAD]) !=74:
1305
- return False, f"Payload length is invalid for packet {pkt[PAYLOAD]}"
1306
- return True, ""
1307
-
1308
-
1309
1277
  def wiliot_pkts_validation(test, all_messages_in_test, all_data_pkts):
1310
1278
  PHASE_NAME = "Wiliot packets validation"
1311
1279
  phase_run_print(PHASE_NAME)
1312
- wiliot_pkts_validation_phase = cert_utils.Phase(PHASE_NAME, rc=TEST_PASSED)
1280
+ wiliot_pkts_validation_phase = Phase(PHASE_NAME, rc=TEST_PASSED)
1313
1281
 
1314
1282
  if len(all_messages_in_test) == 0:
1315
1283
  wiliot_pkts_validation_phase.rc = TEST_FAILED
@@ -1322,7 +1290,7 @@ def wiliot_pkts_validation(test, all_messages_in_test, all_data_pkts):
1322
1290
  wiliot_pkts_validation_phase = seq_id_validation(wiliot_pkts_validation_phase, all_data_pkts)
1323
1291
 
1324
1292
  field_functionality_pass_fail_print(wiliot_pkts_validation_phase, PHASE_NAME)
1325
- test.add_phase(wiliot_pkts_validation_phase)
1293
+ test.phases[-1:-1] = [wiliot_pkts_validation_phase]
1326
1294
  return test
1327
1295
 
1328
1296
 
@@ -1393,7 +1361,7 @@ def timestamps_validation(wiliot_pkts_validation_phase, all_messages_in_test, up
1393
1361
  else:
1394
1362
  if inner_pkt[TIMESTAMP] < previous_ts:
1395
1363
  wiliot_pkts_validation_phase.rc = TEST_FAILED
1396
- wiliot_pkts_validation_phase.reason = f'Timestamp is not incremental for inner packet {inner_pkt[PAYLOAD]}'
1364
+ wiliot_pkts_validation_phase.reason = f'Timestamp is not incremental for inner packet {inner_pkt}'
1397
1365
  return wiliot_pkts_validation_phase
1398
1366
  previous_ts = inner_pkt[TIMESTAMP]
1399
1367
  return wiliot_pkts_validation_phase
@@ -1405,19 +1373,19 @@ def generate_graph_stress_test(test, results, test_pkts_received):
1405
1373
  graph_data = []
1406
1374
  for i in range(0, len(results), 2):
1407
1375
  if i + 1 < len(results):
1408
- graph_data.append({'pkts_per_sec': results[i], 'received_pps': results[i + 1]})
1376
+ graph_data.append({'pkts_per_sec': results[i], 'percent_received': results[i + 1]})
1409
1377
 
1410
1378
  graph_df = pd.DataFrame(graph_data)
1411
1379
  html_file_path = os.path.join(ARTIFACTS_DIR, test.dir, 'stress_graph.html')
1412
1380
 
1413
1381
  # First graph: percentage received vs packets per second
1414
- fig1 = px.line(graph_df, x='pkts_per_sec', y='received_pps',
1415
- title='Packets Per Second Uploaded vs Packets Per Second Advertised',
1416
- labels={'pkts_per_sec': 'Advertised PPS', 'received_pps': 'Uploaded PPS'},
1417
- markers=True, text='received_pps')
1382
+ fig1 = px.line(graph_df, x='pkts_per_sec', y='percent_received',
1383
+ title='Percentage of packets uploaded by packets per second advertised',
1384
+ labels={'pkts_per_sec': 'Packets Sent Per Second', 'percent_received': 'Percentage of packets received'},
1385
+ markers=True, text='percent_received')
1418
1386
 
1419
- # Set y-axis to [0 - highest_pps] scale
1420
- fig1.update_yaxes(range=[0, results[-2]])
1387
+ # Set y-axis to 1-100 scale
1388
+ fig1.update_yaxes(range=[1, 100])
1421
1389
 
1422
1390
  # Position text labels next to the markers
1423
1391
  fig1.update_traces(textposition="top right")
@@ -1450,8 +1418,11 @@ def generate_graph_stress_test(test, results, test_pkts_received):
1450
1418
 
1451
1419
 
1452
1420
  def stress_analysis(test, pps, sent_pkts, received_pkts):
1453
-
1454
- _sent_pkts = [p[12:] for p in sent_pkts]
1421
+ _sent_pkts = []
1422
+ for pkt in sent_pkts:
1423
+ adva_endianness_change = change_endianness(pkt[:12]) + pkt[12:] # Switch to big endian adva
1424
+ _sent_pkts.append(adva_endianness_change)
1425
+
1455
1426
  sent_df = pd.DataFrame(_sent_pkts, columns=[PACKETS])
1456
1427
  received_df = pd.DataFrame(received_pkts, columns=[PACKETS])
1457
1428
 
@@ -1460,29 +1431,29 @@ def stress_analysis(test, pps, sent_pkts, received_pkts):
1460
1431
  pkts_sent_count = len(sent_df)
1461
1432
  pkts_received_count = len(merged_df)
1462
1433
 
1463
- # Prints and calculations
1434
+ # Prints
1435
+ print(f'Number of packets sent: {pkts_sent_count}')
1436
+ print(f'Number of packets received: {pkts_received_count}')
1464
1437
  percentage_received = round(pkts_received_count * 100 / pkts_sent_count)
1465
- utPrint(f'Sent: {pkts_sent_count}, Received: {pkts_received_count} ({percentage_received}%)', "BLUE")
1466
- received_pps = pps * percentage_received / 100
1467
1438
 
1468
1439
  # PASS/FAIL logic
1469
- if percentage_received < 1: # If less than 1% of the packets were received, fail the test
1470
- test.set_phase_rc(str(pps), TEST_FAILED)
1471
- test.add_phase_reason(str(pps), f"{percentage_received}% of the packets were scanned & uploaded by the gateway")
1440
+ stage_pass = pkts_received_count / pkts_sent_count * 100
1441
+ if stage_pass < 1: # If less than 1% of the packets were received, fail the test
1442
+ test.rc = TEST_FAILED
1443
+ test.reason = "Insufficient amount of packets were scanned & uploaded by the gateway"
1472
1444
  else:
1473
- test.set_phase_rc(str(pps), TEST_PASSED)
1474
- test.add_phase_reason(str(pps), f"received pps: {received_pps} ({percentage_received}% of packets)")
1445
+ test.reason = f'{percentage_received}% of packets received, average pps: {pps * percentage_received / 100}'
1475
1446
 
1476
- return test, received_pps
1447
+ return test, percentage_received
1477
1448
 
1478
1449
 
1479
1450
  def generate_adv_payload(test_indicator, unique_pkt=False):
1480
1451
  # Keep last 4 bytes as zeroes so for incrementing them in FW 'ble_sim'
1481
- adva = hex2alias_id_get(get_random_hex_str(12))
1482
- unique_pkt_byte = get_random_hex_str(2) if unique_pkt == False else "00"
1452
+ adva = hex2alias_id_get(cert_utils.get_random_hex_str(12))
1453
+ unique_pkt_byte = cert_utils.get_random_hex_str(2) if unique_pkt == False else "00"
1483
1454
  payload = (ag.Hdr(group_id=ag.GROUP_ID_UNIFIED_PKT_V2).dump() + test_indicator +
1484
- get_random_hex_str(32) + unique_pkt_byte + "00000000")
1455
+ cert_utils.get_random_hex_str(32) + unique_pkt_byte + "00000000")
1485
1456
  return adva + payload
1486
1457
 
1487
1458
  def change_endianness(hex_str: str) -> str:
1488
- return ''.join(f"{b:02X}" for b in bytes.fromhex(hex_str)[::-1])
1459
+ return ''.join(f"{b:02X}" for b in bytes.fromhex(hex_str)[::-1])
@@ -4,7 +4,7 @@ from certificate.wlt_types import *
4
4
  import certificate.cert_common as cert_common
5
5
  import certificate.cert_protobuf as cert_protobuf
6
6
  import certificate.cert_mqtt as cert_mqtt
7
- import datetime, string, json, random, inspect
7
+ import datetime, string, json, random
8
8
 
9
9
  BLE5_MAX_RETRIES = BLE5_MAX_DURATION_MS//20
10
10
 
@@ -40,9 +40,7 @@ def gw_configure(test, cfg={}, version="", extended_cfg={}, ret_pkt=False, wait=
40
40
  while (datetime.datetime.now() - start_time).seconds < DEFAULT_GW_FIELD_UPDATE_TIMEOUT:
41
41
  for p in cert_mqtt.get_all_status_pkts(mqttc):
42
42
  if GW_CONF in p or GW_STATUS in p:
43
- test.gw_api_version = (p.get(GW_CONF, {}).get(GW_API_VERSION) or p.get(GW_STATUS, {}).get(GW_API_VERSION))
44
- if target == DUT and is_gw(test.dut):
45
- test.dut.gw_api_version = test.gw_api_version
43
+ test.gw_api_version = p[GW_CONF][GW_API_VERSION] if GW_CONF in p else p[GW_STATUS][GW_API_VERSION]
46
44
  print_pkt(p)
47
45
  utPrint("SUCCESS: Found GW cfg", "GREEN")
48
46
  wait_time_n_print(2)
@@ -79,18 +77,15 @@ def gw_fw_upgrade(test, version, board_type, target=DUT):
79
77
  def create_gw_config(test, cfg, target=DUT, version=""):
80
78
  gw = test.dut if is_gw(test.dut) and target == DUT else test.tester
81
79
  if version:
82
- conf = {LAT: GW_LATITUDE_DEFAULT, LNG: GW_LONGITUDE_DEFAULT, WIFI_VERSION: version[WIFI_VERSION],
83
- BLE_VERSION: version[BLE_VERSION], ADDITIONAL: dict(cfg)}
80
+ return dict({GW_CONF:{LAT: GW_LATITUDE_DEFAULT, LNG: GW_LONGITUDE_DEFAULT, WIFI_VERSION: version[WIFI_VERSION],
81
+ BLE_VERSION: version[BLE_VERSION], GW_API_VERSION: gw.gw_api_version, ADDITIONAL:dict(cfg)}})
84
82
  elif gw.gw_orig_versions:
85
- conf = {LAT: GW_LATITUDE_DEFAULT, LNG: GW_LONGITUDE_DEFAULT, WIFI_VERSION: gw.gw_orig_versions[WIFI_VERSION],
86
- BLE_VERSION: gw.gw_orig_versions[BLE_VERSION], ADDITIONAL: dict(cfg)}
83
+ return dict({GW_CONF:{LAT: GW_LATITUDE_DEFAULT, LNG: GW_LONGITUDE_DEFAULT, WIFI_VERSION: gw.gw_orig_versions[WIFI_VERSION],
84
+ BLE_VERSION: gw.gw_orig_versions[BLE_VERSION], GW_API_VERSION: gw.gw_api_version, ADDITIONAL:dict(cfg)}})
87
85
  # Protection for FDM gw config
88
86
  else:
89
- conf = {LAT: GW_LATITUDE_DEFAULT, LNG: GW_LONGITUDE_DEFAULT, ADDITIONAL: dict(cfg)}
90
- # If api version was not sent in gw info then the gw_api_version is None, we don't want to set it in the config
91
- if gw.gw_api_version is not None:
92
- conf[GW_API_VERSION] = gw.gw_api_version
93
- return dict({GW_CONF: conf})
87
+ return dict({GW_CONF:{LAT: GW_LATITUDE_DEFAULT, LNG: GW_LONGITUDE_DEFAULT, GW_API_VERSION: gw.gw_api_version,
88
+ ADDITIONAL:dict(cfg)}})
94
89
 
95
90
  def gw_downlink(test, raw_tx_data="", is_ota=False, version="", max_duration=100, max_retries=8, target=DUT):
96
91
  mqttc = test.get_mqttc_by_target(target)
@@ -318,14 +313,14 @@ def brg_configure_ble5(test, cfg_pkt=None, module=None, fields=None, values=None
318
313
  if wait is False:
319
314
  return test, DONE
320
315
  while not pkts_found:
321
- if ((datetime.datetime.now() - start_time).seconds > BLE5_MAX_DURATION_SEC):
316
+ if ((datetime.datetime.now() - start_time).seconds > ((ag.BLE5_PARAM_PRIMARY_CHANNEL_SCAN_CYCLE/1000)+1)):
322
317
  if num_of_tries < 3:
323
318
  num_of_tries += 1
324
319
  start_time = datetime.datetime.now()
325
320
  gw_downlink(test=test, raw_tx_data=cfg_pkt.dump(), max_duration=BLE5_MAX_DURATION_MS, max_retries=BLE5_MAX_RETRIES, target=target)
326
- print(f"Brg configure - BLE5 mode : No pkts found after {BLE5_MAX_DURATION_SEC} seconds, in try number {num_of_tries}")
321
+ 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}")
327
322
  else:
328
- test.add_reason(f"Brg configure - BLE5 mode : No pkts found after {BLE5_MAX_DURATION_SEC} seconds, in 3 tries")
323
+ test.add_reason(f"Brg configure - BLE5 mode : No pkts found after {BLE5_MAX_DURATION_MS} seconds, in 3 tries")
329
324
  test.rc = TEST_FAILED
330
325
  time.sleep(1)
331
326
  mqttc.flush_pkts()
@@ -351,35 +346,15 @@ def send_brg_action(test, action_id, target=DUT, **kwargs):
351
346
  action_pkt = get_default_brg_pkt(test, pkt_type=eval_pkt(f'{ag.ACTIONS_DICT[action_id]}{brg.api_version}'), **kwargs)
352
347
  gw_downlink(test, raw_tx_data=action_pkt.dump(), target=target)
353
348
 
354
- def backward_compatible_handler(test, pkt_type, **kwargs):
355
- datapath_output_power = 8
356
- energy_2400_output_power = 2
357
- calibration_output_power = 2
358
- init_params = inspect.signature(pkt_type.__init__).parameters
359
- safe_kwargs = {}
360
- for k, v in kwargs.items():
361
- if k in init_params:
362
- safe_kwargs[k] = v
363
- else:
364
- utPrint(f"WARNING: Parameter {k} not in {pkt_type.__name__} parameters, ignoring it!", "WARNING")
365
-
366
- if test.active_brg.api_version < ag.API_VERSION_V13:
367
- if "ModuleDatapathV12" in pkt_type.__name__ and BRG_OUTPUT_POWER not in safe_kwargs:
368
- safe_kwargs.update({BRG_OUTPUT_POWER: datapath_output_power})
369
- if "ModuleEnergy2400V12" in pkt_type.__name__ and BRG_OUTPUT_POWER not in safe_kwargs:
370
- safe_kwargs.update({BRG_OUTPUT_POWER: energy_2400_output_power})
371
- if "ModuleCalibrationV12" in pkt_type.__name__ and BRG_OUTPUT_POWER not in safe_kwargs:
372
- safe_kwargs.update({BRG_OUTPUT_POWER: calibration_output_power})
373
- return safe_kwargs
374
-
375
349
  def get_default_brg_pkt(test, pkt_type, group_id=ag.GROUP_ID_GW2BRG, seq_id=0, target=DUT, **kwargs):
376
350
  brg = get_brg_by_target(test, target)
377
351
  seq_id = test.get_seq_id() if seq_id == 0 else seq_id
378
- safe_kwargs = backward_compatible_handler(test, pkt_type, **kwargs)
379
352
  # Bypass from default sub1g ep cfg of 0 (no energizing) ONLY if not using data simulation
380
- if "ModuleEnergySub1G" in pkt_type.__name__ and BRG_PATTERN not in safe_kwargs and test.data != DATA_SIMULATION:
381
- safe_kwargs.update({BRG_PATTERN: ag.SUB1G_ENERGY_PATTERN_ISRAEL})
382
- brg_pkt = WltPkt(hdr=ag.Hdr(group_id=group_id), pkt=pkt_type(brg_mac=brg.id_int if brg else 0, seq_id=seq_id, **safe_kwargs))
353
+ if "ModuleEnergySub1G" in pkt_type.__name__ and BRG_PATTERN not in kwargs and test.data != DATA_SIMULATION:
354
+ # TODO - Remove on next api_version update - this is a patch for parameter name change from api version 11 to 12
355
+ brg_pattern = "sub1g_energy_" + BRG_PATTERN if brg.api_version < ag.API_VERSION_V12 else BRG_PATTERN
356
+ kwargs.update({brg_pattern: ag.SUB1G_ENERGY_PATTERN_ISRAEL})
357
+ brg_pkt = WltPkt(hdr=ag.Hdr(group_id=group_id), pkt=pkt_type(brg_mac=brg.id_int if brg else 0, seq_id=seq_id, **kwargs))
383
358
  return brg_pkt
384
359
 
385
360
  def config_brg_defaults(test, modules=[], ble5=False, wait=True, target=DUT):
@@ -400,7 +375,7 @@ def config_brg_defaults(test, modules=[], ble5=False, wait=True, target=DUT):
400
375
  utPrint(f"SUCCESS: {module.__name__} configured to defaults", "GREEN")
401
376
  return (test, DONE) if not failed_cfg else (test, NO_RESPONSE)
402
377
 
403
- def brg_ota(test, ble_version, search_ack=True, ble5=False, target=DUT, upgrader=TESTER, timeout=VER_UPDATE_TIMEOUT):
378
+ def brg_ota(test, ble_version, search_ack=True, ble5=False, target=DUT, upgrader=TESTER):
404
379
  brg = get_brg_by_target(test, target)
405
380
  mqttc = test.get_mqttc_by_target(upgrader)
406
381
 
@@ -418,7 +393,7 @@ def brg_ota(test, ble_version, search_ack=True, ble5=False, target=DUT, upgrader
418
393
  gw_downlink(test=test, raw_tx_data=action_pkt.dump(), is_ota=True, version=ble_version, max_duration=BLE5_MAX_DURATION_MS, max_retries=BLE5_MAX_RETRIES, target=upgrader)
419
394
 
420
395
  # expected_hash=1 due to different cfgs and versions between builds
421
- test = cert_common.reboot_config_analysis(test=test, expected_hash=1, ble_version=ble_version, timeout=timeout)
396
+ test = cert_common.reboot_config_analysis(test=test, expected_hash=1, ble_version=ble_version, timeout=VER_UPDATE_TIMEOUT)
422
397
  # for debug - print all logs to see failure reason
423
398
  cert_common.get_gw_logs_packets(test, print_log=True)
424
399
  if test.rc == TEST_FAILED and test.exit_on_param_failure:
@@ -23,10 +23,10 @@ SECONDARY_CHANNEL_10 = 10
23
23
  SECONDARY_CHANNEL_21 = 21
24
24
 
25
25
  # Randomize pixel simulation indicator once per run (6 hex chars)
26
- PIXEL_SIM_INDICATOR = get_random_hex_str(6)
26
+ PIXEL_SIM_INDICATOR = cert_utils.get_random_hex_str(6)
27
27
 
28
28
  def init_adva(flow_version_major=0x4, flow_version_minor=0x34):
29
- return "{0:02X}".format(flow_version_major) + get_random_hex_str(8) + "{0:02X}".format(flow_version_minor)
29
+ return "{0:02X}".format(flow_version_major) + cert_utils.get_random_hex_str(8) + "{0:02X}".format(flow_version_minor)
30
30
 
31
31
  random_bytes = lambda n: int.from_bytes(os.urandom(n), "big")
32
32
 
@@ -41,16 +41,15 @@ def brg_pkt_gen(num_of_pkts_per_brg, num_of_brgs, brgs_list=[], pkt_type=PIXELS_
41
41
  if brgs_list:
42
42
  brg_mac = brgs_list[i]
43
43
  else:
44
- brg_mac = cert_common.hex2alias_id_get(get_random_hex_str(12))
44
+ brg_mac = cert_common.hex2alias_id_get(cert_utils.get_random_hex_str(12))
45
45
  bridge_ids.append(brg_mac)
46
46
  adva = cert_common.change_endianness(brg_mac) # Change endianness to little endian
47
-
47
+
48
48
  for j in range(num_of_pkts_per_brg):
49
- serial_pkt_id = f"{i % 256:02X}{j % 256:02X}{idx:04X}" # 8 hex chars - 4 bytes
50
-
49
+ serial_pkt_id = f"{i % 256:02X}{j % 256:02X}{idx:04X}"
50
+
51
51
  if pkt_type == PIXELS_PKT:
52
- payload = (ag.Hdr(group_id=ag.GROUP_ID_UNIFIED_PKT_V2).dump() +
53
- indicator + brg_mac + get_random_hex_str(22) + serial_pkt_id)
52
+ payload = ag.Hdr(group_id=ag.GROUP_ID_UNIFIED_PKT_V2).dump() + indicator + cert_utils.get_random_hex_str(34) + serial_pkt_id
54
53
 
55
54
  if pkt_type == MGMT_PKT:
56
55
  mgmt_pkt = eval_pkt(f'GenericV{ag.API_VERSION_LATEST}')
@@ -58,12 +57,10 @@ def brg_pkt_gen(num_of_pkts_per_brg, num_of_brgs, brgs_list=[], pkt_type=PIXELS_
58
57
  payload = ag.Hdr(group_id=ag.GROUP_ID_BRG2GW).dump() + body.dump()[:-14] + indicator + serial_pkt_id
59
58
 
60
59
  if pkt_type == SENSOR_PKT:
61
- payload = (ag.Hdr(uuid_msb=ag.HDR_DEFAULT_BRG_SENSOR_UUID_MSB, uuid_lsb=ag.HDR_DEFAULT_BRG_SENSOR_UUID_LSB).dump() +
62
- indicator + brg_mac + get_random_hex_str(22) + serial_pkt_id)
60
+ payload = ag.Hdr(uuid_msb=ag.HDR_DEFAULT_BRG_SENSOR_UUID_MSB, uuid_lsb=ag.HDR_DEFAULT_BRG_SENSOR_UUID_LSB).dump() + indicator + cert_utils.get_random_hex_str(34) + serial_pkt_id
63
61
 
64
62
  if pkt_type == SIDE_INFO_SENSOR_PKT:
65
- payload = (ag.Hdr(group_id=ag.GROUP_ID_SIDE_INFO_SENSOR).dump() +
66
- indicator + brg_mac + get_random_hex_str(22) + serial_pkt_id)
63
+ payload = ag.Hdr(group_id=ag.GROUP_ID_SIDE_INFO_SENSOR).dump() + indicator + cert_utils.get_random_hex_str(34) + serial_pkt_id
67
64
 
68
65
  idx += 1
69
66
  pkts += [GenericPkt(adva=adva, payload=payload)]
@@ -1,16 +1,11 @@
1
1
  # Files
2
2
  import os
3
- import random
4
3
  import datetime
5
4
  import importlib.metadata
6
5
  import certificate.ag.wlt_types_ag as ag
7
-
8
- get_random_hex_str = lambda n: ''.join([random.choice('0123456789ABCDEF') for _ in range(n)])
9
-
10
6
  # BASE_DIR should be initiated in the same dir as certificate.py
11
7
  BASE_DIR = os.path.dirname(os.path.abspath(__file__))
12
8
  ARTIFACTS_DIR = os.path.join(os.getcwd(), f"cert_artifacts_{datetime.datetime.now().strftime("%d_%m_%Y__%H_%M_%S")}")
13
-
14
9
  # CERT_VERSION handling - local/PyPi
15
10
  LOCAL_DEV = "local-dev"
16
11
  try:
@@ -19,7 +14,6 @@ except importlib.metadata.PackageNotFoundError:
19
14
  CERT_VERSION = LOCAL_DEV
20
15
  CERT_MQTT_LOG_FILE = "cert_mqtt_log.json"
21
16
  DATA_SIM_LOG_FILE = "data_sim_log.txt"
22
- RESULT_NOTES_FILE = "results_notes.txt"
23
17
  UT_RESULT_FILE_HTML = "results.html"
24
18
  UT_RESULT_FILE_PDF = "results.pdf"
25
19
  UTILS_BASE_REL_PATH = "../../../utils"
@@ -283,7 +277,6 @@ GW_LONGITUDE_DEFAULT = -117.0839
283
277
  GW_API_VER_DEFAULT = "201"
284
278
  GW_API_VER_OLD = "200"
285
279
  GW_API_VER_LATEST = "206"
286
- API_OLDEST_SUPPORTED_VERSION = ag.API_VERSION_V12
287
280
  BRG_CFG_HAS_LEN = 2
288
281
  CLEAR_DATA_PATH_TIMEOUT = 10
289
282
  ACTION_LONG_TIMEOUT = 120
@@ -307,7 +300,6 @@ BLE5_MAX_DURATION_SEC = BLE5_MAX_DURATION_MS // 1000
307
300
  DATA_SIM_EVENT_TESTING_DELAY_SEC = DATA_SIM_EVENT_TESTING_DELAY_MS / 1000
308
301
  DATA_SIM_RSSI_EVENT_TESTING_DELAY_SEC = DATA_SIM_RSSI_EVENT_TESTING_DELAY_MS / 1000
309
302
  DATA_SIM_EVENT_PACER_INTERVAL_TESTING = 10
310
- RSSI_EVENT_PKTS_TO_STABILIZE = 13 # The alpha filter takes about 13 packets to stabilize
311
303
  PACKETS_ECHO_OFF = 16
312
304
  TEST_PASSED = 0
313
305
  TEST_FAILED = -1
@@ -350,7 +342,6 @@ MODULE = "module"
350
342
  NAME = "name"
351
343
  DOCUMENTATION = "documentation"
352
344
  ALL_SUPPORTED_VALUES = "allSupportedValues"
353
- SUPPORTED_FROM_API_VERSION = "SupportedFromApiVersion"
354
345
  PRE_CONFIG = "Pre Configuration"
355
346
  TEST_BODY = "Test Body"
356
347
  RESTORE_CONFIG = "Restore Configuration"
@@ -198,7 +198,7 @@ def gw_app_reponse(ble_serial):
198
198
  start_time = datetime.datetime.now()
199
199
  while (datetime.datetime.now() - start_time).seconds < 2:
200
200
  input = read_from_ble(ble_serial)
201
- if input is not None and GW_APP_VERSION_HEADER in input:
201
+ if GW_APP_VERSION_HEADER in input:
202
202
  print(input)
203
203
  ble_chip_sw_ver = re.search(r'WILIOT_GW_BLE_CHIP_SW_VER=(\d+\.\d+\.\d+)', input).group(1)
204
204
  ble_mac_address = re.search(r'WILIOT_GW_BLE_CHIP_MAC_ADDRESS=([0-9A-F]{12})', input).group(1)
@@ -255,9 +255,6 @@ def interference_analysis(ble_serial):
255
255
  for key in CNTRS_KEYS:
256
256
  diff_dict[key] = handle_wrap_around(end_cntrs[key] - start_cntrs[key])
257
257
  bad_crc_percentage = round((diff_dict[BAD_CRC] / (diff_dict[WLT_RX] + diff_dict[NON_WLT_RX])) * 100)
258
- notes_file_path = os.path.join(ARTIFACTS_DIR, RESULT_NOTES_FILE)
259
- with open(notes_file_path, "a") as f:
260
- f.write(f'Channel {channel[0]} ({channel[1]} MHz) Ambient Interference (bad CRC percentage): {bad_crc_percentage}%\n')
261
258
  print(color('WARNING', f'Channel {channel[0]} ({channel[1]} MHz) Ambient Interference (bad CRC percentage) is: {bad_crc_percentage}%'))
262
259
  print(f'Good CRC packets = {diff_dict[NON_WLT_RX] + diff_dict[WLT_RX] - diff_dict[BAD_CRC]}, bad CRC packets: {diff_dict[BAD_CRC]}')
263
260
 
@@ -327,42 +324,21 @@ def parse_uart_pkts(input, mqttc, custom_broker, gw_id, seq_id):
327
324
  def handle_cmds(input, ble_serial):
328
325
  if input.startswith(RX_NORDIC_RECOVER_RESET):
329
326
  utPrint(f"Simulator received reboot packet", "CYAN")
330
- global GW_SIM_RESET_TS
331
327
  GW_SIM_RESET_TS = datetime.datetime.now()
332
328
  write_to_ble(ble_serial, RESET_GW, sleep=0)
333
329
  if input.startswith(RX_NORDIC_RECOVER_NORESET):
334
- utPrint(f"COM tester recovered", "CYAN")
330
+ utPrint(f"Simulator recovered", "CYAN")
335
331
  write_to_ble(ble_serial, f"{CONNECTIVITY_STATUS} 1 1")
336
332
 
337
- def validate_port(port):
338
- try:
339
- with serial.serial_for_url(url=port, baudrate=921600, timeout=SERIAL_TIMEOUT,
340
- write_timeout=SERIAL_TIMEOUT * 10) as ser:
341
- ser.flushInput()
342
- write_to_ble(ser, txt=VERSION, print_enable=True)
343
- start_time = datetime.datetime.now()
344
- while (datetime.datetime.now() - start_time).seconds < 2:
345
- input = read_from_ble(ser)
346
- if input is not None and GW_APP_VERSION_HEADER in input:
347
- return True
348
- return False
349
- except Exception as e:
350
- utPrint(f"Failed to open serial: {e}", "RED")
351
- return False
352
-
353
-
354
- def gw_sim_run(port, gw_id, custom_broker, disable_interference_analyzer=False):
333
+ def gw_sim_run(port, gw_id, custom_broker, analyze_interference=False):
355
334
 
356
335
  # Init serial side
357
336
  if not port:
358
337
  print("\nNo COM port given. Scanning for available ports:")
359
338
  for port, desc, hwid in sorted(serial.tools.list_ports.comports()):
360
339
  print("{}: {} [{}]".format(port, desc, hwid))
361
- if validate_port(port):
362
- utPrint(f"Found the tester's port ({port})", "GREEN")
363
- break
364
340
  if not port:
365
- print("\nNo available COM port found! Please verify a tester is connected and set the correct --port parameter.")
341
+ print("\nNo available COM port found!")
366
342
  sys.exit(-1)
367
343
  print(f"###>>> GW SIM STARTED WITH PORT {port}")
368
344
  ble_serial = serial.serial_for_url(url=port, baudrate=921600, timeout=SERIAL_TIMEOUT)
@@ -391,19 +367,15 @@ def gw_sim_run(port, gw_id, custom_broker, disable_interference_analyzer=False):
391
367
  write_to_ble(ble_serial, RESET_GW, sleep=5)
392
368
  gw_app_res = gw_app_reponse(ble_serial)
393
369
  if gw_app_res[0] == TEST_FAILED:
394
- utPrint("ERROR: didn't get version response! Please verify a tester is connected and set the correct --port parameter.", "RED")
395
- sys.exit(1)
396
- if gw_app_res[2] not in cert_utils.TESTER_FW_VERSIONS:
397
- utPrint(f"ERROR: Tester FW version={gw_app_res[2]} instead of versions={cert_utils.TESTER_FW_VERSIONS}!\n"
398
- f"Please run the command wlt-cert-tester-upgrade to upgrade the tester firmware!", "RED")
399
- sys.exit(1)
370
+ print("ERROR: didn't get version response!")
371
+ return
400
372
  os.environ[GW_SIM_BLE_MAC_ADDRESS] = gw_app_res[1]
401
373
  os.environ[GW_APP_VERSION_HEADER] = gw_app_res[2]
402
374
  write_to_ble(ble_serial, STOP_ADVERTISING, sleep=2)
403
375
  write_to_ble(ble_serial, f"{CONNECTIVITY_STATUS} 1 1")
404
376
 
405
377
  # Run interference analysis
406
- if not disable_interference_analyzer:
378
+ if analyze_interference:
407
379
  print(color("BLUE", f"\nStarting interference analysis for channels {[ch[0] for ch in CHANNELS_TO_ANALYZE]}. This will take {30 * len(CHANNELS_TO_ANALYZE)} seconds (total)"))
408
380
  interference_analysis(ble_serial)
409
381
 
certificate/cert_mqtt.py CHANGED
@@ -198,8 +198,7 @@ def on_message_json(mqttc, userdata, message):
198
198
  wlt_mqtt_pkts = userdata[PKTS]
199
199
  data = json.loads(message.payload.decode("utf-8"))
200
200
  wlt_mqtt_pkts.insert(WltMqttPkt(data, message.topic, userdata))
201
- text = json.dumps(json.loads(message.payload.decode("utf-8")), indent=4)
202
- write_to_mqtt_log_file("// JSON message received at {}, topic={}:\n{}\n".format(datetime.datetime.now().strftime("%d/%m/%Y, %H:%M:%S"), message.topic, text))
201
+ write_to_mqtt_log_file("// JSON message received at {}, topic={}:\n{}\n".format(datetime.datetime.now().strftime("%d/%m/%Y, %H:%M:%S"), message.topic, str(message.payload.decode("utf-8"))))
203
202
 
204
203
  def on_message_protobuf(mqttc, userdata, message):
205
204
  pb_msg = None
@@ -223,8 +222,7 @@ def on_message_protobuf(mqttc, userdata, message):
223
222
  # Align formats with JSON (bytes to hex strings)
224
223
  if 'status' in message.topic:
225
224
  if ACTION_STATUS in pb_msg_dict:
226
- if BRIDGE_ID in pb_msg_dict[ACTION_STATUS].keys():
227
- pb_msg_dict[ACTION_STATUS][BRIDGE_ID] = base64.b64decode(pb_msg_dict[ACTION_STATUS][BRIDGE_ID]).hex().upper()
225
+ pb_msg_dict[ACTION_STATUS][BRIDGE_ID] = base64.b64decode(pb_msg_dict[ACTION_STATUS][BRIDGE_ID]).hex().upper()
228
226
  if GW_STATUS in pb_msg_dict and ACL_IDS in pb_msg_dict[GW_STATUS][CONFIG][ACL][ACL_VALUE]:
229
227
  ids_list = pb_msg_dict[GW_STATUS][CONFIG][ACL][ACL_VALUE][ACL_IDS]
230
228
  for idx, id in enumerate(ids_list):
@@ -266,9 +264,9 @@ def load_custom_broker(broker_filepath, gw):
266
264
  except FileNotFoundError:
267
265
  raise FileNotFoundError(f"No such file: {broker_filepath}")
268
266
  data = json.load(f)
269
- data[CUSTOM_BROKER_UPDATE_TOPIC] = data[CUSTOM_BROKER_UPDATE_TOPIC].replace(f'<{GW_ID}>', gw)
270
- data[CUSTOM_BROKER_STATUS_TOPIC] = data[CUSTOM_BROKER_STATUS_TOPIC].replace(f'<{GW_ID}>', gw)
271
- data[CUSTOM_BROKER_DATA_TOPIC] = data[CUSTOM_BROKER_DATA_TOPIC].replace(f'<{GW_ID}>', gw)
267
+ data[CUSTOM_BROKER_UPDATE_TOPIC] += gw
268
+ data[CUSTOM_BROKER_STATUS_TOPIC] += gw
269
+ data[CUSTOM_BROKER_DATA_TOPIC] += gw
272
270
  return data
273
271
 
274
272
  def mqttc_init(gw_id, custom_broker, data=DATA_REAL_TAGS):
@@ -300,14 +298,6 @@ def mqttc_init(gw_id, custom_broker, data=DATA_REAL_TAGS):
300
298
  mqttc.subscribe(mqttc.status_topic)
301
299
  print(f"Subscribed to status topic: {mqttc.status_topic}")
302
300
 
303
- # v2 protobuf topics
304
- mqttc.data_topic_pb = re.sub(r'^([^/]+)', r'\1-v2', custom_broker[CUSTOM_BROKER_DATA_TOPIC])
305
- mqttc.subscribe(mqttc.data_topic_pb)
306
- print(f"Subscribed to data topic: {mqttc.data_topic_pb}")
307
- mqttc.status_topic_pb = re.sub(r'^([^/]+)', r'\1-v2', custom_broker[CUSTOM_BROKER_STATUS_TOPIC])
308
- mqttc.subscribe(mqttc.status_topic_pb)
309
- print(f"Subscribed to status topic: {mqttc.status_topic_pb}")
310
-
311
301
  mqttc.flush_pkts = mqttc._userdata[PKTS].flush
312
302
  mqttc.flush_data_pkts = mqttc._userdata[PKTS].flush_data
313
303
  mqttc.flush_status_pkts = mqttc._userdata[PKTS].flush_status
@@ -18,7 +18,6 @@ COLORS = {
18
18
  }
19
19
  color = lambda c, t : COLORS["BOLD"]+COLORS[c]+t+COLORS["ENDC"]
20
20
  pipeline_running = lambda : True if 'BITBUCKET_BUILD_NUMBER' in os.environ else False
21
- is_quiet_setup_running = lambda : True if 'CI_GW' in os.environ else False
22
21
  camelcase_to_title = lambda s: ' '.join(word.capitalize() for word in re.split('(?=[A-Z])', s))
23
22
  SEP = '\n' + '#'*100 + '\n'
24
23
  SEP2 = '\n' + '#'*100 + '\n' + '#'*100 + '\n'