- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# /space/home/slher/rel/Beken/v6_4_5/macsw/ip/umac/src/bam/bam_task.c

Go to the documentation of this file.

    00001
    00013 /*
    00014  * INCLUDE FILES
    00015  ****************************************************************************************
    00016  */
    00017
    00018 // for endian functions
    00019 #include "co_endian.h"
    00020 // for co read/write
    00021 #include "co_utils.h"
    00022 #include "bam.h"
    00023 #include "bam_task.h"
    00024 #include "mac_frame.h"
    00025 #include "me_mgmtframe.h"
    00026 #include "ke_timer.h"
    00027 #include "mm.h"
    00028 #include "mm_task.h"
    00029 #include "rxu_task.h"
    00030 #include "sta_mgmt.h"
    00031 #include "me.h"
    00032 #include "ps.h"
    00033
    00039 /*
    00040  * API MESSAGES HANDLERS
    00041  ****************************************************************************************
    00042  */
    00043
    00044 #if NX_AMPDU_TX
    00045
    00056 static int bam_add_ba_rsp_timeout_ind_handler(ke_msg_id_t const msgid,
    00057                                               void const *param,
    00058                                               ke_task_id_t const dest_id,
    00059                                               ke_task_id_t const src_id)
    00060 {
    00061     if (ke_state_get(dest_id) == BAM_WAIT_RSP)
    00062     {
    00063         uint16_t bam_idx = KE_IDX_GET(dest_id);
    00064
    00065         // Reset information store in the STA_MGMT module
    00066         bam_param_sta_info_tab_reset(bam_idx);
    00067
    00068         // Go back to IDLE state
    00069         ke_state_set(dest_id, BAM_IDLE);
    00070
    00071         TRACE_LMAC(BA, "{BAM-%d} no response from STA, drop agreement", bam_idx);
    00072     }
    00073     // else drop the message
    00074
    00075     return (KE_MSG_CONSUMED);
    00076 }
    00077 #endif
    00078
    00079 #if NX_AMPDU_TX || NX_REORD
    00080
    00092 static void bam_delba_status(void *env, uint32_t status)
    00093 {
    00094     struct bam_env_tag *bam = env;
    00095     uint16_t bam_idx = 0;
    00096
    00097     while ((bam_idx < BAM_IDX_MAX) && (bam != &bam_env[bam_idx]))
    00098     {
    00099         bam_idx++;
    00100     }
    00101
    00102     /* If BAM is not in BAM_DELETE state it means that BA has already been deleted
    00103        (e.g. a DELBA has been received since the transmission of DELBA )*/
    00104     if ((bam_idx == BAM_IDX_MAX)||
    00105         (ke_state_get(KE_BUILD_ID(TASK_BAM, bam_idx)) != BAM_DELETE))
    00106     {
    00107         return;
    00108     }
    00109
    00110     if (!(status & FRAME_SUCCESSFUL_TX_BIT) &&
    00111         (bam->delba_count < BAM_DELBA_MAX_TRY))
    00112     {
    00113         bam->delba_count++;
    00114         bam_send_air_action_frame(bam->sta_idx, bam, MAC_BA_ACTION_DELBA,
    00115                                   0, 0, MAC_RS_TIMEOUT, bam_delba_status);
    00116     }
    00117     else
    00118     {
    00119         bam_send_mm_ba_del_req(bam->sta_idx, bam_idx);
    00120     }
    00121 }
    00122
    00134 static int bam_inactivity_timeout_ind_handler(ke_msg_id_t const msgid,
    00135                                               void const *param,
    00136                                               ke_task_id_t const dest_id,
    00137                                               ke_task_id_t const src_id)
    00138 {
    00139
    00140     if (ke_state_get(dest_id) == BAM_ACTIVE)
    00141     {
    00142         uint16_t bam_idx = KE_IDX_GET(dest_id);
    00143         struct bam_env_tag *bam = &bam_env[bam_idx];
    00144
    00145         // Check if the BA agreement has been inactive for the timeout duration
    00146         if (!bam_env[bam_idx].pkt_cnt &&
    00147              hal_machw_time_past(bam->last_activity_time + bam->ba_timeout * TU_DURATION))
    00148         {
    00149             uint16_t sta_idx = bam_env[bam_idx].sta_idx;
    00150
    00151             TRACE_LMAC(BA, "{BAM-%d} delete agreement with {STA-%d} because of inactivity",
    00152                        bam_idx, sta_idx);
    00153
    00154             // Go to BAM_DELETE state
    00155             ke_state_set(dest_id, BAM_DELETE);
    00156             // Send DELBA packet
    00157             bam->delba_count = 0;
    00158             bam_send_air_action_frame(sta_idx, &bam_env[bam_idx], MAC_BA_ACTION_DELBA, 0, 0,
    00159                                       MAC_RS_TIMEOUT, bam_delba_status);
    00160         }
    00161         else
    00162         {
    00163             // Re-start the timer
    00164             bam_start_inactivity_timer(bam_idx);
    00165         }
    00166     }
    00167
    00168     return (KE_MSG_CONSUMED);
    00169 }
    00170
    00183 static int mm_ba_add_cfm_handler(ke_msg_id_t const msgid,
    00184                                  struct mm_ba_add_cfm const *param,
    00185                                  ke_task_id_t const dest_id,
    00186                                  ke_task_id_t const src_id)
    00187 {
    00188     uint16_t bam_idx = KE_IDX_GET(dest_id);
    00189
    00190     if (ke_state_get(dest_id) != BAM_CHECK_ADMISSION)
    00191     {
    00192         ASSERT_WARN(0);
    00193         return KE_MSG_CONSUMED;
    00194     }
    00195
    00196     // Check the device type
    00197     switch (bam_env[bam_idx].dev_type)
    00198     {
    00199         #if NX_AMPDU_TX
    00200         case BA_ORIGINATOR:
    00201         {
    00202             if (param->status == BA_AGMT_ESTABLISHED)
    00203             {
    00204                 int8_t credit_oft = (int8_t)bam_env[bam_idx].buffer_size -
    00205                     NX_DEFAULT_TX_CREDIT_CNT;
    00206
    00207                 // Initialize the BAW
    00208                 bam_baw_init(&bam_env[bam_idx]);
    00209
    00210                 // Initialize the activity timer
    00211                 bam_env[bam_idx].last_activity_time = hal_machw_time();
    00212
    00213                 // Update the credit offset for this STA/TID pair
    00214                 me_credits_update_ind(param->sta_idx, param->tid, credit_oft);
    00215
    00216                 // Start the activity timeout timer
    00217                 bam_start_inactivity_timer(bam_idx);
    00218
    00219                 // Go back to ACTIVE state
    00220                 ke_state_set(dest_id, BAM_ACTIVE);
    00221
    00222                 TRACE_LMAC(BA, "{BAM-%d} TX agreement with {STA-%d} successfully created",
    00223                            bam_idx, param->sta_idx);
    00224             }
    00225             else
    00226             {
    00227                 // Clear the info of the BA in the sta_info_tab and mac_ba_param
    00228                 bam_param_sta_info_tab_reset(bam_idx);
    00229
    00230                 // Go back to IDLE state
    00231                 ke_state_set(dest_id, BAM_IDLE);
    00232
    00233                 TRACE_LMAC(BA, "{BAM-%d} failed to create TX agreement with {STA-%d}",
    00234                            bam_idx, param->sta_idx);
    00235             }
    00236         } break;
    00237         #endif
    00238
    00239         #if NX_REORD
    00240         case BA_RESPONDER:
    00241         {
    00242             if (param->status == BA_AGMT_ESTABLISHED)
    00243             {
    00244                 // Send AIR_ADDBA RSP frame to the originator.
    00245                 bam_send_air_action_frame(bam_env[bam_idx].sta_idx, &bam_env[bam_idx],
    00246                                           MAC_BA_ACTION_ADDBA_RSP,
    00247                                           bam_env[bam_idx].dialog_token,
    00248                                           bam_build_baparamset(&bam_env[bam_idx]),
    00249                                           MAC_BA_ST_SUCCESS, NULL);
    00250
    00251                 // Save the BAM Task index
    00252                 sta_info_tab[param->sta_idx].ba_info[param->tid].bam_idx_rx = bam_idx;
    00253
    00254                 // Initialize the activity timer
    00255                 bam_env[bam_idx].last_activity_time = hal_machw_time();
    00256
    00257                 // Start the activity timeout timer
    00258                 bam_start_inactivity_timer(bam_idx);
    00259
    00260                 // Go back to ACTIVE state
    00261                 ke_state_set(dest_id, BAM_ACTIVE);
    00262
    00263                 TRACE_LMAC(BA, "{BAM-%d} RX agreement with {STA-%d} successfully created",
    00264                            bam_idx, param->sta_idx);
    00265             }
    00266             else
    00267             {
    00268                 // Send AIR_ADDBA RSP frame to the originator.
    00269                 bam_send_air_action_frame(bam_env[bam_idx].sta_idx, &bam_env[bam_idx],
    00270                                           MAC_BA_ACTION_ADDBA_RSP,
    00271                                           bam_env[bam_idx].dialog_token,
    00272                                           bam_build_baparamset(&bam_env[bam_idx]),
    00273                                           MAC_BA_ST_REQUEST_REFUSED, NULL);
    00274
    00275                 // Go back to IDLE state
    00276                 ke_state_set(dest_id, BAM_IDLE);
    00277
    00278                 TRACE_LMAC(BA, "{BAM-%d} failed to create RX agreement with {STA-%d}",
    00279                            bam_idx, param->sta_idx);
    00280             }
    00281         } break;
    00282         #endif
    00283
    00284         default:
    00285         {
    00286             // Should not happen
    00287             ASSERT_WARN(0);
    00288         } break;
    00289     }
    00290
    00291     return KE_MSG_CONSUMED;
    00292 }
    00293
    00305 static int mm_ba_del_cfm_handler(ke_msg_id_t const msgid,
    00306                                  struct mm_ba_del_cfm const *param,
    00307                                  ke_task_id_t const dest_id,
    00308                                  ke_task_id_t const src_id)
    00309 {
    00310     uint16_t bam_idx = KE_IDX_GET(dest_id);
    00311
    00312     if ((param->status == BA_AGMT_DELETED) &&
    00313         (ke_state_get(KE_BUILD_ID(TASK_BAM, bam_idx)) == BAM_DELETE))
    00314     {
    00315         #if NX_AMPDU_TX
    00316         if (bam_env[bam_idx].dev_type == BA_ORIGINATOR)
    00317         {
    00318             int8_t credit_oft = NX_DEFAULT_TX_CREDIT_CNT -
    00319                                   (int8_t)bam_env[bam_idx].buffer_size +
    00320                                   bam_flush_baw(bam_env[bam_idx].baw);
    00321
    00322             // Update the credit offset for this STA/TID pair
    00323             me_credits_update_ind(param->sta_idx, param->tid, credit_oft);
    00324         }
    00325         #endif
    00326
    00327         bam_delete_ba_agg(bam_idx);
    00328     }
    00329
    00330     return (KE_MSG_CONSUMED);
    00331 }
    00332 #endif
    00333
    00346 static int rxu_mgt_ind_handler(ke_msg_id_t const msgid,
    00347                                struct rxu_mgt_ind const *param,
    00348                                ke_task_id_t const dest_id,
    00349                                ke_task_id_t const src_id)
    00350 {
    00351     // Pointer used to read the RX frame
    00352     uint32_t frame = CPU2HW(param->payload);
    00353     uint8_t action = co_read8p(frame + MAC_ACTION_ACTION_OFT);
    00354
    00355     // Call correct frame handler
    00356     switch (action)
    00357     {
    00358         case MAC_BA_ACTION_ADDBA_REQ:
    00359         {
    00360             uint16_t sta_idx  = param->sta_idx;
    00361             #if (NX_REORD)
    00362             uint16_t bam_idx = 0;
    00363             struct sta_info_tag *sta = &sta_info_tab[sta_idx];
    00364             #endif //(NX_REORD)
    00365             uint8_t dialog_token = co_read8p(frame + MAC_ACTION_TOKEN_OFT);
    00366             uint16_t ba_param = co_read16p(frame + BAM_ADDBAREQ_BA_PARAM_OFFSET);
    00367             uint8_t status = MAC_BA_ST_REQUEST_REFUSED;
    00368
    00369             #if NX_REORD
    00370             do
    00371             {
    00372                 uint8_t tid       = BAM_BA_PARAM_GET(ba_param, TID);
    00373
    00374                 // Check received TID
    00375                 if (tid >= TID_MAX)
    00376                 {
    00377                     break;
    00378                 }
    00379
    00380                 // Check if a BA agreement already exists for this STA/TID pair
    00381                 if (mm_ba_agmt_rx_exists(sta_idx, tid))
    00382                 {
    00383                     // Look for the BAM instance
    00384                     bam_idx = sta_mgmt_get_rx_bam_idx(sta_idx, tid);
    00385
    00386                     // Check BAM state
    00387                     if (ke_state_get(KE_BUILD_ID(TASK_BAM, bam_idx)) == BAM_ACTIVE)
    00388                     {
    00389                         // check buffer size
    00390                         if (bam_env[bam_idx].buffer_size == co_min(BAM_BA_PARAM_GET(ba_param, BUFF_SIZE), NX_REORD_BUF_SIZE))
    00391                         {
    00392                             // ADDBA Request shall be accepted
    00393                             status = MAC_BA_ST_SUCCESS;
    00394                         }
    00395                         else
    00396                         {
    00397                             // ADDBA Request shall be refused and BA agreement deleted
    00398                             status = MAC_BA_ST_REQUEST_REFUSED;
    00399
    00400                             // Go to BAM_DELETE state
    00401                             ke_state_set(KE_BUILD_ID(TASK_BAM, bam_idx), BAM_DELETE);
    00402
    00403                             // Send MM_BA_DEL_REQ to LMAC
    00404                             bam_send_mm_ba_del_req(param->sta_idx, bam_idx);
    00405                         }
    00406                     }
    00407                     break;
    00408                 }
    00409
    00410                 // Don't accept BA agreement from stations in PS mode
    00411                 if (sta->ps_state == PS_MODE_ON)
    00412                 {
    00413                     TRACE_LMAC(BA, "Refuse RX agreement with {STA-%d} in PS mode",
    00414                                sta_idx);
    00415                     status = MAC_BA_ST_REQUEST_REFUSED;
    00416                     break;
    00417                 }
    00418
    00419                 // Try to alloc a new BAM environment
    00420                 bam_idx = bam_alloc_new_task(false);
    00421
    00422                 if (bam_idx == BAM_INVALID_TASK_IDX)
    00423                 {
    00424                     // No more Block Ack agreement can be handled
    00425                     status = MAC_BA_ST_REQUEST_REFUSED;
    00426                     break;
    00427                 }
    00428
    00429                 bam_env[bam_idx].tid              = tid;
    00430                 bam_env[bam_idx].sta_idx          = sta_idx;
    00431                 bam_env[bam_idx].dialog_token     = dialog_token;
    00432                 bam_env[bam_idx].ba_policy        = BAM_BA_PARAM_GET(ba_param, BA_POL);
    00433                 bam_env[bam_idx].dev_type         = BA_RESPONDER;
    00434                 bam_env[bam_idx].ba_timeout       = co_read16p(frame + BAM_ADDBAREQ_BA_TIMEOUT_OFFSET);
    00435                 bam_env[bam_idx].buffer_size      = co_min(BAM_BA_PARAM_GET(ba_param, BUFF_SIZE), NX_REORD_BUF_SIZE);
    00436                 bam_env[bam_idx].ssn              = co_read16p(frame + BAM_ADDBAREQ_BA_SSC_OFFSET)>>MAC_SEQCTRL_NUM_OFT;
    00437                 bam_env[bam_idx].pkt_cnt          = 0;
    00438
    00439                 if (!bam_env[bam_idx].ba_timeout)
    00440                 {
    00441                     // Force inactivity timeout value a non null value
    00442                     bam_env[bam_idx].ba_timeout = BAM_INACTIVITY_TO_DURATION;
    00443                 }
    00444
    00445                 TRACE_LMAC(BA, "{BAM-%d} Start RX agreement with {STA-%d}: tid=%d ssn=%d",
    00446                            bam_idx, sta_idx, tid, bam_env[bam_idx].ssn)
    00447
    00448                 // Send MM_BA_ADD_REQ message to LMAC
    00449                 bam_send_mm_ba_add_req(sta_idx, bam_idx);
    00450
    00451                 // Go to BAM_CHECK_ADMISSION state
    00452                 ke_state_set(KE_BUILD_ID(TASK_BAM, bam_idx), BAM_CHECK_ADMISSION);
    00453
    00454                 return (KE_MSG_CONSUMED);
    00455             } while (0);
    00456             #endif
    00457
    00458             // If we reach this point, an error has occurred, reply with an error status
    00459             bam_send_air_action_frame(sta_idx, NULL, MAC_BA_ACTION_ADDBA_RSP, dialog_token,
    00460                                       ba_param, status, NULL);
    00461             break;
    00462         }
    00463
    00464         #if NX_AMPDU_TX
    00465         case MAC_BA_ACTION_ADDBA_RSP:
    00466         {
    00467             uint16_t status;
    00468             uint16_t ba_param;
    00469             uint8_t bam_idx;
    00470             uint8_t tid;
    00471
    00472             do
    00473             {
    00474                 ba_param = co_read16p(frame + BAM_ADDBARSP_BA_PARAM_OFFSET);
    00475                 tid      = BAM_BA_PARAM_GET(ba_param, TID);
    00476
    00477                 // Check TID
    00478                 if (tid >= TID_MAX)
    00479                 {
    00480                     // Drop the packet
    00481                     status = MAC_BA_ST_SUCCESS;
    00482                     break;
    00483                 }
    00484
    00485                 // Look for the BAM instance
    00486                 bam_idx = sta_mgmt_get_tx_bam_idx(param->sta_idx, tid);
    00487
    00488                 if (bam_idx == BAM_INVALID_TASK_IDX)
    00489                 {
    00490                     // Drop the packet
    00491                     status = MAC_BA_ST_SUCCESS;
    00492                     break;
    00493                 }
    00494
    00495                 // Check state as wait_rsp
    00496                 if (ke_state_get(KE_BUILD_ID(TASK_BAM, bam_idx)) != BAM_WAIT_RSP)
    00497                 {
    00498                     // Drop the packet
    00499                     status = MAC_BA_ST_SUCCESS;
    00500                     break;
    00501                 }
    00502
    00503                 status = MAC_BA_ST_INVALID_PARAMETERS;
    00504
    00505                 // Stop ADDBA response timeout timer
    00506                 ke_timer_clear(BAM_ADD_BA_RSP_TIMEOUT_IND, KE_BUILD_ID(TASK_BAM, bam_idx));
    00507
    00508                 // Check Dialog Token
    00509                 if (co_read8p(frame + MAC_ACTION_TOKEN_OFT) != bam_env[bam_idx].dialog_token)
    00510                 {
    00511                     status = MAC_BA_ST_INVALID_PARAMETERS;
    00512                     break;
    00513                 }
    00514
    00515                 // Check if received TID matches with the sent one
    00516                 if (tid != bam_env[bam_idx].tid)
    00517                 {
    00518                     status = MAC_BA_ST_INVALID_PARAMETERS;
    00519                     break;
    00520                 }
    00521
    00522                 status = co_read16p(frame + BAM_ADDBARSP_STATUS_OFFSET);
    00523
    00524                 // Check received status
    00525                 if (status != MAC_BA_ST_SUCCESS)
    00526                 {
    00527                     break;
    00528                 }
    00529
    00530                 /*
    00531                  * 9.21.2 - If the value in the Buffer Size field of the ADDBA Response is smaller than
    00532                  * the value in the ADDBA Request frame, the originator shall change the size of its
    00533                  * transmission window so that it is not greater than the value in the Buffer Size field
    00534                  * of the ADDBA Response frame and is not greater than the value 64.
    00535                  */
    00536                 if (BAM_BA_PARAM_GET(ba_param, BUFF_SIZE) < bam_env[bam_idx].buffer_size)
    00537                 {
    00538                     bam_env[bam_idx].buffer_size = BAM_BA_PARAM_GET(ba_param, BUFF_SIZE);
    00539                 }
    00540
    00541                 bam_env[bam_idx].amsdu=BAM_BA_PARAM_GET(ba_param, AMSDU_SUP);
    00542
    00543                 // Send MM_BA_ADD_REQ message to LMAC
    00544                 bam_send_mm_ba_add_req(param->sta_idx, bam_idx);
    00545
    00546                 // Go to BAM_CHECK_ADMISSION state
    00547                 ke_state_set(KE_BUILD_ID(TASK_BAM, bam_idx), BAM_CHECK_ADMISSION);
    00548             } while (0);
    00549
    00550             if (status != MAC_BA_ST_SUCCESS)
    00551             {
    00552                 /*
    00553                  * Request has been rejected
    00554                  *      - Clean STA Mgmt
    00555                  *      - Go back to IDLE state
    00556                  */
    00557                 bam_param_sta_info_tab_reset(bam_idx);
    00558
    00559                 ke_state_set(KE_BUILD_ID(TASK_BAM, bam_idx), BAM_IDLE);
    00560                 TRACE_LMAC(BA, "{BAM-%d} STA refused the TX agreement", bam_idx);
    00561             }
    00562             break;
    00563         }
    00564         #endif
    00565
    00566         #if NX_AMPDU_TX || NX_REORD
    00567         case MAC_BA_ACTION_DELBA:
    00568         {
    00569             uint16_t delba_param = co_read16p(frame + BAM_DELBA_PARAM_OFFSET);
    00570             uint8_t tid          = BAM_DELBA_PARAM_GET(delba_param, TID);
    00571             uint16_t bam_idx;
    00572
    00573             do
    00574             {
    00575                 // Check received TID
    00576                 if ((tid >= TID_MAX) || (param->sta_idx == INVALID_STA_IDX))
    00577                 {
    00578                     break;
    00579                 }
    00580
    00581                 // Check if the indicated BA exists
    00582                 if (BAM_DELBA_PARAM_GET(delba_param, INITIATOR))
    00583                 {
    00584                     bam_idx = sta_mgmt_get_rx_bam_idx(param->sta_idx, tid);
    00585                 }
    00586                 else
    00587                 {
    00588                     bam_idx = sta_mgmt_get_tx_bam_idx(param->sta_idx, tid);
    00589                 }
    00590
    00591                 if (bam_idx == BAM_INVALID_TASK_IDX)
    00592                 {
    00593                     break;
    00594                 }
    00595
    00596                 // If BAM task is already being deleted (e.g. because of a previous timeout),
    00597                 // then we have nothing to do upon this DELBA reception
    00598                 if (ke_state_get(KE_BUILD_ID(TASK_BAM, bam_idx)) == BAM_DELETE)
    00599                 {
    00600                     break;
    00601                 }
    00602
    00603                 // Stop the inactivity timeout timer
    00604                 ke_timer_clear(BAM_INACTIVITY_TIMEOUT_IND, KE_BUILD_ID(TASK_BAM, bam_idx));
    00605
    00606                 if ((ke_state_get(KE_BUILD_ID(TASK_BAM, bam_idx)) == BAM_ACTIVE) ||
    00607                     (ke_state_get(KE_BUILD_ID(TASK_BAM, bam_idx)) == BAM_CHECK_ADMISSION))
    00608                 {
    00609                     // Go to BAM_DELETE state
    00610                     ke_state_set(KE_BUILD_ID(TASK_BAM, bam_idx), BAM_DELETE);
    00611
    00612                     TRACE_LMAC(BA, "{BAM-%d} Delete agreement after receiving DELBA",
    00613                                bam_idx);
    00614
    00615                     // Send MM_BA_DEL_REQ to LMAC
    00616                     bam_send_mm_ba_del_req(param->sta_idx, bam_idx);
    00617                 }
    00618                 else
    00619                 {
    00620                     // Move back to IDLE state
    00621                     bam_delete_ba_agg(bam_idx);
    00622                 }
    00623             } while (0);
    00624             break;
    00625         }
    00626         #endif
    00627
    00628         default:
    00629             break;
    00630     }
    00631
    00632     return (KE_MSG_CONSUMED);
    00633 }
    00634
    00635 /*
    00636  * PUBLIC FUNCTIONS
    00637  ****************************************************************************************
    00638  */
    00639
    00641 const struct ke_msg_handler bam_default_state[] =
    00642 {
    00643     // From SME
    00644     #if NX_AMPDU_TX
    00645     {BAM_ADD_BA_RSP_TIMEOUT_IND,    (ke_msg_func_t)bam_add_ba_rsp_timeout_ind_handler},
    00646     #endif
    00647     #if NX_AMPDU_TX || NX_REORD
    00648     {BAM_INACTIVITY_TIMEOUT_IND,    (ke_msg_func_t)bam_inactivity_timeout_ind_handler},
    00649     {MM_BA_DEL_CFM,                 (ke_msg_func_t)mm_ba_del_cfm_handler},
    00650     {MM_BA_ADD_CFM,                 (ke_msg_func_t)mm_ba_add_cfm_handler},
    00651     #endif
    00652     {RXU_MGT_IND,                   (ke_msg_func_t)rxu_mgt_ind_handler},
    00653 };
    00654
    00656 const struct ke_state_handler bam_default_handler = KE_STATE_HANDLER(bam_default_state);
    00657
    00659 ke_state_t bam_state[BAM_IDX_MAX];
    00660