/* Cesar project {{{ * * Copyright (C) 2010 Spidcom * * <<>> * * }}} */ /** * \file bsu/test/utest/src/bsut.c * \brief BSU unit test. * \ingroup bsu */ #include "common/std.h" #include "lib/test.h" #include "lib/bitstream.h" #include "bsu/bsu.h" #include "bsu/test/utest/tests.h" #include "bsu/beacon/beacon.h" #include #include "bsu/inc/bsu.h" #include "bsu/inc/context.h" #include "bsu/inc/interface.h" #include "bsu/ntb/ntb.h" bsu_avln_t* bsu_avln_add (bsu_t *ctx, u64 nid, u8 snid, mac_t mac, bool *added); void bsu_timer_event_process (void *ud); void bsu_avln_schedules_decrease_countdown (bsu_t *ctx, bsu_avln_t *avln); void bsu_update__persistent_schedules (bsu_t *ctx, bsu_beacon_t *beacon); bsu_avln_t* bsu_beacon_process__avln_tracked (bsu_t *ctx, bsu_beacon_t *beacon, pbproc_rx_beacon_params_t *params); void bsu_handle_key_change (bsu_t *ctx); void test_case_bsu_process (test_t test) { uint i; uint central_beacon_nb_recv = 0; bsu_test_t t; bsu_test_init (&t); bsu_activate (t.bsu, true); test_case_begin (test, "BSU process"); test_begin (test, "Process function on neighbour beacon") { bsu_beacon_t beacon_neighbour; pb_beacon_t *bneighbour; bsu_beacon_t beacon; bsu_beacon_t *bprocessed; pb_beacon_t *b; pbproc_tx_beacon_params_t bpneighbour_tx; pbproc_tx_beacon_params_t bp_tx; pbproc_rx_beacon_params_t bpneighbour_rx; pbproc_rx_beacon_params_t bp_rx; memset (&bp_rx, 0, sizeof (pbproc_rx_beacon_params_t)); memset (&bpneighbour_rx, 0, sizeof (pbproc_rx_beacon_params_t)); t.mac_config.tei = 4; /* => Neighbour beacon with bad CRC. */ bsu_test_create_beacon (&t, &beacon_neighbour); bpneighbour_rx.snid = 0x4; bpneighbour_rx.bts = 0; bneighbour = bsu_beacon_write (&beacon_neighbour, BSU_BEACON_TYPE_CENTRAL, &t.mac_config, &bpneighbour_tx); bneighbour->phy_pb.pb_rx.pb_measurement.crc_error = true; bprocessed = bsu_beacon_process (t.bsu, bneighbour, &bpneighbour_rx); blk_release_desc ((blk_t*) bneighbour); /* Central beacon processed? */ test_fail_unless (!bprocessed); test_fail_unless (t.bsu->avlns[0].snid == 0); test_fail_unless (t.bsu->avlns[0].beacon.vf.nid == 0); test_fail_unless (t.bsu->beacon_nb_sent [BSU_BEACON_TYPE_CENTRAL] == 0); test_fail_unless (t.bsu->stats.neighbor_beacon_nb == 0); test_fail_unless (t.bsu->stats.neighbor_beacon_last_mac == 0); /* NTB called? */ test_fail_unless (t.bsu->avlns[0].sync.init == false); test_fail_unless (t.bsu->avlns[0].sync.sync_nb == 0); /* => First neighbour beacon reception. */ bneighbour = bsu_beacon_write (&beacon_neighbour, BSU_BEACON_TYPE_CENTRAL, &t.mac_config, &bpneighbour_tx); bneighbour->phy_pb.pb_rx.pb_measurement.crc_error = false; bprocessed = bsu_beacon_process (t.bsu, bneighbour, &bpneighbour_rx); /* Central beacon processed? */ test_fail_unless (bprocessed); test_fail_unless (t.bsu->avlns[0].snid == bpneighbour_rx.snid); test_fail_unless (t.bsu->avlns[0].beacon.vf.nid == beacon_neighbour.vf.nid); central_beacon_nb_recv++; test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_CENTRAL] == central_beacon_nb_recv); if (CONFIG_STATS) { test_fail_unless (t.bsu->stats.neighbor_beacon_nb == 1); test_fail_unless (t.bsu->stats.neighbor_beacon_last_mac == 0x123456789abcull); } /* NTB called? */ test_fail_unless (t.bsu->avlns[0].sync.init == true); test_fail_unless (t.bsu->avlns[0].sync.sync_nb == 0); test_fail_unless (!bprocessed->params.frequency_error_valid); /* Cleanup. */ blk_release (bprocessed); /* => Next neighbour beacon receptions. */ for (i = 1; i <= BSU_NTB_CLK_SYNC_NB_STABLE_DEFAULT; i++) { bprocessed = bsu_beacon_process (t.bsu, bneighbour, &bpneighbour_rx); /* Central beacon processed? */ test_fail_unless (bprocessed); test_fail_unless (t.bsu->avlns[0].snid == bpneighbour_rx.snid); test_fail_unless (t.bsu->avlns[0].beacon.vf.nid == beacon_neighbour.vf.nid); central_beacon_nb_recv++; test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_CENTRAL] == central_beacon_nb_recv); /* NTB called? */ test_fail_unless (t.bsu->avlns[0].sync.init == true); test_fail_unless (t.bsu->avlns[0].sync.sync_nb == i); if (i == BSU_NTB_CLK_SYNC_NB_STABLE_DEFAULT) test_fail_unless (bprocessed->params.frequency_error_valid); else test_fail_unless (!bprocessed->params.frequency_error_valid); /* Cleanup. */ blk_release (bprocessed); } test_fail_unless (!CONFIG_STATS || t.bsu->stats.neighbor_beacon_nb == 1 + BSU_NTB_CLK_SYNC_NB_STABLE_DEFAULT); /* Cleanup. */ blk_release_desc ((blk_t*) bneighbour); /* => Our AVLN. */ bsu_track_avln (t.bsu, beacon_neighbour.vf.nid, 0x4, beacon_neighbour.vf.stei, beacon_neighbour.bmis.mac_address.mac_address); test_fail_unless (t.bsu->stats.neighbor_beacon_nb == 0); test_fail_unless (t.bsu->stats.neighbor_beacon_last_mac == 0); /* Reset synchronisation. */ bsu_ntb_init (&t.bsu->sta_avln->sync); /* => Beacon with bad CRC. */ bsu_test_create_beacon (&t, &beacon); bp_rx.snid = 0x4; bp_rx.bts = 0; b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_CENTRAL, &t.mac_config, &bp_tx); b->phy_pb.pb_rx.pb_measurement.crc_error = true; bprocessed = bsu_beacon_process (t.bsu, b, &bp_rx); blk_release_desc ((blk_t*) b); /* Central beacon processed? */ test_fail_unless (!bprocessed); test_fail_unless (t.bsu->sta_avln->snid == t.bsu->snid_track); test_fail_unless (t.bsu->sta_avln->beacon.vf.nid == t.bsu->nid_track); test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_CENTRAL] == central_beacon_nb_recv); /* NTB called? */ test_fail_unless (t.bsu->sta_avln->sync.init == false); /* => First beacon reception. */ b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_CENTRAL, &t.mac_config, &bp_tx); b->phy_pb.pb_rx.pb_measurement.crc_error = false; bprocessed = bsu_beacon_process (t.bsu, b, &bp_rx); /* Central beacon processed? */ test_fail_unless (bprocessed); test_fail_unless (t.bsu->sta_avln->snid == bp_rx.snid); test_fail_unless (t.bsu->sta_avln->beacon.vf.nid == beacon.vf.nid); central_beacon_nb_recv++; test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_CENTRAL] == central_beacon_nb_recv); test_fail_unless (t.bsu->stats.neighbor_beacon_nb == 0); test_fail_unless (t.bsu->stats.neighbor_beacon_last_mac == 0); /* NTB called? */ test_fail_unless (t.bsu->sta_avln->sync.init == true); test_fail_unless (t.bsu->sta_avln->sync.sync_nb == 0); test_fail_unless (!bprocessed->params.frequency_error_valid); /* Cleanup. */ blk_release_desc ((blk_t*) b); blk_release (bprocessed); } test_end; test_begin (test, "Central beacon received with discover request") { bsu_beacon_t beacon; bsu_test_create_beacon (&t, &beacon); pb_beacon_t *b; pbproc_tx_beacon_params_t btx; pbproc_rx_beacon_params_t brx; memset (&brx, 0, sizeof (pbproc_rx_beacon_params_t)); brx.snid = 0x2; b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_CENTRAL, &t.mac_config, &btx); b->phy_pb.pb_rx.pb_measurement.crc_error = false; t.bsu->sta_avln->beacon.beacon_period_start_date = phy_date () - t.bsu->aclf->beacon_period_tck - 1000; bsu_beacon_t *bbeacon = bsu_beacon_process (t.bsu, b, &brx); blk_release (bbeacon); /* Change MAC config TEI for the test. */ bsu_track_avln (t.bsu, beacon.vf.nid, brx.snid, t.mac_config.tei, beacon.bmis.mac_address.mac_address); t.mac_config.tei = beacon.bmis.discover.tei; memset (&t.sar, 0, sizeof (bsu_test_sar_t)); bsu_test_upper_layer_beacon_received_init (&t); bsu_beacon_recv (t.bsu, b, &brx); /* Discover beacon sent ? */ test_fail_unless (t.sar.beacon != NULL); test_fail_unless (t.sar.mfs != NULL); test_fail_unless (t.sar.mfs->common.lid == MAC_LID_DISCOVER); test_fail_unless (t.bsu->beacon_nb_sent [BSU_BEACON_TYPE_DISCOVER] == 1); central_beacon_nb_recv += 2; test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_CENTRAL] == central_beacon_nb_recv); /* Upper layer receives it ? */ test_fail_unless (t.ul.beacon); test_fail_unless (t.ul.beacon->next); blk_release ((blk_t*) t.ul.beacon->next); blk_release ((blk_t*) t.ul.beacon); } test_end; test_begin (test, "Discover beacon: associated do not track discover") { bsu_beacon_t beacon; bsu_test_create_beacon (&t, &beacon); uint i; t.mac_config.tei = 254; bsu_update_sta_type_t type [] = { BSU_UPDATE_STA_TYPE_STA, BSU_UPDATE_STA_TYPE_CCO }; bsu_ntb_init (&t.bsu->poweron.sync); for (i = 0; i < COUNT (type); i++) { bsu_update (t.bsu, &beacon, type[i]); pb_beacon_t *b; pbproc_tx_beacon_params_t btx; pbproc_rx_beacon_params_t brx; memset (&brx, 0, sizeof (pbproc_rx_beacon_params_t)); brx.snid = 0x3; b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_DISCOVER, &t.mac_config, &btx); b->phy_pb.pb_rx.pb_measurement.crc_error = false; t.bsu->sta_avln->beacon.beacon_period_start_date = phy_date () - t.bsu->aclf->beacon_period_tck - 1000; bsu_beacon_t *bprocessed = bsu_beacon_process (t.bsu, b, &brx); bsu_avln_t *avln = bsu_avln_get ( t.bsu, beacon.vf.nid, brx.snid, beacon.bmis.mac_address.mac_address); test_fail_unless (bprocessed); test_fail_unless (avln == NULL); blk_release_desc ((blk_t*) b); blk_release (bprocessed); b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_CENTRAL, &t.mac_config, &btx); b->phy_pb.pb_rx.pb_measurement.crc_error = false; bprocessed = bsu_beacon_process (t.bsu, b, &brx); test_fail_unless (bprocessed); avln = bsu_avln_get ( t.bsu, beacon.vf.nid, brx.snid, beacon.bmis.mac_address.mac_address); test_fail_unless (avln != NULL); test_fail_unless (avln != t.bsu->sta_avln); blk_release_desc ((blk_t*) b); blk_release (bprocessed); bsu_track_avln (t.bsu, beacon.vf.nid, brx.snid, 1, beacon.bmis.mac_address.mac_address); test_fail_unless (avln == t.bsu->sta_avln); bsu_avln_remove (t.bsu, beacon.vf.nid, brx.snid, beacon.bmis.mac_address.mac_address); test_fail_unless (&t.bsu->poweron == t.bsu->sta_avln); } } test_end; test_begin (test, "Beacon with incoherent data inside.") { pb_beacon_t *beacon = (pb_beacon_t*) blk_alloc_desc (); pbproc_rx_beacon_params_t bp_rx; memset (beacon->data, 0, BLK_SIZE); beacon->phy_pb.pb_rx.pb_measurement.crc_error = false; beacon->first_data_word = 0x3; bp_rx.snid = 0x4; bp_rx.bts = 0; /* Neighbour AVLN. */ bsu_beacon_t *bbeacon = bsu_beacon_process (t.bsu, beacon, &bp_rx); test_fail_unless (bbeacon == NULL); bsu_avln_t *avln = bsu_avln_get (t.bsu, 0x3, 0x4, MAC_ZERO); test_fail_unless (avln == NULL); blk_release_desc (&beacon->blk); /* Our AVLN. */ beacon = (pb_beacon_t*) blk_alloc_desc (); memset (beacon->data, 0, BLK_SIZE); beacon->phy_pb.pb_rx.pb_measurement.crc_error = false; beacon->first_data_word = 0x3; bp_rx.snid = 0x4; bp_rx.bts = 0; t.bsu->nid_track = 0x3; t.bsu->snid_track = bp_rx.snid; t.bsu->tei_track = 0; t.bsu->is_sta = BSU_UPDATE_STA_TYPE_STA; bbeacon = bsu_beacon_process (t.bsu, beacon, &bp_rx); test_fail_unless (bbeacon == NULL); blk_release_desc (&beacon->blk); } test_end; bsu_test_uninit (&t); } void test_case_bsu_process_sta_is_cco (test_t test) { test_case_begin (test, "STA is CCO"); bsu_test_t t; bsu_test_init (&t); test_begin (test, "Receive Discover beacon") { bsu_beacon_t beacon; bsu_test_create_beacon (&t, &beacon); bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_CCO); pb_beacon_t *b; pbproc_tx_beacon_params_t btx; pbproc_rx_beacon_params_t brx; memset (&brx, 0, sizeof (pbproc_rx_beacon_params_t)); brx.snid = 0x2; b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_CENTRAL, &t.mac_config, &btx); b->phy_pb.pb_rx.pb_measurement.crc_error = false; bsu_beacon_t *bbeacon = bsu_beacon_process (t.bsu, b, &brx); test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_CENTRAL] == 1); test_fail_unless (bbeacon); test_fail_unless (t.bsu->sta_avln->sync.init == false); blk_release_desc ((blk_t*) b); blk_release (bbeacon); b = bsu_beacon_write (&beacon, BSU_BEACON_TYPE_DISCOVER, &t.mac_config, &btx); b->phy_pb.pb_rx.pb_measurement.crc_error = false; bbeacon = bsu_beacon_process (t.bsu, b, &brx); test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_DISCOVER] == 1); test_fail_unless (bbeacon); test_fail_unless (t.bsu->sta_avln->sync.init == false); blk_release_desc ((blk_t*) b); blk_release (bbeacon); } test_end; bsu_test_uninit (&t); } void test_case_bsu_update_init (bsu_test_t *test, bsu_beacon_t *beacon) { uint i; bsu_test_create_beacon (test, beacon); bsu_test_create_beacon (test, &test->bsu->sta_avln->beacon); for (i = 0; i < COUNT (test->bsu->aclf->bpsd); i++) test->bsu->aclf->bpsd[i] = i * test->bsu->aclf->beacon_period_tck; beacon->beacon_period_start_date = bsu_aclf_beacon_period_start_date_next (test->bsu->aclf) - test->bsu->aclf->beacon_period_tck; } void test_case_bsu_update (test_t test) { bsu_test_t t; bsu_beacon_t beacon; bsu_test_init (&t); bsu_activate (t.bsu, true); test_case_begin (test, "BSU Update"); test_begin (test, "update BSU in time") { bsu_test_create_beacon (&t, &beacon); beacon.beacon_period_start_date = bsu_aclf_beacon_period_start_date_next (t.bsu->aclf); t.bsu->is_sta = false; bsu_update (t.bsu, &beacon, true /* is station. */); test_fail_unless (memcmp (&t.bsu->sta_avln->beacon, &beacon, sizeof (bsu_beacon_t)) == 0); test_fail_unless (t.bsu->is_sta == true); /* Change station situation. */ t.bsu->is_sta = true; bsu_update (t.bsu, &beacon, false /* is CCo. */); test_fail_unless (memcmp (&t.bsu->sta_avln->beacon, &beacon, sizeof (bsu_beacon_t)) == 0); test_fail_unless (t.bsu->is_sta == false); } test_end; test_begin (test, "Old data") { test_case_bsu_update_init (&t, &beacon); t.bsu->is_sta = false; t.bsu->sta_avln->beacon.bmis.ps.ps[0].pscd--; t.bsu->sta_avln->beacon.bmis.ps.ps[1].pscd--; bsu_update (t.bsu, &beacon, true /* is station. */); test_fail_unless (memcmp (&t.bsu->sta_avln->beacon, &beacon, sizeof (bsu_beacon_t)) != 0); test_fail_unless (t.bsu->is_sta == true); } test_end; test_begin (test, "New persistent schedule") { test_case_bsu_update_init (&t, &beacon); t.bsu->sta_avln->beacon.bmis.ps.nb = 1; bsu_update (t.bsu, &beacon, true /* is station. */); /* Only the second schedules should be touched by the function. */ t.bsu->sta_avln->beacon.bmis.ps.ps[1].pscd++; test_fail_unless (t.bsu->sta_avln->beacon.bmis.ps.nb == beacon.bmis.ps.nb); uint i; for (i = 0; i < beacon.bmis.ps.nb; i++) { test_fail_unless (t.bsu->sta_avln->beacon.bmis.ps.ps[i].cscd == beacon.bmis.ps.ps[i].cscd); test_fail_unless (t.bsu->sta_avln->beacon.bmis.ps.ps[i].pscd == beacon.bmis.ps.ps[i].pscd); } } test_end; test_begin (test, "Beacon entries without countdown.") { test_case_bsu_update_init (&t, &beacon); t.bsu->sta_avln->beacon.bmis.mac_address.present = false; t.bsu->sta_avln->beacon.bmis.discover.present = false; t.bsu->sta_avln->beacon.bmis.discover_info.present = false; t.bsu->sta_avln->beacon.bmis.bpsto.present = false; t.bsu->sta_avln->beacon.bmis.nps.ns = 0; t.bsu->sta_avln->beacon.bmis.region.nb = 0; bsu_update (t.bsu, &beacon, true /* is station. */); test_fail_unless (t.bsu->sta_avln->beacon.bmis.mac_address.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.discover.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.discover_info.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.bpsto.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.nps.ns == beacon.bmis.nps.ns); test_fail_unless (t.bsu->sta_avln->beacon.bmis.region.nb == beacon.bmis.region.nb); } test_end; test_begin (test, "Beacon entries with countdown.") { test_case_bsu_update_init (&t, &beacon); t.bsu->sta_avln->beacon.bmis.handover.present = false; t.bsu->sta_avln->beacon.bmis.relocation.present = false; t.bsu->sta_avln->beacon.bmis.aclsc.present = false; t.bsu->sta_avln->beacon.bmis.cns.present = false; t.bsu->sta_avln->beacon.bmis.change_hm.present = false; t.bsu->sta_avln->beacon.bmis.change_snid.present = false; t.bsu->sta_avln->beacon.bmis.mac_address.present = false; bsu_update (t.bsu, &beacon, true /* is station. */); test_fail_unless (t.bsu->sta_avln->beacon.bmis.handover.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.relocation.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.aclsc.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.cns.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.change_hm.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.change_snid.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.mac_address.present == true); } test_end; test_begin (test, "bmi eks update:Sta:On time") { test_case_bsu_update_init (&t, &beacon); beacon.beacon_period_start_date = bsu_aclf_beacon_period_start_date_next (t.bsu->aclf); t.bsu->sta_avln->beacon.bmis.eks.present = true; t.bsu->sta_avln->beacon.bmis.eks.kccd = 3; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK; t.bsu->sta_avln->beacon.bmis.eks.new_eks = 6; beacon.bmis.eks.present = false; beacon.bmis.eks.kccd = 0; beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NB; beacon.bmis.eks.new_eks = MAC_EKS_NB; bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_STA); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.present == false); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kccd == 0); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NB); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.new_eks == MAC_EKS_NB); } test_end; test_begin (test, "bmi eks update:Sta:Late") { test_case_bsu_update_init (&t, &beacon); t.bsu->sta_avln->beacon.bmis.eks.present = true; t.bsu->sta_avln->beacon.bmis.eks.kccd = 3; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK; t.bsu->sta_avln->beacon.bmis.eks.new_eks = 6; beacon.bmis.eks.present = false; beacon.bmis.eks.kccd = 0; beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NB; beacon.bmis.eks.new_eks = MAC_EKS_NB; bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_STA); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.present == false); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kccd == 0); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NB); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.new_eks == MAC_EKS_NB); } test_end; test_begin (test, "bmi eks update:CCo:On time:New countdown") { test_case_bsu_update_init (&t, &beacon); beacon.beacon_period_start_date = bsu_aclf_beacon_period_start_date_next (t.bsu->aclf); t.bsu->sta_avln->beacon.bmis.eks.present = false; t.bsu->sta_avln->beacon.bmis.eks.kccd = 0; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NB; t.bsu->sta_avln->beacon.bmis.eks.new_eks = MAC_EKS_NB; beacon.bmis.eks.present = true; beacon.bmis.eks.kccd = 5; beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK; beacon.bmis.eks.new_eks = 4; bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_CCO); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kccd == 5); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.new_eks == 4); } test_end; test_begin (test, "bmi eks update:CCo:Late:New countdown") { test_case_bsu_update_init (&t, &beacon); t.bsu->sta_avln->beacon.bmis.eks.present = false; t.bsu->sta_avln->beacon.bmis.eks.kccd = 0; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NB; t.bsu->sta_avln->beacon.bmis.eks.new_eks = MAC_EKS_NB; beacon.bmis.eks.present = true; beacon.bmis.eks.kccd = 5; beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK; beacon.bmis.eks.new_eks = 4; bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_CCO); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kccd == 5); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.new_eks == 4); } test_end; test_begin (test, "bmi eks update:CCo:On time:Preserve countdown") { test_case_bsu_update_init (&t, &beacon); beacon.beacon_period_start_date = bsu_aclf_beacon_period_start_date_next (t.bsu->aclf); t.bsu->sta_avln->beacon.bmis.eks.present = true; t.bsu->sta_avln->beacon.bmis.eks.kccd = 3; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK; t.bsu->sta_avln->beacon.bmis.eks.new_eks = 4; beacon.bmis.eks.present = false; beacon.bmis.eks.kccd = 0; beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NB; beacon.bmis.eks.new_eks = MAC_EKS_NB; bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_CCO); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kccd == 3); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.new_eks == 4); } test_end; test_begin (test, "bmi eks update:CCo:Late:Preserve countdown") { test_case_bsu_update_init (&t, &beacon); t.bsu->sta_avln->beacon.bmis.eks.present = true; t.bsu->sta_avln->beacon.bmis.eks.kccd = 3; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK; t.bsu->sta_avln->beacon.bmis.eks.new_eks = 4; beacon.bmis.eks.present = false; beacon.bmis.eks.kccd = 0; beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NB; beacon.bmis.eks.new_eks = MAC_EKS_NB; bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_CCO); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kccd == 3); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.new_eks == 4); } test_end; bsu_test_uninit (&t); } void test_case_bsu_timer_event_cco_ucco (test_t test, bsu_test_t *t, bsu_update_sta_type_t type) { test_within (test); bsu_beacon_t beacon; mfs_t *mfs; uint i,j, lid = type == BSU_UPDATE_STA_TYPE_CCO ? MAC_LID_SPC_CENTRAL : MAC_LID_DISCOVER; bsu_avln_t cmp_avln; bsu_test_init (t); bsu_activate (t->bsu, true); bsu_test_avln_create (t, &cmp_avln); u32 now = phy_date (); for (i = 0; i < BSU_ACLF_BPSD_NB; i++) t->bsu->aclf->bpsd[i] = now + i * t->bsu->aclf->beacon_period_tck; bsu_test_create_beacon (t, &beacon); /* First case, update beacon in time. */ bsu_test_upper_layer_beacon_received_init (t); beacon.beacon_period_start_date = bsu_aclf_beacon_period_start_date_next (t->bsu->aclf); bsu_update (t->bsu, &beacon, type); t->bsu->sta_avln->beacon.vf.nm = MAC_NM_UNCOORDINATED; t->bsu->sta_avln->beacon.bmis.bpsto.present = false; cmp_avln.beacon.vf.nm = MAC_NM_UNCOORDINATED; bsu_timer_event_process (t->bsu); test_fail_unless (t->ul.beacon != INVALID_PTR); test_fail_unless (t->ul.beacon->params.direction == BSU_BEACON_DIRECTION_TO_PLC); test_fail_unless (t->ul.beacon->next == NULL); /* Release the reference handled by the CP. */ blk_release (t->ul.beacon); mfs = mac_store_mfs_get (t->mac_store, true, true, false, lid, MAC_TEI_BCAST); mfs->tx.head = NULL; test_fail_unless (mfs != NULL); blk_release (mfs); /* Second case, beacon not updated. */ bsu_test_upper_layer_beacon_received_init (t); t->bsu->sta_avln->beacon.beacon_period_start_date = t->bsu->aclf->bpsd[0] - 1; for (i = 0; i < 7; i++) { cmp_avln.beacon.beacon_period_start_date = phy_date () - t->bsu->aclf->beacon_period_tck - 1000; bsu_avln_schedules_decrease_countdown (t->bsu, &cmp_avln); bsu_timer_event_process (t->bsu); test_fail_unless (t->ul.beacon != INVALID_PTR); test_fail_unless (t->ul.beacon->params.direction == BSU_BEACON_DIRECTION_TO_PLC); blk_release (t->ul.beacon); for (j = 0; j < cmp_avln.beacon.bmis.ps.nb; j++) { test_fail_unless (cmp_avln.beacon.bmis.ps.ps[j].pscd == t->bsu->sta_avln->beacon.bmis.ps.ps[j].pscd); test_fail_unless (cmp_avln.beacon.bmis.ps.ps[j].cscd == t->bsu->sta_avln->beacon.bmis.ps.ps[j].cscd); test_fail_unless (t->bsu->sta_avln->beacon.bmis.ps.nb == cmp_avln.beacon.bmis.ps.nb); } } mfs = mac_store_mfs_get (t->mac_store, true, true, false, lid, MAC_TEI_BCAST); test_fail_unless (mfs != NULL); /* Release MFS. */ mac_store_mfs_remove (t->mac_store, mfs); blk_release (mfs); bsu_test_uninit (t); } void test_case_bsu_timer_event (test_t test) { test_case_begin (test, "Timer event called"); test_begin (test, "STA") { uint i, j; bsu_test_t t; bsu_avln_t cmp_avln; bsu_test_init (&t); bsu_activate (t.bsu, true); t.bsu->aclf->pwl_sync.trig_present = false; t.phy->phy_date = 0; t.bsu->sta_avln->sync.init = true; bsu_beacon_t beacon; bsu_test_create_beacon (&t, &beacon); bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_STA); bsu_test_avln_create (&t, t.bsu->sta_avln); bsu_test_avln_create (&t, &cmp_avln); cmp_avln.beacon.vf.nm = t.bsu->sta_avln->beacon.vf.nm = MAC_NM_UNCOORDINATED; for (j = 0; j < 10; j++) { t.bsu->sta_avln->beacon.beacon_period_start_date = t.bsu->aclf->bpsd[0] - t.bsu->aclf->beacon_period_tck; cmp_avln.beacon.beacon_period_start_date = t.bsu->aclf->bpsd[0] - t.bsu->aclf->beacon_period_tck; bsu_avln_schedules_decrease_countdown (t.bsu, &cmp_avln); bsu_timer_event_process (t.bsu); for (i = 0; i < BSU_ACLF_BPSD_NB; i++) test_fail_unless ( t.bsu->aclf->bpsd[i] = (i+j+1) * t.bsu->aclf->beacon_period_tck); for (i = 0; i < cmp_avln.beacon.bmis.ps.nb; i++) { test_fail_unless (t.bsu->sta_avln->beacon.bmis.ps.ps[i].pscd == cmp_avln.beacon.bmis.ps.ps[i].pscd); test_fail_unless (t.bsu->sta_avln->beacon.bmis.ps.ps[i].cscd == cmp_avln.beacon.bmis.ps.ps[i].cscd); } /* Fake beacon sent to the upper layer (i.e. the cp)? */ test_fail_unless (t.ul.beacon != INVALID_PTR); test_fail_unless (t.ul.beacon->params.direction == BSU_BEACON_DIRECTION_FROM_BSU); blk_release (t.ul.beacon); t.ul.beacon = INVALID_PTR; } bsu_test_uninit (&t); } test_end; test_begin (test, "STA:Fake beacon from bsu:PLC beacon received") { bsu_test_t t; bsu_test_init (&t); bsu_activate (t.bsu, true); bsu_beacon_t beacon; bsu_test_create_beacon (&t, &beacon); bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_STA); t.phy->phy_date = 0; t.bsu->sta_avln->sync.init = true; u32 bpsd0; bsu_aclf_beacon_period_start_date (t.bsu->aclf, &bpsd0, 1); t.bsu->sta_avln->beacon.beacon_period_start_date = bpsd0 + 1; bsu_timer_event_process (t.bsu); test_fail_unless (t.ul.beacon == INVALID_PTR); bsu_test_uninit (&t); } test_end; test_begin (test, "STA:Fake beacon from bsu:PLC beacon not received") { bsu_test_t t; bsu_test_init (&t); bsu_activate (t.bsu, true); bsu_beacon_t beacon; bsu_test_create_beacon (&t, &beacon); bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_STA); t.phy->phy_date = 0; t.bsu->sta_avln->sync.init = true; u32 bpsd0; bsu_aclf_beacon_period_start_date (t.bsu->aclf, &bpsd0, 1); t.bsu->sta_avln->beacon.beacon_period_start_date = bpsd0 - t.bsu->aclf->beacon_period_tck; t.bsu->sta_avln->beacon.bmis.eks.present = true; t.bsu->sta_avln->beacon.bmis.eks.kccd = 2; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK; t.bsu->sta_avln->beacon.bmis.eks.new_eks = 7; bsu_timer_event_process (t.bsu); test_fail_unless (t.ul.beacon != INVALID_PTR); test_fail_unless (t.ul.beacon->params.direction == BSU_BEACON_DIRECTION_FROM_BSU); test_fail_unless (t.ul.beacon->bmis.eks.present == true); test_fail_unless (t.ul.beacon->bmis.eks.kccd == 2); test_fail_unless (t.ul.beacon->bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (t.ul.beacon->bmis.eks.new_eks == 7); blk_release (t.ul.beacon); t.ul.beacon = INVALID_PTR; bsu_test_uninit (&t); } test_end; test_begin (test, "CCo") { bsu_test_t t; test_case_bsu_timer_event_cco_ucco (test, &t, BSU_UPDATE_STA_TYPE_CCO); mfs_t *mfs; uint i; bsu_avln_t cmp_avln; bsu_test_init (&t); bsu_activate (t.bsu, true); bsu_test_avln_create (&t, &cmp_avln); u32 now = phy_date (); for (i = 0; i < BSU_ACLF_BPSD_NB; i++) t.bsu->aclf->bpsd[i] = now + i * t.bsu->aclf->beacon_period_tck; bsu_test_create_beacon (&t, &t.bsu->sta_avln->beacon); t.bsu->sta_avln->beacon.bmis.discover.tei = t.mac_config.tei; /* First case, update beacon in time. */ bsu_test_upper_layer_beacon_received_init (&t); t.bsu->sta_avln->beacon.beacon_period_start_date = bsu_aclf_beacon_period_start_date_next (t.bsu->aclf); t.bsu->is_sta = BSU_UPDATE_STA_TYPE_CCO; bsu_timer_event_process (t.bsu); test_fail_unless (t.ul.beacon); test_fail_unless (t.ul.beacon->params.direction == BSU_BEACON_DIRECTION_TO_PLC); test_fail_unless (t.ul.beacon->next); test_fail_unless (t.ul.beacon->next->params.direction == BSU_BEACON_DIRECTION_TO_PLC); blk_release (t.ul.beacon->next); blk_release (t.ul.beacon); mfs = mac_store_mfs_get (t.mac_store, true, true, false, MAC_LID_SPC_CENTRAL, MAC_TEI_BCAST); test_fail_unless (mfs != NULL); mfs->tx.head = NULL; blk_release (mfs); /* Release MFS. */ mac_store_mfs_remove (t.mac_store, mfs); mfs = mac_store_mfs_get (t.mac_store, true, true, false, MAC_LID_DISCOVER, MAC_TEI_BCAST); test_fail_unless (mfs != NULL); mfs->tx.head = NULL; blk_release (mfs); /* Release MFS. */ mac_store_mfs_remove (t.mac_store, mfs); bsu_test_uninit (&t); } test_end; test_begin (test, "UCCo") { bsu_test_t t; test_case_bsu_timer_event_cco_ucco ( test, &t, BSU_UPDATE_STA_TYPE_CCO); } test_end; } void test_case_bsu_activate (test_t test) { bsu_test_t t; bsu_test_init (&t); /* bsu test init set a sync variable in poweron table. */ memset (&t.bsu->poweron, 0, sizeof (bsu_avln_t)); test_case_begin (test, "BSU activate"); test_begin (test, "Activate/deactivate") { u32 bpsd[4]; uint i; bsu_beacon_t beacon; bsu_test_create_beacon (&t, &beacon); bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_CCO); bsu_power_on (t.bsu, 0); bsu_activate (t.bsu, true); test_fail_unless (t.bsu->activate == true); bsu_aclf_beacon_period_start_date (t.bsu->aclf, bpsd, COUNT(bpsd)); for (i = 0; i < COUNT (bpsd) - 1; i++) test_fail_unless (bpsd[i] != bpsd[i+1]); test_fail_unless (t.ca.nb_beacon_periods == 3); for (i = 0; i < t.ca.nb_beacon_periods; i++) test_fail_unless (t.ca.beacon_periods[i].start_date == bpsd[i]); bsu_activate (t.bsu, false); test_fail_unless (t.bsu->activate == false); test_fail_unless (t.bsu->sta_avln == &t.bsu->poweron); /* Reactivate the BSU. */ bsu_aclf_beacon_period_start_date (t.bsu->aclf, bpsd, COUNT (bpsd)); bsu_activate (t.bsu, true); for (i = 0; i < t.ca.nb_beacon_periods; i++) test_fail_unless (t.ca.beacon_periods[i].start_date != bpsd[i]); /* Verify that new bpsd start date are for now. */ bsu_aclf_beacon_period_start_date (t.bsu->aclf, bpsd, COUNT (bpsd)); for (i = 0; i < t.ca.nb_beacon_periods; i++) test_fail_unless (t.ca.beacon_periods[i].start_date == bpsd[i]); } test_end; bsu_test_uninit (&t); } void test_case_bsu_power_on (test_t test) { bsu_test_t t; bsu_test_init (&t); test_case_begin (test, "BSU power ON"); test_begin (test, "Power on") { bsu_beacon_t beacon; bsu_test_create_beacon (&t, &beacon); bsu_update (t.bsu, &beacon, BSU_UPDATE_STA_TYPE_STA); bsu_power_on (t.bsu, 0xa); test_fail_unless (t.bsu->sta_avln == &t.bsu->poweron); test_fail_unless ( memcmp (&t.bsu->sta_avln->beacon.bmis.ps, &t.bsu->sta_avln->beacon.bmis.ps, sizeof (bsu_beacon_bmi_persistent_schedule_desc_t)) == 0); test_fail_unless ( memcmp (&t.bsu->sta_avln->beacon.bmis.nps, &t.bsu->sta_avln->beacon.bmis.nps, sizeof (bsu_beacon_bmi_non_persistent_schedule_t)) == 0); } test_end; bsu_test_uninit (&t); } void test_case_bsu_persistent_schedules_update__cscma_cscd_permanent ( test_t test, uint ps_nb) { uint i; bsu_test_t t; bsu_beacon_t beacon; test_within (test); bsu_test_init (&t); memset (&t.bsu->sta_avln->beacon, 0, sizeof (bsu_beacon_t)); t.bsu->sta_avln->beacon.vf.nm = MAC_NM_CSMA_ONLY; bsu_test_create_beacon (&t, &beacon); beacon.bmis.ps.nb = ps_nb; beacon.bmis.ps.ps[0].cscd = HPAV_SCHEDULE_PERMAMENT_VALUE; for (i = 0; i < BSU_ACLF_BPSD_NB; i++) t.bsu->aclf->bpsd[i] = i * t.bsu->aclf->beacon_period_tck; bsu_update__persistent_schedules (t.bsu, &beacon); test_fail_unless (t.bsu->sta_avln->beacon.bmis.ps.nb == ps_nb); for (i = 0; i < ps_nb; i++) { test_fail_unless (t.bsu->sta_avln->beacon.bmis.ps.ps[i].pscd == beacon.bmis.ps.ps[i].pscd); test_fail_unless (t.bsu->sta_avln->beacon.bmis.ps.ps[i].cscd == beacon.bmis.ps.ps[i].cscd); } bsu_test_uninit (&t); } void test_case_bsu_persistent_schedules_update__cscma_cscd_non_permanent ( test_t test, uint ps_nb) { uint i; bsu_test_t t; bsu_beacon_t beacon; test_within (test); bsu_test_init (&t); memset (&t.bsu->sta_avln->beacon, 0, sizeof (bsu_beacon_t)); t.bsu->sta_avln->beacon.vf.nm = MAC_NM_CSMA_ONLY; bsu_test_create_beacon (&t, &beacon); beacon.bmis.ps.nb = ps_nb; bsu_update__persistent_schedules (t.bsu, &beacon); test_fail_unless (t.bsu->sta_avln->beacon.bmis.ps.nb == ps_nb); uint bd = (bsu_aclf_beacon_period_start_date_next (t.bsu->aclf) - beacon.beacon_period_start_date) / bsu_aclf_beacon_period_tck (t.bsu->aclf); for (i = 0; i < ps_nb; i++) { uint pscd = beacon.bmis.ps.ps[i].pscd; uint cscd = beacon.bmis.ps.ps[i].cscd; if ((int) (pscd - bd) < 0) { bd -= pscd; pscd = 0; if (bd) cscd -= bd; } else pscd -= bd; test_fail_unless (t.bsu->sta_avln->beacon.bmis.ps.ps[i].pscd == pscd); test_fail_unless (t.bsu->sta_avln->beacon.bmis.ps.ps[i].cscd == cscd); } bsu_test_uninit (&t); } void test_case_bsu_persistent_schedules_update (test_t test) { uint i; test_case_begin (test, "BSU update persistent schedules"); test_begin (test, "CSMA only permanent persistent schedule") { for (i = 0; i < BSU_BEACON_BMI_PERSISTENT_SCHEDULE_MAX; i++) test_case_bsu_persistent_schedules_update__cscma_cscd_permanent ( test, i); } test_end; test_begin (test, "CSMA only persistent schedule") { for (i = 0; i <= BSU_BEACON_BMI_PERSISTENT_SCHEDULE_MAX; i++) test_case_bsu_persistent_schedules_update__cscma_cscd_non_permanent ( test, i); } test_end; } void test_case_bsu_nek_index (test_t test) { test_case_begin (test, "NEK index"); bsu_test_t t; bsu_test_init (&t); test_begin (test, "Current index") { bsu_test_avln_create (&t, t.bsu->sta_avln); test_fail_unless (bsu_nek_index_current (t.bsu) == t.bsu->nek_switch); test_fail_unless (bsu_nek_index_next (t.bsu) == !t.bsu->nek_switch); t.bsu->nek_switch = 1; test_fail_unless (bsu_nek_index_current (t.bsu) == t.bsu->nek_switch); test_fail_unless (bsu_nek_index_next (t.bsu) == !t.bsu->nek_switch); } test_end; bsu_test_uninit (&t); } void test_case_bsu_handle_key_change (test_t test) { test_case_begin (test, "Handle key change"); bsu_test_t t; bsu_test_init (&t); test_begin (test, "No key bentry"); { t.bsu->nek_switch = 0; t.bsu->sta_avln->beacon.bmis.eks.present = false; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK; t.bsu->sta_avln->beacon.bmis.eks.kccd = 1; bsu_handle_key_change (t.bsu); test_fail_unless (t.bsu->nek_switch == 0); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.present == false); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kccd == 1); } test_end; test_begin (test, "Key bentry:Not NEK"); { t.bsu->nek_switch = 0; t.bsu->sta_avln->beacon.bmis.eks.present = true; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NMK; t.bsu->sta_avln->beacon.bmis.eks.kccd = 4; bsu_handle_key_change (t.bsu); test_fail_unless (t.bsu->nek_switch == 0); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NMK); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kccd == 3); } test_end; test_begin (test, "Key bentry:NEK"); { t.bsu->nek_switch = 0; t.bsu->sta_avln->beacon.bmis.eks.present = true; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK; t.bsu->sta_avln->beacon.bmis.eks.kccd = 4; bsu_handle_key_change (t.bsu); test_fail_unless (t.bsu->nek_switch == 0); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.present == true); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kccd == 3); } test_end; test_begin (test, "Key bentry:Not NEK:KCCD == 1"); { t.bsu->nek_switch = 0; t.bsu->sta_avln->beacon.bmis.eks.present = true; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NMK; t.bsu->sta_avln->beacon.bmis.eks.kccd = 1; bsu_handle_key_change (t.bsu); test_fail_unless (t.bsu->nek_switch == 0); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.present == false); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NMK); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kccd == 1); } test_end; test_begin (test, "Key bentry:NEK:KCCD == 1"); { t.bsu->nek_switch = 0; t.bsu->sta_avln->beacon.bmis.eks.present = true; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK; t.bsu->sta_avln->beacon.bmis.eks.kccd = 1; bsu_handle_key_change (t.bsu); test_fail_unless (t.bsu->nek_switch == 1); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.present == false); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kbc == BSU_BEACON_EKS_KBC_NEK); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.kccd == 1); } test_end; test_begin (test, "Delete previous NEK after NEK change"); { t.bsu->nek_switch = 0; t.mac_config.nek[0].eks = MAC_EKS_MIN; t.mac_config.nek[1].eks = MAC_EKS_MAX; t.bsu->sta_avln->beacon.bmis.eks.present = true; t.bsu->sta_avln->beacon.bmis.eks.kbc = BSU_BEACON_EKS_KBC_NEK; t.bsu->sta_avln->beacon.bmis.eks.kccd = 1; bsu_handle_key_change (t.bsu); test_fail_unless (t.mac_config.nek[0].eks == MAC_EKS_MIN); test_fail_unless (t.mac_config.nek[1].eks == MAC_EKS_MAX); bsu_handle_key_change (t.bsu); test_fail_unless (t.mac_config.nek[0].eks == MAC_EKS_CLEAR); test_fail_unless (t.mac_config.nek[1].eks == MAC_EKS_MAX); } test_end; bsu_test_uninit (&t); } void test_case_bsu_discover_update (test_t test) { test_case_begin (test, "Update discover info beacon entry"); test_begin (test, "update") { bsu_test_t t; bsu_test_init (&t); bsu_beacon_t beacon; bsu_test_create_beacon (&t, &beacon); memset (&t.bsu->sta_avln->beacon.bmis.discover_info, 0, sizeof (bsu_beacon_bmi_discover_info_t)); test_fail_unless (memcmp (&beacon.bmis.discover_info, &t.bsu->sta_avln->beacon.bmis.discover_info, sizeof (bsu_beacon_bmi_discover_info_t)) != 0); bsu_update_discover_info (t.bsu, &beacon.bmis.discover_info); test_fail_unless (memcmp (&beacon.bmis.discover_info, &t.bsu->discover_info, sizeof (bsu_beacon_bmi_discover_info_t)) == 0); /* change update flag. */ bitstream_direct_write (&beacon.bmis.discover_info.info_data, 0, 1, 1); bsu_update_discover_info (t.bsu, &beacon.bmis.discover_info); test_fail_unless ( memcmp (&beacon.bmis.discover_info, &t.bsu->discover_info, sizeof (bsu_beacon_bmi_discover_info_t)) == 0); /* change update flag. */ bitstream_direct_write (&beacon.bmis.discover_info.info_data, 0, 0, 1); bsu_update_discover_info (t.bsu, &beacon.bmis.discover_info); test_fail_unless ( memcmp (&beacon.bmis.discover_info, &t.bsu->sta_avln->beacon.bmis.discover_info, sizeof (bsu_beacon_bmi_discover_info_t)) != 0); test_fail_unless ( bitstream_direct_read ( &t.bsu->discover_info.info_data, 0, 1) == true); /* Simulate BSU reset the flag after sending a discover beacon. */ t.bsu->discover_info = beacon.bmis.discover_info; bsu_update_discover_info (t.bsu, &beacon.bmis.discover_info); test_fail_unless ( memcmp (&beacon.bmis.discover_info, &t.bsu->discover_info, sizeof (bsu_beacon_bmi_discover_info_t)) == 0); test_fail_unless ( bitstream_direct_read ( &t.bsu->discover_info.info_data, 0, 1) == false); bsu_test_uninit (&t); } test_end; } void test_case_bsu_add_avln_array_full (test_t t) { test_case_begin (t, "Array BSU AVLN full"); bsu_test_t ctx; bsu_test_init (&ctx); test_begin (t, "Add new AVLN") { bsu_avln_t *avln; bool added; uint i; u32 now = phy_date (); for (i = 0; i < BSU_FOREIGN_AVLNS_NB; i++) { avln = bsu_avln_add ( ctx.bsu, i, i, MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, i), &added); avln->beacon.beacon_period_start_date = now + i; test_fail_unless (added); } test_fail_unless (ctx.bsu->avlns_nb == BSU_FOREIGN_AVLNS_NB); /* Add a new AVLN, the first one with NID == 0, snid == 0 should be * removed. */ avln = bsu_avln_add ( ctx.bsu, 200, 0x4, MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, 0xfe), &added); test_fail_unless (added); test_fail_unless (avln->beacon.vf.nid == 200); test_fail_unless (avln->snid == 4); test_fail_unless (avln->cco_mac_address == MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, 0xfe)); test_fail_unless (!avln->sync.init); test_fail_unless (avln == &ctx.bsu->avlns[0]); /* Try to get the first one. */ avln = bsu_avln_get (ctx.bsu, 0, 0, MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, 0x0)); test_fail_unless (!avln); } test_end; bsu_test_uninit (&ctx); } void test_case_bsu_avln_remove (test_t t) { test_case_begin (t, "AVLN remove"); test_begin ( t, "add and remove avlns with sta_avln setted before and after") { bsu_test_t ctx; bsu_test_init (&ctx); bool added; uint i; for (i = 0; i < BSU_FOREIGN_AVLNS_NB; i++) { bsu_avln_add (ctx.bsu, i, i, i, &added); test_fail_unless (added); } /* sta_avln is the one removed. */ ctx.bsu->sta_avln = &ctx.bsu->avlns[1]; /* Reinitialise the sync information wrote by bsu_test_init. */ bsu_ntb_init (&ctx.bsu->poweron.sync); bsu_avln_remove (ctx.bsu, 1, 1, 1); test_fail_unless (ctx.bsu->sta_avln == &ctx.bsu->poweron); /* sta_avln is the first one. */ ctx.bsu->sta_avln = &ctx.bsu->avlns[0]; bsu_avln_remove (ctx.bsu, 2, 2, 2); test_fail_unless (ctx.bsu->sta_avln == &ctx.bsu->avlns[0]); /* sta_avln is the 4th one. */ ctx.bsu->sta_avln = &ctx.bsu->avlns[4]; bsu_avln_remove (ctx.bsu, 3, 3, 3); test_fail_unless (ctx.bsu->sta_avln == &ctx.bsu->avlns[3]); bsu_test_uninit (&ctx); } test_end; } void test_case_bsu_update_tracking (test_t t) { test_case_begin (t, "Update tracking"); test_begin (t, "update tracking") { u8 tei = MAC_TEI_STA_MAX; mac_t mac = MAC_ADDRESS (0x00, 0x13, 0xd7, 0x78, 0x79, 0x80); bsu_test_t ctx; bsu_test_init (&ctx); test_fail_unless (ctx.bsu->tei_track != tei); test_fail_unless (ctx.bsu->cco_mac_address_track != mac); bsu_update_tracking (ctx.bsu, tei, mac); test_fail_unless (ctx.bsu->tei_track == tei); test_fail_unless (ctx.bsu->cco_mac_address_track == mac); bsu_test_uninit (&ctx); } test_end; } void test_case_bsu_update_nid_snid (test_t t) { test_case_begin (t, "Update NID and SNID"); test_begin (t, "Update NID and SNID") { bsu_test_t ctx; bsu_test_init (&ctx); bool added; bsu_avln_add (ctx.bsu, 0x123456789abcull, 3, MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, 0x01), &added); test_fail_unless (added); /* sta_avln is the one removed. */ ctx.bsu->sta_avln = &ctx.bsu->avlns[0]; bsu_update_nid_snid (ctx.bsu, 0x111111111ull, 4); test_fail_unless (ctx.bsu->sta_avln->snid == 4); test_fail_unless (ctx.bsu->sta_avln->beacon.vf.nid == 0x111111111ull); bsu_test_uninit (&ctx); } test_end; } void test_bsu_process_track_beacon (test_t test, bsu_test_t *ctx, u32 bts) { test_within (test); bsu_beacon_t beacon; pbproc_rx_beacon_params_t rx_params; bool added; uint i; memset (&rx_params, 0, sizeof (pbproc_rx_beacon_params_t)); bsu_avln_add (ctx->bsu, 0x123456789abcull, 3, MAC_ADDRESS (0x00, 0x13, 0xd7, 0x00, 0x00, 0x01), &added); ctx->bsu->sta_avln->sync.init = true; ctx->bsu->sta_avln->sync.ntb_offset_tck = 0; ctx->bsu->sta_avln->sync.fe = 0.0; bsu_test_create_beacon (ctx, &beacon); beacon.bmis.bpsto.bpsto = 0; rx_params.preamble_sysdate = rx_params.preamble_date = rx_params.bts = bts; bsu_beacon_process__avln_tracked (ctx->bsu, &beacon, &rx_params); /* Verify the beacon period start date computed by the beacon * reception. BPSD[0] is never modified by a beacon reception. */ test_fail_unless (ctx->bsu->aclf->bpsd[0] == 0); for (i = 1; i < BSU_ACLF_BPSD_NB; i++) { test_fail_unless (i * ctx->bsu->aclf->beacon_period_theo_tck - MAC_TOLERANCE_TCK == ctx->bsu->aclf->bpsd[i]); } } void test_case_bsu_process_track_beacon (test_t test) { test_case_begin (test, "Process a tracked central beacon"); bsu_test_t ctx; bsu_test_init (&ctx); test_begin (test, "received in the previous beacon period for the" " next one") { test_bsu_process_track_beacon (test, &ctx, 0 - MAC_TOLERANCE_TCK); } test_end; test_begin (test, "received in the previous beacon period for the" " next one but just before the tolerance.") { test_bsu_process_track_beacon (test, &ctx, 0 - MAC_TOLERANCE_TCK - 1); } test_end; bsu_test_uninit (&ctx); } void test_suite_bsu (test_t t) { test_suite_begin (t, "BSU test"); test_case_bsu_activate (t); test_case_bsu_power_on (t); test_case_bsu_process (t); test_case_bsu_process_sta_is_cco (t); test_case_bsu_update (t); test_case_bsu_update_nid_snid (t); test_case_bsu_timer_event (t); test_case_bsu_persistent_schedules_update (t); test_case_bsu_nek_index (t); test_case_bsu_handle_key_change (t); test_case_bsu_discover_update (t); test_case_bsu_add_avln_array_full (t); test_case_bsu_avln_remove (t); test_case_bsu_update_tracking (t); test_case_bsu_process_track_beacon (t); }