/* Cesar project {{{ * * Copyright (C) 2007-2012 Spidcom * * <<>> * * }}} */ /** * \file test_lib_cesar.c * \brief Station executable used for the test lib cesar program. * \ingroup */ #include "common/std.h" #include "common/defs/homeplugAV.h" #include "host/station/station.h" /* for 'station_ctx_t' */ #include "hal/phy/maximus/dur/maximus/inc/maximus_phy_dur.h" /* for 'maximus_phy_dur_init()' */ #include "hal/ipmbox/ipmbox.h" #include "hal/ipmbox/maximus/inc/maximus_ipmbox_ctx.h" /* for 'ipmbox_t' */ #include "hal/ipmbox/maximus/inc/maximus_interrupts.h" /* for 'HAL_IPMBOX_..._INTERRUPT' */ #include "maximus/common/types/ethernet_types.h" /* for 'ETHERNET_TYPE_...' */ #include "common/ipmbox/msg.h" #include "common/defs/homeplugAV.h" #define RESULT_SUCCESS 0x00 #define CM_SET_KEY_REQ_MMTYPE 0x6008 /* DRV_STA_....CNF MMENTRY only contains 1 byte: Result */ #define DRV_STA_CNF_LEN (HPAV_MME_HEADER + 1) /* CM_SET_KEY.CNF MMENTRY contains: - 1 byte: Result - 4 bytes: My Nonce - 4 bytes: Your Nonce - 1 byte: PID - 2 bytes: PRN - 1 byte: PMN - 1 byte: CCo Capability => 14 bytes in total */ #define CM_SET_KEY_CNF_LEN (HPAV_MME_HEADER + 14) extern station_ctx_t my_station; ipmbox_t *ctx; int user_data = 123; void rx_cb_mbx (void *user_data, u32 *first_msg, uint length) { /* Reset IT. */ maximus_pending_isrs &= ~(1 << HAL_IPMBOX_RX_INTERRUPT); ipmbox_msg_mbx_t *msg_mbx = (ipmbox_msg_mbx_t *) ctx->rx_mbx.mailbox; /* When receiving an Ether SCI message of type MME REQ from Maximus, * send the answer (an Ether SCI message of type MME CNF) * with an Ether SCI message of type BUFFER_RELEASED. */ /* REQ data length. */ uint data_length = ipmbox_msg_get_mme_priv_length (msg_mbx->header); /* REQ data. */ u32 buffer_addr; if (1 != ipmbox_empty_buf_get (ctx, &buffer_addr, 1)) { station_log (&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_ETHER, "%s: cannot get empty buf", __FUNCTION__); } memcpy ((u32 *) buffer_addr, (u32 *) msg_mbx->buffer_addr, data_length); /* CNF data. */ char *cnf_data = (char *) buffer_addr; /* REQ => CNF */ *(cnf_data + HPAV_GET_MMTYPE_OFFSET (HPAV_MTYPE_MME)) = *(cnf_data + HPAV_GET_MMTYPE_OFFSET (HPAV_MTYPE_MME)) + 1; *(cnf_data + HPAV_MME_HEADER) = RESULT_SUCCESS; /* CNF data length. */ uint cnf_data_length = 0; u16 mmtype = ( (u16) (*(cnf_data + HPAV_GET_MMTYPE_OFFSET (HPAV_MTYPE_MME) + 1) << 8) | (u16) (*(cnf_data + HPAV_GET_MMTYPE_OFFSET (HPAV_MTYPE_MME)))); if (CM_SET_KEY_REQ_MMTYPE == mmtype) { cnf_data_length = CM_SET_KEY_CNF_LEN; } else /* mmtype = DRV_STA_....REQ */ { cnf_data_length = DRV_STA_CNF_LEN; } /* Tx. */ msg_mbx->header = ipmbox_msg_create_header_mme_priv (cnf_data_length); msg_mbx->buffer_addr = buffer_addr; ipmbox_tx_mbx (ctx, (u32 *) msg_mbx, 2); return; } void rx_cb_data (void *user_data, u32 *first_msg, uint length) { /* Reset IT. */ maximus_pending_isrs &= ~(1 << HAL_IPMBOX_RX_INTERRUPT); /* In this test, we should not receive an Ether SCI message of type DATA * from Maximus. */ station_log (&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_ETHER, "%s: rx cb data should not be called", __FUNCTION__); return; } void empty_buf_cb (void *user_data) { // Reset IT maximus_pending_isrs &= ~(1 << HAL_IPMBOX_BUF_INTERRUPT); /* When receiving an Ether SCI message of type BUFFER_ADD from Maximus, * do nothing: just keep the allocated buffer for future Tx DATA / MME. */ } int uninit_ether (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data) { /* Uninitialize the HAL ipmbox. */ ipmbox_uninit (ctx); /* Now make the return parameter list. */ fcall_param_reset (*param); return 0; } int main (void) { station_log_set_level (&my_station, STATION_LOG_WARNING); station_log_set_mask (&my_station, STATION_LOGTYPE_ALL); my_station.pipe_log_fd = 1; maximus_phy_dur_init (&my_station); /* Initialize the HAL ipmbox. */ ctx = ipmbox_init (); ipmbox_register_rx_data_cb (ctx, (void *) &user_data, &rx_cb_data); ipmbox_register_rx_mbx_cb (ctx, (void *) &user_data, &rx_cb_mbx); ipmbox_register_empty_buf_cb (ctx, (void *) &user_data, &empty_buf_cb); /* Enable assertions on warnings. */ ctx->warning_assert = true; /* Activate ipmbox interruptions. */ ipmbox_activate (ctx, true); fcall_register (my_station.fcall, "uninit_ether", (void*) &uninit_ether, NULL); return 0; }