- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# /space/home/slher/rel/Beken/v6_4_5/macsw/modules/ke/src/ke_task.c

Go to the documentation of this file.

    00001
    00020 /*
    00021  * INCLUDE FILES
    00022  ****************************************************************************************
    00023  */
    00024 #include <stddef.h>
    00025 #include "co_int.h"
    00026 #include "co_bool.h"
    00027 #include "rwnx_config.h"
    00028 #include "dbg_assert.h"
    00029
    00030 #include "ke_config.h"
    00031 #include "ke_task.h"
    00032 #include "ke_env.h"
    00033 #include "ke_queue.h"
    00034 #include "ke_event.h"
    00035 #include "ke_mem.h"
    00036 #include "dbg.h"
    00037
    00038
    00039 #include "mm_task.h"
    00040 #include "dbg_task.h"
    00041 #include "scan_task.h"
    00042
    00043 #if (NX_TDLS)
    00044 #include "tdls_task.h"
    00045 #endif
    00046
    00047 #if NX_UMAC_PRESENT
    00048 #include "scanu_task.h"
    00049 #include "me_task.h"
    00050 #include "sm_task.h"
    00051 #include "bam_task.h"
    00052 #include "apm_task.h"
    00053 #if RW_MESH_EN
    00054 #include "mesh_task.h"
    00055 #endif
    00056 #endif
    00057
    00059 static const struct ke_task_desc TASK_DESC[TASK_MAX] =
    00060 {
    00061     // ** LMAC tasks  **
    00063     [TASK_MM] = {mm_state_handler, &mm_default_handler, mm_state, MM_STATE_MAX, MM_IDX_MAX},
    00064
    00066     [TASK_DBG] = {NULL, &dbg_default_handler, NULL, 1, 1},
    00067
    00068     #if NX_HW_SCAN
    00070     [TASK_SCAN] = {NULL, &scan_default_handler, scan_state, SCAN_STATE_MAX, SCAN_IDX_MAX},
    00071     #endif
    00072
    00073     #if (NX_TDLS)
    00074     [TASK_TDLS] = {NULL, &tdls_default_handler, tdls_state, TDLS_STATE_MAX, TDLS_IDX_MAX},
    00075     #endif
    00076
    00077     #if NX_UMAC_PRESENT
    00079     [TASK_SCANU] = {scanu_state_handler, &scanu_default_handler, scanu_state, SCANU_STATE_MAX, SCANU_IDX_MAX},
    00081     [TASK_ME]  = {NULL, &me_default_handler, me_state, ME_STATE_MAX, ME_IDX_MAX},
    00083     [TASK_SM]  = {NULL, &sm_default_handler, sm_state, SM_STATE_MAX, SM_IDX_MAX},
    00085     [TASK_BAM] = {NULL, &bam_default_handler, bam_state, BAM_STATE_MAX, BAM_IDX_MAX},
    00086     #if NX_BEACONING
    00088     [TASK_APM] = {NULL, &apm_default_handler, apm_state, APM_STATE_MAX, APM_IDX_MAX},
    00089     #endif
    00090     #if (RW_MESH_EN && NX_UMAC_PRESENT)
    00092     [TASK_MESH] = {NULL, &mesh_default_handler, mesh_state, MESH_STATE_MAX, MESH_IDX_MAX},
    00093     #endif //(RW_MESH_EN && NX_UMAC_PRESENT)
    00094     #endif //(NX_UMAC_PRESENT)
    00095 };
    00096
    00097
    00098
    00102 static bool cmp_dest_id(struct co_list_hdr const * msg, uint32_t dest_id)
    00103 {
    00104     return ((struct ke_msg*)msg)->dest_id == dest_id;
    00105 }
    00106
    00118 static void ke_task_saved_update(ke_task_id_t const ke_task_id)
    00119 {
    00120     struct ke_msg * msg;
    00121
    00122     for(;;)
    00123     {
    00124         // if the state has changed look in the Save queue if a message
    00125         // need to be handled
    00126         msg = (struct ke_msg*) ke_queue_extract(&ke_env.queue_saved,
    00127                                                 &cmp_dest_id,
    00128                                                 (uint32_t) ke_task_id);
    00129
    00130         if (msg == NULL) break;
    00131
    00132         //printf ("-- saved found %x %x\n", ke_task_id, msg->id);
    00133
    00134         // Insert it back in the sent queue
    00135         GLOBAL_INT_DISABLE();
    00136         ke_queue_push(&ke_env.queue_sent, (struct co_list_hdr*)msg);
    00137         GLOBAL_INT_RESTORE();
    00138
    00139         // trigger the event
    00140         ke_evt_set(KE_EVT_KE_MESSAGE_BIT);
    00141     }
    00142
    00143     return;
    00144 }
    00145
    00146
    00159 void ke_state_set(ke_task_id_t const id,
    00160                   ke_state_t const state_id)
    00161 {
    00162     ke_state_t *ke_stateid_ptr = NULL;
    00163     int idx = KE_IDX_GET(id);
    00164     int type = KE_TYPE_GET(id);
    00165
    00166     // sanity checks
    00167     ASSERT_ERR(type < TASK_MAX);
    00168     ASSERT_ERR(ke_task_local(type));
    00169     ASSERT_ERR(idx < TASK_DESC[type].idx_max);
    00170
    00171     // Get the state
    00172     ke_stateid_ptr = &TASK_DESC[type].state[idx];
    00173
    00174     ASSERT_ERR(ke_stateid_ptr);
    00175
    00176     dbg(D_KE D_INF "set tsk:%x:%x\n", id, state_id);
    00177     TRACE_KERNEL(STATE, "set %kS", id, state_id);
    00178
    00179     // set the state
    00180     if (*ke_stateid_ptr != state_id)
    00181     {
    00182         *ke_stateid_ptr = state_id;
    00183
    00184         // if the state has changed update the SAVE queue
    00185         ke_task_saved_update(id);
    00186     }
    00187 }
    00188
    00189
    00199 ke_state_t ke_state_get(ke_task_id_t const id)
    00200 {
    00201     int idx = KE_IDX_GET(id);
    00202     int type = KE_TYPE_GET(id);
    00203
    00204     ASSERT_ERR(type < TASK_MAX);
    00205     ASSERT_ERR(ke_task_local(type));
    00206     ASSERT_ERR(idx < TASK_DESC[type].idx_max);
    00207
    00208     // Get the state
    00209     return TASK_DESC[type].state[idx];
    00210 }
    00211
    00212
    00224 static ke_msg_func_t ke_handler_search(ke_msg_id_t const msg_id,
    00225                                        struct ke_state_handler const *state_handler)
    00226 {
    00227     // Get the message handler function by parsing the message table
    00228     for (int i = (state_handler->msg_cnt-1); 0 <= i; i--)
    00229     {
    00230         if (state_handler->msg_table[i].id == msg_id)
    00231         {
    00232             // If handler is NULL, message should not have been received in this state
    00233             ASSERT_ERR(state_handler->msg_table[i].func);
    00234
    00235             return state_handler->msg_table[i].func;
    00236         }
    00237     }
    00238
    00239     // If we execute this line of code, it means that we did not find the handler
    00240     return NULL;
    00241 }
    00242
    00254 static ke_msg_func_t ke_task_handler_get(ke_msg_id_t const msg_id,
    00255                                          ke_task_id_t const task_id)
    00256 {
    00257     ke_msg_func_t func = NULL;
    00258     int type = KE_TYPE_GET(task_id);
    00259     int idx = KE_IDX_GET(task_id);
    00260
    00261     ASSERT_ERR(type < TASK_MAX);
    00262     ASSERT_ERR(ke_task_local(type));
    00263     ASSERT_ERR(idx < TASK_DESC[type].idx_max);
    00264
    00265     const struct ke_task_desc *desc = TASK_DESC + type;
    00266
    00267     ASSERT_ERR(desc);
    00268
    00269     // Retrieve a pointer to the task instance data
    00270     if (desc->state_handler)
    00271     {
    00272         func = ke_handler_search(msg_id, desc->state_handler + desc->state[idx]);
    00273     }
    00274
    00275     // No handler... need to retrieve the default one
    00276     if (func == NULL && desc->default_handler)
    00277     {
    00278         func = ke_handler_search(msg_id, desc->default_handler);
    00279     }
    00280
    00281     return func;
    00282 }
    00283
    00284
    00298 void ke_task_schedule(int dummy)
    00299 {
    00300     // Process one message at a time to ensure that events having higher priority are
    00301     // handled in time
    00302     do
    00303     {
    00304         int msg_status;
    00305         struct ke_msg *msg;
    00306         // Get a message from the queue
    00307         GLOBAL_INT_DISABLE();
    00308         msg = (struct ke_msg*) ke_queue_pop(&ke_env.queue_sent);
    00309         GLOBAL_INT_RESTORE();
    00310         if (msg == NULL) break;
    00311
    00312         // Retrieve a pointer to the task instance data
    00313         ke_msg_func_t func = ke_task_handler_get(msg->id, msg->dest_id);
    00314
    00315         // handler found?
    00316         //printf("%s\n", __FUNCTION__);
    00317         //ASSERT_ERR2(func, msg->id, msg->dest_id);
    00318
    00319         dbg(D_INF D_KE "Dispatching msg:%x from tsk:%x to tsk:%x\n",
    00320             msg->id, msg->src_id, msg->dest_id);
    00321         TRACE_KERNEL(MSG_LOCAL, "Dispatching %kM from %kT to %kT",
    00322                      msg->id, msg->src_id, msg->dest_id);
    00323
    00324         // Call the message handler
    00325         if (func != NULL)
    00326         {
    00327             msg_status = func(msg->id, ke_msg2param(msg), msg->dest_id, msg->src_id);
    00328         }
    00329         else
    00330         {
    00331             dbg(D_CRT D_KE "No handler found for msg:%x from tsk:%x to tsk:%x\n",
    00332                 msg->id, msg->src_id, msg->dest_id);
    00333             TRACE_KERNEL(ERR, "No handler found for %kM from %kT to %kT",
    00334                          msg->id, msg->src_id, msg->dest_id);
    00335             msg_status = KE_MSG_CONSUMED;
    00336         }
    00337
    00338         switch (msg_status)
    00339         {
    00340         case KE_MSG_CONSUMED:
    00341             // Free the message
    00342             ke_msg_free(msg);
    00343
    00344         case KE_MSG_NO_FREE:
    00345             break;
    00346
    00347         case KE_MSG_SAVED:
    00348             // The message has been saved
    00349             // Insert it at the end of the save queue
    00350             ke_queue_push(&ke_env.queue_saved, (struct co_list_hdr*) msg);
    00351             break;
    00352
    00353         default:
    00354             ASSERT_ERR(0);
    00355         } // switch case
    00356     } while(0);
    00357
    00358     // Verify if we can clear the event bit
    00359     GLOBAL_INT_DISABLE();
    00360     if (co_list_is_empty(&ke_env.queue_sent))
    00361         ke_evt_clear(KE_EVT_KE_MESSAGE_BIT);
    00362     GLOBAL_INT_RESTORE();
    00363     //printf("leaving %s\n", __FUNCTION__);
    00364 }
    00365
    00377 int ke_msg_discard(ke_msg_id_t const msgid,
    00378                    void const *param,
    00379                    ke_task_id_t const dest_id,
    00380                    ke_task_id_t const src_id)
    00381 {
    00382     return KE_MSG_CONSUMED;
    00383 }
    00384
    00396 int ke_msg_save(ke_msg_id_t const msgid,
    00397                 void const *param,
    00398                 ke_task_id_t const dest_id,
    00399                 ke_task_id_t const src_id)
    00400 {
    00401     return KE_MSG_SAVED;
    00402 }
    00403