summaryrefslogtreecommitdiff
path: root/cesar/cp/station
diff options
context:
space:
mode:
authorsave2008-04-07 14:17:42 +0000
committersave2008-04-07 14:17:42 +0000
commit3d58a62727346b7ac1a6cb36fed1a06ed72228dd (patch)
treed7788c3cf9f76426aef0286d0202e2097f0fa0eb /cesar/cp/station
parent095dca4b0a8d4924093bab424f71f588fdd84613 (diff)
Moved the complete svn base into the cesar directory.
git-svn-id: svn+ssh://pessac/svn/cesar/trunk@1769 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cesar/cp/station')
-rw-r--r--cesar/cp/station/Module2
-rw-r--r--cesar/cp/station/ecos.ecc.sh5
-rw-r--r--cesar/cp/station/inc/station_actions.h86
-rw-r--r--cesar/cp/station/inc/station_apivs.h49
-rw-r--r--cesar/cp/station/inc/station_ctx.h77
-rw-r--r--cesar/cp/station/inc/station_data.h401
-rw-r--r--cesar/cp/station/inc/station_event_handler.h73
-rw-r--r--cesar/cp/station/inc/station_types.h103
-rw-r--r--cesar/cp/station/maximus/Module5
-rw-r--r--cesar/cp/station/maximus/inc/maximus_cp_station.h49
-rw-r--r--cesar/cp/station/maximus/src/maximus_cp_station.c535
-rw-r--r--cesar/cp/station/src/station_actions.c1261
-rw-r--r--cesar/cp/station/src/station_apivs.c148
-rw-r--r--cesar/cp/station/src/station_core.c265
-rw-r--r--cesar/cp/station/src/station_data.c577
-rw-r--r--cesar/cp/station/src/station_event_handler.c76
-rw-r--r--cesar/cp/station/station.h97
17 files changed, 3809 insertions, 0 deletions
diff --git a/cesar/cp/station/Module b/cesar/cp/station/Module
new file mode 100644
index 0000000000..00235e9565
--- /dev/null
+++ b/cesar/cp/station/Module
@@ -0,0 +1,2 @@
+SOURCES := station_actions.c station_apivs.c station_core.c station_event_handler.c station_data.c
+
diff --git a/cesar/cp/station/ecos.ecc.sh b/cesar/cp/station/ecos.ecc.sh
new file mode 100644
index 0000000000..8253d98c9a
--- /dev/null
+++ b/cesar/cp/station/ecos.ecc.sh
@@ -0,0 +1,5 @@
+config=${1:-ecos-gen.ecc}
+ecosconfig --config=$config new linux default
+cat >> $config <<EOF
+EOF
+ecosconfig --config=$config check
diff --git a/cesar/cp/station/inc/station_actions.h b/cesar/cp/station/inc/station_actions.h
new file mode 100644
index 0000000000..a7f5b16f10
--- /dev/null
+++ b/cesar/cp/station/inc/station_actions.h
@@ -0,0 +1,86 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/station/inc/station_actions.h
+ * \brief all the action called from the visual state machine
+ * \ingroup cp_station
+ */
+#ifndef STATION_EVENTS_H_
+#define STATION_EVENTS_H_
+
+#include "cp/station/station.h"
+#include "cp/station/inc/station_event_handler.h"
+#include "cp/msg/msg.h"
+#include "cp/beacon/beacon.h"
+
+/**
+ * \brief called when the ustt timer has expired
+ * \param
+ * \return
+ */
+void
+station_ustt_expires(void);
+
+
+void init_system (void);
+void launch_bbt_timer (void);
+
+/**
+ * \brief return a random number between min and max
+ * if max == 0, return a number between 0 and RAND_MAX
+ * \param min
+ * \param max
+ * \return the random value
+ */
+uint rand_in(uint min, uint max);
+
+void launch_beacon_timer (void);
+void launch_ustt_timer (void);
+void transmit_unassoc_sta_mme(void);
+void station_bbt_expires(void);
+VS_VOID process_usta_mme (VS_VOIDPTR mme_address);
+VS_VOID trace_cco (VS_VOID);
+VS_VOID trace_pond (VS_VOID);
+VS_VOID trace_sta (VS_VOID);
+VS_VOID trace_ucco (VS_VOID);
+VS_VOID trace_usta (VS_VOID);
+VS_VOID try_associate (VS_VOIDPTR beacon_address);
+/**
+ * \brief process cc_assoc_req message received by the cco
+ * \param address of the message
+ * \return
+ */
+VS_VOID process_cc_assoc_req (VS_VOIDPTR mme_address);
+VS_VOID process_cc_assoc_cnf (VS_VOIDPTR mme_address);
+
+VS_VOID process_cc_set_tei_map_ind (VS_VOIDPTR mme_address);
+VS_VOID process_cc_set_tei_map_req (VS_VOIDPTR mme_address);
+
+VS_VOID send_discover_beacon_as_ucco (VS_VOID);
+
+VS_VOID process_drv_set_mac_address (VS_VOIDPTR msg);
+VS_VOID process_drv_set_avln_hfid (VS_VOIDPTR msg);
+VS_VOID process_drv_set_cco_preference (VS_VOIDPTR msg);
+VS_VOID process_drv_set_dpw_req (VS_VOIDPTR msg);
+VS_VOID process_drv_set_m_sta_hfid (VS_VOIDPTR msg);
+VS_VOID process_drv_set_nid (VS_VOIDPTR msg);
+VS_VOID process_drv_set_npw (VS_VOIDPTR msg);
+VS_VOID process_drv_set_sl (VS_VOIDPTR msg);
+VS_VOID process_drv_set_snid (VS_VOIDPTR msg);
+VS_VOID process_drv_set_tonemask (VS_VOIDPTR msg);
+VS_VOID process_drv_set_u_sta_hfid (VS_VOIDPTR msg);
+
+VS_VOID cp_station_set_assoc_status (VS_BOOL associated);
+VS_VOID cp_station_set_auth_status (VS_BOOL is_authenticated);
+VS_VOID cp_station_set_cco_status (VS_BOOL is_cco);
+VS_VOID process_drv_start_mac_req (VS_VOIDPTR msg);
+
+VS_VOID process_drv_set_was_cco (VS_VOIDPTR msg);
+
+
+#endif /*STATION_EVENTS_H_*/
diff --git a/cesar/cp/station/inc/station_apivs.h b/cesar/cp/station/inc/station_apivs.h
new file mode 100644
index 0000000000..827e1643fb
--- /dev/null
+++ b/cesar/cp/station/inc/station_apivs.h
@@ -0,0 +1,49 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/station/inc/event_handler.h
+ * \brief event handler for the fsm events
+ * \ingroup cp_sta
+ */
+#ifndef STATION_APIVS_H_
+#define STATION_APIVS_H_
+
+
+#include "cp/vstate_fsm/src/main_fsm.h"
+#include "cp/vstate_fsm/src/main_fsmAction.h"
+#include "cp/vstate_fsm/src/main_fsmData.h"
+#include "cp/station/inc/station_event_handler.h"
+
+#include "lib/visual_state_api/src/SEMLibE.h"
+
+/**
+ * \brief init the visual state fsm
+ * \param
+ * \return
+ */
+void
+cp_station_init_fsm(void);
+
+/**
+ * \brief process the event stored in the event handler
+ * \param
+ * \return
+ */
+void
+cp_station_process_fsm_event(void);
+
+
+void
+cp_station_test_fsm(void);
+
+
+void
+cp_station_print_fsm_states(void);
+
+
+#endif /*STATION_APIVS_H_*/
diff --git a/cesar/cp/station/inc/station_ctx.h b/cesar/cp/station/inc/station_ctx.h
new file mode 100644
index 0000000000..6eee974ef4
--- /dev/null
+++ b/cesar/cp/station/inc/station_ctx.h
@@ -0,0 +1,77 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/station/inc/station_ctx.h
+ * \brief
+ * \ingroup cp_station
+ */
+#ifndef CP_STATION_CTX_H_
+#define CP_STATION_CTX_H_
+
+#include "hal/timer/timer.h"
+#include "hle/hle.h"
+#include "interface/interface.h"
+#include "cp/cco/cco.h"
+//#include "cp/beacon/inc/beacons_ctx.h"
+#include "cp/beacon/inc/ntb_clock_sync.h"
+
+struct cp_sta_flash_params_t {
+ u64 mac_address;
+ u32 cco_preference;
+ u32 was_cco;
+ u32 sl;
+ char npw[MAX_PWD_SIZE+1];
+ char dpw[MAX_PWD_SIZE+1];
+ char m_sta_hfid[MAX_HFID_SIZE+1];
+ char u_sta_hfid[MAX_HFID_SIZE+1];
+ char avln_hfid[MAX_HFID_SIZE+1];
+};
+typedef struct cp_sta_flash_params_t cp_sta_flash_params_t;
+
+struct cp_sta_secu_params_t {
+ u8 nmk[16];
+ u8 nid[7];
+};
+typedef struct cp_sta_secu_params_t cp_sta_secu_params_t;
+
+#if 0
+typedef struct cp_cco_t cp_cco_t;
+#endif
+
+struct cp_sta_t
+{
+ mac_config_t *mac_config;
+ mac_store_t *mac_store;
+ pbproc_t *pbproc;
+ sar_t *sar;
+ hal_timer_t *hal_timer;
+ cl_t *cl;
+ hle_t *hle;
+ interface_t *interface;
+
+ cp_beacon_t *cp_beacon;
+
+ ntb_t *ntb;
+ cp_secu_t *sec;
+ cp_cco_t *cco;
+
+ cp_sta_flash_params_t cp_sta_flash_params;
+ cp_sta_secu_params_t cp_sta_secu_params;
+
+ mac_t mac_addr;
+ u64 nid;
+ bool hoip;
+ u8 numDisSta;
+ u8 numDisNet;
+ bool authentication;
+};
+
+typedef struct cp_sta_t cp_sta_t;
+
+
+#endif /*CP_STATION_CTX_H_*/
diff --git a/cesar/cp/station/inc/station_data.h b/cesar/cp/station/inc/station_data.h
new file mode 100644
index 0000000000..862d13441a
--- /dev/null
+++ b/cesar/cp/station/inc/station_data.h
@@ -0,0 +1,401 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/station/inc/station_data.h
+ * \brief the data stored
+ * \ingroup cp_station
+ */
+#ifndef STATION_DATA_H_
+#define STATION_DATA_H_
+
+#include <string.h>
+#include "mac/common/store.h"
+#include "cp/cp_types.h"
+#include "cp/station/inc/station_types.h"
+#include "cp/station/inc/station_ctx.h"
+#include "cl/cl.h"
+#include "SEMTypes.h"
+
+typedef enum process_usta_result_t
+{
+ BECOME_CCO,
+ USTA_MATCHING_NID,
+ CHECK_EXISTING_OTHER_AVLN
+} process_usta_result_t;
+
+/*
+cl_t *
+station_get_cl_ctx(void);
+
+mac_store_t *
+station_get_mac_store_ctx(void);
+*/
+
+cp_sta_t *my_cp_sta_ctx;
+/**
+ * \brief return the nid of the station
+ * \param ctx pointer to station context.
+ * \return the nid !
+ */
+nid_t
+cp_station_get_nid(cp_sta_t *ctx);
+
+/**
+ * \brief return the snid of the station
+ * \param
+ * \return the snid !
+ */
+snid_t
+cp_station_get_snid(void);
+
+/**
+ * \brief return the cco capability of the station
+ * \param
+ * \return guess what ? the cco capa !
+ * ie : 0 : cco level 0
+ * 1 : level 1
+ * ...
+ */
+u8
+cp_station_get_cco_capa(void);
+
+/**
+ * \brief return true if the station is cco
+ * \param
+ * \return
+ */
+bool
+cp_station_get_is_cco(void);
+
+/**
+ * \brief return true if the station is pcco capable
+ * \param
+ * \return
+ */
+bool
+cp_station_get_pcco_capa(void);
+
+/**
+ * \brief return true if the station is can be backup cco
+ * \param
+ * \return
+ */
+bool
+cp_station_get_backup_cco_capa(void);
+
+
+/**
+ * \brief return the number of associated station of the avln
+ * \param
+ * \return the number
+ */
+u8
+cp_station_get_number_of_assoc(void);
+
+/**
+ * \brief set the new tei of the station
+ * \param new_tei : the new tei
+ * \param lease_time : liease time of this tei
+ * \return
+ */
+void
+cp_station_set_tei(const tei_t new_tei, const u16 lease_time);
+
+/**
+ * \brief get the new tei of the station
+ * \return the tei of the station
+ */
+tei_t
+cp_station_get_tei(void *v);
+
+/**
+ * \brief set the mac address of the station
+ * \param ctx pointer to station context.
+ * \param mac_address : the mac address
+ * \return
+ */
+void
+cp_station_set_mac_address(cp_sta_t *ctx, mac_address_t mac_address);
+
+/**
+ * \brief return the mac address of the station
+ * \param ctx pointer to station context.
+ * \return
+ */
+void
+cp_station_get_mac_address(cp_sta_t *ctx, mac_address_t *mac_address);
+
+/**
+ * \brief clear the associated sta list
+ * \return
+ */
+void
+cp_station_clear_assoc_sta_list(void);
+
+/**
+ * \brief init the storage class
+ * \param
+ * \return
+ */
+void
+cp_station_data_init(mac_store_t *mac_store_ctx, cl_t *interf_cl_ctx, pbproc_t *pbproc_ctx);
+
+
+/**
+ * \brief in the POND state, this function will record the cm_unassociated_sta.ind
+ * received.
+ * \param mac_address : the osa of the message
+ * \param cco_capa : the cco_capa field of the message
+ * \param nid : the nid field of the message
+ * \return
+ */
+void
+cp_station_add_usta(const mac_address_t mac_address, const u8 cco_capa, const nid_t nid);
+
+/**
+ * \brief this will process the previously recorded messages, to know if
+ * in which state the station should go.
+ * \return process_usta_result_t
+ */
+process_usta_result_t
+cp_station_process_recorded_usta(void);
+
+/**
+ * \brief this will compare the field of a received cm_unssociated_sta.ind
+ * with the station's parameters
+ * \param mac_address : the osa of the message
+ * \param cco_capa : the cco_capa field of the message
+ * \param nid : the nid field of the message
+ * \return
+ */
+process_usta_result_t
+cp_station_process_usta(const mac_address_t mac_address, const u8 cco_capa, const nid_t nid);
+
+/**
+ * \brief this will add an avln to the discovered avln list of the station
+ * \param nid : the nid of the new avln
+ * \param snid : the snid of the new avln
+ * \return
+ */
+void
+cp_station_add_avln(const nid_t nid, const snid_t snid);
+
+/**
+ * \brief associate a new station. call this function when cco
+ * (the station has no TEI)
+ * \param sta : information about the new station
+ * \return TEI of the newly associated station, or 0 if failed
+ */
+tei_t
+cp_station_associate_new(const station_t sta);
+
+/**
+ * \brief renew the TEI of a station
+ * \param sta : information about the new station
+ * \return TEI of the newly associated station, or 0 if failed
+ */
+tei_t
+cp_station_renew(const station_t sta);
+
+/**
+ * \brief add a station to the associated station list.
+ * (the station already had a TEI)
+ * \param tei : tei of the station
+ * \param sta : information about the new station
+ * \return
+ */
+void
+cp_station_associate_old(const tei_t tei, const station_t sta);
+
+/**
+ * \brief remove a station from the associated station list.
+ * \param tei : tei of the station
+ * \return
+ */
+void
+cp_station_remove_associated(const tei_t tei);
+
+/**
+ * \brief return the data of an associated sta
+ * \param sta : the returned data
+ * \param from_first : set to true if you want to search station from the begining of the list
+ * \param tei : if you already know the tei of the station, set it here
+ * \return TEI of the next station in the list, or 0 if none
+ */
+tei_t
+cp_station_get_associate_info(station_t *sta, const bool from_first, const tei_t tei);
+
+/**
+ * \brief return the tei associated to this mac address
+ * \param mac : the mac address
+ * \return the tei
+ */
+tei_t
+cp_station_find_tei_from_mac(const mac_address_t mac_address);
+
+/**
+ * \brief get the status of the station
+ * \param
+ * \return the current status of the station
+ */
+cp_station_status_t
+cp_station_get_status(void);
+
+/**
+ * \brief set the association status of the station
+ * \param become_associated true to set station in associated station state
+ * \return
+ */
+VS_VOID
+cp_station_set_assoc_status (VS_BOOL become_associated);
+
+/**
+ * Return the association status of the station
+ *
+ * \return boolean informing if the sta is associated or not.
+ */
+VS_BOOL
+cp_station_get_assoc_status (void);
+
+/**
+ * Return the association status of the station
+ *
+ * \param ctx the station context.
+ * \return boolean informing if the sta is associated or not.
+ */
+VS_BOOL
+cp_station_is_associated(cp_sta_t *ctx);
+
+/**
+ * \brief set the cco status of the station
+ * \param is_cco true to set station in cco state
+ * \return
+ */
+VS_VOID
+cp_station_set_cco_status (VS_BOOL is_cco);
+
+/**
+ * \brief set the authentication status of the station
+ * \param become_authenticated true to set station in authenticated station state
+ * \return
+ */
+VS_VOID
+cp_station_set_auth_status (VS_BOOL become_authenticated);
+
+/**
+ * Return the authentication status of the station
+ *
+ * \return boolean informing if the sta is authenticated or not.
+ */
+VS_BOOL
+cp_station_get_auth_status (void);
+
+/**
+ * Return the authentication status of the station
+ *
+ * \param ctx the station context.
+ * \return boolean informing if the sta is authenticated or not.
+ */
+VS_BOOL
+cp_station_is_authenticated(cp_sta_t *ctx);
+
+/**
+ * \brief return true if the station is pco
+ * \param
+ * \return
+ */
+bool
+cp_station_get_is_pco(void);
+
+/**
+ * \brief return true if the station is backup cco
+ * \param
+ * \return
+ */
+bool
+cp_station_get_is_backup_cco(void);
+
+/**
+ * \brief return the number of station recorded in the discovered sta list
+ * \param
+ * \return
+ */
+u16
+cp_station_get_num_discovered_sta(void);
+
+/**
+ * \brief return the number of discovered AVLN
+ * \param
+ * \return
+ */
+u16
+cp_station_get_num_discovered_avln(void);
+
+/**
+ * \brief return true if the station user appointed cco
+ * \param
+ * \return
+ */
+bool
+cp_station_get_is_user_appointed_cco(void);
+
+/**
+ * Get the Handover in progress status.
+ *
+ * \param sta the station context
+ * \return the handover progress status.
+ */
+bool
+cp_station_get_hoip (cp_sta_t *sta);
+
+/**
+ * Set the Handover in progress status.
+ *
+ * \param sta context.
+ * \param hoip handover in progress.
+ */
+void
+cp_station_set_hoip(cp_sta_t *sta, uint hoip);
+
+/**
+ * get the rstbf flag
+ *
+ * \param sta the sta context.
+ */
+bool
+cp_station_get_rtsbf(cp_sta_t *sta);
+
+/**
+ * Set the sta rtsbf
+ *
+ * \param sta the station context
+ * \param rstbf the flag
+ */
+void
+cp_station_set_rtsbf (cp_sta_t *sta, bool rtsbf);
+
+/**
+ * Get the number of distant STAs
+ *
+ * \param sta the station context
+ * \return the number of distant stations
+ */
+u8
+cp_station_get_num_dis_sta(cp_sta_t *sta);
+
+/**
+ * Get number of distant networks.
+ *
+ * \param sta the sta context.
+ * \return the number of distant networks.
+ */
+u8
+cp_station_get_num_dis_net(cp_sta_t *sta);
+
+
+#endif /*STATION_DATA_H_*/
diff --git a/cesar/cp/station/inc/station_event_handler.h b/cesar/cp/station/inc/station_event_handler.h
new file mode 100644
index 0000000000..7d986d6183
--- /dev/null
+++ b/cesar/cp/station/inc/station_event_handler.h
@@ -0,0 +1,73 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/station/inc/event_handler.h
+ * \brief event handler for the fsm events
+ * \ingroup cp_station
+ */
+
+#ifndef EVENTHANDLER_H_
+#define EVENTHANDLER_H_
+
+
+#include "cp/msg/inc/msg_const.h"
+#include "cp/interf/inc/interf_types.h"
+#include "cp/vstate_fsm/src/SEMTypes.h"
+#include "cp/station/station.h"
+#include <cyg/kernel/kapi.h>
+
+#define EVENT_QUEUE_SIZE (INTERF_NB_BUFFER * 3)
+
+#if (INTERF_NB_BUFFER > EVENT_QUEUE_SIZE)
+ #error "event queue size too small."
+#endif
+
+
+typedef struct event_t
+{
+ SEM_EVENT_TYPE event_type;
+ VS_VOIDPTR mme_address;
+} event_t;
+
+typedef enum ev_err_code_t
+{
+ EV_OK = 0,
+ EV_QUEUE_FULL,
+ EV_QUEUE_EMPTY
+} ev_err_code_t;
+
+
+/**
+ * \brief initialize the event handler
+ * \param
+ * \return
+ */
+void
+cp_station_initialize_handler(void);
+
+/**
+ * \brief add an event to the event stack
+ * \param event_type : the event type. They are defined in main_fsmData.h
+ * \param mme_address : if necessary, pointer to a mme,
+ * or beacon address if the event is related to a beacon
+ * \return error code or 0 if success
+ */
+ev_err_code_t
+cp_station_add_event(const SEM_EVENT_TYPE event_type, const VS_VOIDPTR mme_address);
+
+/**
+ * \brief retrieve an event from the event stack
+ * \param event : the retieved event
+ * \return error code or 0 if success
+ */
+ev_err_code_t
+cp_station_get_event(event_t *event);
+
+
+
+#endif /*EVENTHANDLER_H_*/
diff --git a/cesar/cp/station/inc/station_types.h b/cesar/cp/station/inc/station_types.h
new file mode 100644
index 0000000000..512eb097dd
--- /dev/null
+++ b/cesar/cp/station/inc/station_types.h
@@ -0,0 +1,103 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/station/inc/station_types.h
+ * \brief main types and constantes of station module
+ * \ingroup cp_station
+ */
+#ifndef STA_TYPES_H_
+#define STA_TYPES_H_
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_arch.h>
+
+#include "SEMTypes.h"
+
+#include "cp/secu/inc/secu_types.h"
+
+/*
+ * station module constantes
+ */
+// the number of alarm that we can create
+#define ALARM_NB 20
+
+/*
+ * Homeplug AV constantes
+ */
+#define MinCCoScanTime_ms 1000
+#define MaxCCoScanTime_ms 2000
+#define MinScanTime_ms 2000
+#define MaxScanTime_ms 4000
+#define USAI_ms 1000
+#define MaxDiscoverPeriod_ms 10000
+#define LEASE_TIME_USTA 0xF // Table 11-212
+#define LEASE_TIME_AUTH_STA 0x0B40 // Table 11-212
+/*
+ * the event flags
+ * these are some flag, so take care to give a value with all bits set to 0 but one.
+ */
+typedef enum station_flag_t
+{
+ STATION_FLAG_MSG_RCV = 0x1, // the sta has received a mme (for sta or cco)
+ STATION_FLAG_BUF_REL = 0x2, // some buffer can be released
+ STATION_FLAG_FSM = 0x4, // some event are ready to be processed in the FSM
+ STATION_FLAG_USTT = 0x8
+ // TBC
+} station_flag_t;
+
+typedef enum station_status_t
+{
+ STATION_UNASSOCIATED,
+ STATION_ASSOCIATED,
+ STATION_AUTHENTICATED
+} cp_station_status_t;
+
+typedef struct station_event_t
+{
+ cyg_flag_value_t flag_value;
+ void (*func) (void);
+} station_event_t;
+
+typedef struct alarm_def_t
+{
+ bool alarm_used; // set to true if this alarm is used
+ cyg_alarm alarm;
+ cyg_handle_t alarm_handle;
+ cyg_flag_t *cyg_flag; // the wait-event handler
+ station_flag_t station_flag; // the flag to set
+ SEM_EVENT_TYPE event_type; // to set if the previous flag is == to STATION_FLAG_FSM
+} alarm_def_t;
+
+typedef struct station_t
+{
+ mac_address_t mac_address;
+ cyg_tick_count_t tei_lease_time; // date when the tei will expires
+ cyg_tick_count_t last_discover_beacon; // date of the last discover beacon received from this station
+ u8 cco_capa; // CCO capability of the station (0 : level 0, 1 : level 1 ...)
+ bool proxy_net_capa; // proxy networking capability of the station
+ cp_station_status_t station_status;
+ aes_key_t dak; // dak of the station
+} station_t;
+
+typedef struct u_station_t
+{
+ mac_address_t mac_address;
+ u8 cco_capa; // CCO capability of the station
+ nid_t nid; // expected nid of the u_sta
+} u_station_t;
+
+
+typedef struct avln_t
+{
+ nid_t nid; // nid of the avln
+ snid_t snid; // snid of the avln
+ station_t sta[THEORICAL_MAX_STA_NB]; // stations of the avln
+}avln_t;
+
+
+#endif /*STA_TYPES_H_*/
diff --git a/cesar/cp/station/maximus/Module b/cesar/cp/station/maximus/Module
new file mode 100644
index 0000000000..7c08fc98d1
--- /dev/null
+++ b/cesar/cp/station/maximus/Module
@@ -0,0 +1,5 @@
+SOURCES := maximus_cp_station.c
+MODULES := lib/visual_state_api hal/phy/maximus hal/leon/maximus hal/timer \
+ mac/common mac/ca mac/pbproc mac/sar \
+ hle cl \
+ cp/cco cp/beacon cp/interf cp/msg cp/secu cp/station cp/vstate_fsm
diff --git a/cesar/cp/station/maximus/inc/maximus_cp_station.h b/cesar/cp/station/maximus/inc/maximus_cp_station.h
new file mode 100644
index 0000000000..6290bdba61
--- /dev/null
+++ b/cesar/cp/station/maximus/inc/maximus_cp_station.h
@@ -0,0 +1,49 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus_cp_station.h
+ * \brief Declaration of Maximus function calls used for the station configuration
+ * \ingroup
+ */
+#ifndef cp_station_maximus_inc_maximus_cp_station_h
+#define cp_station_maximus_inc_maximus_cp_station_h
+
+#include "hal/phy/defs.h" // for 'PHY_CARRIER_NB'
+#include "host/fwd.h" // for 'station_ctx_t', 'fcall_ctx_t', and 'sci_msg_t',
+#include "host/fcall.h" // for 'fcall_param_t'
+
+// typedef unsigned char mac_address_t[6]; // defined in 'cp/cp_types.h'
+typedef bool cco_preference_t;
+typedef bool was_cco_t;
+typedef char npw_t[64];
+typedef char dpw_t[64];
+typedef char m_sta_hfid_t[64];
+typedef char u_sta_hfid_t[64];
+typedef char avln_hfid_t[64];
+typedef u8 sl_t;
+typedef u8 tonemask_t[(PHY_CARRIER_NB + 7) / 8];
+// typedef unsigned char snid_t; // defined in 'cp/cp_types.h'
+
+void maximus_cp_station_init (station_ctx_t *station);
+
+int maximus_set_mac_address (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+int maximus_set_cco_preference (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+int maximus_set_was_cco (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+int maximus_set_npw (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+int maximus_set_dpw (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+int maximus_set_m_sta_hfid (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+int maximus_set_u_sta_hfid (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+int maximus_set_avln_hfid (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+int maximus_set_sl (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+int maximus_set_tonemask (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+int maximus_set_snid (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+
+int maximus_mac_start (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+int maximus_mac_stop (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data);
+
+#endif /* cp_station_maximus_inc_maximus_cp_station_h */
diff --git a/cesar/cp/station/maximus/src/maximus_cp_station.c b/cesar/cp/station/maximus/src/maximus_cp_station.c
new file mode 100644
index 0000000000..5b8e961efa
--- /dev/null
+++ b/cesar/cp/station/maximus/src/maximus_cp_station.c
@@ -0,0 +1,535 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file maximus_cp_station.c
+ * \brief Maximus function calls used for the station configuration
+ * \ingroup
+ */
+
+#include "common/std.h"
+
+#include "cp/beacon/beacons.h"
+#include "cp/beacon/inc/beacons_ctx.h"
+#include "cp/beacon/forward.h"
+
+#include "cp/station/maximus/inc/maximus_cp_station.h"
+#include "cp/station/inc/station_data.h" // for cp station functions
+#include "cp/station/inc/station_actions.h" // for process drv functions
+#include "cp/station/station.h" // for 'cp_station_mac_start()'
+#include "common/defs/ethernet.h" // for 'ETH_PACKET_MAX_SIZE'
+#include <stdio.h> // for 'sprintf()'
+#include <errno.h>
+
+char mme[ETH_PACKET_MAX_SIZE];
+
+void maximus_cp_station_init (station_ctx_t *station)
+{
+ dbg_assert_ptr(station);
+ if (NULL == station)
+ {
+ errno = EINVAL;
+ station_log(&my_station, STATION_LOG_ERROR, STATION_LOGTYPE_STATION,
+ "%s: errno = %d", __FUNCTION__, errno);
+ }
+ else
+ {
+ fcall_register(station->fcall, "maximus_set_mac_address", (void*)&maximus_set_mac_address, NULL);
+ fcall_register(station->fcall, "maximus_set_cco_preference", (void*)&maximus_set_cco_preference, NULL);
+ fcall_register(station->fcall, "maximus_set_was_cco", (void*)&maximus_set_was_cco, NULL);
+ fcall_register(station->fcall, "maximus_set_npw", (void*)&maximus_set_npw, NULL);
+ fcall_register(station->fcall, "maximus_set_dpw", (void*)&maximus_set_dpw, NULL);
+ fcall_register(station->fcall, "maximus_set_m_sta_hfid", (void*)&maximus_set_m_sta_hfid, NULL);
+ fcall_register(station->fcall, "maximus_set_u_sta_hfid", (void*)&maximus_set_u_sta_hfid, NULL);
+ fcall_register(station->fcall, "maximus_set_avln_hfid", (void*)&maximus_set_avln_hfid, NULL);
+ fcall_register(station->fcall, "maximus_set_sl", (void*)&maximus_set_sl, NULL);
+ fcall_register(station->fcall, "maximus_set_tonemask", (void*)&maximus_set_tonemask, NULL);
+ fcall_register(station->fcall, "maximus_set_snid", (void*)&maximus_set_snid, NULL);
+
+ fcall_register(station->fcall, "maximus_mac_start", (void*)&maximus_mac_start, NULL);
+ fcall_register(station->fcall, "maximus_mac_stop", (void*)&maximus_mac_stop, NULL);
+ }
+}
+
+
+int maximus_set_mac_address (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+ mac_address_t mac_address;
+ const unsigned short int mac_address_length = 6;
+ memset(mac_address, '\0', mac_address_length);
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_set_mac_address");
+
+ /* get parameters content */
+
+ if ( fcall_is_param(*param, *msg, "mac_address")
+ && (0 == fcall_param_bind(*param, *msg, "mac_address", mac_address_length, &mac_address)) )
+ {
+ /* do other tasks ... */
+ int i;
+ char buffer[STATION_MAX_LOG_SIZE];
+
+ sprintf(buffer, "mac address = 0x");
+ for (i=0; i<mac_address_length; i++)
+ {
+ sprintf(buffer, " %X", (unsigned short int)mac_address[i]);
+ }
+ sprintf(buffer, "\n");
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "%s", buffer);
+
+ cp_station_set_mac_address(NULL, mac_address);
+
+ ret = 0;
+ }
+
+ if ( fcall_is_param(*param, *msg, "mme")
+ && (0 == fcall_param_bind(*param, *msg, "mme", ETH_PACKET_MAX_SIZE, &mme)) )
+ {
+ /* do other tasks ... */
+ process_drv_set_mac_address((void *)mme);
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
+
+int maximus_set_cco_preference (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+ cco_preference_t cco_preference = false;
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_set_cco_preference");
+
+ /* get parameters content */
+
+ if ( fcall_is_param(*param, *msg, "cco_preference")
+ && (0 == fcall_param_bind(*param, *msg, "cco_preference", sizeof(cco_preference_t), &cco_preference)) )
+ {
+ /* do other tasks ... */
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "cco preference = %u\n", (unsigned short int)cco_preference);
+ //cp_station_set_cco_preference(cco_preference); // TBD
+
+ ret = 0;
+ }
+
+ if ( fcall_is_param(*param, *msg, "mme")
+ && (0 == fcall_param_bind(*param, *msg, "mme", ETH_PACKET_MAX_SIZE, &mme)) )
+ {
+ /* do other tasks ... */
+ process_drv_set_cco_preference((void *)&mme);
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
+
+int maximus_set_was_cco (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+ was_cco_t was_cco = false;
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_set_was_cco");
+
+ /* get parameters content */
+
+ if ( fcall_is_param(*param, *msg, "was_cco")
+ && (0 == fcall_param_bind(*param, *msg, "was_cco", sizeof(was_cco_t), &was_cco)) )
+ {
+ /* do other tasks ... */
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "previous cco status = %u\n", (unsigned short int)was_cco);
+ //cp_station_set_was_cco(was_cco); // TBD
+
+ ret = 0;
+ }
+
+ if ( fcall_is_param(*param, *msg, "mme")
+ && (0 == fcall_param_bind(*param, *msg, "mme", ETH_PACKET_MAX_SIZE, &mme)) )
+ {
+ /* do other tasks ... */
+ process_drv_set_was_cco((void *)&mme);
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
+
+int maximus_set_npw (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+ npw_t npw;
+ const unsigned short int npw_length = 65;
+ memset(npw, '\0', npw_length);
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_set_npw");
+
+ /* get parameters content */
+
+ if ( fcall_is_param(*param, *msg, "npw")
+ && (0 == fcall_param_bind(*param, *msg, "npw", npw_length, &npw)) )
+ {
+ /* do other tasks ... */
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "npw = %s\n", npw);
+ //cp_station_set_npw(npw); // TBD
+
+ ret = 0;
+ }
+
+ if ( fcall_is_param(*param, *msg, "mme")
+ && (0 == fcall_param_bind(*param, *msg, "mme", ETH_PACKET_MAX_SIZE, &mme)) )
+ {
+ /* do other tasks ... */
+ process_drv_set_npw((void *)&mme);
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
+
+int maximus_set_dpw (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+ dpw_t dpw;
+ const unsigned short int dpw_length = 65;
+ memset(dpw, '\0', dpw_length);
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_set_dpw");
+
+ /* get parameters content */
+
+ if ( fcall_is_param(*param, *msg, "dpw")
+ && (0 == fcall_param_bind(*param, *msg, "dpw", dpw_length, &dpw)) )
+ {
+ /* do other tasks ... */
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "dpw = %s\n", dpw);
+ //cp_station_set_dpw(dpw); // TBD
+
+ ret = 0;
+ }
+
+ if ( fcall_is_param(*param, *msg, "mme")
+ && (0 == fcall_param_bind(*param, *msg, "mme", ETH_PACKET_MAX_SIZE, &mme)) )
+ {
+ /* do other tasks ... */
+ process_drv_set_dpw_req((void *)&mme);
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
+
+int maximus_set_m_sta_hfid (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+ m_sta_hfid_t m_sta_hfid;
+ const unsigned short int m_sta_hfid_length = 65;
+ memset(m_sta_hfid, '\0', m_sta_hfid_length);
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_set_m_sta_hfid");
+
+ /* get parameters content */
+
+ if ( fcall_is_param(*param, *msg, "m_sta_hfid")
+ && (0 == fcall_param_bind(*param, *msg, "m_sta_hfid", m_sta_hfid_length, &m_sta_hfid)) )
+ {
+ /* do other tasks ... */
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "m_sta_hfid = %s\n", m_sta_hfid);
+ //cp_station_set_m_sta_hfid(m_sta_hfid); // TBD
+
+ ret = 0;
+ }
+
+ if ( fcall_is_param(*param, *msg, "mme")
+ && (0 == fcall_param_bind(*param, *msg, "mme", ETH_PACKET_MAX_SIZE, &mme)) )
+ {
+ /* do other tasks ... */
+ process_drv_set_m_sta_hfid((void *)&mme);
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
+
+int maximus_set_u_sta_hfid (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+ u_sta_hfid_t u_sta_hfid;
+ const unsigned short int u_sta_hfid_length = 65;
+ memset(u_sta_hfid, '\0', u_sta_hfid_length);
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_set_u_sta_hfid");
+
+ /* get parameters content */
+
+ if ( fcall_is_param(*param, *msg, "u_sta_hfid")
+ && (0 == fcall_param_bind(*param, *msg, "u_sta_hfid", u_sta_hfid_length, &u_sta_hfid)) )
+ {
+ /* do other tasks ... */
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "u_sta_hfid = %s\n", u_sta_hfid);
+ //cp_station_set_u_sta_hfid(u_sta_hfid); // TBD
+
+ ret = 0;
+ }
+
+ if ( fcall_is_param(*param, *msg, "mme")
+ && (0 == fcall_param_bind(*param, *msg, "mme", ETH_PACKET_MAX_SIZE, &mme)) )
+ {
+ /* do other tasks ... */
+ process_drv_set_u_sta_hfid((void *)&mme);
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
+
+int maximus_set_avln_hfid (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+ avln_hfid_t avln_hfid;
+ const unsigned short int avln_hfid_length = 65;
+ memset(avln_hfid, '\0', avln_hfid_length);
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_set_avln_hfid");
+
+ /* get parameters content */
+
+ if ( fcall_is_param(*param, *msg, "avln_hfid")
+ && (0 == fcall_param_bind(*param, *msg, "avln_hfid", avln_hfid_length, &avln_hfid)) )
+ {
+ /* do other tasks ... */
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "avln_hfid = %s\n", avln_hfid);
+ //cp_station_set_avln_hfid(avln_hfid); // TBD
+
+ ret = 0;
+ }
+
+ if ( fcall_is_param(*param, *msg, "mme")
+ && (0 == fcall_param_bind(*param, *msg, "mme", ETH_PACKET_MAX_SIZE, &mme)) )
+ {
+ /* do other tasks ... */
+ process_drv_set_avln_hfid((void *)&mme);
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
+
+int maximus_set_sl (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+ sl_t sl = '\0';
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_set_sl");
+
+ /* get parameters content */
+
+ if ( fcall_is_param(*param, *msg, "sl")
+ && (0 == fcall_param_bind(*param, *msg, "sl", sizeof(sl_t), &sl)) )
+ {
+ /* do other tasks ... */
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "sl = %u\n", (unsigned short int)sl);
+ //cp_station_set_sl(sl); // TBD
+
+ ret = 0;
+ }
+
+ if ( fcall_is_param(*param, *msg, "mme")
+ && (0 == fcall_param_bind(*param, *msg, "mme", ETH_PACKET_MAX_SIZE, &mme)) )
+ {
+ /* do other tasks ... */
+ process_drv_set_sl((void *)&mme);
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
+
+int maximus_set_tonemask (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+ tonemask_t tonemask;
+ const unsigned short int tonemask_length = (PHY_CARRIER_NB + 7) / 8;
+ memset(tonemask, '\0', tonemask_length);
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_set_tonemask");
+
+ /* get parameters content */
+
+ if ( fcall_is_param(*param, *msg, "tonemask")
+ && (0 == fcall_param_bind(*param, *msg, "tonemask", tonemask_length, &tonemask)) )
+ {
+ /* do other tasks ... */
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "tonemask = %s\n", tonemask);
+ //cp_station_set_tonemask(tonemask); // TBD
+
+ ret = 0;
+ }
+
+ if ( fcall_is_param(*param, *msg, "mme")
+ && (0 == fcall_param_bind(*param, *msg, "mme", ETH_PACKET_MAX_SIZE, &mme)) )
+ {
+ /* do other tasks ... */
+ process_drv_set_tonemask((void *)&mme);
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
+
+int maximus_set_snid (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+ snid_t snid = '\0';
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_set_snid");
+
+ /* get parameters content */
+
+ if ( fcall_is_param(*param, *msg, "snid")
+ && (0 == fcall_param_bind(*param, *msg, "snid", sizeof(snid_t), &snid)) )
+ {
+ /* do other tasks ... */
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "snid = %u\n", (unsigned short int)snid);
+ //cp_station_set_snid(snid); // TBD
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
+
+
+int maximus_mac_start (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_mac_start");
+
+ /* get parameters content */
+
+ if (fcall_is_param(*param, *msg, "mme"))
+ {
+ if (0 == fcall_param_bind(*param, *msg, "mme", ETH_PACKET_MAX_SIZE, &mme))
+ {
+ /* do other tasks ... */
+ process_drv_start_mac_req((void *)mme);
+
+ ret = 0;
+ }
+ }
+ else
+ {
+ /* do other tasks ... */
+ cp_station_mac_start();
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
+
+int maximus_mac_stop (fcall_ctx_t *fcall, fcall_param_t **param, sci_msg_t **msg, void *data)
+{
+ int ret = -1;
+
+ station_log(&my_station, STATION_LOG_DEBUG, STATION_LOGTYPE_FCALL,
+ "=> maximus_mac_stop");
+
+ /* get parameters content */
+
+ if (fcall_is_param(*param, *msg, "mme"))
+ {
+ if (0 == fcall_param_bind(*param, *msg, "mme", ETH_PACKET_MAX_SIZE, &mme))
+ {
+ /* do other tasks ... */
+ //process_drv_stop_mac_req((void *)mme);
+
+ ret = 0;
+ }
+ }
+ else
+ {
+ /* do other tasks ... */
+ //cp_station_mac_stop();
+
+ ret = 0;
+ }
+
+ /* now make the return parameter list */
+ fcall_param_reset(*param);
+
+ return ret;
+}
diff --git a/cesar/cp/station/src/station_actions.c b/cesar/cp/station/src/station_actions.c
new file mode 100644
index 0000000000..ba0ec9a593
--- /dev/null
+++ b/cesar/cp/station/src/station_actions.c
@@ -0,0 +1,1261 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/station/src/station_events.c
+ * \brief the events generated in station module
+ * \ingroup cp_station
+ */
+
+#include "common/std.h"
+#include "cp/beacon/beacons.h"
+#include "cp/station/inc/station_actions.h"
+
+extern cp_sta_t cp_sta_global;
+
+extern int mme_buffer_count;
+extern int mme_buffer_first;
+extern int mme_buffer_last;
+extern u8 * mme_tx_buffer[MME_BUFFER_MAXCOUNT];
+
+/*
+void
+station_ustt_expires(void)
+{
+ printf("%u %s()\n", cyg_hal_sys_getpid(), __FUNCTION__);
+ sta_add_event(USTT_EXPIRES, NULL);
+}
+*/
+void
+transmit_unassoc_sta_mme(void)
+{
+ //printf("%u %s()\n", cyg_hal_sys_getpid(), __FUNCTION__);
+ msg_cm_unassociated_sta_ind_send(BROADCAST_MAC_AD);
+}
+
+void
+init_system (void)
+{
+// printf("%u %s()\n", cyg_hal_sys_getpid(), __FUNCTION__);
+}
+
+void
+launch_bbt_timer (void)
+{
+ bool sta_was_cco = false;
+ uint min_bbt, max_bbt, bbt;
+
+ //printf("%u %s()\n", cyg_hal_sys_getpid(), __FUNCTION__);
+ // TODO check if before the previous reboot the sta was CCO
+ // if yes, set sta_was_cco to true
+ // calculate the BBT
+ if (sta_was_cco)
+ {
+ min_bbt = MinCCoScanTime_ms;
+ max_bbt = MaxCCoScanTime_ms;
+ }
+ else
+ {
+ min_bbt = MinScanTime_ms;
+ max_bbt = MaxScanTime_ms;
+ }
+ bbt = rand_in(min_bbt, max_bbt);
+ dbg_assert( (bbt > MinCCoScanTime_ms) && (bbt < MaxScanTime_ms) );
+ // set the BBT timer
+ //printf("%u bbt = %i ms\n", cyg_hal_sys_getpid(), bbt);
+ cp_station_gen_timed_event(&station_flag, STATION_FLAG_FSM, BBT_EXPIRES, bbt);
+
+}
+
+uint rand_in(uint min, uint max)
+{
+ double tmp;
+
+ if(max)
+ {
+ dbg_assert(min < max);
+ tmp = rand_r( & station_seed);
+ tmp /= RAND_MAX;
+ tmp *= (max - min);
+ return (uint) (tmp + min);
+ }
+ else return rand_r( & station_seed);
+}
+
+void
+launch_beacon_timer (void)
+{
+ //printf("%u %s()\n", cyg_hal_sys_getpid(), __FUNCTION__);
+
+}
+void
+launch_ustt_timer (void)
+{
+ uint ustt;
+
+ //printf("%u %s()\n", cyg_hal_sys_getpid(), __FUNCTION__);
+
+ ustt = rand_in(0, USAI_ms);
+ // TODO si la station est USTA, ustt se choisit sur un autre intervalle
+ if(ustt < 10) ustt = 10; // tick is 10 ms
+ //printf("%u ustt = %i \n", cyg_hal_sys_getpid(), ustt);
+ dbg_assert(ustt < USAI_ms);
+ dbg_assert(ustt);
+ cp_station_gen_timed_event(&station_flag, STATION_FLAG_FSM, USTT_EXPIRES, ustt);
+
+}
+
+void
+station_bbt_expires(void) // see figure 7-76
+{
+ process_usta_result_t process_usta_result;
+
+ //printf("%u %s()\n", cyg_hal_sys_getpid(), __FUNCTION__);
+ // check the condition "NID match & Should become CCO"
+ if( (process_usta_result = cp_station_process_recorded_usta()) == BECOME_CCO)
+ {
+ cp_station_add_event(TO_CCO, NULL);
+ return;
+ }
+ if(process_usta_result == CHECK_EXISTING_OTHER_AVLN)
+ {
+ // no other AVLN has been detected, and no matching nid so become uCCO
+ // fire the transition anyway, it is protected with a positive state condition
+ cp_station_add_event(POND_TO_UCCO, NULL);
+ return;
+ }
+ // there are some matching nid or some other avln, so become usta
+ // fire the condition anyway but we know that it some case it will not fire
+ cp_station_add_event(TO_USTA, NULL);
+}
+
+VS_VOID
+record_usta_mme (VS_VOIDPTR mme_address)
+{
+ cm_unassociated_sta_t *cm_unassociated_sta;
+ msg_mme_t *msg_mme;
+
+ //printf("%u %s() mme_address = 0x%08lX\n", cyg_hal_sys_getpid(), __FUNCTION__, mme_address);
+ dbg_assert ( !msg_check_wrong_mme_const_values (mme_address));
+
+ msg_mme = mme_address;
+ cm_unassociated_sta = (cm_unassociated_sta_t *) &msg_mme->mm_entry;
+ cp_station_add_usta(msg_mme->osa, cm_unassociated_sta->cco_capability, cm_unassociated_sta->nid);
+}
+
+VS_VOID
+process_usta_mme (VS_VOIDPTR mme_address)
+{
+ cm_unassociated_sta_t *cm_unassociated_sta;
+ msg_mme_t *msg_mme;
+ process_usta_result_t process_usta_result;
+
+ //printf("%u %s()\n", cyg_hal_sys_getpid(), __FUNCTION__);
+ dbg_assert ( !msg_check_wrong_mme_const_values (mme_address));
+
+ msg_mme = mme_address;
+ cm_unassociated_sta = (cm_unassociated_sta_t *) &msg_mme->mm_entry;
+ process_usta_result = cp_station_process_usta(msg_mme->osa, cm_unassociated_sta->cco_capability, cm_unassociated_sta->nid);
+ if(process_usta_result == BECOME_CCO) cp_station_add_event(TO_CCO, NULL);
+}
+
+#define TRACE_FSM_STATE 1
+
+VS_VOID trace_cco (VS_VOID)
+{
+ cp_station_set_cco_status(true);
+#if TRACE_FSM_STATE
+ printf("%u station 0x%016llx is now CCO\n",cyg_hal_sys_getpid(),cp_sta_global.cp_sta_flash_params.mac_address);
+#endif
+}
+VS_VOID trace_pond (VS_VOID)
+{
+#if TRACE_FSM_STATE
+ printf("%u station 0x%016llx is now POND\n",cyg_hal_sys_getpid(),cp_sta_global.cp_sta_flash_params.mac_address);
+#endif
+}
+VS_VOID trace_sta (VS_VOID)
+{
+#if TRACE_FSM_STATE
+ printf("%u station 0x%016llx is now associated STA\n",cyg_hal_sys_getpid(),cp_sta_global.cp_sta_flash_params.mac_address);
+#endif
+}
+VS_VOID trace_ucco (VS_VOID)
+{
+#if TRACE_FSM_STATE
+ printf("%u station 0x%016llx is now UCCO\n",cyg_hal_sys_getpid(),cp_sta_global.cp_sta_flash_params.mac_address);
+#endif
+}
+VS_VOID trace_usta (VS_VOID)
+{
+#if TRACE_FSM_STATE
+ printf("%u station 0x%016llx is now USTA\n",cyg_hal_sys_getpid(),cp_sta_global.cp_sta_flash_params.mac_address);
+#endif
+}
+
+VS_VOID try_associate (VS_VOIDPTR beacon_address)
+{
+ beacon_t *beacon;
+
+ dbg_assert(beacon_address);
+ beacon = (beacon_t *) beacon_address;
+ // check if NID match
+ if(beacon->nid != cp_station_get_nid(NULL)) return; //TODO : pass CP ctx as first argument instead of NULL pointer...
+ // if yes, then we start the association procedure (see 7.3.2)
+ // first, send a cm_assoc.req to the cco
+ msg_cc_assoc_req_send(ZEROS_MAC_AD);
+}
+
+VS_VOID process_cc_assoc_req (VS_VOIDPTR mme_address)
+{ // 11.2.28
+ cc_assoc_req_t *cc_assoc_req;
+ msg_mme_t *msg_mme;
+ station_t sta;
+ tei_t tei, next_tei;
+ u16 lease_time_m = 0xF; // default lease time in minutes
+ u8 number_of_associated_sta;
+ unsigned int i;
+
+ dbg_assert ( !msg_check_wrong_mme_const_values (mme_address));
+ msg_mme = (msg_mme_t *) mme_address;
+ cc_assoc_req = (cc_assoc_req_t *) msg_mme->mm_entry;
+ // check if nid match
+ if(cc_assoc_req->nid != cp_station_get_nid(NULL)) return; //TODO : pass CP ctx as first argument instead of NULL pointer...
+ // check req_type
+ if(cc_assoc_req->req_type == 0)
+ {
+ // try to associate the new sta
+ sta.cco_capa = cc_assoc_req->cco_capability;
+ sta.last_discover_beacon = cyg_current_time();
+ sta.tei_lease_time = sta.last_discover_beacon + lease_time_m * MINUTES_TO_TICK_FACTOR;
+ memcpy(sta.mac_address, msg_mme->osa, sizeof(mac_address_t));
+ sta.proxy_net_capa = cc_assoc_req->proxy_networking_capability;
+ sta.station_status = STATION_ASSOCIATED;
+ tei = cp_station_associate_new(sta);
+ if( ! tei)
+ {
+ // we failed to associate the sta
+ msg_cc_assoc_cnf_send(msg_mme->osa, 1, 0, 0);
+ }
+ else
+ {
+ // we succed to associate the sta
+ msg_cc_assoc_cnf_send(msg_mme->osa, 0, tei, lease_time_m);
+ // send the message cc_set_tei_map.ind to the newly associated station
+ number_of_associated_sta = cp_station_get_number_of_assoc();
+ for(i=0 ; i<number_of_associated_sta ; i+= SET_TEI_MAP_SUB_NB_ELEM)
+ msg_cc_set_tei_map_ind_send(msg_mme->osa, 0, 0, i);
+ // and send cc_set_tei_map.ind in add mode to all other stations
+ // BEWARE, msg_cc_set_tei_map_ind_send() also use station_get_associate_info function
+ // and this may corrupt info
+ next_tei = cp_station_get_associate_info(&sta, true, 0);
+ for(i=1 ; i<number_of_associated_sta ; i++)
+ {
+ if(memcmp(sta.mac_address, msg_mme->osa, sizeof(mac_address_t)))
+ msg_cc_set_tei_map_ind_send(sta.mac_address, 1, tei, 0);
+ next_tei = cp_station_get_associate_info(&sta, false, next_tei);
+ }
+ }
+ return;
+ }
+ if(cc_assoc_req->req_type == 1)
+ {
+ // this is a TEI renewal
+ // calculate the new lease_time
+ if(sta.station_status == STATION_AUTHENTICATED)
+ lease_time_m = LEASE_TIME_AUTH_STA;
+ sta.tei_lease_time = cyg_current_time() + lease_time_m * MINUTES_TO_TICK_FACTOR;
+ // process the renew
+ tei = cp_station_renew(sta);
+ if( ! tei)
+ {
+ // we failed to renew the tei
+ msg_cc_assoc_cnf_send(msg_mme->osa, 1, 0, 0);
+ }
+ else
+ {
+ // we succed to associate the sta
+ msg_cc_assoc_cnf_send(msg_mme->osa, 0, tei, lease_time_m);
+ return;
+ }
+ }
+ // how can we be there ???
+ dbg_assert(0);
+}
+
+VS_VOID process_cc_assoc_cnf (VS_VOIDPTR mme_address)
+{
+ cc_assoc_cnf_t *cc_assoc_cnf;
+ msg_mme_t *msg_mme;
+
+ dbg_assert ( !msg_check_wrong_mme_const_values (mme_address));
+ msg_mme = (msg_mme_t *) mme_address;
+ cc_assoc_cnf = (cc_assoc_cnf_t *) msg_mme->mm_entry;
+ // check if nid match
+ if(cc_assoc_cnf->nid != cp_station_get_nid(NULL)) return; //TODO : pass CP ctx as first argument instead of NULL pointer...
+ // if yes, check the assoc result
+ if(cc_assoc_cnf->result == 0)
+ {
+ // association success
+ cp_station_set_tei(cc_assoc_cnf->sta_tei, cc_assoc_cnf->lease_time);
+ cp_station_add_event(TO_STA, NULL);
+ }
+ else
+ {
+ // et sinon quoi ?
+ // TODO
+ }
+}
+
+VS_VOID process_cc_set_tei_map_ind (VS_VOIDPTR mme_address)
+{
+ msg_mme_t *msg_mme;
+
+ dbg_assert ( !msg_check_wrong_mme_const_values (mme_address));
+ msg_mme = (msg_mme_t *) mme_address;
+ msg_cc_set_tei_map_ind_send(msg_mme->osa, 0, 0, 0);
+
+}
+
+VS_VOID
+process_cc_set_tei_map_req (VS_VOIDPTR mme_address)
+{//11.2.34
+ u8 i;
+ cc_set_tei_map_ind_t *cc_set_tei_map_ind;
+ msg_mme_t *msg_mme;
+ station_t sta;
+
+ dbg_assert ( !msg_check_wrong_mme_const_values (mme_address));
+ msg_mme = (msg_mme_t *) mme_address;
+ cc_set_tei_map_ind = (cc_set_tei_map_ind_t *) msg_mme->mm_entry;
+ switch(cc_set_tei_map_ind->mode)
+ {
+ case 0: // update entire sta list
+ cp_station_clear_assoc_sta_list();
+ // intentionaly no break here !!!
+ case 1: // add some new sta
+ for(i=0 ; i < cc_set_tei_map_ind->num ; i++)
+ {
+ sta.cco_capa = 0;
+ sta.last_discover_beacon = 0;
+ memcpy(sta.mac_address, cc_set_tei_map_ind->sub[i].mac_address, sizeof(mac_address_t));
+ sta.proxy_net_capa = 0;
+ if(cc_set_tei_map_ind->sub[i].status == 0x0)
+ sta.station_status = STATION_ASSOCIATED;
+ else sta.station_status = STATION_AUTHENTICATED;
+ sta.tei_lease_time = 0;
+ cp_station_associate_old(cc_set_tei_map_ind->sub[i].tei, sta);
+ }
+ break;
+ case 2: // remove sta from the list
+ for(i=0 ; i < cc_set_tei_map_ind->num ; i++)
+ {
+ cp_station_remove_associated(cc_set_tei_map_ind->sub[i].tei);
+ }
+ break;
+ }
+}
+
+
+VS_VOID
+send_discover_beacon_as_ucco (VS_VOID)
+{
+ // first, create and send a discover beacon
+#if 0
+ beacon_send_discover();
+#else
+ // TODO : call the right function dedicated to sending discover beacon,
+ // with right arguments (like the beacon context...)
+ cp_beacon_cco_send_discover_beacon (cp_sta_global.cp_beacon); // TODO : the pointer to beacon context should be
+ // an argument of the local send_discover_beacon_as_ucco() function...
+#endif
+ // then, launch the timer for the next beacon
+ cp_station_gen_timed_event(&station_flag, STATION_FLAG_FSM, UCCO_MAX_DISCOVER_EXPIRES, MaxDiscoverPeriod_s * 1000);
+}
+
+/**
+ * \brief Read and verify MME message header info.
+ *
+ * \param msg the MME message buffer
+ * \param recv_mme_header the pointer to structure where to copy header info extracted sequentially from MME message buffer
+ *
+ * \return size of header if valid header, else (-1)
+ */
+int read_mme_header(VS_VOIDPTR msg, mme_header_type *recv_mme_header)
+{
+ u8 *buf = (u8*)msg;
+ bitstream_t bstr_ctx;
+ int header_size = (-1); // by default, -1 indicates invalid header (not finding IEEE ETHERTYPE 0x88E1 pattern at expected offset or other invalid field)
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+
+ dbg_assert(msg);
+ dbg_assert(recv_mme_header);
+
+ //*(buf+12)=0x81; *(buf+13)=0x00; *(buf+14)=0x03; *(buf+15)=0x04;
+
+ /* decode whole header info, depending on "VLAN Tag" field is present or not */
+ bitstream_init(&bstr_ctx,(u8*)msg,MME_HEADER_MAXSIZE,BITSTREAM_READ);
+ memset(recv_mme_header,0x00,sizeof(*recv_mme_header));
+ bitstream_access(&bstr_ctx,&(recv_mme_header->un_osa.u64),48);
+ bitstream_access(&bstr_ctx,&(recv_mme_header->un_oda.u64),48);
+ /* see if "VLAN Tag" field is present or not... */
+ bitstream_access(&bstr_ctx,&(recv_mme_header->un_mtype.u32),16);
+ if ((big_to_cpuhost_endian_u32(recv_mme_header->un_mtype.u32) >> 16) == (u32)MSG_MTYPE_IEEE_ETHERTYPE)
+ {
+ // Header without "AVLN Tag' field (IEEE_ETHERTYPE value 0x88E1 found at "VLAN tag" field offset => no "VLAN Tag" field in this header)
+ printf("%u %s() : Header without AVLN Tag field...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ recv_mme_header->vlan_tag_flag = false;
+ header_size = MME_HEADER_MINSIZE;
+ }
+ else
+ {
+ // May be, Header with "AVLN Tag" field
+ printf("%u %s() : May be, Header with AVLN Tag field...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ recv_mme_header->vlan_tag_flag = true;
+ header_size = MME_HEADER_MAXSIZE;
+ // read last 16 bits of VLAN Tag field...
+ bitstream_access(&bstr_ctx,&(recv_mme_header->un_vlan_tag.u32),16);
+ // ... and recombine them with first 16 bits already read, ...
+ recv_mme_header->un_vlan_tag.u32 = (recv_mme_header->un_vlan_tag.u32 << 16) | recv_mme_header->un_mtype.u32;
+#if 0
+ printf("%u %s() : vlan_tag = 0x%04x\n",cyg_hal_sys_getpid(),__FUNCTION__,(u16)(big_to_cpuhost_endian_u32(recv_mme_header->un_vlan_tag.u32)>>16));
+#endif
+ // ... and then, verify the IEEE 802.1Q VLAN Tag pattern (0x8100) at the expected offset
+ if ((big_to_cpuhost_endian_u32(recv_mme_header->un_vlan_tag.u32)>>16) != (u32)MSG_VLAN_TAG_IEEE_802_1Q)
+ header_size = (-1);
+ // read the MTYPE field (16 bits)...
+ bitstream_access(&bstr_ctx,&(recv_mme_header->un_mtype.u32),16);
+ // ... and verify the IEEE ETHERTYPE pattern (0x88E1) at this offset...
+ if (big_to_cpuhost_endian_u32(recv_mme_header->un_mtype.u32) == (u32)MSG_MTYPE_IEEE_ETHERTYPE)
+ header_size = (-1);
+ }
+
+ bitstream_access(&bstr_ctx,&(recv_mme_header->un_mmv.u32),8);
+ // HP_AV section 11.1.5 : Implementations based on HomePlug AV specification Version 1.1
+ // shall discard all MMEs with MMV greater than 0x01
+ if (recv_mme_header->un_mmv.u32 > 1)
+ header_size = (-1);
+
+ bitstream_access(&bstr_ctx,&(recv_mme_header->un_mmtype.u32),16);
+ bitstream_access(&bstr_ctx,&(recv_mme_header->un_fmi.u32),16);
+ bitstream_finalise(&bstr_ctx);
+
+ big_to_cpuhost_endian(&(recv_mme_header->un_osa.b[0]),MAC_ADDR_SIZE);
+ big_to_cpuhost_endian(&(recv_mme_header->un_oda.b[0]),MAC_ADDR_SIZE);
+ big_to_cpuhost_endian(&(recv_mme_header->un_vlan_tag.b[0]),4);
+ big_to_cpuhost_endian(&(recv_mme_header->un_mtype.b[0]),2);
+ little_to_cpuhost_endian(&(recv_mme_header->un_mmtype.b[0]),4);
+
+ if (header_size != (-1))
+ printf
+ ("%u /* VALID MME HEADER (len = %u bytes) :\n",cyg_hal_sys_getpid(),header_size);
+ else
+ printf
+ ("%u /* INVALID MME HEADER :\n",cyg_hal_sys_getpid());
+
+ display_mme_header(recv_mme_header);
+
+ if (header_size == (-1))
+ {
+ printf ("%u /*\n",cyg_hal_sys_getpid());
+ printf ("%u /* => IGNORING THIS INVALID MESSAGE !\n",cyg_hal_sys_getpid());
+ printf ("%u /*\n",cyg_hal_sys_getpid());
+ }
+ return header_size;
+}
+
+/***
+ * \brief Dump MME specific payload data.
+ *
+ * \param buffer the MME message buffer
+ * \param mme_header_len the length of MME header
+ * \param mme_data_len the length of MME data
+ */
+void
+mme_payload_hexdump(u8 *buffer,int mme_header_len,int mme_data_len)
+{
+ int i, j;
+
+ j = 0;
+ printf("%u /* ",cyg_hal_sys_getpid());
+ for (i = 0; i < (mme_data_len / 16); i++)
+ {
+ for (j = 0; j < 16; j++) printf ("%02x.",buffer[mme_header_len+(i*16)+j]);
+ printf("\n");
+ printf("%u /* ",cyg_hal_sys_getpid());
+ }
+ for (i = 0; i < (mme_data_len % 16); i++)
+ {
+ printf ("%02x.",buffer[mme_header_len+(j*16)+i]);
+ }
+ printf("\n");
+}
+
+/***
+ * \brief Build and send a ".CNF" MME message.
+ *
+ * \param msg_ctx the incoming MME message context
+ * \param recv_mme_header the incoming MME header working data structure
+ * \param cnf_result the CNF result field value
+ * \param cnf_errcode the CNF error code field value
+ * \param send_mme_len pointer to result length of the MME to be sent
+ * \mme_tx_buffer buffer where to build the MME
+ */
+void
+build_and_send_cnf(msg_ctx_t *msg_ctx,
+ mme_header_type *recv_mme_header,
+ mme_drv_cnf_type *send_mme,
+ e_drv_mme_cnf_result cnf_result,
+ e_drv_mme_cnf_errcode cnf_errcode,
+ uint *send_mme_len,
+ u8 *mme_tx_buffer)
+{
+ mfs_tx_t *txmfs;
+ bool txmfs_added;
+
+ /* preparing answer to incoming MME */
+ cp_mme_build_cnf (recv_mme_header,
+ send_mme,
+ cnf_result,
+ cnf_errcode,
+ send_mme_len,
+ mme_tx_buffer,
+ &mme_buffer_first);
+
+ /* as we've finished to work with the buffer associated to received MME, free this buffer... */
+ printf("%u AVANT interface_mme_recv_done()...\n",cyg_hal_sys_getpid());
+ interface_mme_recv_done (cp_sta_global.interface, msg_ctx->cl_mme_data);
+ printf("%u APRES interface_mme_recv_done()...\n",cyg_hal_sys_getpid());
+
+ /* answer to initial OSA (sending the answer to incoming MME) */
+ if (msg_ctx->mfs == (mfs_rx_t *)NULL)
+ {
+ /* (answer = DRV MME ".CNF" for incoming DRV MME ".REQ") */
+ printf("%u AVANT interface_mme_send()...\n",cyg_hal_sys_getpid());
+ interface_mme_send (cp_sta_global.interface, mme_tx_buffer, *send_mme_len, NULL);
+ printf("%u APRES interface_mme_send()...\n",cyg_hal_sys_getpid());
+ }
+ else
+ {
+ /* (answer to other incoming MME) */
+ txmfs = mac_store_mfs_add_tx (cp_sta_global.mac_store, msg_ctx->mfs->common.bcast, true, msg_ctx->mfs->common.tei, MAC_LID_NONE, &txmfs_added);
+
+ /* Vérif MFS : assert si NULL (aucune MFS disponible !?) */
+ dbg_assert (txmfs);
+
+ interface_mme_send (cp_sta_global.interface, mme_tx_buffer, *send_mme_len, txmfs);
+ blk_release (txmfs);
+ blk_release (msg_ctx->mfs);
+ }
+ /* update buffer management data */
+ printf("%u ### AVANT liberation mme_buffer (first = %d ; last = %d ; count = %d) ###\n",
+ cyg_hal_sys_getpid(), mme_buffer_first, mme_buffer_last, mme_buffer_count);
+ mme_buffer_first = (mme_buffer_first + 1) % MME_BUFFER_MAXCOUNT;
+ mme_buffer_count--;
+ printf("%u ### APRES liberation mme_buffer (first = %d ; last = %d ; count = %d) ###\n",
+ cyg_hal_sys_getpid(), mme_buffer_first, mme_buffer_last, mme_buffer_count);
+}
+
+VS_VOID
+process_drv_set_mac_address (VS_VOIDPTR msg)
+{
+ msg_ctx_t *msg_ctx;
+ bitstream_t bstr_ctx;
+ mme_header_type recv_mme_header;
+ int mme_header_len;
+ uint pld_maxlen = MAC_ADDR_SIZE;
+ mme_drv_cnf_type send_mme;
+ uint send_mme_len;
+ e_drv_mme_cnf_result cnf_result;
+ e_drv_mme_cnf_errcode cnf_errcode;
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+ msg_ctx = (msg_ctx_t *)msg;
+
+ /* decode MME header */
+ mme_header_len = read_mme_header(msg_ctx->buffer,&recv_mme_header);
+
+ if (mme_header_len != (-1))
+ {
+ /* dump MME specific payload data */
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* MME PAYLOAD :\n",cyg_hal_sys_getpid());
+ mme_payload_hexdump(msg_ctx->buffer,mme_header_len,pld_maxlen);
+
+ /* decode MME specific payload data and prepare answer to incoming MME */
+ cnf_result = E_DRVMME_RESULT_SUCCESS;
+ cnf_errcode = 0 /*E_DRVMME_ERRCODE_BAD_PARAMETER*/;
+
+ bitstream_init(&bstr_ctx,((u8*)msg_ctx->buffer)+mme_header_len,pld_maxlen,BITSTREAM_READ);
+ cp_sta_global.cp_sta_flash_params.mac_address = 0;
+ bitstream_access(&bstr_ctx,&cp_sta_global.cp_sta_flash_params.mac_address,48);
+ bitstream_finalise(&bstr_ctx);
+#if 0
+ big_to_cpuhost_endian((u8 *)&cp_sta_global.cp_sta_flash_params.mac_address,MAC_ADDR_SIZE);
+ printf("%u /* @MAC ............ %02x:%02x:%02x:%02x:%02x:%02x (0x%016llx)\n",
+ cyg_hal_sys_getpid(),
+ (u8)(cp_sta_global.cp_sta_flash_params.mac_address >> 40),
+ (u8)(cp_sta_global.cp_sta_flash_params.mac_address >> 32),
+ (u8)(cp_sta_global.cp_sta_flash_params.mac_address >> 24),
+ (u8)(cp_sta_global.cp_sta_flash_params.mac_address >> 16),
+ (u8)(cp_sta_global.cp_sta_flash_params.mac_address >> 8),
+ (u8)(cp_sta_global.cp_sta_flash_params.mac_address ),
+ cp_sta_global.cp_sta_flash_params.mac_address
+ );
+#else
+ printf("%u /* @MAC ............ %02x:%02x:%02x:%02x:%02x:%02x (0x%016llx)\n",
+ cyg_hal_sys_getpid(),
+ (u8)(cp_sta_global.cp_sta_flash_params.mac_address ),
+ (u8)(cp_sta_global.cp_sta_flash_params.mac_address >> 8),
+ (u8)(cp_sta_global.cp_sta_flash_params.mac_address >> 16),
+ (u8)(cp_sta_global.cp_sta_flash_params.mac_address >> 24),
+ (u8)(cp_sta_global.cp_sta_flash_params.mac_address >> 32),
+ (u8)(cp_sta_global.cp_sta_flash_params.mac_address >> 40),
+ cp_sta_global.cp_sta_flash_params.mac_address
+ );
+#endif
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+
+ /* answer to incoming MME (acknowledge MME request) */
+ build_and_send_cnf(msg_ctx,
+ &recv_mme_header,
+ &send_mme,
+ cnf_result,
+ cnf_errcode,
+ &send_mme_len,
+ mme_tx_buffer[mme_buffer_first]);
+ }
+
+}
+
+VS_VOID
+process_drv_set_avln_hfid (VS_VOIDPTR msg)
+{
+ msg_ctx_t *msg_ctx;
+ bitstream_t bstr_ctx;
+ mme_header_type recv_mme_header;
+ int mme_header_len;
+ uint pld_maxlen = MAX_HFID_SIZE;
+ mme_drv_cnf_type send_mme;
+ uint send_mme_len;
+ e_drv_mme_cnf_result cnf_result;
+ e_drv_mme_cnf_errcode cnf_errcode;
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+ msg_ctx = (msg_ctx_t *)msg;
+
+ /* decode MME header */
+ mme_header_len = read_mme_header(msg_ctx->buffer,&recv_mme_header);
+
+ if (mme_header_len != (-1))
+ {
+ /* dump MME specific payload data */
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* MME PAYLOAD :\n",cyg_hal_sys_getpid());
+ mme_payload_hexdump(msg_ctx->buffer,mme_header_len,pld_maxlen);
+
+ /* decode MME specific payload data and prepare answer to incoming MME */
+ cnf_result = E_DRVMME_RESULT_SUCCESS;
+ cnf_errcode = 0 /*E_DRVMME_ERRCODE_BAD_PARAMETER*/;
+
+ strncpy(cp_sta_global.cp_sta_flash_params.avln_hfid,&msg_ctx->buffer[mme_header_len],MAX_HFID_SIZE);
+ cp_sta_global.cp_sta_flash_params.avln_hfid[MAX_HFID_SIZE] = '\0';
+ if (!check_password_or_hfid_is_valid(cp_sta_global.cp_sta_flash_params.avln_hfid,0,MAX_HFID_SIZE))
+ {
+ cnf_result = E_DRVMME_RESULT_FAILURE;
+ cnf_errcode = E_DRVMME_ERRCODE_INVALID_VALUE;
+ }
+
+ printf ("%u /* AVLN_HFID ....... %s\n",cyg_hal_sys_getpid(),cp_sta_global.cp_sta_flash_params.avln_hfid);
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+
+ /* answer to incoming MME (acknowledge MME request) */
+ build_and_send_cnf(msg_ctx,
+ &recv_mme_header,
+ &send_mme,
+ cnf_result,
+ cnf_errcode,
+ &send_mme_len,
+ mme_tx_buffer[mme_buffer_first]);
+ }
+
+}
+
+VS_VOID
+process_drv_set_cco_preference (VS_VOIDPTR msg)
+{
+ msg_ctx_t *msg_ctx;
+ bitstream_t bstr_ctx;
+ mme_header_type recv_mme_header;
+ int mme_header_len;
+ uint pld_maxlen = 1;
+ mme_drv_cnf_type send_mme;
+ uint send_mme_len;
+ e_drv_mme_cnf_result cnf_result;
+ e_drv_mme_cnf_errcode cnf_errcode;
+ u8 cco_pref;
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+ msg_ctx = (msg_ctx_t *)msg;
+
+ /* decode MME header */
+ mme_header_len = read_mme_header(msg_ctx->buffer,&recv_mme_header);
+
+ if (mme_header_len != (-1))
+ {
+ /* dump MME specific payload data */
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* MME PAYLOAD :\n",cyg_hal_sys_getpid());
+ mme_payload_hexdump(msg_ctx->buffer,mme_header_len,pld_maxlen);
+
+ /* decode MME specific payload data and prepare answer to incoming MME */
+ cnf_result = E_DRVMME_RESULT_SUCCESS;
+ cnf_errcode = 0 /*E_DRVMME_ERRCODE_BAD_PARAMETER*/;
+
+ bitstream_init(&bstr_ctx,((u8*)msg_ctx->buffer)+mme_header_len,pld_maxlen,BITSTREAM_READ);
+ bitstream_access(&bstr_ctx,&cco_pref,8);
+ bitstream_finalise(&bstr_ctx);
+
+ if (cco_pref == 0)
+ cp_sta_global.cp_sta_flash_params.cco_preference = false;
+ else if (cco_pref == 1)
+ cp_sta_global.cp_sta_flash_params.cco_preference = true;
+ else
+ {
+ cp_sta_global.cp_sta_flash_params.cco_preference = false;
+ cnf_result = E_DRVMME_RESULT_FAILURE;
+ cnf_errcode = E_DRVMME_ERRCODE_INVALID_VALUE;
+ }
+
+ printf ("%u /* preferred CCo ... %s\n",cyg_hal_sys_getpid(),get_str_yes_no(cp_sta_global.cp_sta_flash_params.cco_preference));
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+
+ /* answer to incoming MME (acknowledge MME request) */
+ build_and_send_cnf(msg_ctx,
+ &recv_mme_header,
+ &send_mme,
+ cnf_result,
+ cnf_errcode,
+ &send_mme_len,
+ mme_tx_buffer[mme_buffer_first]);
+ }
+
+}
+
+VS_VOID
+process_drv_set_dpw_req (VS_VOIDPTR msg)
+{
+ msg_ctx_t *msg_ctx;
+ bitstream_t bstr_ctx;
+ mme_header_type recv_mme_header;
+ int mme_header_len;
+ uint pld_maxlen = MAX_PWD_SIZE;
+ mme_drv_cnf_type send_mme;
+ uint send_mme_len;
+ e_drv_mme_cnf_result cnf_result;
+ e_drv_mme_cnf_errcode cnf_errcode;
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+ msg_ctx = (msg_ctx_t *)msg;
+
+ /* decode MME header */
+ mme_header_len = read_mme_header(msg_ctx->buffer,&recv_mme_header);
+
+ if (mme_header_len != (-1))
+ {
+ /* dump MME specific payload data */
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* MME PAYLOAD :\n",cyg_hal_sys_getpid());
+ mme_payload_hexdump(msg_ctx->buffer,mme_header_len,pld_maxlen);
+
+ /* decode MME specific payload data and prepare answer to incoming MME */
+ cnf_result = E_DRVMME_RESULT_SUCCESS;
+ cnf_errcode = 0 /*E_DRVMME_ERRCODE_BAD_PARAMETER*/;
+
+ strncpy(cp_sta_global.cp_sta_flash_params.dpw,&msg_ctx->buffer[mme_header_len],MAX_PWD_SIZE);
+ cp_sta_global.cp_sta_flash_params.dpw[MAX_PWD_SIZE] = '\0';
+ if (!check_password_or_hfid_is_valid(cp_sta_global.cp_sta_flash_params.dpw,0,MAX_PWD_SIZE))
+ {
+ cnf_result = E_DRVMME_RESULT_FAILURE;
+ cnf_errcode = E_DRVMME_ERRCODE_INVALID_VALUE;
+ }
+
+ printf ("%u /* DPW ............. %s\n",cyg_hal_sys_getpid(),cp_sta_global.cp_sta_flash_params.dpw);
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+
+ /* answer to incoming MME (acknowledge MME request) */
+ build_and_send_cnf(msg_ctx,
+ &recv_mme_header,
+ &send_mme,
+ cnf_result,
+ cnf_errcode,
+ &send_mme_len,
+ mme_tx_buffer[mme_buffer_first]);
+ }
+
+}
+
+VS_VOID
+process_drv_set_m_sta_hfid (VS_VOIDPTR msg)
+{
+ msg_ctx_t *msg_ctx;
+ bitstream_t bstr_ctx;
+ mme_header_type recv_mme_header;
+ int mme_header_len;
+ uint pld_maxlen = MAX_HFID_SIZE;
+ mme_drv_cnf_type send_mme;
+ uint send_mme_len;
+ e_drv_mme_cnf_result cnf_result;
+ e_drv_mme_cnf_errcode cnf_errcode;
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+ msg_ctx = (msg_ctx_t *)msg;
+
+ /* decode MME header */
+ mme_header_len = read_mme_header(msg_ctx->buffer,&recv_mme_header);
+
+ if (mme_header_len != (-1))
+ {
+ /* dump MME specific payload data */
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* MME PAYLOAD :\n",cyg_hal_sys_getpid());
+ mme_payload_hexdump(msg_ctx->buffer,mme_header_len,pld_maxlen);
+
+ /* decode MME specific payload data and prepare answer to incoming MME */
+ cnf_result = E_DRVMME_RESULT_SUCCESS;
+ cnf_errcode = 0 /*E_DRVMME_ERRCODE_BAD_PARAMETER*/;
+
+ strncpy(cp_sta_global.cp_sta_flash_params.m_sta_hfid,&msg_ctx->buffer[mme_header_len],MAX_HFID_SIZE);
+ cp_sta_global.cp_sta_flash_params.m_sta_hfid[MAX_HFID_SIZE] = '\0';
+ if (!check_password_or_hfid_is_valid(cp_sta_global.cp_sta_flash_params.m_sta_hfid,0,MAX_HFID_SIZE))
+ {
+ cnf_result = E_DRVMME_RESULT_FAILURE;
+ cnf_errcode = E_DRVMME_ERRCODE_INVALID_VALUE;
+ }
+
+ printf ("%u /* M_STA_HFID ...... %s\n",cyg_hal_sys_getpid(),cp_sta_global.cp_sta_flash_params.m_sta_hfid);
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+
+ /* answer to incoming MME (acknowledge MME request) */
+ build_and_send_cnf(msg_ctx,
+ &recv_mme_header,
+ &send_mme,
+ cnf_result,
+ cnf_errcode,
+ &send_mme_len,
+ mme_tx_buffer[mme_buffer_first]);
+ }
+
+}
+
+VS_VOID process_drv_set_nid (VS_VOIDPTR msg)
+{
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+
+}
+
+VS_VOID process_drv_set_npw (VS_VOIDPTR msg)
+{
+ msg_ctx_t *msg_ctx;
+ bitstream_t bstr_ctx;
+ mme_header_type recv_mme_header;
+ int mme_header_len;
+ uint pld_maxlen = MAX_PWD_SIZE;
+ mme_drv_cnf_type send_mme;
+ uint send_mme_len;
+ e_drv_mme_cnf_result cnf_result;
+ e_drv_mme_cnf_errcode cnf_errcode;
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+ msg_ctx = (msg_ctx_t *)msg;
+
+ /* decode MME header */
+ mme_header_len = read_mme_header(msg_ctx->buffer,&recv_mme_header);
+
+ if (mme_header_len != (-1))
+ {
+ /* dump MME specific payload data */
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* MME PAYLOAD :\n",cyg_hal_sys_getpid());
+ mme_payload_hexdump(msg_ctx->buffer,mme_header_len,pld_maxlen);
+
+ /* decode MME specific payload data and prepare answer to incoming MME */
+ cnf_result = E_DRVMME_RESULT_SUCCESS;
+ cnf_errcode = 0 /*E_DRVMME_ERRCODE_BAD_PARAMETER*/;
+
+ strncpy(cp_sta_global.cp_sta_flash_params.npw,&msg_ctx->buffer[mme_header_len],MAX_PWD_SIZE);
+ cp_sta_global.cp_sta_flash_params.npw[MAX_PWD_SIZE] = '\0';
+ if (!check_password_or_hfid_is_valid(cp_sta_global.cp_sta_flash_params.npw,MIN_NPW_SIZE,MAX_PWD_SIZE))
+ {
+ cnf_result = E_DRVMME_RESULT_FAILURE;
+ cnf_errcode = E_DRVMME_ERRCODE_INVALID_VALUE;
+ }
+
+ printf ("%u /* NPW ............. %s\n",cyg_hal_sys_getpid(),cp_sta_global.cp_sta_flash_params.npw);
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+
+ /* answer to incoming MME (acknowledge MME request) */
+ build_and_send_cnf(msg_ctx,
+ &recv_mme_header,
+ &send_mme,
+ cnf_result,
+ cnf_errcode,
+ &send_mme_len,
+ mme_tx_buffer[mme_buffer_first]);
+ }
+
+}
+
+VS_VOID process_drv_set_sl (VS_VOIDPTR msg)
+{
+ msg_ctx_t *msg_ctx;
+ bitstream_t bstr_ctx;
+ mme_header_type recv_mme_header;
+ int mme_header_len;
+ uint pld_maxlen = 1;
+ mme_drv_cnf_type send_mme;
+ uint send_mme_len;
+ e_drv_mme_cnf_result cnf_result;
+ e_drv_mme_cnf_errcode cnf_errcode;
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+ msg_ctx = (msg_ctx_t *)msg;
+
+ /* decode MME header */
+ mme_header_len = read_mme_header(msg_ctx->buffer,&recv_mme_header);
+
+ if (mme_header_len != (-1))
+ {
+ /* dump MME specific payload data */
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* MME PAYLOAD :\n",cyg_hal_sys_getpid());
+ mme_payload_hexdump(msg_ctx->buffer,mme_header_len,pld_maxlen);
+
+ /* decode MME specific payload data and prepare answer to incoming MME */
+ cnf_result = E_DRVMME_RESULT_SUCCESS;
+ cnf_errcode = 0 /*E_DRVMME_ERRCODE_BAD_PARAMETER*/;
+
+ if (msg_ctx->buffer[mme_header_len] <= 2)
+ cp_sta_global.cp_sta_flash_params.sl = msg_ctx->buffer[mme_header_len];
+ else
+ {
+ cp_sta_global.cp_sta_flash_params.sl = 0;
+ cnf_result = E_DRVMME_RESULT_FAILURE;
+ cnf_errcode = E_DRVMME_ERRCODE_INVALID_VALUE;
+ }
+ printf ("%u /* SL .............. %u\n",cyg_hal_sys_getpid(),cp_sta_global.cp_sta_flash_params.sl);
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+
+ /* answer to incoming MME (acknowledge MME request) */
+ build_and_send_cnf(msg_ctx,
+ &recv_mme_header,
+ &send_mme,
+ cnf_result,
+ cnf_errcode,
+ &send_mme_len,
+ mme_tx_buffer[mme_buffer_first]);
+ }
+
+}
+
+VS_VOID process_drv_set_snid (VS_VOIDPTR msg)
+{
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+
+}
+
+VS_VOID process_drv_set_tonemask (VS_VOIDPTR msg)
+{
+ msg_ctx_t *msg_ctx;
+ bitstream_t bstr_ctx;
+ mme_header_type recv_mme_header;
+ int mme_header_len;
+ uint pld_maxlen;
+ mme_drv_cnf_type send_mme;
+ uint send_mme_len;
+ e_drv_mme_cnf_result cnf_result;
+ e_drv_mme_cnf_errcode cnf_errcode;
+ u16 tonemask_offset;
+ u16 tonemask_length_in_bits;
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+ msg_ctx = (msg_ctx_t *)msg;
+
+ /* decode MME header */
+ mme_header_len = read_mme_header(msg_ctx->buffer,&recv_mme_header);
+
+ if (mme_header_len != (-1))
+ {
+ /* dump MME specific payload data */
+ pld_maxlen = 4 + (((msg_ctx->buffer[26] + (256 * msg_ctx->buffer[27])) + 7) / 8);
+
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* MME PAYLOAD :\n",cyg_hal_sys_getpid());
+ mme_payload_hexdump(msg_ctx->buffer,mme_header_len,pld_maxlen);
+
+ /* decode MME specific payload data and prepare answer to incoming MME */
+ cnf_result = E_DRVMME_RESULT_SUCCESS;
+ cnf_errcode = 0 /*E_DRVMME_ERRCODE_BAD_PARAMETER*/;
+
+ tonemask_offset = (u16)msg_ctx->buffer[mme_header_len]+256*(u16)msg_ctx->buffer[mme_header_len+1];
+ tonemask_length_in_bits = (u16)msg_ctx->buffer[mme_header_len+2]+256*(u16)msg_ctx->buffer[mme_header_len+3];
+ printf("%u /* tonemask cfg .... offset = %u ; length (in bits) = %u\n",
+ cyg_hal_sys_getpid(),
+ tonemask_offset,
+ tonemask_length_in_bits);
+ if ( ((tonemask_length_in_bits+7)/8) > TONEMASK_MAXSIZE)
+ {
+ cnf_result = E_DRVMME_RESULT_FAILURE;
+ cnf_errcode = E_DRVMME_ERRCODE_INVALID_VALUE;
+ }
+ printf ("%u /* tonemask ........ (see payload dump)\n",cyg_hal_sys_getpid());
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+
+ /* answer to incoming MME (acknowledge MME request) */
+ build_and_send_cnf(msg_ctx,
+ &recv_mme_header,
+ &send_mme,
+ cnf_result,
+ cnf_errcode,
+ &send_mme_len,
+ mme_tx_buffer[mme_buffer_first]);
+ }
+
+}
+
+VS_VOID process_drv_set_u_sta_hfid (VS_VOIDPTR msg)
+{
+ msg_ctx_t *msg_ctx;
+ bitstream_t bstr_ctx;
+ mme_header_type recv_mme_header;
+ int mme_header_len;
+ uint pld_maxlen = MAX_HFID_SIZE;
+ mme_drv_cnf_type send_mme;
+ uint send_mme_len;
+ e_drv_mme_cnf_result cnf_result;
+ e_drv_mme_cnf_errcode cnf_errcode;
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+ msg_ctx = (msg_ctx_t *)msg;
+
+ /* decode MME header */
+ mme_header_len = read_mme_header(msg_ctx->buffer,&recv_mme_header);
+
+ if (mme_header_len != (-1))
+ {
+ /* dump MME specific payload data */
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* MME PAYLOAD :\n",cyg_hal_sys_getpid());
+ mme_payload_hexdump(msg_ctx->buffer,mme_header_len,pld_maxlen);
+
+ /* decode MME specific payload data and prepare answer to incoming MME */
+ cnf_result = E_DRVMME_RESULT_SUCCESS;
+ cnf_errcode = 0 /*E_DRVMME_ERRCODE_BAD_PARAMETER*/;
+
+ strncpy(cp_sta_global.cp_sta_flash_params.u_sta_hfid,&msg_ctx->buffer[mme_header_len],MAX_HFID_SIZE);
+ cp_sta_global.cp_sta_flash_params.u_sta_hfid[MAX_HFID_SIZE] = '\0';
+ if (!check_password_or_hfid_is_valid(cp_sta_global.cp_sta_flash_params.u_sta_hfid,0,MAX_HFID_SIZE))
+ {
+ cnf_result = E_DRVMME_RESULT_FAILURE;
+ cnf_errcode = E_DRVMME_ERRCODE_INVALID_VALUE;
+ }
+
+ printf ("%u /* U_STA_HFID ...... %s\n",cyg_hal_sys_getpid(),cp_sta_global.cp_sta_flash_params.u_sta_hfid);
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+
+ /* answer to incoming MME (acknowledge MME request) */
+ build_and_send_cnf(msg_ctx,
+ &recv_mme_header,
+ &send_mme,
+ cnf_result,
+ cnf_errcode,
+ &send_mme_len,
+ mme_tx_buffer[mme_buffer_first]);
+ }
+
+}
+
+VS_VOID
+process_drv_set_was_cco (VS_VOIDPTR msg)
+{
+ msg_ctx_t *msg_ctx;
+ bitstream_t bstr_ctx;
+ mme_header_type recv_mme_header;
+ int mme_header_len;
+ uint pld_maxlen = 1;
+ mme_drv_cnf_type send_mme;
+ uint send_mme_len;
+ e_drv_mme_cnf_result cnf_result;
+ e_drv_mme_cnf_errcode cnf_errcode;
+ u8 was_cco;
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+ msg_ctx = (msg_ctx_t *)msg;
+
+ /* decode MME header */
+ mme_header_len = read_mme_header(msg_ctx->buffer,&recv_mme_header);
+
+ if (mme_header_len != (-1))
+ {
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* MME PAYLOAD :\n",cyg_hal_sys_getpid());
+ mme_payload_hexdump(msg_ctx->buffer,mme_header_len,pld_maxlen);
+
+ /* decode MME specific payload data and prepare answer to incoming MME */
+ cnf_result = E_DRVMME_RESULT_SUCCESS;
+ cnf_errcode = 0 /*E_DRVMME_ERRCODE_BAD_PARAMETER*/;
+
+ bitstream_init(&bstr_ctx,((u8*)msg_ctx->buffer)+mme_header_len,pld_maxlen,BITSTREAM_READ);
+ bitstream_access(&bstr_ctx,&was_cco,8);
+ bitstream_finalise(&bstr_ctx);
+
+ if (was_cco == 0)
+ cp_sta_global.cp_sta_flash_params.was_cco = false;
+ else if (was_cco == 1)
+ cp_sta_global.cp_sta_flash_params.was_cco = true;
+ else
+ {
+ cp_sta_global.cp_sta_flash_params.was_cco = false;
+ cnf_result = E_DRVMME_RESULT_FAILURE;
+ cnf_errcode = E_DRVMME_ERRCODE_INVALID_VALUE;
+ }
+
+ printf ("%u /* was CCo ......... %s\n",cyg_hal_sys_getpid(),get_str_yes_no(cp_sta_global.cp_sta_flash_params.was_cco));
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+
+ /* answer to incoming MME (acknowledge MME request) */
+ build_and_send_cnf(msg_ctx,
+ &recv_mme_header,
+ &send_mme,
+ cnf_result,
+ cnf_errcode,
+ &send_mme_len,
+ mme_tx_buffer[mme_buffer_first]);
+ }
+
+}
+
+VS_VOID process_drv_start_mac_req (VS_VOIDPTR msg)
+{
+ msg_ctx_t *msg_ctx;
+ mme_header_type recv_mme_header;
+ int mme_header_len;
+ uint pld_maxlen = 0;
+ mme_drv_cnf_type send_mme;
+ uint send_mme_len;
+ e_drv_mme_cnf_result cnf_result;
+ e_drv_mme_cnf_errcode cnf_errcode;
+ E_ErrCode ret;
+ int i;
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+ msg_ctx = (msg_ctx_t *)msg;
+
+ /* decode MME header */
+ mme_header_len = read_mme_header(msg_ctx->buffer,&recv_mme_header);
+
+ if (mme_header_len != (-1))
+ {
+ /* dump MME specific payload data */
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* MME PAYLOAD :\n",cyg_hal_sys_getpid());
+ mme_payload_hexdump(msg_ctx->buffer,mme_header_len,pld_maxlen);
+
+ /* decode MME specific payload data and prepare answer to incoming MME */
+ cnf_result = E_DRVMME_RESULT_SUCCESS;
+ cnf_errcode = 0 /*E_DRVMME_ERRCODE_BAD_PARAMETER*/;
+ /* (no MME specific payload data to decode)*/
+
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+
+ /* acknowledge MME request (acknowledge MME request) */
+ build_and_send_cnf(msg_ctx,
+ &recv_mme_header,
+ &send_mme,
+ cnf_result,
+ cnf_errcode,
+ &send_mme_len,
+ mme_tx_buffer[mme_buffer_first]);
+
+ /*
+ * TODO : init some cp_sta_secu_params parameters from flash parameters
+ * and then, we shall/can start...
+ */
+ ret = secu_npw2nmk(cp_sta_global.cp_sta_flash_params.npw, cp_sta_global.cp_sta_secu_params.nmk);
+ ret = secu_nmk2nid(cp_sta_global.cp_sta_secu_params.nmk, cp_sta_global.cp_sta_flash_params.sl, cp_sta_global.cp_sta_secu_params.nid);
+ memcpy(&cp_sta_global.nid,cp_sta_global.cp_sta_secu_params.nid,7);
+ //cp_sta_global.nid = cp_sta_global.nid >> 8;
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* STA params defined from NPW :\n",cyg_hal_sys_getpid());
+ printf ("%u /* NMK_HS .......... ",cyg_hal_sys_getpid());
+ for (i = 0; i < 16; i++) printf("%02x.",cp_sta_global.cp_sta_secu_params.nmk[i]);
+ printf ("\n");
+ printf ("%u /* NID ............. ",cyg_hal_sys_getpid());
+ for (i = 0; i < 7; i++) printf("%02x.",cp_sta_global.cp_sta_secu_params.nid[i]);
+ printf (" (0x%016llx)",cp_sta_global.nid);
+ printf ("\n");
+ }
+
+}
+
+VS_VOID process_drv_stop_mac_req (VS_VOIDPTR msg)
+{
+ msg_ctx_t *msg_ctx;
+ mme_header_type recv_mme_header;
+ int mme_header_len;
+ uint pld_maxlen = 0;
+ mme_drv_cnf_type send_mme;
+ uint send_mme_len;
+ e_drv_mme_cnf_result cnf_result;
+ e_drv_mme_cnf_errcode cnf_errcode;
+
+ diag_printf("%u %s()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ dbg_assert(msg);
+ msg_ctx = (msg_ctx_t *)msg;
+
+ /* decode MME header */
+ mme_header_len = read_mme_header(msg_ctx->buffer,&recv_mme_header);
+
+ if (mme_header_len != (-1))
+ {
+ /* dump MME specific payload data */
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+ printf ("%u /* MME PAYLOAD :\n",cyg_hal_sys_getpid());
+ mme_payload_hexdump(msg_ctx->buffer,mme_header_len,pld_maxlen);
+
+ /* decode MME specific payload data and prepare answer to incoming MME */
+ cnf_result = E_DRVMME_RESULT_SUCCESS;
+ cnf_errcode = 0 /*E_DRVMME_ERRCODE_BAD_PARAMETER*/;
+ /* (no MME specific payload data to decode)*/
+
+ printf ("%u /***************************************************/\n",cyg_hal_sys_getpid());
+
+ /* acknowledge MME request (acknowledge MME request) */
+ build_and_send_cnf(msg_ctx,
+ &recv_mme_header,
+ &send_mme,
+ cnf_result,
+ cnf_errcode,
+ &send_mme_len,
+ mme_tx_buffer[mme_buffer_first]);
+ }
+
+}
diff --git a/cesar/cp/station/src/station_apivs.c b/cesar/cp/station/src/station_apivs.c
new file mode 100644
index 0000000000..3a4df197da
--- /dev/null
+++ b/cesar/cp/station/src/station_apivs.c
@@ -0,0 +1,148 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/station/src/station_apivs.c
+ * \brief here are all the functions to control the visual state fsm
+ * \ingroup cp_station
+ */
+
+
+#include "common/std.h"
+
+#include "cp/beacon/inc/bentry.h"
+#include "cp/beacon/inc/beacons_ctx.h"
+#include "cp/beacon/forward.h"
+#include "cp/beacon/inc/beacons_work.h"
+
+#include "cp/station/inc/station_apivs.h"
+
+
+
+// Define SEM_CONTEXT storage
+static SEM_CONTEXT *pSEMContext;
+
+
+void
+cp_station_init_fsm(void)
+{
+ // Define completion code storage
+ unsigned char cc;
+
+ //printf("%s\n", __FUNCTION__);
+ // Initialize the VS System.
+ if ((cc = SMP_Connect(&pSEMContext, &main_fsm)) != SES_OKAY)
+ dbg_assert(0); // error handling
+ // Initialize all needed data
+ main_fsmSMP_InitAll(&pSEMContext);
+ // send the reset event to the fsm
+ if(cp_station_add_event(SE_RESET, NULL) != EV_OK) dbg_assert(0);
+}
+
+
+
+void
+cp_station_process_fsm_event(void)
+{
+ msg_ctx_t *msg_ctx;
+ event_t event;
+ // Define completion code storage
+ unsigned char cc;
+ // Define action expression variable.
+ SEM_ACTION_EXPRESSION_TYPE actionExpressNo;
+
+ dbg_assert(pSEMContext);
+ //printf("%s\n", __FUNCTION__);
+ // get the event from the handler
+ while(cp_station_get_event(&event) != EV_QUEUE_EMPTY)
+ {
+ //printf("event type : 0x%x\n", event.event_type);
+ // Deduct the event
+ if ((cc = main_fsmSMP_Deduct(pSEMContext, event.event_type, event.mme_address)) != SES_OKAY)
+ dbg_assert(0); // error handling
+ // Get resulting action expressions and execute them.
+ while ((cc = SMP_GetOutput(pSEMContext, &actionExpressNo)) == SES_FOUND)
+ {
+ //printf("SMP_GetOutput : context %i, mainVSaction %i, actionexpressno %i\n", pSEMContext, MainVSAction , actionExpressNo);
+ SMP_TableAction(pSEMContext, MainVSAction , actionExpressNo);
+ }
+ if (cc != SES_OKAY)
+ dbg_assert(0); // error handling
+ // Change the next state vector.
+ if ((cc = SMP_NextState(pSEMContext)) != SES_OKAY)
+ dbg_assert(0); // error handling
+ // finaly, free the message buffer (if ir exist)
+ if(event.mme_address)
+ {
+ msg_ctx = (msg_ctx_t *)event.mme_address;
+ //dbg_assert ( !msg_check_wrong_mme_const_values (event.mme_address));
+ dbg_assert ( !msg_check_wrong_mme_const_values ((msg_mme_t *)msg_ctx->buffer));
+#if 0
+ interf_release_buf(event.mme_address);
+#else
+ /* TODO : (re)faire le (bon) release ici ? ... */
+#endif
+ }
+ }
+}
+
+
+// this function is for test purpose only
+void
+cp_station_test_fsm(void)
+{
+/* msg_mme_t *msg;
+ msg_param_t msg_param;
+
+ msg = msg_sending_common_part("ABCEFG", &msg_param);
+
+
+ printf("start of fsm test\n");
+ // send the reset event to the fsm
+ if(sta_add_event(SE_RESET, NULL) != EV_OK) dbg_assert(0);
+ station_process_fsm_event();
+ station_print_fsm_states();
+ // send the USTA event to the fsm
+ if(sta_add_event(TO_USTA, NULL) != EV_OK) dbg_assert(0);
+ station_process_fsm_event();
+ station_print_fsm_states();
+ // set the fsm to UCCO
+ if(sta_add_event(BEACON_TIMER_EXPIRES, NULL) != EV_OK) dbg_assert(0);
+ station_process_fsm_event();
+ station_print_fsm_states();
+ // go to associated sta state
+ if(sta_add_event(SE_RESET, NULL) != EV_OK) dbg_assert(0);
+ if(sta_add_event(TO_STA, msg) != EV_OK) dbg_assert(0);
+ station_process_fsm_event();
+ station_print_fsm_states();
+ // go to CCO
+ if(sta_add_event(BECOME_BACKUP_CCO, NULL) != EV_OK) dbg_assert(0);
+ if(sta_add_event(BEACON_TIMER_EXPIRES, NULL) != EV_OK) dbg_assert(0);
+ station_process_fsm_event();
+ station_print_fsm_states();
+ */
+}
+
+
+// this function is for test purpose only
+void
+cp_station_print_fsm_states(void)
+{
+ SEM_STATE_MACHINE_TYPE i;
+ SEM_STATE_TYPE StateNo = STATE_UNDEFINED;
+
+ for (i = 0 ; i < VS_NOF_STATE_MACHINES ; i++)
+ {
+ if (SMP_State (pSEMContext, i, &StateNo) != SES_FOUND)
+ printf ("\nState machine is in undefined state\n");
+ else
+ printf ("%2d ; ", StateNo);
+ }
+ printf("\n");
+}
+
+
diff --git a/cesar/cp/station/src/station_core.c b/cesar/cp/station/src/station_core.c
new file mode 100644
index 0000000000..0e01c21721
--- /dev/null
+++ b/cesar/cp/station/src/station_core.c
@@ -0,0 +1,265 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/station/src/station_fsm.c
+ * \brief finite state machine and main loop of the thread station
+ * \ingroup cp_station
+ */
+
+#include "common/std.h"
+
+#include "cp/beacon/inc/bentry.h"
+
+#include "cp/beacon/beacons.h"
+#include "cp/beacon/inc/beacons_ctx.h"
+#include "cp/beacon/forward.h"
+#include "cp/beacon/inc/beacons_work.h"
+
+#include "cp/station/station.h"
+
+extern cp_sta_t cp_sta_global;
+
+/*
+ * global variables of station module
+ */
+// this is for the STA events
+cyg_flag_t station_flag;
+// the seed used for random numbers
+uint station_seed = 894;
+
+
+/*
+ * locale variables
+ */
+const station_event_t station_event[] =
+ {
+ { STATION_FLAG_MSG_RCV, interf_received },
+ { STATION_FLAG_BUF_REL, interf_buf_to_release },
+// { STATION_FLAG_USTT, station_ustt_expires},
+ //{ STATION_FLAG_PERIODIC_UNASSO, station_send_cm_unassoc_sta_mme_periodicaly },
+ //{ STATION_FLAG_MSG_RCV_STA, msg_dispatch}
+ { STATION_FLAG_FSM, cp_station_process_fsm_event}
+ };
+static alarm_def_t alarm_def[ALARM_NB];
+static cyg_mutex_t alarm_lock;
+// variable for counter and alarm
+cyg_handle_t real_time_counter;
+cyg_handle_t real_time_clock_handle;
+
+/*
+ * functions of station module
+ */
+
+void
+cp_station_init (mac_store_t *mac_store_ctx, cl_t *interf_cl_ctx, pbproc_t *pbproc_ctx, ca_t *ca_ctx)
+{
+ uint i;
+ // init the counter
+ real_time_clock_handle = cyg_real_time_clock();
+ cyg_clock_to_counter(real_time_clock_handle, &real_time_counter);
+ // 1) init the station module
+ // init the event
+ printf("%u %s() : AVANT cyg_flag_init()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ cyg_flag_init (&station_flag);
+ printf("%u %s() : APRES cyg_flag_init()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ // init the alarm
+ for(i=0 ; i<COUNT(alarm_def) ; i++)
+ alarm_def[i].alarm_used = false;
+ cyg_mutex_init( & alarm_lock);
+ // init the sta handler
+ cp_station_initialize_handler();
+ // initialize the station data
+ cp_station_data_init(mac_store_ctx, interf_cl_ctx, pbproc_ctx);
+
+ // TODO init station_seed
+ // wait 60 ms for some zero cross (to calculate network frequency)
+// #if DEBUG == 0
+// cyg_thread_delay (interf_ms_to_cyg_tick (60));
+// #endif
+ cp_station_init_fsm();
+ #if DEBUG == 0
+ // TODO remove the following function call when not in debug mode
+ cp_station_mac_start();
+ #endif
+}
+
+
+void
+cp_station_mac_start(void)
+{
+ /*
+ * before "executing" the MAC_START order, derive some internal station parameters
+ * from explicit station parameters obtained from the driver
+ */
+#if 0
+ /* TODO :
+ secu_npw2nmk(,,);
+ secu_nmk2nid(,);
+ */
+ /*
+ * init some cp_sta_secu_params parameters from flash parameters
+ * and then, we shall/can start...
+ */
+ ret = secu_npw2nmk(cp_sta_flash_params.npw, cp_sta_secu_params.nmk);
+ ret = secu_nmk2nid(cp_sta_secu_params.nmk, cp_sta_flash_params.sl, cp_sta_secu_params.nid);
+ printf("/***************************************************/\n");
+ printf("/* STA params defined from NPW :\n");
+ printf("/* NMK_HS .......... ");
+ for (i = 0; i < 16; i++) printf("%02x.",cp_sta_secu_params.nmk[i]);
+ printf("\n");
+ printf("/* NID ............. ");
+ for (i = 0; i < 7; i++) printf("%02x.",cp_sta_secu_params.nid[i]);
+ printf("\n");
+#endif
+
+ /* post the MAC_START order to the station event handler */
+ if(cp_station_add_event(RECEIVE_DRV_MAC_START_REQ, NULL) != EV_OK) dbg_assert(0);
+}
+
+
+void
+cp_station_wait_event (cyg_addrword_t data)
+{
+ cyg_flag_value_t flag_value, flag_mask;
+ uint i;
+
+#if DEBUG
+ printf("%u %s() : CP thread entry-point...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+#endif
+
+ //Power-Line frequency detection (50Hz or 60Hz)
+ printf("%u %s() : AVANT 1er acl_frequency()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ cp_beacon_acl_frequency_detection(cp_sta_global.cp_beacon);
+ printf("%u %s() : APRES 1er acl_frequency()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ cyg_thread_delay(2);
+ printf("%u %s() : AVANT 2em acl_frequency()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ cp_beacon_acl_frequency_detection(cp_sta_global.cp_beacon);
+ printf("%u %s() : APRES 2em acl_frequency()...\n",cyg_hal_sys_getpid(),__FUNCTION__);
+ printf("%u %s() : beacon period (in 25Mhz ticks) = %u\n",cyg_hal_sys_getpid(),__FUNCTION__,cp_sta_global.cp_beacon->pwl.bp_ntb);
+
+ // create the flag mask
+ flag_mask = 0;
+ for(i=0 ; i<COUNT(station_event) ; i++)
+ {
+ flag_mask |= station_event[i].flag_value;
+ }
+ // the infinite loop of the thread
+//#if DEBUG
+// printf("%u %s() : station ready and waiting for event (@station_flag=0x%08lx ; flag_mask=0x%08lx)...\n",cyg_hal_sys_getpid(),__FUNCTION__,(unsigned long)&station_flag,(unsigned long)flag_mask);
+//#endif
+ while (1)
+ {
+#if DEBUG
+ printf("%u %s() : station ready and waiting for event (@station_flag=0x%08lx ; flag_mask=0x%08lx)...\n",cyg_hal_sys_getpid(),__FUNCTION__,(unsigned long)&station_flag,(unsigned long)flag_mask);
+#endif
+ // wait for a station event
+ flag_value = cyg_flag_wait (&station_flag, flag_mask, CYG_FLAG_WAITMODE_OR );
+ printf("%u %s() : flag_value : %x\n",cyg_hal_sys_getpid(),__FUNCTION__,flag_value);
+ // process the event
+ for (i=0; i<COUNT (station_event) ; i++)
+ {
+ if (flag_value & station_event[i].flag_value)
+ {
+ // we find an event, so we clear it
+#if DEBUG
+ printf("%u %s() : we find an event (flag_value=0x%08lx ; flag_mask=0x%08lx)...\n",cyg_hal_sys_getpid(),__FUNCTION__,(unsigned long)flag_value,(unsigned long)flag_mask);
+#endif
+ cyg_flag_maskbits (&station_flag, ~station_event[i].flag_value);
+#if DEBUG
+ printf("%u %s() : ... so, we clear it before we treat it (station_flag=0x%08lx ; flag_mask=0x%08lx)...\n",cyg_hal_sys_getpid(),__FUNCTION__,(unsigned long)*((u32*)&station_flag),(unsigned long)flag_mask);
+#endif
+ // and then we process it
+ dbg_assert (station_event[i].func);
+ station_event[i].func ();
+ }
+ }
+ }
+}
+
+
+
+
+void
+cp_station_gen_timed_event(cyg_flag_t *cyg_flag, station_flag_t station_flag, SEM_EVENT_TYPE event_type, uint event_delay_ms)
+{
+ uint i;
+ cyg_tick_count_t trigger_time;
+
+ dbg_assert(cyg_flag);
+
+cyg_mutex_lock ( & alarm_lock);
+
+ // search for an available alarm
+ for(i=0 ; (i<COUNT(alarm_def)) && (alarm_def[i].alarm_used == true) ; i++);
+ dbg_assert(i<COUNT(alarm_def));
+ alarm_def[i].alarm_used = true;
+
+cyg_mutex_unlock ( & alarm_lock);
+
+ // create the alarm
+ alarm_def[i].cyg_flag = cyg_flag;
+ alarm_def[i].station_flag = station_flag;
+ alarm_def[i].event_type = event_type;
+ cyg_alarm_create ( real_time_counter,
+ cp_station_alarm_handler,
+ i,
+ & alarm_def[i].alarm_handle,
+ & alarm_def[i].alarm
+ );
+ // initialize the alarm
+ trigger_time = interf_ms_to_cyg_tick(event_delay_ms) + cyg_current_time();
+ cyg_alarm_initialize(alarm_def[i].alarm_handle, trigger_time, 0);
+ //printf("%u %s() : create alarm %i at %i\n",cyg_hal_sys_getpid(),__FUNCTION__, i, (int) cyg_current_time());
+}
+
+void
+cp_station_stop_timed_event(cyg_flag_t *cyg_flag, station_flag_t station_flag)
+{
+ uint i;
+
+cyg_mutex_lock ( & alarm_lock);
+
+ // search for the alarm to stop
+ for(i=0 ; i<COUNT(alarm_def) ; i++)
+ if( (alarm_def[i].cyg_flag == cyg_flag)
+ && (alarm_def[i].station_flag == station_flag) ) break;
+ if(i < COUNT(alarm_def))
+ {
+ cyg_alarm_disable(alarm_def[i].alarm_handle);
+ alarm_def[i].alarm_used = false;
+ cyg_flag_maskbits(cyg_flag, ~ station_flag);
+ //printf("%u %s() : delete alarm %i\n",cyg_hal_sys_getpid(),__FUNCTION__, i);
+ }
+
+cyg_mutex_unlock ( & alarm_lock);
+
+}
+
+void
+cp_station_alarm_handler(cyg_handle_t alarm, cyg_addrword_t data)
+// warning : this function is called in DSR context
+{
+ dbg_assert(data < COUNT(alarm_def));
+ dbg_assert(alarm_def[data].cyg_flag);
+
+cyg_mutex_lock ( & alarm_lock);
+
+ // release the alarm
+ alarm_def[data].alarm_used = false;
+ // generate the event
+ cyg_flag_setbits (alarm_def[data].cyg_flag, alarm_def[data].station_flag);
+ //printf("%u %s() : got event at %i\n",cyg_hal_sys_getpid(),__FUNCTION__, (int) cyg_current_time());
+ if(alarm_def[data].station_flag == STATION_FLAG_FSM)
+ {
+ cp_station_add_event(alarm_def[data].event_type, NULL);
+ }
+
+cyg_mutex_unlock ( & alarm_lock);
+
+}
+
diff --git a/cesar/cp/station/src/station_data.c b/cesar/cp/station/src/station_data.c
new file mode 100644
index 0000000000..97d947218c
--- /dev/null
+++ b/cesar/cp/station/src/station_data.c
@@ -0,0 +1,577 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/station/src/station_data.c
+ * \brief
+ * \ingroup cp_station
+ */
+
+#include "common/std.h"
+
+#include "cp/beacon/beacons.h"
+#include "cp/beacon/inc/beacons_ctx.h"
+#include "cp/beacon/forward.h"
+
+#include "cp/station/station.h"
+
+static avln_t m_avln[MAX_AVLN_NB];
+static u_station_t m_u_sta[MAX_AVLN_NB + MAX_STA_NB];
+static u8 m_tei;
+static u8 m_number_of_assoc_sta;
+static bool m_is_cco;
+
+mac_store_t *m_mac_store_ctx = NULL;
+cl_t *m_cl_ctx = NULL;
+pbproc_t *m_pbproc_ctx = NULL;
+
+
+/*
+cl_t *
+station_get_cl_ctx(void)
+{
+ return m_interf_cl_ctx;
+}
+
+mac_store_t *
+station_get_mac_store_ctx(void)
+{
+ return m_mac_store_ctx;
+}
+*/
+
+nid_t
+cp_station_get_nid(cp_sta_t *ctx)
+{
+#if 0
+ return m_avln[0].nid;
+#else
+ return ctx->nid;
+#endif
+}
+
+snid_t
+cp_station_get_snid(void)
+{
+ return m_avln[0].snid;
+}
+
+u8
+cp_station_get_cco_capa(void)
+{
+ return m_avln[0].sta[m_tei].cco_capa;
+}
+
+u8
+cp_station_get_number_of_assoc(void)
+{
+ return m_number_of_assoc_sta;
+}
+
+void
+cp_station_set_tei(const tei_t new_tei, const u16 lease_time)
+{
+ tei_t old_tei;
+ old_tei = m_tei;
+ m_tei = new_tei;
+ memcpy(&m_avln[0].sta[new_tei], &m_avln[0].sta[old_tei], sizeof(m_avln[0].sta[new_tei]));
+ m_avln[0].sta[new_tei].tei_lease_time = cyg_current_time() + lease_time * MINUTES_TO_TICK_FACTOR;
+}
+
+tei_t
+cp_station_get_tei(void *v)
+{
+ return m_tei;
+}
+
+void
+cp_station_set_mac_address(cp_sta_t *ctx, mac_address_t mac_address)
+{
+#if 0
+ memcpy(m_avln[0].sta[m_tei].mac_address, mac_address, sizeof(mac_address_t));
+#else
+ memcpy(&(ctx->cp_sta_flash_params.mac_address), mac_address, sizeof(mac_address_t));
+#endif
+}
+
+void
+cp_station_get_mac_address(cp_sta_t *ctx, mac_address_t *mac_address)
+{
+#if 0
+ memcpy(mac_address, &m_avln[0].sta[m_tei].mac_address, sizeof(mac_address_t));
+#else
+ memcpy(mac_address, &(ctx->cp_sta_flash_params.mac_address), sizeof(mac_address_t));
+#endif
+}
+
+void
+cp_station_clear_assoc_sta_list(void)
+{
+ memset(m_avln, 0, sizeof(m_avln));
+ m_number_of_assoc_sta = 0;
+}
+
+void
+cp_station_data_init(mac_store_t *mac_store_ctx, cl_t *interf_cl_ctx, pbproc_t *pbproc_ctx)
+{
+ //printf("%s\n", __FUNCTION__);
+ // erase the usta list
+ memset(m_u_sta, 0, sizeof(m_u_sta));
+ // erase the associated stations list
+ cp_station_clear_assoc_sta_list();
+ // set the tei to not attibuted
+ m_tei = 0;
+ m_is_cco = false;
+ m_mac_store_ctx = mac_store_ctx;
+ m_cl_ctx = interf_cl_ctx;
+ m_pbproc_ctx = pbproc_ctx;
+ // TODO remplir les champ nid et snid de m_avln[0]
+ // TODO remplir les champs cco_capa, etc de m_avln[0].sta[0]
+}
+
+void
+cp_station_add_usta(const mac_address_t mac_address, const u8 cco_capa, const nid_t nid)
+{
+ unsigned int i=0;
+
+ //printf("%s\n", __FUNCTION__);
+ // search for the first empty slot
+ while( (memcmp(m_u_sta[i].mac_address, ZEROS_MAC_AD, sizeof(mac_address_t)))
+ && (i<COUNT(m_u_sta)) )
+ i++;
+ // check if a slot was found
+ if(i == COUNT(m_u_sta))
+ {
+ dbg_assert(0);
+ return;
+ }
+ // if yes, fill the blank
+ m_u_sta[i].cco_capa = cco_capa;
+ memcpy(m_u_sta[i].mac_address, mac_address, sizeof(mac_address_t));
+ m_u_sta[i].nid = nid;
+}
+
+process_usta_result_t
+cp_station_process_recorded_usta(void)
+{
+ unsigned int i=0;
+ bool sta_matching_nid = false, become_cco = false;
+ process_usta_result_t process_usta_result;
+ // 7.4.1
+ //printf("%s\n", __FUNCTION__);
+ while( (memcmp(m_u_sta[i].mac_address, ZEROS_MAC_AD, sizeof(mac_address_t)))
+ && (i<COUNT(m_u_sta)) )
+ {
+ process_usta_result = cp_station_process_usta(m_u_sta[i].mac_address, m_u_sta[i].cco_capa, m_u_sta[i].nid);
+ if(process_usta_result == USTA_MATCHING_NID)
+ {
+ sta_matching_nid = true;
+ become_cco = false;
+ }
+ if( (process_usta_result == BECOME_CCO) && ( ! sta_matching_nid) )
+ {
+ become_cco = true;
+ }
+ i++;
+ }
+ if(become_cco) return BECOME_CCO;
+ if(sta_matching_nid) return USTA_MATCHING_NID;
+ return CHECK_EXISTING_OTHER_AVLN;
+}
+
+
+process_usta_result_t
+cp_station_process_usta(const mac_address_t mac_address, const u8 cco_capa, const nid_t nid)
+{
+ // check if the nid match
+ //printf("%s\n", __FUNCTION__);
+ if(nid == m_avln[0].nid)
+ {
+ // TODO : reply to the question : what if the station is
+ // user prefered cco but has lesser capability ???
+ // check if the other sta had better cco capability
+ if(cco_capa < m_avln[0].sta[m_tei].cco_capa)
+ {
+ return BECOME_CCO;
+ }
+ // if not, check if the other sta had same capability but upper mac adress
+ if( (cco_capa == m_avln[0].sta[m_tei].cco_capa)
+ && (memcmp(mac_address, m_avln[0].sta[m_tei].mac_address, sizeof(mac_address_t)) < 0) )
+ {
+ return BECOME_CCO;
+ }
+ // the other sta has matching nid, but we should not become cco
+ return USTA_MATCHING_NID;
+ }
+ return CHECK_EXISTING_OTHER_AVLN;
+}
+
+void
+cp_station_add_avln(const nid_t nid, const snid_t snid)
+{
+ int i;
+ //printf("%s\n", __FUNCTION__);
+ // search if the nid is already known
+ for(i=0 ; i<MAX_AVLN_NB ; i++)
+ {
+ if(m_avln[i].nid == nid) return;
+ }
+ // this is a new avln, add it to the list
+ // search for the first empty slot
+ for(i=0 ; i<MAX_AVLN_NB ; i++)
+ {
+ if( ! m_avln[i].nid)
+ {
+ m_avln[i].nid = nid;
+ m_avln[i].snid = snid;
+ return;
+ }
+ }
+ // we should never be here
+ dbg_assert(0);
+}
+
+tei_t
+cp_station_associate_new(const station_t sta)
+{
+ int i=1;
+
+ // check if the station is not already associated
+ while( memcmp(m_avln[0].sta[i].mac_address, sta.mac_address, sizeof(mac_address_t)) && (i<MAX_TEI))
+ {
+ i++;
+ }
+ if(i != MAX_TEI)
+ {
+ // the mac address is already associated
+ dbg_assert(0);
+ return 0;
+ }
+ i=1;
+ // search for a free tei
+ while( memcmp(m_avln[0].sta[i].mac_address, ZEROS_MAC_AD, sizeof(mac_address_t)) && (i<MAX_TEI))
+ {
+ i++;
+ }
+ if(i == MAX_TEI) return 0;
+ cp_station_associate_old(i, sta);
+ return i;
+}
+
+tei_t
+cp_station_renew(const station_t sta)
+{
+ int i = 1;
+
+ // check if the station is associated
+ while( memcmp(m_avln[0].sta[i].mac_address, sta.mac_address, sizeof(mac_address_t)) && (i<MAX_TEI))
+ {
+ i++;
+ }
+ if(i == MAX_TEI)
+ {
+ // the station is not associated
+ dbg_assert(0);
+ return 0;
+ }
+ m_avln[0].sta[i].tei_lease_time = sta.tei_lease_time;
+ return i;
+}
+
+void
+cp_station_associate_old(const tei_t tei, const station_t sta)
+{
+ // check if the slot is blank
+ if( ! memcmp(&m_avln[0].sta[tei].mac_address, ZEROS_MAC_AD, sizeof(mac_address_t)))
+ m_number_of_assoc_sta ++;
+ // add the station to the list
+ memcpy(&m_avln[0].sta[tei], &sta, sizeof(station_t));
+ // add the statio to the mac store
+ // TODO
+ //mac_store_sta_add (m_mac_store_ctx, tei);
+}
+
+void
+cp_station_remove_associated(const tei_t tei)
+{
+ // check if the slot is blank
+ if( ! memcmp(&m_avln[0].sta[tei].mac_address, ZEROS_MAC_AD, sizeof(mac_address_t)))
+ return;
+ // first, remove the station from the mac store
+
+ // then remove the station from the station_data
+ memset(&m_avln[0].sta[tei], 0, sizeof(station_t));
+ if(m_number_of_assoc_sta) m_number_of_assoc_sta --;
+
+
+}
+
+tei_t
+cp_station_get_associate_info(station_t *sta, const bool from_first, const tei_t tei)
+{
+ u8 i;
+ u8 station_pointer;
+
+ dbg_assert(sta);
+ if(from_first)
+ {
+ i = 1;
+ while( ! memcmp(m_avln[0].sta[i].mac_address, ZEROS_MAC_AD, sizeof(mac_address_t)) && (i<THEORICAL_MAX_STA_NB))
+ i++;
+ if(i == THEORICAL_MAX_STA_NB)
+ {
+ bzero(sta, sizeof(station_t));
+ return 0;
+ }
+ // we found a station
+ station_pointer = i+1;
+ memcpy(sta, & m_avln[0].sta[i], sizeof(station_t));
+ }
+ else
+ {
+ dbg_assert(tei);
+ dbg_assert( ! memcmp(m_avln[0].sta[i].mac_address, ZEROS_MAC_AD, sizeof(mac_address_t)));
+ memcpy(sta, & m_avln[0].sta[tei], sizeof(station_t));
+ station_pointer = tei+1;
+ }
+ i = station_pointer;
+ // search for the next sta to find
+ while( ! memcmp(m_avln[0].sta[i].mac_address, ZEROS_MAC_AD, sizeof(mac_address_t)) && (i<THEORICAL_MAX_STA_NB)) i++;
+ if(i == THEORICAL_MAX_STA_NB)
+ {
+ return 0;
+ }
+ // we found a station
+ return i;
+}
+
+tei_t
+cp_station_find_tei_from_mac(const mac_address_t mac_address)
+{
+ int i;
+ // check if the mac address is not the broadcast mac address
+ if( ! memcmp(mac_address, BROADCAST_MAC_AD, sizeof(mac_address_t))) return 0xFF;
+ // check if the mac address is unknown, and in this case use broadcast TEI
+ if( ! memcmp(mac_address, ZEROS_MAC_AD, sizeof(mac_address_t))) return 0xFF;
+ // TODO : what about multicast address ??
+ // search for the TEI of an unicast mac address
+ for(i=0 ; i<THEORICAL_MAX_STA_NB ; i++)
+ if( ! memcmp(mac_address, m_avln[0].sta[i].mac_address, sizeof(mac_address_t))) return i;
+ // if we did not find anything, return the tei broadcast
+ return 0xFF;
+}
+
+/**
+ * \brief set the association status of the station
+ * \param become_associated true to set station in associated station state
+ * \return
+ */
+VS_VOID
+cp_station_set_assoc_status (VS_BOOL become_associated)
+{
+ if(become_associated)
+ m_avln[0].sta[m_tei].station_status = STATION_ASSOCIATED;
+ else m_avln[0].sta[m_tei].station_status = STATION_UNASSOCIATED;
+}
+
+VS_BOOL
+cp_station_get_assoc_status (void)
+{
+ return (m_avln[0].sta[m_tei].station_status == STATION_ASSOCIATED) || (m_avln[0].sta[m_tei].station_status == STATION_AUTHENTICATED);
+}
+
+VS_BOOL
+cp_station_is_associated(cp_sta_t *ctx)
+{
+ return cp_station_get_assoc_status ();
+}
+
+
+cp_station_status_t
+cp_station_get_status(void)
+{
+ return m_avln[0].sta[m_tei].station_status;
+}
+
+/**
+ * \brief set the cco status of the station
+ * \param is_cco true if station is cco
+ * \return
+ */
+VS_VOID
+cp_station_set_cco_status(VS_BOOL is_cco)
+{
+ m_is_cco = is_cco;
+}
+
+bool
+cp_station_get_is_cco(void)
+{
+ return m_is_cco;
+}
+
+bool
+cp_station_get_pcco_capa(void)
+{
+ return m_avln[0].sta[m_tei].proxy_net_capa;
+}
+
+bool
+cp_station_get_backup_cco_capa(void)
+{
+ // TODO a changer quand la fonction est implémentée
+ return false;
+}
+
+/**
+ * \brief set the authentication status of the station
+ * \param become_authenticated true to set station in authenticated station state
+ * \return
+ */
+VS_VOID
+cp_station_set_auth_status (VS_BOOL become_authenticated)
+{
+ if(become_authenticated)
+ m_avln[0].sta[m_tei].station_status = STATION_AUTHENTICATED;
+ else m_avln[0].sta[m_tei].station_status = STATION_ASSOCIATED;
+}
+
+VS_BOOL
+cp_station_get_auth_status (void)
+{
+ return (m_avln[0].sta[m_tei].station_status == STATION_AUTHENTICATED);
+}
+
+VS_BOOL
+cp_station_is_authenticated(cp_sta_t *ctx)
+{
+ return cp_station_get_auth_status ();
+}
+
+bool
+cp_station_get_is_pco(void)
+{
+ // TODO a changer quand la fonction est implémentée
+ return false;
+}
+
+bool
+cp_station_get_is_backup_cco(void)
+{
+ // TODO a changer quand la fonction est implémentée
+ return false;
+}
+
+u16
+cp_station_get_num_discovered_sta(void)
+{
+ u16 count = 0, i, j;
+ for(i=0 ; i<MAX_AVLN_NB ; i++)
+ for(j=0 ; j<THEORICAL_MAX_STA_NB ; j++)
+ if(m_avln[i].sta[j].last_discover_beacon) count ++;
+ return count;
+}
+
+u16
+cp_station_get_num_discovered_avln(void)
+{
+ u16 count = 0, i;
+
+ for(i=0 ; i<MAX_AVLN_NB ; i++)
+ if(m_avln[i].snid) count++;
+ return count;
+}
+
+bool
+cp_station_get_is_user_appointed_cco(void)
+{
+ // TODO a changer quand la fonction est implémentée
+ return false;
+}
+
+/**
+ * Get the Handover in progress status.
+ *
+ * \param sta the station context
+ * \return the handover progress status.
+ */
+bool
+cp_station_get_hoip (cp_sta_t *sta)
+{
+ dbg_assert (sta);
+
+ return sta->hoip;
+}
+
+/**
+ * Set the Handover in progress status.
+ *
+ * \param sta context.
+ * \param hoip handover in progress.
+ */
+void
+cp_station_set_hoip(cp_sta_t *sta, uint hoip)
+{
+ dbg_assert (sta);
+
+ sta->hoip = hoip;
+}
+
+/**
+ * get the rstbf flag
+ *
+ * \param sta the sta context.
+ */
+bool
+cp_station_get_rtsbf(cp_sta_t *sta)
+{
+ dbg_assert (sta);
+
+ return sta->mac_config->rts_broadcast;
+}
+
+/**
+ * Set the sta rtsbf
+ *
+ * \param sta the station context
+ * \param rstbf the flag
+ */
+void
+cp_station_set_rtsbf (cp_sta_t *sta, bool rtsbf)
+{
+ dbg_assert (sta);
+ sta->mac_config->rts_broadcast = true;
+}
+
+/**
+ * Get the number of distant STAs
+ *
+ * \param sta the station context
+ * \return the number of distant stations
+ */
+u8
+cp_station_get_num_dis_sta(cp_sta_t *sta)
+{
+ dbg_assert (sta);
+
+ return sta->numDisSta;
+}
+
+/**
+ * Get number of distant networks.
+ *
+ * \param sta the sta context.
+ * \return the number of distant networks.
+ */
+u8
+cp_station_get_num_dis_net(cp_sta_t *sta)
+{
+ dbg_assert (sta);
+
+ return sta->numDisNet;
+}
+
diff --git a/cesar/cp/station/src/station_event_handler.c b/cesar/cp/station/src/station_event_handler.c
new file mode 100644
index 0000000000..a534a7d7c3
--- /dev/null
+++ b/cesar/cp/station/src/station_event_handler.c
@@ -0,0 +1,76 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}}
+ * \file cp/station/src/station_event_handler.c
+ * \brief a simple event handler
+ * \ingroup cp/station
+ *
+ */
+
+#include "common/std.h"
+
+#include "cp/beacon/beacons.h"
+#include "cp/beacon/inc/beacons_ctx.h"
+#include "cp/beacon/forward.h"
+
+#include "cp/station/inc/station_event_handler.h"
+
+
+static event_t events[EVENT_QUEUE_SIZE];
+static u32 head, tail;
+static cyg_mutex_t mutex_event;
+
+void
+cp_station_initialize_handler()
+{
+ tail = 0;
+ head = 1;
+ cyg_mutex_init(&mutex_event);
+}
+
+
+ev_err_code_t
+cp_station_add_event(const SEM_EVENT_TYPE event_type, const VS_VOIDPTR mme_address)
+{
+ msg_ctx_t *msg_ctx = (msg_ctx_t *)mme_address;
+ ev_err_code_t return_value = EV_QUEUE_FULL;
+
+ #if DEBUG
+ //if(mme_address) dbg_assert ( !msg_check_wrong_mme_const_values (mme_address));
+ if(mme_address) dbg_assert ( !msg_check_wrong_mme_const_values (msg_ctx->buffer));
+ #endif
+cyg_mutex_lock(&mutex_event);
+ if( ((head+1)%EVENT_QUEUE_SIZE) != tail)
+ {
+ events[head].event_type = event_type;
+ //events[head].mme_address = (VS_VOIDPTR) mme_address;
+ events[head].mme_address = (VS_VOIDPTR) msg_ctx;
+ head++;
+ head %= EVENT_QUEUE_SIZE;
+ return_value = EV_OK;
+ }
+cyg_mutex_unlock(&mutex_event);
+ // generate the event
+ cyg_flag_setbits (&station_flag, STATION_FLAG_FSM);
+ return return_value;
+}
+
+
+ev_err_code_t
+cp_station_get_event(event_t *event)
+{
+ if( ((tail+1)%EVENT_QUEUE_SIZE) != head)
+ {
+ tail++;
+ tail %= EVENT_QUEUE_SIZE;
+ event->event_type = events[tail].event_type;
+ event->mme_address = events[tail].mme_address;
+ return EV_OK;
+ }
+ return EV_QUEUE_EMPTY;
+}
+
diff --git a/cesar/cp/station/station.h b/cesar/cp/station/station.h
new file mode 100644
index 0000000000..dab1f204f6
--- /dev/null
+++ b/cesar/cp/station/station.h
@@ -0,0 +1,97 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2007 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file cp/station/station.h
+ * \brief
+ * \ingroup cp_sta
+ */
+#ifndef CP_STATION_H_
+#define CP_STATION_H_
+
+#include <stdlib.h>
+
+#include <cyg/kernel/kapi.h>
+#include <cyg/hal/hal_arch.h>
+
+#include "cp/interf/interf.h"
+#include "cp/station/inc/station_types.h"
+#include "cp/station/inc/station_apivs.h"
+#include "cp/station/inc/station_actions.h"
+#include "cp/station/inc/station_data.h"
+#include "cp/beacon/beacon.h"
+#include "cl/cl.h"
+#include "mac/common/store.h"
+
+/*
+ * some global variables
+ */
+
+extern uint station_seed;
+extern cyg_flag_t station_flag;
+
+
+/**
+ * \brief Init station module
+ * This is the cp entry point.
+ * \param
+ * \return
+ */
+void
+cp_station_init (mac_store_t *mac_store_ctx, cl_t *interf_cl_ctx, pbproc_t *pbproc_ctx, ca_t *ca_ctx);
+
+/**
+ * \brief start mac service
+ * \param
+ * \return
+ */
+void
+cp_station_mac_start(void);
+
+/**
+ * \brief wait for a station event
+ * \param
+ * \return
+ */
+void
+cp_station_wait_event (cyg_addrword_t data);
+
+/**
+ * \brief create an alarm that will generate an event after
+ * the specified delay
+ * \param cyg_flag : the event handle
+ * \param station_flag : the event flag
+ * \param event_delay_ms : the amount of time to wait
+ * \return
+ */
+void
+cp_station_gen_timed_event(cyg_flag_t *cyg_flag, station_flag_t station_flag, SEM_EVENT_TYPE event_type, uint event_delay_ms);
+
+/**
+ * \brief will stop an alarm previously created with station_gen_timed_event
+ *
+ * \param cyg_flag : the event handle
+ * \param station_flag : the event flag
+ * \return
+ */
+void
+cp_station_stop_timed_event(cyg_flag_t *cyg_flag, station_flag_t station_flag);
+
+
+/**
+ * \brief this function is called when the amount of time specified
+ * with station_wait_event() has elapsed.
+ * warning : this function is called in DSR context
+ *
+ * \param see ecos manual about alarm
+ * \return
+ */
+void
+cp_station_alarm_handler(cyg_handle_t alarm, cyg_addrword_t data);
+
+
+#endif /* CP_STATION_H_ */