/* Cesar project {{{ * * Copyright (C) 2009 Spidcom * * <<>> * * }}} */ /** * \file src/test_dataplane.c * \brief Data plane test. * \ingroup test */ #include "common/std.h" #include "lib/trace.h" #include "mac/common/ntb.h" #include "inc/context.h" #include "cl/cl_mactotei.h" #include "host/fcall/fcall.h" #define TEST_DATAPLANE_PRIORITY 16 /** Global Data plane test context. */ static test_dataplane_t test_dataplane_global; #include "config/fcall/mme.h" #if CONFIG_FCALL_MME # include "interface/interface.h" # include "interface/inc/context.h" #endif #if CONFIG_FCALL_MME /* Stub. */ void cp_mme_recv (void *user_data, uint tei, u8 *buffer, uint length, bool mme_recv, bool encryption) { interface_mme_recv_done (user_data, buffer, mme_recv); } /* Stub. */ void cp_mme_buffer_add (void *user_data, u8 *buffer) { /* Nothing. */ } #endif /* CONFIG_FCALL_MME */ /* Stub. */ bool ce_measurements_none (void *user, pbproc_rx_params_t *rx_params, uint pb_nb, blk_t **first, blk_t **last, pb_t *chandata, uint nb_chandata, u8 **ce_pb_crc_error) { *first = NULL; *last = NULL; if (chandata) blk_release_desc_range_nb (&chandata->blk, nb_chandata); /* Pretend it was encrypted. */ rx_params->eks = 1; *ce_pb_crc_error = NULL; return false; } static void test_dataplane_thread (cyg_addrword_t data) { test_dataplane_t *ctx = (void *) data; dbg_assert (ctx); /* Handle messages. */ while (1) { dbg_check (cyg_semaphore_wait (&ctx->msg_sem)); dbg_assert (ctx->msg.cb); ctx->msg.cb (ctx, &ctx->msg); ctx->msg.cb = NULL; } } static int test_dataplane_activate_fcall (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data) { dbg_assert (fcall); dbg_assert (param && *param); dbg_assert (msg && *msg); test_dataplane_t *ctx = (void *) data; dbg_assert (ctx); /* Read message. */ bool activate; if (!fcall_param_bind_helper ("activate", activate)) activate = true; /* Activate. */ pbproc_activate (ctx->pbproc, activate); /* Return. */ fcall_param_reset (*param); return 0; } static int test_dataplane_set_config_fcall (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data) { dbg_assert (fcall); dbg_assert (param && *param); dbg_assert (msg && *msg); test_dataplane_t *ctx = (void *) data; dbg_assert (ctx); /* Read message. */ uint tei, snid; bool authenticated; mac_t mac; if (fcall_param_bind_long_helper ("tei", tei)) ctx->config.tei = tei; if (fcall_param_bind_long_helper ("snid", snid)) { ctx->snid = snid; ctx->beacon_period.snid = snid; } if (fcall_param_bind_helper ("authenticated", authenticated)) ctx->config.authenticated = authenticated; if (fcall_param_bind_ll_helper ("mac", mac)) ctx->config.sta_mac_address = mac; /* Return. */ fcall_param_reset (*param); return 0; } static int test_dataplane_add_mac_fcall (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data) { dbg_assert (fcall); dbg_assert (param && *param); dbg_assert (msg && *msg); test_dataplane_t *ctx = (void *) data; dbg_assert (ctx); /* Read message. */ uint tei; mac_t mac; if (!fcall_param_bind_long_helper ("tei", tei)) return -1; if (!fcall_param_bind_ll_helper ("mac", mac)) return -1; /* Add MAC to MAC to TEI table. */ cl_mactotei_blk_t *table; table = cl_mactotei_new (); cl_mactotei_copy_except_tag (ctx->cl, table, MAC_TEI_BCAST); cl_mactotei_addr_add (table, mac, tei, tei); cl_mactotei_use_table (ctx->cl, table); /* Return. */ fcall_param_reset (*param); return 0; } static void test_dataplane_init (test_dataplane_t *ctx) { dbg_assert (ctx); /* Traces. */ trace_init (); /* Data plane. */ mac_config_init (&ctx->config); ctx->config.tei = 1; ctx->config.seed = phy_seed (); ctx->snid = 1; ctx->store = mac_store_init (); ctx->pbproc = pbproc_init (&ctx->config, ctx->store); mac_ntb_init (pbproc_get_phy (ctx->pbproc), &ctx->config); ctx->sar = sar_init (ctx->store, ctx->pbproc, pbproc_get_ca (ctx->pbproc), ctx->config.seed); sar_init_measure_context (ctx->sar, ctx); sar_init_measurement_cb (ctx->sar, ce_measurements); ctx->cl = cl_init (ctx->store, ctx->sar, &ctx->config); ctx->hle = hle_init (ctx->cl); ctx->hal_timer = hal_timer_init (pbproc_get_phy (ctx->pbproc)); /* Fcall. */ fcall_ctx_t *fcall; #if CONFIG_FCALL_MME interface_t *interface = interface_init (ctx->hle, ctx->cl, ctx->sar, &ctx->config); interface_callback_init (interface, cp_mme_recv, cp_mme_buffer_add, interface); fcall = interface->fcall->fcall_ctx; #else /* !CONFIG_FCALL_MME */ fcall = my_station.fcall; my_station.pipe_log_fd = 1; #endif /* !CONFIG_FCALL_MME */ ca_test_fcall_beacon_period_init (&ctx->beacon_period, &ctx->config, pbproc_get_phy (ctx->pbproc), pbproc_get_ca (ctx->pbproc), ctx->hal_timer, fcall, ctx->snid); mac_test_fcall_set_tonemap_init (&ctx->set_tonemap, &ctx->config, ctx->store, fcall); test_dataplane_trace_dump_init (ctx, fcall); fcall_register (fcall, "activate", test_dataplane_activate_fcall, ctx); fcall_register (fcall, "set_config", test_dataplane_set_config_fcall, ctx); fcall_register (fcall, "add_mac", test_dataplane_add_mac_fcall, ctx); /* Activate data plane (but not PBProc). */ hle_activate (ctx->hle, true); sar_activate (ctx->sar, true); /* Test thread. */ cyg_thread_create (TEST_DATAPLANE_PRIORITY, &test_dataplane_thread, (cyg_addrword_t) ctx, "test_dataplane", ctx->thread_stack, sizeof (ctx->thread_stack), &ctx->thread, &ctx->thread_storage); cyg_thread_resume (ctx->thread); } /** Entry point. */ void cyg_user_start (void) { test_dataplane_init (&test_dataplane_global); }