- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# /space/home/slher/rel/Beken/v6_4_5/macsw/ip/umac/src/apm/apm_task.c

Go to the documentation of this file.

    00001
    00013 #include "apm.h"
    00014 #include "apm_task.h"
    00015 #include "me_utils.h"
    00016 #include "bam.h"
    00017 #include "ke_timer.h"
    00018 #include "vif_mgmt.h"
    00019 #include "chan.h"
    00020 #include "me_task.h"
    00021 #include "me.h"
    00022 #include "ps.h"
    00023 #include "tpc.h"
    00024
    00025 #if NX_BEACONING
    00026
    00045 static int
    00046 apm_start_req_handler(ke_msg_id_t const msgid,
    00047                          struct apm_start_req *param,
    00048                          ke_task_id_t const dest_id,
    00049                          ke_task_id_t const src_id)
    00050 {
    00051
    00052     struct apm_start_cfm *cfm;
    00053     uint8_t status;
    00054     // Channel context index
    00055     uint8_t chan_idx;
    00056
    00057     do
    00058     {
    00059         struct vif_info_tag *vif = &vif_info_tab[param->vif_idx];
    00060
    00061         // Check if the VIF is configured as AP
    00062         if (vif->type != VIF_AP)
    00063         {
    00064             status = CO_BAD_PARAM;
    00065             break;
    00066         }
    00067
    00068         // Check if we are busy or not
    00069         if (ke_state_get(TASK_APM) != APM_IDLE)
    00070         {
    00071             status = CO_BUSY;
    00072             break;
    00073         }
    00074
    00075         // Check if the AP is not already started
    00076         if (vif->active)
    00077         {
    00078             status = CO_OP_IN_PROGRESS;
    00079             break;
    00080         }
    00081
    00082         // Sanity check - We should not have a channel context already registered
    00083         ASSERT_ERR(vif->chan_ctxt == NULL);
    00084
    00085         // Save the parameters
    00086         apm_env.param = param;
    00087
    00088         if (chan_ctxt_add(&param->chan, &chan_idx) == CO_OK)
    00089         {
    00090             struct me_bss_info *bss = &vif->bss_info;
    00091
    00092             // Save the BW and channel information in the VIF
    00093             bss->chan = param->chan;
    00094
    00095             // Initialize TX power
    00096             bss->power_constraint = 0;
    00097             tpc_update_vif_tx_power(vif);
    00098
    00099             // Link the VIF to the channel context
    00100             chan_ctxt_link(param->vif_idx, chan_idx);
    00101
    00102             // If the AP is started on 2.4GHz band, we need to get the highest 11b rate
    00103             // that might be used for the non-ERP protection
    00104             if (param->chan.band == PHY_BAND_2G4)
    00105             {
    00106                 uint32_t basic_11b_rates;
    00107                 basic_11b_rates = me_legacy_rate_bitfield_build(&(bss->rate_set), true) & 0x0F;
    00108                 // Get highest allowed 11b rate
    00109                 if (basic_11b_rates)
    00110                     // Get highest allowed 11b rate
    00111                     bss->high_11b_rate = 31 - co_clz(basic_11b_rates);
    00112                 else
    00113                     // If no 11b basic rates, set the highest mandatory one
    00114                     bss->high_11b_rate = HW_RATE_2MBPS;
    00115             }
    00116
    00117             // Set the BSS parameters to LMAC
    00118             apm_set_bss_param();
    00119         }
    00120         else
    00121         {
    00122             status = CO_FAIL;
    00123             break;
    00124         }
    00125
    00126         // We will now proceed to the AP starting
    00127         return (KE_MSG_NO_FREE);
    00128     } while(0);
    00129
    00130     cfm = KE_MSG_ALLOC(APM_START_CFM, src_id, dest_id, apm_start_cfm);
    00131     cfm->status = status;
    00132     cfm->vif_idx = param->vif_idx;
    00133
    00134     // Send the message
    00135     ke_msg_send(cfm);
    00136
    00137     return (KE_MSG_CONSUMED);
    00138 }
    00139
    00155 static int
    00156 me_set_ps_disable_cfm_handler(ke_msg_id_t const msgid,
    00157                               void const *param,
    00158                               ke_task_id_t const dest_id,
    00159                               ke_task_id_t const src_id)
    00160 {
    00161     // Sanity check
    00162     ASSERT_ERR((ke_state_get(TASK_APM) == APM_BSS_PARAM_SETTING) ||
    00163                (ke_state_get(TASK_APM) == APM_IDLE) ||
    00164                (ke_state_get(TASK_APM) == APM_STOPPING));
    00165
    00166     // Check the state
    00167     if ((ke_state_get(TASK_APM) == APM_BSS_PARAM_SETTING) ||
    00168         (ke_state_get(TASK_APM) == APM_STOPPING))
    00169     {
    00170         // Send the next BSS configuration message
    00171         apm_bss_config_send();
    00172     }
    00173
    00174     return (KE_MSG_CONSUMED);
    00175 }
    00176
    00192 static int
    00193 mm_bss_param_setting_handler(ke_msg_id_t const msgid,
    00194                              void const *param,
    00195                              ke_task_id_t const dest_id,
    00196                              ke_task_id_t const src_id)
    00197 {
    00198     // Sanity check - This message can be received only in the CHAN CTXT ADDING state
    00199     ASSERT_ERR(ke_state_get(TASK_APM) == APM_BSS_PARAM_SETTING);
    00200
    00201     // Send the next BSS parameter configuration message
    00202     apm_bss_config_send();
    00203
    00204     return (KE_MSG_CONSUMED);
    00205 }
    00206
    00222 static int
    00223 me_set_active_cfm_handler(ke_msg_id_t const msgid,
    00224                           void const *param,
    00225                           ke_task_id_t const dest_id,
    00226                           ke_task_id_t const src_id)
    00227 {
    00228     // Sanity check - This message can be received only in the STA ADDING state
    00229     ASSERT_ERR((ke_state_get(TASK_APM) == APM_BSS_PARAM_SETTING) ||
    00230                (ke_state_get(TASK_APM) == APM_IDLE) ||
    00231                (ke_state_get(TASK_APM) == APM_STOPPING));
    00232
    00233     // Check the state
    00234     if (ke_state_get(TASK_APM) == APM_BSS_PARAM_SETTING)
    00235     {
    00236         // Sanity check - All the BSS configuration parameters shall be set
    00237         ASSERT_ERR(co_list_is_empty(&apm_env.bss_config));
    00238
    00239         // Set the beacon information to the LMAC
    00240         apm_bcn_set();
    00241     }
    00242     else if (ke_state_get(TASK_APM) == APM_STOPPING)
    00243     {
    00244         // Send the confirmation
    00245         ke_msg_send_basic(APM_STOP_CFM, TASK_API, TASK_APM);
    00246         ke_state_set(TASK_APM, APM_IDLE);
    00247     }
    00248
    00249     return (KE_MSG_CONSUMED);
    00250 }
    00251
    00269 static int
    00270 mm_bcn_change_cfm_handler(ke_msg_id_t const msgid,
    00271                           void const *param,
    00272                           ke_task_id_t const dest_id,
    00273                           ke_task_id_t const src_id)
    00274 {
    00275     // Sanity check - This message can be received only in the APM_SCHEDULING_CHAN_CTX state
    00276     ASSERT_ERR(ke_state_get(TASK_APM) == APM_BCN_SETTING);
    00277
    00278     // Set the beacon information to the LMAC
    00279     apm_start_cfm(CO_OK);
    00280
    00281     return (KE_MSG_CONSUMED);
    00282 }
    00283
    00296 static int
    00297 mm_chan_ctxt_unlink_cfm_handler(ke_msg_id_t const msgid,
    00298                                 void const *param,
    00299                                 ke_task_id_t const dest_id,
    00300                                 ke_task_id_t const src_id)
    00301 {
    00302     // Sanity check - This message can be received during the stopping procedure only
    00303     ASSERT_ERR(ke_state_get(TASK_APM) == APM_STOPPING);
    00304
    00305     // Send the next BSS stopping message
    00306     apm_bss_config_send();
    00307
    00308     return (KE_MSG_CONSUMED);
    00309 }
    00310
    00323 static int
    00324 mm_set_vif_state_cfm_handler(ke_msg_id_t const msgid,
    00325                              void const *param,
    00326                              ke_task_id_t const dest_id,
    00327                              ke_task_id_t const src_id)
    00328 {
    00329     // Sanity check - This message can be received only in the stopping and idle states
    00330     ASSERT_ERR((ke_state_get(TASK_APM) == APM_STOPPING) ||
    00331                (ke_state_get(TASK_APM) == APM_IDLE));
    00332
    00333     // Check if we are in the connection process
    00334     if (ke_state_get(TASK_APM) == APM_STOPPING)
    00335     {
    00336         // Send the next BSS stopping message
    00337         apm_bss_config_send();
    00338     }
    00339
    00340     return (KE_MSG_CONSUMED);
    00341 }
    00342
    00357 static int
    00358 apm_stop_req_handler(ke_msg_id_t const msgid,
    00359                      struct apm_stop_req const *param,
    00360                      ke_task_id_t const dest_id,
    00361                      ke_task_id_t const src_id)
    00362 {
    00363     struct vif_info_tag *vif = &vif_info_tab[param->vif_idx];
    00364
    00365     if ((vif->type != VIF_AP) || (!vif->active))
    00366     {
    00367         // Not an AP (or not started) respond immediately
    00368         ke_msg_send_basic(APM_STOP_CFM, src_id, dest_id);
    00369         return KE_MSG_CONSUMED;
    00370     }
    00371     else if (ke_state_get(TASK_APM) != APM_IDLE)
    00372     {
    00373         // Task is currently busy, postpone this message
    00374         return KE_MSG_SAVED;
    00375     }
    00376
    00377     // Stop the AP (confirmation will be sent once stopped)
    00378     apm_stop(vif);
    00379     return KE_MSG_CONSUMED;
    00380 }
    00381
    00398 static int
    00399 apm_start_cac_req_handler(ke_msg_id_t const msgid,
    00400                           struct apm_start_cac_req const *param,
    00401                           ke_task_id_t const dest_id,
    00402                           ke_task_id_t const src_id)
    00403 {
    00404     struct apm_start_cac_cfm *cfm;
    00405     uint8_t status = CO_OK;
    00406     uint8_t chan_idx = 0;
    00407
    00408     do
    00409     {
    00410         struct vif_info_tag *vif = &vif_info_tab[param->vif_idx];
    00411
    00412         // Check if the VIF is configured as AP
    00413         if (vif->type != VIF_AP) {
    00414             status = CO_BAD_PARAM;
    00415             break;
    00416         }
    00417
    00418         // Check if the AP is not already started
    00419         if (vif->active) {
    00420             status = CO_BUSY;
    00421             break;
    00422         }
    00423
    00424         // Check if we are busy or not
    00425         if (ke_state_get(TASK_APM) != APM_IDLE) {
    00426             status = CO_BUSY;
    00427             break;
    00428         }
    00429
    00430         // create new channel context
    00431         if (chan_ctxt_add(&param->chan, &chan_idx) == CO_OK) {
    00432             // and Link the VIF to the channel context
    00433             chan_ctxt_link(param->vif_idx, chan_idx);
    00434         } else {
    00435             status = CO_FAIL;
    00436             break;
    00437         }
    00438
    00439         #if (NX_POWERSAVE)
    00440         // Disable PS during the whole CAC period
    00441         GLOBAL_INT_DISABLE();
    00442         ps_env.prevent_sleep |= PS_CAC_STARTED;
    00443         GLOBAL_INT_RESTORE();
    00444         #endif
    00445
    00446
    00447     } while(0);
    00448
    00449     // Send the confirmation
    00450     cfm = KE_MSG_ALLOC(APM_START_CAC_CFM, src_id, dest_id, apm_start_cac_cfm);
    00451     cfm->status = status;
    00452     cfm->ch_idx = chan_idx;
    00453
    00454     // Send the message
    00455     ke_msg_send(cfm);
    00456
    00457     return (KE_MSG_CONSUMED);
    00458 }
    00459
    00474 static int
    00475 apm_stop_cac_req_handler(ke_msg_id_t const msgid,
    00476                          struct apm_stop_cac_req const *param,
    00477                          ke_task_id_t const dest_id,
    00478                          ke_task_id_t const src_id)
    00479 {
    00480     do
    00481     {
    00482         struct vif_info_tag *vif = &vif_info_tab[param->vif_idx];
    00483
    00484         // Check if the VIF is configured as AP
    00485         if (vif->type != VIF_AP) {
    00486             break;
    00487         }
    00488
    00489         // Check if the AP is not already started
    00490         if (vif->active) {
    00491             break;
    00492         }
    00493
    00494         // Check if we are busy or not
    00495         if (ke_state_get(TASK_APM) != APM_IDLE) {
    00496             break;
    00497         }
    00498
    00499         chan_ctxt_unlink(param->vif_idx);
    00500
    00501         #if (NX_POWERSAVE)
    00502         //  Power Save can be used
    00503         GLOBAL_INT_DISABLE();
    00504         ps_env.prevent_sleep &= ~PS_CAC_STARTED;
    00505         GLOBAL_INT_RESTORE();
    00506         #endif
    00507
    00508     } while(0);
    00509
    00510     // Send the confirmation
    00511     ke_msg_send_basic(APM_STOP_CAC_CFM, src_id, dest_id);
    00512
    00513     return (KE_MSG_CONSUMED);
    00514 }
    00515
    00516
    00518 const struct ke_msg_handler apm_default_state[] =
    00519 {
    00520     {APM_START_REQ, (ke_msg_func_t)apm_start_req_handler},
    00521     {APM_STOP_REQ, (ke_msg_func_t)apm_stop_req_handler},
    00522     {ME_SET_ACTIVE_CFM, (ke_msg_func_t)me_set_active_cfm_handler},
    00523     {MM_BCN_CHANGE_CFM, (ke_msg_func_t)mm_bcn_change_cfm_handler},
    00524     {MM_SET_BSSID_CFM, mm_bss_param_setting_handler},
    00525     {MM_SET_BASIC_RATES_CFM, mm_bss_param_setting_handler},
    00526     {MM_SET_BEACON_INT_CFM, mm_bss_param_setting_handler},
    00527     {ME_SET_PS_DISABLE_CFM, (ke_msg_func_t)me_set_ps_disable_cfm_handler},
    00528     {MM_SET_VIF_STATE_CFM, (ke_msg_func_t)mm_set_vif_state_cfm_handler},
    00529     {MM_CHAN_CTXT_UNLINK_CFM, (ke_msg_func_t)mm_chan_ctxt_unlink_cfm_handler},
    00530     {APM_START_CAC_REQ, (ke_msg_func_t)apm_start_cac_req_handler},
    00531     {APM_STOP_CAC_REQ, (ke_msg_func_t)apm_stop_cac_req_handler},
    00532 };
    00533
    00535 const struct ke_state_handler apm_default_handler =
    00536     KE_STATE_HANDLER(apm_default_state);
    00537
    00539 ke_state_t apm_state[APM_IDX_MAX];
    00540
    00542
    00543 #endif
    00544