/* Cesar project {{{ * * Copyright (C) 2007 Spidcom * * <<>> * * }}} */ /** * \file mac/common/src/mfs.c * \brief MAC frame stream functions. * \ingroup mac_common */ #include "common/std.h" #include "mac/common/mfs.h" #include "mac/common/defs.h" #include "mac/common/timings.h" /** MFS MME window size. */ #define MFS_WINDOW_SIZE_MME 8 /** MFS DATA window size. */ #define MFS_WINDOW_SIZE_DATA 200 static void mfs_common_init (mfs_common_t *mfs_common, bool tx, bool bcast, bool mme, uint lid, uint tei) { mfs_common->tx = tx; mfs_common->bcast = bcast; mfs_common->mme = mme; mfs_common->ats = false; mfs_common->lid = lid; mfs_common->tei = tei; mfs_common->lid_alias = MAC_LID_NONE; mfs_common->unassociated = false; list_init_node (&mfs_common->store_unassociated_link); /* mfs_common->expiration_ntb */ if (tx) mfs_common->expiration_delay_tck = MAC_MS_TO_TCK (MFS_PB_TX_DELAY_MS); else mfs_common->expiration_delay_tck = MAC_MS_TO_TCK (MFS_PB_RX_DELAY_MS); } void mfs_rx_init (mfs_rx_t *mfs, bool bcast, bool mme, uint lid, uint tei) { dbg_assert_ptr (mfs); dbg_assert ((mme && lid == MAC_LID_NONE) || (!mme && MAC_LID_IS_XLID (lid))); dbg_assert (tei != MAC_TEI_BCAST); mfs_common_init (&mfs->common, false, bcast, mme, lid, tei); mfs->head = NULL; mfs->ssn_min = 0; mfs->window_size = mme ? MFS_WINDOW_SIZE_MME : MFS_WINDOW_SIZE_DATA; mfs->window_size_encoded = mfs_rx_window_size_encode (mfs->window_size); mfs->release = false; link_stats_rx_reset (&mfs->stats); } void mfs_rx_init_unassociated (mfs_rx_t *mfs, bool bcast, bool mme, uint lid, uint tei) { mfs_rx_init (mfs, bcast, mme, lid, tei); mfs->common.unassociated = true; } void mfs_tx_init (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei) { dbg_assert_ptr (mfs); dbg_assert ((mme && lid == MAC_LID_NONE) || (!mme && (MAC_LID_IS_XLID (lid) || MAC_LID_IS_BEACON (lid)))); dbg_assert ((bcast && tei == MAC_TEI_BCAST) || (!bcast && MAC_TEI_IS_STA (tei)) || (!bcast && mme && tei == MAC_TEI_UNASSOCIATED)); mfs_common_init (&mfs->common, true, bcast, mme, lid, tei); mfs->cfp = false; mfs->burst_count = 0; list_init_node (&mfs->ca_link); mfs->ca_state = CA_MFS_STATE_UNKNOWN; mfs->seg_nb = 0; mfs->pending_seg_nb = 0; mfs->fsm_state = bcast ? MFS_FSM_CMD_NOP : MFS_FSM_CMD_INIT; mfs->min_ssn = 0; mfs->window_size = mme ? MFS_WINDOW_SIZE_MME : MFS_WINDOW_SIZE_DATA; mfs->window_holes_seg_nb = 0; if (mme) mfs->cap = 2; else mfs->cap = MAC_LID_IS_PLID (lid) ? lid : 0; mfs->head = NULL; dbg_invalid_ptr (mfs->tail); mfs->last_seg_offset = 0; mfs->next_ssn = 0; mfs->beacon = false; link_stats_tx_reset (&mfs->stats); } void mfs_tx_init_unassociated (mfs_tx_t *mfs, bool bcast, bool mme, uint lid, uint tei) { dbg_assert (mfs); mfs_tx_init (mfs, bcast, mme, lid, tei); mfs->common.unassociated = true; mfs->fsm_state = MFS_FSM_CMD_NOP; } u8 mfs_rx_window_size_encode (u16 window_size) { uint i; static u16 encode_table[] = { 4, 8, 16, 24, 32, 48, 64, 80, 96, 112, 128, 144, 160, 192, 224, 256 }; dbg_assert (window_size >= 4 && window_size <= 256); DICHOTOMY_SEARCH (0, COUNT (encode_table), i, window_size < encode_table[i]); return i - 1; }