/* 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" 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_avln_get (bsu_t *ctx, u64 nid, u16 snid); void test_case_bsu_process (test_t test) { bsu_test_t t; bsu_test_init (&t); bsu_activate (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; bsu_test_create_beacon (&t, &beacon_neighbour); 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; 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); /* NTB called ? */ test_fail_unless (t.bsu->avlns[0].sync.init == false); 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 (!bprocessed->params.frequency_error_valid); 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); test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_CENTRAL] == 1); blk_release (bprocessed); /* NTB called ? */ test_fail_unless (t.bsu->avlns[0].sync.init == true); /* Second shoot... */ 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); /* NTB called ? */ test_fail_unless (t.bsu->avlns[0].sync.init == true); test_fail_unless (bprocessed->params.frequency_error_valid); blk_release_desc ((blk_t*) bneighbour); test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_CENTRAL] == 2); blk_release (bprocessed); /* Our AVLN. */ bsu_track_avln ( beacon_neighbour.vf.nid, 0x4, beacon_neighbour.vf.stei); t.bsu->sta_avln->sync.init = false; bsu_test_create_beacon (&t, &beacon); 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); /* 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] == 2); blk_release_desc ((blk_t*) b); /* NTB called ? */ test_fail_unless (t.bsu->sta_avln->sync.init == false); 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 = 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); test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_CENTRAL] == 3); /* NTB called ? */ test_fail_unless (t.bsu->sta_avln->sync.init == true); test_fail_unless (t.bsu->sta_avln->sync.second_shoot); test_fail_unless (bprocessed->params.frequency_error_valid); 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 () - BSU_ACLF_BP_50HZ_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 (beacon.vf.nid, brx.snid, t.mac_config.tei); 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); test_fail_unless (t.bsu->beacon_nb_recv [BSU_BEACON_TYPE_CENTRAL] == 5); /* 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 }; for (i = 0; i < COUNT (type); i++) { bsu_update (&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 () - BSU_ACLF_BP_50HZ_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); 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); 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 (beacon.vf.nid, brx.snid, 1); test_fail_unless (avln == t.bsu->sta_avln); bsu_avln_remove (beacon.vf.nid, brx.snid); 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); 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 (&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 * BSU_ACLF_BP_50HZ_TCK; beacon->beacon_period_start_date = bsu_aclf_beacon_period_start_date_next (test->bsu->aclf) - BSU_ACLF_BP_50HZ_TCK; } void test_case_bsu_update (test_t test) { bsu_test_t t; bsu_beacon_t beacon; bsu_test_init (&t); bsu_activate (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 (&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 (&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 (&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 (&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.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 (&beacon, true /* is station. */); test_fail_unless (t.bsu->sta_avln->beacon.bmis.mac_address_present.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.eks.present = false; 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.present = false; bsu_update (&beacon, true /* is station. */); test_fail_unless (t.bsu->sta_avln->beacon.bmis.eks.present == true); 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.present == true); } 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 (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 * BSU_ACLF_BP_50HZ_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 (&beacon, type); t->bsu->sta_avln->beacon.vf.nm = BSU_BEACON_NM_UNCOORDINATED; t->bsu->sta_avln->beacon.bmis.bpsto.present = false; cmp_avln.beacon.vf.nm = BSU_BEACON_NM_UNCOORDINATED; bsu_timer_event_process (t->bsu); test_fail_unless (t->ul.beacon != INVALID_PTR); 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 () - BSU_ACLF_BP_50HZ_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); 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_beacon_t beacon; bsu_power_on (0); bsu_activate (true); bsu_test_create_beacon (&t, &beacon); bsu_update (&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 = BSU_BEACON_NM_UNCOORDINATED; u32 now = phy_date (); for (i = 0; i < BSU_ACLF_BPSD_NB; i++) t.bsu->aclf->bpsd[i] = now + i * BSU_ACLF_BP_50HZ_TCK; for (j = 0; j < 10; j++) { t.bsu->sta_avln->beacon.beacon_period_start_date = t.bsu->aclf->bpsd[0] - BSU_ACLF_BP_50HZ_TCK; cmp_avln.beacon.beacon_period_start_date = t.bsu->aclf->bpsd[0] - BSU_ACLF_BP_50HZ_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) * BSU_ACLF_BP_50HZ_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); } } 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 (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 * BSU_ACLF_BP_50HZ_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->next); 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); 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 (&beacon, BSU_UPDATE_STA_TYPE_CCO); bsu_power_on (0); bsu_activate (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 (false); test_fail_unless (t.bsu->activate == false); } 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 (&beacon, BSU_UPDATE_STA_TYPE_STA); bsu_power_on (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 = BSU_BEACON_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 * BSU_ACLF_BP_50HZ_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 = BSU_BEACON_NM_CSMA_ONLY; bsu_test_create_beacon (&t, &beacon); beacon.bmis.ps.nb = ps_nb; u32 now = phy_date (); for (i = 0; i < BSU_ACLF_BPSD_NB; i++) t.bsu->aclf->bpsd[i] = now + i * BSU_ACLF_BP_50HZ_TCK; 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->nek_switch); test_fail_unless (bsu_nek_index_next () == !t.bsu->nek_switch); t.bsu->nek_switch = 1; test_fail_unless (bsu_nek_index_current () == t.bsu->nek_switch); test_fail_unless (bsu_nek_index_next () == !t.bsu->nek_switch); } 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 (&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 (&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 (&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 (&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_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_timer_event (t); test_case_bsu_persistent_schedules_update (t); test_case_bsu_nek_index (t); test_case_bsu_discover_update (t); }