/* Cesar project {{{ * * Copyright (C) 2008 Spidcom * * <<>> * * }}} */ /** * \file src/beacon.c * \brief Unit test for the beacon module. * \ingroup cp_beacon * * « long description » */ #include "common/std.h" #include "lib/slist.h" #include "lib/test.h" #include "lib/circular_buffer.h" #include "mac/common/ntb.h" #include "mac/common/store.h" #include "cp/beacon/beacon.h" #include "cp/av/beacon/discover.h" #include "cp/cp.h" #include "cp/inc/context.h" #include "cl/inc/context.h" #include "mac/sar/inc/context.h" #define TEST_CCO_MAC 0x0013d7001001ull void cp_beacon_receive (cp_t *ctx, bsu_beacon_t *beacon); void cp_beacon_sta_compute_schedules (cp_t *ctx, bsu_beacon_t *beacon_data); struct test_beacon_t { cp_t cp; mac_config_t mac_config; cl_t cl; sar_t sar; bsu_aclf_t aclf; uint ca; bool bsu_updated; }; typedef struct test_beacon_t test_beacon_t; void test_beacon_init (test_beacon_t *ctx) { memset (ctx, 0, sizeof (test_beacon_t)); lib_rnd_init (&ctx->cp.rnd, 0x1234); ctx->cp.mac_config = &ctx->mac_config; ctx->cp.sar = &ctx->sar; ctx->cp.cl = &ctx->cl; ctx->cp.bsu_aclf = &ctx->aclf; ctx->cp.bsu = (bsu_t *) &ctx->bsu_updated; *((bsu_aclf_frequency_t*) &ctx->aclf.frequency) = BSU_ACLF_FREQ_50HZ; *((bsu_aclf_bp_t*) &ctx->aclf.beacon_period_theo_tck) = BSU_ACLF_BP_50HZ_TCK; ctx->aclf.beacon_period_tck = ctx->aclf.beacon_period_theo_tck; ctx->cp.mac_store = mac_store_init(); ctx->cp.ca = (ca_t*) &ctx->ca; cp_sta_mgr_init (&ctx->cp); cp_cco_bw_init (&ctx->cp); cp_cco_region_init (&ctx->cp); cp_beacon_init (&ctx->cp); ctx->cp.beacon.last_countdown_call_date_active = true; } void test_beacon_uninit (test_beacon_t *ctx) { cp_beacon_uninit (&ctx->cp); cp_cco_bw_uninit (&ctx->cp); cp_cco_region_uninit (&ctx->cp); cp_sta_mgr_uninit (&ctx->cp); mac_store_uninit (ctx->cp.mac_store); } bsu_beacon_t* test_new_beacon (void) { /** Create a central beacon. */ bsu_beacon_t *beacon = blk_alloc (); dbg_assert (beacon); memset (beacon, 0, sizeof (bsu_beacon_t)); beacon->vf.nid = 1; beacon->vf.stei = 1; beacon->vf.bt = BSU_BEACON_TYPE_CENTRAL; beacon->vf.hm = MAC_COEXISTENCE_FULL_HYBRID_MODE; beacon->vf.ncnr = false; beacon->vf.npsm = false; beacon->vf.numslots = 0; beacon->vf.slotusage = 0; beacon->vf.slotid = 0; beacon->vf.aclsss = true; beacon->vf.hoip = false; beacon->vf.rtsbf = false; beacon->vf.nm = MAC_NM_CSMA_ONLY; beacon->vf.ccocap = 0; beacon->bmis.change_snid.present = true; beacon->bmis.change_snid.snidccd = 3; beacon->bmis.change_snid.new_snid = 0xC; beacon->bmis.mac_address.present = true; beacon->bmis.mac_address.mac_address = TEST_CCO_MAC; beacon->bmis.region.nb = 1; beacon->bmis.region.region[0].end_time_atu = 3907; beacon->bmis.region.region[0].rt = CP_CCO_REGION_TYPE_BEACON; beacon->bmis.nps.ns = 1; beacon->bmis.nps.sais[0].end_time_atu = 3907; beacon->bmis.nps.sais[0].glid = 0x45; beacon->bmis.nps.sais[0].stpf = false; beacon->bmis.nbe = 4; beacon->params.rx_parameters.snid = 0; beacon->params.rx_parameters.access = HPAV_ACCESS_IN_HOME; beacon->params.direction = BSU_BEACON_DIRECTION_FROM_PLC; beacon->params.frequency_error_valid = false; return beacon; } /** Uninitialise * \param test the test object. * * The uninit procedure, shall stop the timers and release all the object * referenced by the beacon module. * * * Stop the HAL timer * * Stop the eCos timer * * Release all beacon received and not processed yet. * * Call the uninit function for the common sub context. * * Environment * This test shall insert some data in the pointers and the context. * * 1. Add at least two beacon in the received list. * 2. Add a central beacon in the central sub context. * 3. Add a discover beacon in the discover sub context. * 4. Add a proxy beacon in the discover sub context. * * Result * At the end the beacon module shall not have any referenced on any object. */ void test_case_beacon_uninit (test_t test) { test_case_begin (test, "Beacon uninit"); test_begin (test, "remove beacons received") { test_beacon_t ctx; test_beacon_init (&ctx); bsu_beacon_t *b; uint i; for (i = 0; i < 2; i++) { b = blk_alloc (); b->next = NULL; b->params.direction = BSU_BEACON_DIRECTION_FROM_PLC; cp_beacon_receive (&ctx.cp, b); } test_beacon_uninit (&ctx); test_fail_unless (slist_empty (ctx.cp.beacon.list., bare)); } test_end; } void test_case_beacon__deactivate (test_t test) { test_case_begin (test, "Deactivate"); test_begin (test, "Deactivate beacon module") { test_beacon_t ctx; uint nb_beacons = 2; test_beacon_init (&ctx); /* Still configuring the test... */ ctx.cp.beacon.leon_timer.status = true; /* Allocate some beacons. */ uint i; for (i = 0; i < nb_beacons; i++) { bsu_beacon_t *beacon = blk_alloc (); beacon->next = NULL; slist_push_back (ctx.cp.beacon.list., beacon, bare); } /* test. */ cp_beacon_deactivate (&ctx.cp); test_fail_unless (slist_empty (ctx.cp.beacon.list., bare)); test_beacon_uninit (&ctx); test_fail_if (blk_check_memory () != true, "Memory leaks"); } test_end; } static void test_beacon_variant_field (test_t test, bsu_beacon_t *beacon, cp_nid_t nid, mac_coexistence_mode_t hm, u8 slot_usage, u8 slot_id, bool hoipflag) { test_begin (test, "variant field: Constant values") { test_fail_unless (beacon->vf.ncnr == CP_BEACON_NON_COORDINATED_NETWORK); test_fail_unless (beacon->vf.npsm == CP_BEACON_NPSM_NOT_ACTIVE); test_fail_unless (beacon->vf.numslots == 1); test_fail_unless (beacon->vf.aclsss == 0); test_fail_unless (beacon->vf.rtsbf == false); test_fail_unless (beacon->vf.nm == MAC_NM_CSMA_ONLY); test_fail_unless (beacon->vf.ccocap == CP_CCO_LEVEL); } test_end; test_begin (test, "Variant field: variant fields") { test_fail_unless (beacon->vf.nid == nid); test_fail_unless (beacon->vf.hm == hm); test_fail_unless (beacon->vf.slotusage == slot_usage); test_fail_unless (beacon->vf.slotid == slot_id); test_fail_unless (beacon->vf.hoip == hoipflag); } test_end; } static void test_beacon_discover_info (test_t test, bsu_beacon_t *beacon, bool updated, bool cco_status, bool pco_status, u8 nb_sta, u8 nb_net, bool authenticated) { test_begin (test, "Beacon entries : discover info") { u32 info_data; bitstream_t bitstream; bitstream_write_init (&bitstream, &info_data, 4); bitstream_write (&bitstream, (int)updated, 1); bitstream_write (&bitstream, CP_CCO_LEVEL, 2); bitstream_write (&bitstream, CP_PCO_CAP, 1); bitstream_write (&bitstream, CP_BACKUP_CCO_CAP, 1); bitstream_write (&bitstream, cco_status, 1); bitstream_write (&bitstream, pco_status, 1); bitstream_write (&bitstream, false, 1); bitstream_write (&bitstream, nb_sta, 8); bitstream_write (&bitstream, nb_net, 8); bitstream_write (&bitstream, authenticated, 1); bitstream_write (&bitstream, false, 1); bitstream_write (&bitstream, 0, 6); bitstream_finalise (&bitstream); /* discover info data are always present */ test_fail_unless (beacon->bmis.discover_info.present == true); test_fail_unless (beacon->bmis.discover_info.info_data == info_data); } test_end; } static void test_beacon_bentries (test_t test, bsu_beacon_t *beacon, bool disc_flag, cp_tei_t disc_tei, uint hoip_cd, cp_tei_t hoip_tei, uint kc_cd, enum bsu_beacon_eks_kbc_t kbc, u8 eks, mac_coexistence_mode_t new_hm, uint snid_cd, cp_snid_t new_snid) { test_begin (test, "Beacon entries") { /* Discover. */ test_fail_unless (beacon->bmis.discover.present == disc_flag); if (disc_flag) test_fail_unless (beacon->bmis.discover.tei == disc_tei); /* Handover in progress. */ if (beacon->bmis.handover.present) { test_fail_unless (beacon->bmis.handover.hcd == hoip_cd); test_fail_unless (beacon->bmis.handover.tei == hoip_tei); } /* eks. */ if (beacon->bmis.eks.present) { test_fail_unless (beacon->bmis.eks.kccd == kc_cd); test_fail_unless (beacon->bmis.eks.kbc == kbc); test_fail_unless (beacon->bmis.eks.new_eks == eks); } /* Change hm. */ if (beacon->bmis.change_hm.present) { test_fail_unless (beacon->bmis.change_hm.hmccd == CP_BEACON_COUNTDOWN_HM); test_fail_unless (beacon->bmis.change_hm.newhm == new_hm); } /* Change snid. */ if (beacon->bmis.change_snid.present) { test_fail_unless (beacon->bmis.change_snid.snidccd == snid_cd); test_fail_unless (beacon->bmis.change_snid.new_snid == new_snid); } /* others. */ test_fail_unless (beacon->bmis.bpsto.present == true); test_fail_unless (beacon->bmis.mac_address.present == true); test_fail_unless (beacon->bmis.relocation.present == false); test_fail_unless (beacon->bmis.aclsc.present == false); test_fail_unless (beacon->bmis.cns.present == false); } test_end; } void test_suite_beacon__beacon_generation (test_t test) { test_beacon_t ctx; bsu_beacon_t beacon; test_beacon_init (&ctx); /* Data set one */ const cp_nid_t nid_1 = 0x001456789ABCDEF0ull; const cp_tei_t tei_1 = 42; const cp_snid_t snid_1 = 0xFE; const u8 slot_id_1 = 1; enum cp_beacon_hoip_e hoip_flag_1 = CP_BEACON_HOIP_FALSE; const bool cco_flag_1 = true; const bool pco_flag_1 = false; const bool authen_1 = true; const mac_coexistence_mode_t hm_1 = MAC_COEXISTENCE_AV_ONLY_MODE; const uint kc_cd = 0xAB; const enum bsu_beacon_eks_kbc_t kbc = BSU_BEACON_EKS_KBC_NEK; const u8 eks = 0x12; const uint hoip_cd = 0xCD; const cp_tei_t hoip_tei = 44; const mac_coexistence_mode_t new_hm = MAC_COEXISTENCE_FULL_HYBRID_MODE; const u8 snid_cd = 0xA; const cp_snid_t new_snid = 0xF; cp_net_t *net_1 = cp_sta_mgr_add_avln (&ctx.cp, snid_1, nid_1); cp_sta_own_data_set_tei (&ctx.cp, tei_1); cp_net_set_slot_id_and_usage (&ctx.cp, net_1, slot_id_1, 0); cp_sta_mgr_set_our_avln (&ctx.cp, net_1); cp_av_beacon_handover_hoipflag (&ctx.cp, hoip_flag_1); cp_sta_own_data_set_cco_status (&ctx.cp, cco_flag_1); cp_sta_own_data_set_pco_status (&ctx.cp, pco_flag_1); cp_sta_own_data_set_authenticated_status (&ctx.cp, authen_1); ctx.cp.beacon.discover.discover_interval_bp = 10; ((cp_sta_own_data_t *)&ctx.cp.sta_mgr.sta_own_data)->hybrid_mode = hm_1; cp_beacon_change_hm (&ctx.cp, new_hm); ctx.cp.beacon.eks.kccd = kc_cd; ctx.cp.beacon.eks.kbc = kbc; ctx.cp.beacon.eks.new_eks = eks; ctx.cp.beacon.hoip.hoipcd = hoip_cd; ctx.cp.beacon.hoip.cco = hoip_tei; ctx.cp.beacon.snids.snidcd = snid_cd; ctx.cp.beacon.snids.snid = new_snid; ctx.cp.beacon.discover.countdown_bp = 0; // so that the flag is true /* Regions. */ cp_cco_region_alloc_t *region; uint end_time_atu = 3907; region = cp_cco_region_alloc_init (&ctx.cp); region->type = CP_BEACON_REGION_TYPE_SHARED_CSMA; region->end_time_atu = end_time_atu; cp_cco_region_alloc_add (&ctx.cp, &ctx.cp.region.region_list, region); slab_release (region); /* Fill the beacon data share memory */ cp_beacon_fill (&ctx.cp, &beacon); test_suite_begin (test, "Beacon generation"); test_case_begin (test, "fill share memory"); /* Check the variant fields */ test_beacon_variant_field (test, &beacon, nid_1, hm_1, (1 << slot_id_1), slot_id_1, hoip_flag_1); /* Check the discover info field */ test_beacon_discover_info (test, &beacon, true, cco_flag_1, pco_flag_1, 0, 0, authen_1); /* Check most bentry fields */ test_beacon_bentries (test, &beacon, true, tei_1, hoip_cd, hoip_tei, kc_cd, kbc, eks, new_hm, snid_cd, new_snid); /* Check regions bentries */ test_begin (test, "Region") { test_fail_unless (beacon.bmis.region.nb == 1); test_fail_unless (beacon.bmis.region.region[0].rt == CP_BEACON_REGION_TYPE_SHARED_CSMA); test_fail_unless (beacon.bmis.region.region[0].end_time_atu == end_time_atu); } test_end; /* Check schedule bentries */ test_begin (test, "schedule") { test_fail_unless (beacon.bmis.ps.nb == 0); test_fail_unless (beacon.bmis.nps.ns == 0); } test_end; /* Change values */ /* Data set two */ const cp_nid_t nid_2 = 0x001567890ABCDEF0ull; const cp_tei_t tei_2 = 43; const cp_snid_t snid_2 = 0xEF; const u8 slot_id_2 = 2; enum cp_beacon_hoip_e hoip_flag_2 = CP_BEACON_HOIP_TRUE; const bool cco_flag_2 = false; const bool pco_flag_2 = true; const bool authen_2 = false; const mac_coexistence_mode_t hm_2 = MAC_COEXISTENCE_NB - 1; cp_net_t *net_2 = cp_sta_mgr_add_avln (&ctx.cp, snid_2, nid_2); cp_sta_own_data_set_tei (&ctx.cp, tei_2); cp_net_set_slot_id_and_usage (&ctx.cp, net_2, slot_id_2, 0); cp_sta_mgr_set_our_avln (&ctx.cp, net_2); cp_av_beacon_handover_hoipflag (&ctx.cp, hoip_flag_2); cp_sta_own_data_set_cco_status (&ctx.cp, cco_flag_2); cp_sta_own_data_set_pco_status (&ctx.cp, pco_flag_2); cp_sta_own_data_set_authenticated_status (&ctx.cp, authen_2); ((cp_sta_own_data_t *)&ctx.cp.sta_mgr.sta_own_data)->hybrid_mode = hm_2; ctx.cp.beacon.eks.kccd = 0; ctx.cp.beacon.hoip.hoipcd = 0; ctx.cp.beacon.snids.snidcd = 0; ctx.cp.beacon.hm.hmcd = 0; /* Regions. */ region = cp_cco_region_alloc_init (&ctx.cp); region->type = CP_BEACON_REGION_TYPE_BEACON; region->end_time_atu = end_time_atu - 10; cp_cco_region_alloc_add (&ctx.cp, &ctx.cp.region.region_list, region); slab_release (region); region = cp_cco_region_alloc_init (&ctx.cp); region->type = CP_BEACON_REGION_TYPE_STAYOUT; region->end_time_atu = end_time_atu + 10; cp_cco_region_alloc_add (&ctx.cp, &ctx.cp.region.region_list, region); slab_release (region); /* Schedules. */ uint nb, ns; int i; cp_cco_bw_alloc_t *sched; for (i = 1, nb = 0; i < 8; i += 6, nb++) { for (ns=0; ns < 2; ns++) { sched = cp_cco_bw_alloc_init (&ctx.cp); sched->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_PERSISTENT; sched->pscd = i; sched->cscd = i; sched->stpf = false; sched->glid = 0x55 + nb; sched->end_time_atu = end_time_atu + nb * 10 + ns * 5; sched->start_time_atu = end_time_atu + nb * 10 + ns * 5 -4; cp_cco_bw_alloc_add (&ctx.cp, &ctx.cp.bw.alloc_list, sched); slab_release (sched); } } for (ns = 0; ns < BSU_BEACON_BMIS_SCHEDULES_SAI_MAX; ns++) { sched = cp_cco_bw_alloc_init (&ctx.cp); sched->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT; sched->pscd = ns; sched->cscd = ns; sched->stpf = false; sched->glid = 0x45 + ns; sched->start_time_atu = end_time_atu - 10 * (ns + 1) -9; sched->end_time_atu = end_time_atu - 10 * (ns + 1); cp_cco_bw_alloc_add (&ctx.cp, &ctx.cp.bw.alloc_list, sched); slab_release (sched); } /* Fill the beacon data share memory */ cp_beacon_fill (&ctx.cp, &beacon); test_suite_begin (test, "Beacon generation 2"); test_case_begin (test, "fill share memory 2"); /* Check the variant fields */ test_beacon_variant_field (test, &beacon, nid_2, hm_2, (1 << slot_id_2) + (1 << slot_id_1), slot_id_2, hoip_flag_2); /* Check the discover info field */ test_beacon_discover_info (test, &beacon, true, cco_flag_2, pco_flag_2, 0, 1, authen_2); /* Check most bentry fields */ test_beacon_bentries (test, &beacon, false, tei_2, 0, 0, 0, 0, 0, 0, 0, 0); /* Check regions bentries */ test_begin (test, "Region 2") { test_fail_unless (beacon.bmis.region.nb == 3); test_fail_unless (beacon.bmis.region.region[0].rt == CP_BEACON_REGION_TYPE_BEACON); test_fail_unless (beacon.bmis.region.region[0].end_time_atu == end_time_atu - 10); test_fail_unless (beacon.bmis.region.region[1].rt == CP_BEACON_REGION_TYPE_SHARED_CSMA); test_fail_unless (beacon.bmis.region.region[1].end_time_atu == end_time_atu); test_fail_unless (beacon.bmis.region.region[2].rt == CP_BEACON_REGION_TYPE_STAYOUT); test_fail_unless (beacon.bmis.region.region[2].end_time_atu == end_time_atu + 10); } test_end; /* Check schedule bentries */ test_begin (test, "schedule 2") { for (i = 1, nb = 0; i < 8; i += 6, nb++) { test_fail_unless (beacon.bmis.ps.ps[nb].pscd == i); test_fail_unless (beacon.bmis.ps.ps[nb].cscd == i); test_fail_unless (beacon.bmis.ps.ps[nb].ns == 2); for (ns = 0; ns < 2; ns++) { test_fail_unless (beacon.bmis.ps.ps[nb].sais[ns].stpf == false); test_fail_unless (beacon.bmis.ps.ps[nb].sais[ns].glid == 0x55 + nb); test_fail_unless ( beacon.bmis.ps.ps[nb].sais[ns].start_time_atu == end_time_atu + nb * 10 + ns * 5 - 4); test_fail_unless ( beacon.bmis.ps.ps[nb].sais[ns].end_time_atu == end_time_atu + nb * 10 + ns * 5); } } test_fail_unless (beacon.bmis.ps.nb == nb); for (i = BSU_BEACON_BMIS_SCHEDULES_SAI_MAX - 1, ns = 0; i >= 0; i--, ns++) { test_fail_unless (beacon.bmis.nps.sais[ns].stpf == false); test_fail_unless (beacon.bmis.nps.sais[ns].glid == 0x45 + i); test_fail_unless ( beacon.bmis.nps.sais[ns].start_time_atu == end_time_atu - (i + 1) * 10 - 9); test_fail_unless ( beacon.bmis.nps.sais[ns].end_time_atu == end_time_atu - (i + 1) * 10); } test_fail_unless (beacon.bmis.nps.ns == ns); } test_end; test_beacon_uninit (&ctx); } void test_case_beacon_snid_change_cco (test_t test) { uint snid; cp_net_t *net; test_beacon_t ctx; test_case_begin (test, "CCo"); test_beacon_init (&ctx); net = cp_sta_mgr_add_avln (&ctx.cp, 0xA, 1); cp_sta_own_data_set_snid (&ctx.cp, 0xA); cp_sta_own_data_set_tei (&ctx.cp, 1); cp_sta_mgr_set_our_avln (&ctx.cp, net); cp_sta_own_data_set_cco_status (&ctx.cp, true); cp_sta_own_data_set_mac_address (&ctx.cp, 0x123456789ABCull); test_begin (test, "Change SNID") { /* Process the test. */ test_fail_unless (ctx.cp.beacon.snids.snid == 0); test_fail_unless (ctx.cp.beacon.snids.snidcd == 0); snid = 1; cp_beacon_change_snid (&ctx.cp, snid); test_fail_unless (ctx.cp.beacon.snids.snid == snid); test_fail_unless (ctx.cp.beacon.snids.snidcd == CP_BEACON_COUNTDOWN_SNID); } test_end; test_begin (test, "Change SNID, check bentry in Central beacon") { cp_cco_region_alloc_t *region; cp_cco_bw_alloc_t *alloc; set_t set_schedules; set_t set_regions; bsu_beacon_t beacon; set_init (&set_schedules, cp_cco_bw_alloc_less); set_init (&set_regions, cp_cco_region_alloc_less); cp_cco_region_init (&ctx.cp); cp_cco_bw_init (&ctx.cp); /* Regions. */ region = cp_cco_region_alloc_init (&ctx.cp); region->type = CP_BEACON_REGION_TYPE_SHARED_CSMA; region->end_time_atu = 3907; cp_cco_region_alloc_add (&ctx.cp, &ctx.cp.region.region_list, region); slab_release (region); /* Schedules. */ alloc = cp_cco_bw_alloc_init (&ctx.cp); alloc->pscd = 7; alloc->cscd = 7; alloc->stpf = false; alloc->glid = 0x45; alloc->end_time_atu = 3907; alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_PERSISTENT; cp_cco_bw_alloc_add (&ctx.cp, &ctx.cp.bw.alloc_list, alloc); slab_release (alloc); cp_beacon_fill (&ctx.cp, &beacon); test_fail_unless (beacon.bmis.change_snid.present == true); test_fail_unless (beacon.bmis.change_snid.snidccd == ctx.cp.beacon.snids.snidcd); test_fail_unless (beacon.bmis.change_snid.new_snid == ctx.cp.beacon.snids.snid); cp_cco_bw_alloc_clean (&ctx.cp, &set_schedules); cp_cco_region_alloc_clean (&ctx.cp, &set_regions); cp_beacon_sta_compute_schedules (&ctx.cp, &beacon); alloc = cp_cco_bw_alloc_get_first (&ctx.cp, &ctx.cp.bw.alloc_list); test_fail_unless (alloc->persistence == CP_CCO_BW_ALLOC_PERSISTENCE_PERSISTENT); alloc = cp_cco_bw_alloc_get_next (&ctx.cp, &ctx.cp.bw.alloc_list, alloc); test_fail_unless (!alloc); cp_cco_region_alloc_clean (&ctx.cp, &set_regions); cp_cco_bw_alloc_clean (&ctx.cp, &set_schedules); cp_cco_bw_uninit (&ctx.cp); cp_cco_region_uninit (&ctx.cp); } test_end; /* Uninit all the data. */ test_beacon_uninit (&ctx); } void test_case_beacon_snid_change_sta (test_t test) { test_case_begin (test, "Station"); u32 last_countdown_call_date = phy_date () - BSU_ACLF_BP_60HZ_TCK - 100; test_begin (test, "Beacon reception") { bsu_beacon_t *beacon; cp_net_t *net; cp_sta_own_data_t *own; test_beacon_t ctx; test_beacon_init (&ctx); /** Init the context. */ ctx.cp.bsu_aclf->beacon_period_tck = BSU_ACLF_BP_60HZ_TCK; ctx.cp.beacon.last_countdown_call_date_active = true; ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; /* Configure station own data. */ net = cp_sta_mgr_add_avln (&ctx.cp, 0, 1); cp_sta_own_data_set_tei (&ctx.cp, 2); cp_sta_own_data_set_mac_address (&ctx.cp, 0x23456789abcull); cp_sta_mgr_set_our_avln (&ctx.cp, net); own = cp_sta_mgr_get_sta_own_data (&ctx.cp); own->nid_track = 1; own->tei_track = 1; own->cco_mac_addr_track = TEST_CCO_MAC; /** Check snid default values. */ test_fail_unless (ctx.cp.beacon.snids.snid == 0); test_fail_unless (ctx.cp.beacon.snids.snidcd == 0); test_fail_unless (cp_net_get_snid (&ctx.cp, net) == 0x0); test_fail_unless (cp_sta_own_data_get_snid (&ctx.cp) == 0x0); /** Create a central beacon. */ beacon = test_new_beacon (); beacon->bmis.change_snid.present = true; beacon->bmis.change_snid.new_snid = 0xC; beacon->bmis.change_snid.snidccd = 3; cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); /** Check snid values are taken. */ test_fail_unless (ctx.cp.beacon.snids.snid == 0xC); test_fail_unless (ctx.cp.beacon.snids.snidcd == 3); test_fail_unless (cp_net_get_snid (&ctx.cp, net) == 0x0); test_fail_unless (cp_sta_own_data_get_snid (&ctx.cp) == 0x0); /** Create the next beacon (countdown decreased). */ beacon = test_new_beacon (); beacon->bmis.change_snid.snidccd = 2; /** launch the test. */ cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); /** Check countdown. */ test_fail_unless (ctx.cp.beacon.snids.snid == 0xC); test_fail_unless (ctx.cp.beacon.snids.snidcd == 2); test_fail_unless (cp_net_get_snid (&ctx.cp, net) == 0x0); test_fail_unless (cp_sta_own_data_get_snid (&ctx.cp) == 0x0); /** Create the next beacon (countdown decreased). */ beacon = test_new_beacon (); beacon->bmis.change_snid.snidccd = 1; /** launch the test. */ cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); /** Check countdown. */ test_fail_unless (ctx.cp.beacon.snids.snid == 0xC); test_fail_unless (ctx.cp.beacon.snids.snidcd == 1); test_fail_unless (cp_net_get_snid (&ctx.cp, net) == 0x0); test_fail_unless (cp_sta_own_data_get_snid (&ctx.cp) == 0x0); /* Create the beacon. */ beacon = test_new_beacon (); beacon->bmis.change_snid.present = false; beacon->bmis.nbe--; beacon->params.rx_parameters.snid = 0xC; /* launch the test. */ cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); /** Check new snid is 0xC. */ test_fail_unless (ctx.cp.beacon.snids.snid == 0xC); test_fail_unless (ctx.cp.beacon.snids.snidcd == 0); test_fail_unless (cp_net_get_snid (&ctx.cp, net) == 0xC); test_fail_unless (cp_sta_own_data_get_snid (&ctx.cp) == 0xC); dbg_check (mac_store_sta_remove (ctx.cp.mac_store, 1)); test_beacon_uninit (&ctx); } test_end; test_begin (test, "Beacon missed") { test_beacon_t ctx; cp_net_t *net; cp_cco_region_alloc_t *region; cp_cco_bw_alloc_t *alloc; test_beacon_init (&ctx); /* Regions. */ region = cp_cco_region_alloc_init (&ctx.cp); region->type = CP_BEACON_REGION_TYPE_SHARED_CSMA; region->end_time_atu = 3907; cp_cco_region_alloc_add (&ctx.cp, &ctx.cp.region.region_list, region); slab_release (region); /* Schedules. */ alloc = cp_cco_bw_alloc_init (&ctx.cp); alloc->stpf = false; alloc->glid = 0x45; alloc->end_time_atu = 3907; alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT; cp_cco_bw_alloc_add (&ctx.cp, &ctx.cp.bw.alloc_list, alloc); slab_release (alloc); /* Configure station own data. */ net = cp_sta_mgr_add_avln (&ctx.cp, 1, 1); cp_sta_own_data_set_tei (&ctx.cp, 2); cp_sta_own_data_set_mac_address (&ctx.cp, 0x23456789abcull); cp_sta_mgr_set_our_avln (&ctx.cp, net); /* Configure the test. */ ctx.cp.beacon.snids.snidcd = 2; ctx.cp.beacon.snids.snid = 0xc; ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_beacon_not_received (&ctx.cp); test_fail_unless (ctx.cp.beacon.snids.snidcd == 1); test_fail_unless (ctx.cp.beacon.snids.snid == 0xc); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_beacon_not_received (&ctx.cp); test_fail_unless (ctx.cp.beacon.snids.snidcd == 0); test_fail_unless (ctx.cp.beacon.snids.snid == 0xc); test_fail_unless (cp_net_get_snid (&ctx.cp, net) == 0xC); test_fail_unless (cp_sta_own_data_get_snid (&ctx.cp) == 0xC); test_beacon_uninit (&ctx); } test_end; } void test_suite_beacon_snid_change (test_t test) { test_suite_begin (test, "Change SNID"); test_case_beacon_snid_change_cco (test); test_case_beacon_snid_change_sta (test); } void test_case_beacon_hm_change_sta (test_t test) { test_case_begin (test, "Station"); u32 last_countdown_call_date = phy_date () - BSU_ACLF_BP_60HZ_TCK - 100; test_begin (test, "Beacon reception") { test_beacon_t ctx; bsu_beacon_t *beacon; cp_net_t *net; cp_sta_own_data_t *own; /** Init the context. */ test_beacon_init (&ctx); ctx.cp.bsu_aclf->beacon_period_tck = BSU_ACLF_BP_60HZ_TCK; /** Configure station own data. */ own = cp_sta_mgr_get_sta_own_data (&ctx.cp); net = cp_sta_mgr_add_avln (&ctx.cp, 0, 1); cp_sta_own_data_set_tei (&ctx.cp, 2); cp_sta_own_data_set_mac_address (&ctx.cp, 0x23456789abcull); cp_sta_mgr_set_our_avln (&ctx.cp, net); own = cp_sta_mgr_get_sta_own_data (&ctx.cp); own->nid_track = 1; own->tei_track = 1; own->cco_mac_addr_track = TEST_CCO_MAC; own->hybrid_mode = 0; /** Create a central beacon. */ beacon = test_new_beacon (); beacon->bmis.change_hm.present = true; beacon->bmis.change_hm.newhm = 1; beacon->bmis.change_hm.hmccd = 3; beacon->bmis.nbe = 4; /** Check default values. */ test_fail_unless (ctx.cp.beacon.hm.hm == 0); test_fail_unless (ctx.cp.beacon.hm.hmcd == 0); test_fail_unless (own->hybrid_mode == 0); /* launch the test. */ cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); /** Check values are taken. */ test_fail_unless (ctx.cp.beacon.hm.hm == 0x1); test_fail_unless (ctx.cp.beacon.hm.hmcd == 3); test_fail_unless (own->hybrid_mode == 0); /** Create the new beacon. */ beacon = test_new_beacon (); beacon->bmis.change_hm.hmccd = 2; /** launch the test. */ cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); /** Check values are taken. */ test_fail_unless (ctx.cp.beacon.hm.hm == 0x1); test_fail_unless (ctx.cp.beacon.hm.hmcd == 2); test_fail_unless (own->hybrid_mode == 0); /** Create the new beacon. */ beacon = test_new_beacon (); beacon->bmis.change_hm.hmccd = 1; /* launch the test. */ cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); test_fail_unless (ctx.cp.beacon.hm.hm == 0x1); test_fail_unless (ctx.cp.beacon.hm.hmcd == 1); test_fail_unless (own->hybrid_mode == 0); /* Create the beacon. */ beacon = test_new_beacon (); beacon->bmis.change_hm.present = false; beacon->bmis.nbe = 3; /* launch the test. */ cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); test_fail_unless (ctx.cp.beacon.hm.hm == 0x1); test_fail_unless (ctx.cp.beacon.hm.hmcd == 0); test_fail_unless (own->hybrid_mode == 0x1); dbg_check (mac_store_sta_remove (ctx.cp.mac_store, 1)); test_beacon_uninit (&ctx); } test_end; test_begin (test, "Beacon missed") { test_beacon_t ctx; cp_net_t *net; cp_cco_region_alloc_t *region; cp_cco_bw_alloc_t *alloc; cp_sta_own_data_t *own; test_beacon_init (&ctx); /* Regions. */ region = cp_cco_region_alloc_init (&ctx.cp); region->type = CP_BEACON_REGION_TYPE_SHARED_CSMA; region->end_time_atu = 3907; cp_cco_region_alloc_add (&ctx.cp, &ctx.cp.region.region_list, region); slab_release (region); /* Schedules. */ alloc = cp_cco_bw_alloc_init (&ctx.cp); alloc->stpf = false; alloc->glid = 0x45; alloc->end_time_atu = 3907; alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT; cp_cco_bw_alloc_add (&ctx.cp, &ctx.cp.bw.alloc_list, alloc); slab_release (alloc); /* Configure station own data. */ own = cp_sta_mgr_get_sta_own_data (&ctx.cp); net = cp_sta_mgr_add_avln (&ctx.cp, 0, 1); cp_sta_own_data_set_tei (&ctx.cp, 2); cp_sta_own_data_set_mac_address (&ctx.cp, 0x23456789abcull); cp_sta_mgr_set_our_avln (&ctx.cp, net); /* Configure the test. */ ctx.cp.beacon.hm.hmcd = 2; ctx.cp.beacon.hm.hm = 0x1; ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_beacon_not_received (&ctx.cp); test_fail_unless (ctx.cp.beacon.hm.hmcd == 1); test_fail_unless (ctx.cp.beacon.hm.hm == 0x1); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_beacon_not_received (&ctx.cp); test_fail_unless (ctx.cp.beacon.hm.hmcd == 0); test_fail_unless (ctx.cp.beacon.hm.hm == 0x1); test_fail_unless (own->hybrid_mode == 0x1); test_beacon_uninit (&ctx); } test_end; } void test_suite_beacon_hm_change (test_t test) { test_suite_begin (test, "Hybrid mode change"); test_case_beacon_hm_change_sta (test); } void test_case_beacon_eks_change_cco (test_t test) { cp_key_t nek; cp_net_t *net; test_beacon_t ctx; test_case_begin (test, "CCo"); /** Configure the context. */ test_beacon_init (&ctx); /** Configure our station. */ net = cp_sta_mgr_add_avln (&ctx.cp, 0xA, 1); cp_sta_own_data_set_tei (&ctx.cp, 1); cp_sta_mgr_set_our_avln (&ctx.cp, net); cp_sta_own_data_set_cco_status (&ctx.cp, true); cp_sta_own_data_set_mac_address (&ctx.cp, 0x123456789ABCull); test_begin (test, "Change EKS") { uint i; /** Check default values. */ test_fail_unless (ctx.cp.beacon.eks.kccd == 0); test_fail_unless (ctx.cp.beacon.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (ctx.cp.beacon.eks.new_eks == 0); /** Change nek. */ for (i = 0; i < COUNT (nek.key); i++) nek.key[i] = i; cp_beacon_change_nek (&ctx.cp, MAC_EKS_MIN, nek, false /* not now*/); /** Check new values. */ test_fail_unless (ctx.cp.beacon.eks.new_eks == MAC_EKS_MIN); test_fail_unless (ctx.cp.beacon.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (ctx.cp.beacon.eks.kccd == CP_BEACON_COUNTDOWN_EKS); } test_end; /* Uninit all the data. */ test_beacon_uninit (&ctx); } void test_case_beacon_eks_change_sta (test_t test) { test_case_begin (test, "Station"); u32 last_countdown_call_date = phy_date () - BSU_ACLF_BP_60HZ_TCK - 100; test_begin (test, "Beacon reception") { bsu_beacon_t *beacon; cp_net_t *net; cp_sta_own_data_t *own; test_beacon_t ctx; /** Init the context. */ test_beacon_init (&ctx); /** Configure station own data. */ own = cp_sta_mgr_get_sta_own_data (&ctx.cp); net = cp_sta_mgr_add_avln (&ctx.cp, 0, 1); cp_sta_own_data_set_tei (&ctx.cp, 2); cp_sta_own_data_set_mac_address (&ctx.cp, 0x23456789abcull); cp_sta_mgr_set_our_avln (&ctx.cp, net); own = cp_sta_mgr_get_sta_own_data (&ctx.cp); own->nid_track = 1; own->tei_track = 1; own->cco_mac_addr_track = TEST_CCO_MAC; /** Create a central beacon. */ beacon = test_new_beacon (); beacon->bmis.eks.present = true; beacon->bmis.eks.kccd = 2; beacon->bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK; beacon->bmis.eks.new_eks = MAC_EKS_MIN + 1; mac_eks_t ref_eks_current = MAC_EKS_MIN + 2; mac_eks_t ref_eks_next = MAC_EKS_MIN + 3; ctx.mac_config.nek[bsu_nek_index_current (INVALID_PTR)].eks = ref_eks_current; ctx.mac_config.nek[bsu_nek_index_next (INVALID_PTR)].eks = ref_eks_next; /** Check default values. */ test_fail_unless (ctx.cp.beacon.eks.kccd == 0); test_fail_unless (ctx.cp.beacon.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (ctx.cp.beacon.eks.new_eks == MAC_EKS_MIN); /* launch the test. */ cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); test_fail_unless (ctx.cp.beacon.eks.kccd == 2); test_fail_unless (ctx.cp.beacon.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (ctx.cp.beacon.eks.new_eks == MAC_EKS_MIN + 1); test_fail_unless ( ctx.mac_config.nek[bsu_nek_index_current (INVALID_PTR)].eks == ref_eks_current); test_fail_unless (ctx.mac_config.nek[bsu_nek_index_next (INVALID_PTR)].eks == ref_eks_next); /* Create the beacon. */ beacon = test_new_beacon (); beacon->bmis.eks.kccd = 1; /* launch the test. */ cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); test_fail_unless (ctx.cp.beacon.eks.kccd == 1); test_fail_unless (ctx.cp.beacon.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (ctx.cp.beacon.eks.new_eks == MAC_EKS_MIN + 1); test_fail_unless ( ctx.mac_config.nek[bsu_nek_index_current (INVALID_PTR)].eks == ref_eks_current); test_fail_unless (ctx.mac_config.nek[bsu_nek_index_next (INVALID_PTR)].eks == ref_eks_next); /* Create the beacon. */ beacon = test_new_beacon (); beacon->bmis.eks.present = false; beacon->bmis.nbe--; /* launch the test. */ cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); test_fail_unless (ctx.cp.beacon.eks.kccd == 0); test_fail_unless (ctx.cp.beacon.eks.kbc == BSU_BEACON_EKS_KBC_NB); test_fail_unless (ctx.cp.beacon.eks.new_eks == MAC_EKS_MIN + 1); test_fail_unless ( ctx.mac_config.nek[bsu_nek_index_current (INVALID_PTR)].eks == ref_eks_current); test_fail_unless (ctx.mac_config.nek[bsu_nek_index_next (INVALID_PTR)].eks == MAC_EKS_CLEAR); dbg_check (mac_store_sta_remove (ctx.cp.mac_store, 1)); test_beacon_uninit (&ctx); } test_end; test_begin (test, "Beacon missed") { cp_net_t *net; cp_cco_region_alloc_t *region; cp_cco_bw_alloc_t *alloc; test_beacon_t ctx; test_beacon_init (&ctx); /* Regions. */ region = cp_cco_region_alloc_init (&ctx.cp); region->type = CP_BEACON_REGION_TYPE_SHARED_CSMA; region->end_time_atu = 3907; cp_cco_region_alloc_add (&ctx.cp, &ctx.cp.region.region_list, region); slab_release (region); /* Schedules. */ alloc = cp_cco_bw_alloc_init (&ctx.cp); alloc->stpf = false; alloc->glid = 0x45; alloc->end_time_atu = 3907; alloc->persistence = CP_CCO_BW_ALLOC_PERSISTENCE_NOT_PERSISTENT; cp_cco_bw_alloc_add (&ctx.cp, &ctx.cp.bw.alloc_list, alloc); slab_release (alloc); /* Configure station own data. */ net = cp_sta_mgr_add_avln (&ctx.cp, 0, 1); cp_sta_own_data_set_tei (&ctx.cp, 2); cp_sta_own_data_set_mac_address (&ctx.cp, 0x23456789abcull); cp_sta_mgr_set_our_avln (&ctx.cp, net); /* Configure the test. */ ctx.cp.beacon.eks.kccd = 2; ctx.cp.beacon.eks.kbc = BSU_BEACON_EKS_KBC_NEK; ctx.cp.beacon.eks.new_eks = MAC_EKS_MIN + 1; ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_beacon_not_received (&ctx.cp); test_fail_unless (ctx.cp.beacon.eks.kccd == 1); test_fail_unless (ctx.cp.beacon.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (ctx.cp.beacon.eks.new_eks == MAC_EKS_MIN + 1); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_beacon_not_received (&ctx.cp); test_fail_unless (ctx.cp.beacon.eks.kccd == 0); test_fail_unless (ctx.cp.beacon.eks.kbc == BSU_BEACON_EKS_KBC_NB); test_fail_unless (ctx.cp.beacon.eks.new_eks == MAC_EKS_MIN + 1); test_beacon_uninit (&ctx); } test_end; } void test_suite_beacon_eks_change (test_t test) { test_suite_begin (test, "Encryption key change"); test_case_beacon_eks_change_cco (test); test_case_beacon_eks_change_sta (test); } void test_suite_beacon_mac_address_bentry (test_t test) { test_suite_begin (test, "Central beacon"); test_case_begin (test, "Mac address bentry missing"); test_begin (test, "Beacon reception") { bsu_beacon_t *beacon; cp_net_t *net; cp_sta_own_data_t *own; test_beacon_t ctx; /** Init the context. */ test_beacon_init (&ctx); ctx.cp.beacon.last_countdown_call_date_active = false; /** Configure station own data. */ own = cp_sta_mgr_get_sta_own_data (&ctx.cp); net = cp_sta_mgr_add_avln (&ctx.cp, 0, 1); cp_sta_own_data_set_tei (&ctx.cp, 2); cp_sta_own_data_set_mac_address (&ctx.cp, 0x23456789abcull); cp_sta_mgr_set_our_avln (&ctx.cp, net); own->nid_track = 1; own->tei_track = 1; own->cco_mac_addr_track = MAC_ZERO; /** Create a central beacon. */ beacon = test_new_beacon (); beacon->bmis.mac_address.present = false; /* launch the test. */ cp_beacon_receive (&ctx.cp, beacon); cp_beacon_get_and_process_beacon (&ctx.cp); cp_sta_t *cco = cp_net_get_cco (&ctx.cp, net); test_fail_unless (cco); test_fail_unless (cp_sta_get_mac_address (cco) == MAC_BROADCAST); test_fail_unless (cp_sta_get_cco_status (cco) == true); slab_release (cco); /* Mac address in the central beacon is present, but our track on the * mac address is still MAC_ZERO. */ beacon = test_new_beacon (); beacon->bmis.mac_address.present = true; beacon->bmis.mac_address.mac_address = MAC_ADDRESS (0x01, 0x23, 0x45, 0x67, 0x8a, 0xbc); cp_beacon_receive (&ctx.cp, beacon); cp_beacon_get_and_process_beacon (&ctx.cp); cco = cp_net_get_cco (&ctx.cp, net); test_fail_unless (cco); /* The beacon is not processed. */ test_fail_unless (cp_sta_get_mac_address (cco) != beacon->bmis.mac_address.mac_address); test_fail_unless (cp_sta_get_cco_status (cco) == true); slab_release (cco); /* MAC address tracked is different from our CCo. */ beacon = test_new_beacon (); beacon->bmis.mac_address.present = true; beacon->bmis.mac_address.mac_address = MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, 0x01); cp_beacon_receive (&ctx.cp, beacon); cp_beacon_get_and_process_beacon (&ctx.cp); cco = cp_net_get_cco (&ctx.cp, net); test_fail_unless (cco); test_fail_unless (cp_sta_get_mac_address (cco) != beacon->bmis.mac_address.mac_address); test_fail_unless (cp_sta_get_cco_status (cco) == true); slab_release (cco); /* Set the track mac address. */ own->cco_mac_addr_track = MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, 0x01); /* This beacon should be processed as our CCo's central beacon. */ beacon = test_new_beacon (); beacon->bmis.mac_address.present = true; beacon->bmis.mac_address.mac_address = MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, 0x01); cp_beacon_receive (&ctx.cp, beacon); cp_beacon_get_and_process_beacon (&ctx.cp); cco = cp_net_get_cco (&ctx.cp, net); test_fail_unless (cco); test_fail_unless (cp_sta_get_mac_address (cco) == beacon->bmis.mac_address.mac_address); test_fail_unless (cp_sta_get_cco_status (cco) == true); slab_release (cco); /* This one should no be processed as our CCo's central beacon. It * comes from another one. */ beacon = test_new_beacon (); beacon->bmis.mac_address.present = true; beacon->bmis.mac_address.mac_address = MAC_ADDRESS (0x01, 0x23, 0x45, 0x67, 0x8a, 0xbc); cp_beacon_receive (&ctx.cp, beacon); cp_beacon_get_and_process_beacon (&ctx.cp); cco = cp_net_get_cco (&ctx.cp, net); test_fail_unless (cco); test_fail_unless (cp_sta_get_mac_address (cco) == MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, 0x01)); test_fail_unless (cp_sta_get_cco_status (cco) == true); slab_release (cco); dbg_check (mac_store_sta_remove (ctx.cp.mac_store, 1)); test_beacon_uninit (&ctx); } test_end; } void test_suite_beacon_no_net (test_t t) { test_suite_begin (t, "No net for beacon processing"); test_case_begin (t, "Beacon process"); u32 last_countdown_call_date = phy_date () - BSU_ACLF_BP_60HZ_TCK - 100; test_begin (t, "let's go") { test_beacon_t ctx; test_beacon_init (&ctx); bsu_beacon_t *beacon = blk_alloc (); cp_beacon_fill (&ctx.cp, beacon); uint i; for (i = 0; i < HPAV_AVLNS_NB_MAX; i++) cp_sta_mgr_add_avln (&ctx.cp, i + 1, i); test_fail_unless (!cp_sta_mgr_add_avln (&ctx.cp, 15, 30)); beacon->params.rx_parameters.snid = 0xf; beacon->vf.nid = 0x1234; beacon->params.direction = BSU_BEACON_DIRECTION_FROM_PLC; cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); test_fail_unless (!cp_sta_mgr_get_avln (&ctx.cp, 15, 30)); test_beacon_uninit (&ctx); } test_end; } void test_suite_beacon_spoc_update (test_t test) { test_beacon_t ctx; u32 last_countdown_call_date = phy_date () - BSU_ACLF_BP_60HZ_TCK - 100; test_beacon_init (&ctx); test_suite_begin (test, "SPOC update"); test_case_begin (test, "Frequency error invalid and valid"); test_begin (test, "SPOC only updated if F.E. is valid") { cp_sta_own_data_t *own = cp_sta_mgr_get_sta_own_data (&ctx.cp); ctx.cp.beacon.spoc_update_interval_ms = 1; bsu_beacon_t *beacon = test_new_beacon (); cp_sta_mgr_add_avln (&ctx.cp, beacon->params.rx_parameters.snid, beacon->vf.nid); ctx.cp.beacon.spoc_update_date = phy_date () - 1; cp_sta_own_data_set_nid (&ctx.cp, beacon->vf.nid); own->nid_track = beacon->vf.nid; own->tei_track = beacon->vf.stei; own->cco_mac_addr_track = TEST_CCO_MAC; beacon->params.rx_parameters.snid = cp_sta_own_data_get_snid (&ctx.cp); /* Process a received beacon with a frequency error invalid. */ cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); test_fail_unless (!ctx.cp.beacon.spoc_updated); /* This received beacon has a valid frequency error, SPOC should be * updated. */ beacon = test_new_beacon (); beacon->params.frequency_error_valid = true; beacon->params.rx_parameters.snid = cp_sta_own_data_get_snid (&ctx.cp); ctx.cp.beacon.spoc_update_date = phy_date () - 1; cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); test_fail_unless (ctx.cp.beacon.spoc_updated); /* This received beacon has a invalid frequency error. SPOC updated * flag stay at true. */ beacon = test_new_beacon (); beacon->params.frequency_error_valid = false; ctx.cp.beacon.spoc_update_date = phy_date () - 1; cp_beacon_receive (&ctx.cp, beacon); ctx.cp.beacon.last_countdown_call_date = last_countdown_call_date; cp_beacon_get_and_process_beacon (&ctx.cp); test_fail_unless (ctx.cp.beacon.spoc_updated); } test_end; test_beacon_uninit (&ctx); } void test_suite_beacon_hoip_ended (test_t t) { test_suite_begin (t, "Handover ended, avoid to send the last beacon"); test_case_begin (t, "Handover in progress"); test_beacon_t ctx; test_beacon_init (&ctx); test_begin (t, "Handover not ended") { ctx.bsu_updated = false; ctx.cp.beacon.hoip.hoipcd = 2; cp_beacon_cco_update_beacon_data (&ctx.cp); test_fail_unless (ctx.bsu_updated); } test_end; test_begin (t, "Handover Ended") { ctx.bsu_updated = false; ctx.cp.beacon.hoip.hoipcd = 1; cp_beacon_cco_update_beacon_data (&ctx.cp); test_fail_unless (!ctx.bsu_updated); } test_end; test_beacon_uninit (&ctx); } void test_suite_beacon_update_tracking (test_t t) { test_suite_begin (t, "Update tracking"); test_case_begin (t, "Update tracking"); test_begin (t, "update tracking") { test_beacon_t ctx; test_beacon_init (&ctx); u8 tei = MAC_TEI_STA_MAX; mac_t mac = MAC_ADDRESS (0x00, 0x13, 0xd7, 0x78, 0x79, 0x80); cp_net_t *net = cp_sta_mgr_add_avln (&ctx.cp, 1, 1); cp_sta_t *sta = cp_sta_mgr_sta_add (&ctx.cp, net, tei, mac); cp_sta_own_data_t *own = cp_sta_mgr_get_sta_own_data (&ctx.cp); test_fail_unless (own->tei_track != tei); test_fail_unless (own->cco_mac_addr_track != mac); cp_beacon_update_tracking (&ctx.cp, sta); test_fail_unless (own->tei_track == tei); test_fail_unless (own->cco_mac_addr_track == mac); slab_release (sta); test_beacon_uninit (&ctx); } test_end; } int main (void) { test_t test; test_init (test, 0, NULL); test_case_beacon_uninit (test); test_case_beacon__deactivate (test); test_suite_beacon__beacon_generation (test); test_suite_beacon_snid_change (test); test_suite_beacon_hm_change (test); test_suite_beacon_eks_change (test); test_suite_beacon_mac_address_bentry (test); test_suite_beacon_no_net (test); test_suite_beacon_spoc_update (test); test_suite_beacon_hoip_ended (test); test_suite_beacon_update_tracking (test); test_case_begin (test, "Memory allocation"); test_begin (test, "memory leaks") { test_fail_if (blk_check_memory () != true, "Memory leaks"); } test_end; test_result (test); HAL_PLATFORM_EXIT (test_nb_failed (test) == 0 ? 0 : 1); return test_nb_failed (test) == 0 ? 0 : 1; }