#ifndef cp2_mme_h #define cp2_mme_h /* Cesar project {{{ * * Copyright (C) 2008 Spidcom * * <<>> * * }}} */ /** * \file cp2/mme.h * \brief Definition of the MME types. * \ingroup cp2 */ #include "lib/bitstream.h" #include "lib/blk.h" #include "cp2/types.h" #include "cp2/secu/secu.h" /* MMTYPE base values for DRV MME messages. */ #define DRV_STA_SET_MAC_ADDR 0xA000 #define DRV_STA_SET_CCO_PREF 0xA004 #define DRV_STA_SET_WAS_CCO 0xA008 #define DRV_STA_SET_NPW 0xA00C #define DRV_STA_SET_DPW 0xA010 #define DRV_STA_SET_SL 0xA014 #define DRV_STA_SET_M_STA_HFID 0xA018 #define DRV_STA_SET_U_STA_HFID 0xA01C #define DRV_STA_SET_AVLN_HFID 0xA020 #define DRV_STA_SET_TONEMASK 0xA024 #define DRV_STA_START 0xA028 #define DRV_STA_STOP 0xA02C #define DRV_STA_SET_NID 0xA030 /* MMTYPE sub-values for MMEs (REQ, CNF, IND or RSP). */ #define CP_MME_REQ 0x00 #define CP_MME_CNF 0x01 #define CP_MME_IND 0x02 #define CP_MME_RSP 0x03 /** MMTYPE constants. */ enum cp_mmtype_t { CC_CCO_APPOINT_REQ = 0x0000, CC_CCO_APPOINT_CNF = 0x0001, CC_BACKUP_APPOINT_REQ = 0x0004, CC_BACKUP_APPOINT_CNF = 0x0005, CC_LINK_INFO_REQ = 0x0008, CC_LINK_INFO_CNF = 0x0009, CC_LINK_INFO_IND = 0x000A, CC_LINK_INFO_RSP = 0x000B, CC_HANDOVER_REQ = 0x000C, CC_HANDOVER_CNF = 0x000D, CC_HANDOVER_INFO_IND = 0x0012, CC_HANDOVER_INFO_RSP = 0x0013, CC_DISCOVER_LIST_REQ = 0x0014, CC_DISCOVER_LIST_CNF = 0x0015, CC_DISCOVER_LIST_IND = 0x0016, CC_LINK_NEW_REQ = 0x0018, CC_LINK_NEW_CNF = 0x0019, CC_LINK_MOD_REQ = 0x001C, CC_LINK_MOD_CNF = 0x001D, CC_LINK_SQZ_REQ = 0x0020, CC_LINK_SQZ_CNF = 0x0021, CC_LINK_REL_REQ = 0x0024, CC_LINK_REL_IND = 0x0025, CC_DETECT_REPORT_REQ = 0x0028, CC_DETECT_REPORT_CNF = 0x0029, CC_WHO_RU_REQ = 0x002C, CC_WHO_RU_CNF = 0x002D, CC_ASSOC_REQ = 0x0030, CC_ASSOC_CNF = 0x0031, CC_LEAVE_REQ = 0x0034, CC_LEAVE_CNF = 0x0035, CC_LEAVE_IND = 0x0036, CC_LEAVE_RSP = 0x0037, CC_SET_TEI_MAP_REQ = 0x0038, CC_SET_TEI_MAP_IND = 0x0039, CC_RELAY_REQ = 0x003C, CC_RELAY_IND = 0x003D, CC_BEACON_RELIABILITY_REQ = 0x0040, CC_BEACON_RELIABILITY_CNF = 0x0041, CC_ALLOC_MOVE_REQ = 0x0044, CC_ALLOC_MOVE_CNF = 0x0045, CC_ACCESS_NEW_REQ = 0x0048, CC_ACCESS_NEW_CNF = 0x0049, CC_ACCESS_NEW_IND = 0x004A, CC_ACCESS_NEW_RSP = 0x004B, CC_ACCESS_REL_REQ = 0x004C, CC_ACCESS_REL_CNF = 0x004D, CC_ACCESS_REL_IND = 0x004E, CC_ACCESS_REL_RSP = 0x004F, CC_DCPPC_IND = 0x0052, CC_DCPPC_RSP = 0x0053, CC_HP1_DET_REQ = 0x0054, CC_HP1_DET_CNF = 0x0055, CC_BLE_UPDATE_IND = 0x005A, CP_PROXY_APPOINT_REQ = 0x2000, CP_PROXY_APPOINT_CNF = 0x2001, PH_PROXY_APPOINT_IND = 0x2006, CP_PROXY_WAKE_REQ = 0x2008, NN_INL_REQ = 0x4000, NN_INL_CNF = 0x4001, NN_NEW_REQ = 0x4004, NN_NEW_CNF = 0x4005, NN_NEW_IND = 0x4006, NN_ADD_ALLOC_REQ = 0x4008, NN_ADD_ALLOC_CNF = 0x4009, NN_ADD_ALLOC_IND = 0x400A, NN_REL_ALLOC_REQ = 0x400C, NN_REL_ALLOC_CNF = 0x400D, NN_REL_NET_IND = 0x4012, CM_UNASSOCIATED_STA_IND = 0x6002, CM_ENCRYPTED_PAYLOAD_IND = 0x6006, CM_ENCRYPTED_PAYLOAD_RSP = 0x6007, CM_SET_KEY_REQ = 0x6008, CM_SET_KEY_CNF = 0x6009, CM_GET_KEY_REQ = 0x600C, CM_GET_KEY_CNF = 0x600D, CM_SC_JOIN_REQ = 0x6010, CM_SC_JOIN_CNF = 0x6011, CM_CHAN_EST_IND = 0x6016, CM_TM_UPDATE_IND = 0x601A, CM_AMP_MAP_REQ = 0x601C, CM_AMP_MAP_CNF = 0x601D, CM_BRG_INFO_REQ = 0x6020, CM_BRG_INFO_CNF = 0x6021, CM_CONN_NEW_REQ = 0x6024, CM_CONN_NEW_CNF = 0x6025, CM_CONN_REL_IND = 0x602A, CM_CONN_REL_RSP = 0x602B, CM_CONN_MOD_REQ = 0x602C, CM_CONN_MOD_CNF = 0x602D, CM_CONN_INFO_REQ = 0x6030, CM_CONN_INFO_CNF = 0x6031, CM_STA_CAP_REQ = 0x6034, CM_STA_CAP_CNF = 0x6035, CM_NW_INFO_REQ = 0x6038, CM_NW_INFO_CNF = 0x6039, CM_GET_BEACON_REQ = 0x603C, CM_GET_BEACON_CNF = 0x603D, CM_HFID_REQ = 0x6040, CM_HFID_CNF = 0x6041, CM_MME_ERROR_IND = 0x6046, CM_NW_STATS_REQ = 0x6048, CM_NW_STATS_CNF = 0x6049, CM_LINK_STATS_REQ = 0x604C, CM_LINK_STATS_CNF = 0x604D, DRV_STA_SET_MAC_ADDR_REQ = DRV_STA_SET_MAC_ADDR + CP_MME_REQ, DRV_STA_SET_MAC_ADDR_CNF = DRV_STA_SET_MAC_ADDR + CP_MME_CNF, DRV_STA_SET_CCO_PREF_REQ = DRV_STA_SET_CCO_PREF + CP_MME_REQ, DRV_STA_SET_CCO_PREF_CNF = DRV_STA_SET_CCO_PREF + CP_MME_CNF, DRV_STA_SET_WAS_CCO_REQ = DRV_STA_SET_WAS_CCO + CP_MME_REQ, DRV_STA_SET_WAS_CCO_CNF = DRV_STA_SET_WAS_CCO + CP_MME_CNF, DRV_STA_SET_WAS_CCO_IND = DRV_STA_SET_WAS_CCO + CP_MME_IND, DRV_STA_SET_WAS_CCO_RSP = DRV_STA_SET_WAS_CCO + CP_MME_RSP, DRV_STA_SET_NPW_REQ = DRV_STA_SET_NPW + CP_MME_REQ, DRV_STA_SET_NPW_CNF = DRV_STA_SET_NPW + CP_MME_CNF, DRV_STA_SET_DPW_REQ = DRV_STA_SET_DPW + CP_MME_REQ, DRV_STA_SET_DPW_CNF = DRV_STA_SET_DPW + CP_MME_CNF, DRV_STA_SET_SL_REQ = DRV_STA_SET_SL + CP_MME_REQ, DRV_STA_SET_SL_CNF = DRV_STA_SET_SL + CP_MME_CNF, DRV_STA_SET_M_STA_HFID_REQ = DRV_STA_SET_M_STA_HFID + CP_MME_REQ, DRV_STA_SET_M_STA_HFID_CNF = DRV_STA_SET_M_STA_HFID + CP_MME_CNF, DRV_STA_SET_U_STA_HFID_REQ = DRV_STA_SET_U_STA_HFID + CP_MME_REQ, DRV_STA_SET_U_STA_HFID_CNF = DRV_STA_SET_U_STA_HFID + CP_MME_CNF, DRV_STA_SET_AVLN_HFID_REQ = DRV_STA_SET_AVLN_HFID + CP_MME_REQ, DRV_STA_SET_AVLN_HFID_CNF = DRV_STA_SET_AVLN_HFID + CP_MME_CNF, DRV_STA_SET_TONEMASK_REQ = DRV_STA_SET_TONEMASK + CP_MME_REQ, DRV_STA_SET_TONEMASK_CNF = DRV_STA_SET_TONEMASK + CP_MME_CNF, DRV_STA_START_REQ = DRV_STA_START + CP_MME_REQ, DRV_STA_START_CNF = DRV_STA_START + CP_MME_CNF, DRV_STA_STOP_REQ = DRV_STA_STOP + CP_MME_REQ, DRV_STA_STOP_CNF = DRV_STA_STOP + CP_MME_CNF, DRV_STA_SET_NID_REQ = DRV_STA_SET_NID + CP_MME_REQ, DRV_STA_SET_NID_CNF = DRV_STA_SET_NID + CP_MME_CNF, }; typedef enum cp_mmtype_t cp_mmtype_t; /** Payload encryption key select. */ enum cp_mme_peks_t { /** Encrypted using destination station DAK. */ CP_MME_PEKS_DAK, /** Encrypted using NMK known to station. */ CP_MME_PEKS_NMK, /** First TEK identifier. */ CP_MME_PEKS_TEK_MIN, /** Last TEK identifier. */ CP_MME_PEKS_TEK_MAX = 0xe, /** Number of TEK identifiers. */ CP_MME_PEKS_TEK_NB = CP_MME_PEKS_TEK_MAX - CP_MME_PEKS_TEK_MIN + 1, /** No encryption. */ CP_MME_PEKS_NONE = 0xf, /** Number of valid PEKS in a MME. */ CP_MME_PEKS_NB, /** Special value meaning no encapsulation in a * CM_ENCRYPTED_PAYLOAD.IND. */ CP_MME_PEKS_SPC_NOT_EMBEDDED = 0x100, }; typedef enum cp_mme_peks_t cp_mme_peks_t; /** MME peer (sender or recipient, depending of the MME direction). * * This structure contains information needed to send a MME to the right * destination. It is contained in the RX MME handle in order to respond to a * received MME. */ struct cp_mme_peer_t { /** Peer MAC address. */ mac_t mac; /** VLAN tag or 0 if none. */ u32 vlan_tag; /** Peer TEI, or 0xff if not TEI based. */ cp_tei_t tei; /** Send to every stations of our AVLN. */ bool all_sta; }; typedef struct cp_mme_peer_t cp_mme_peer_t; /** Relay information for the MME relay. */ struct cp_mme_relay_t { /** Mac address corresponding to the Final destination in the REQ and the * Original source for the IND. */ mac_t mac_fa; /** Final TEI. */ cp_tei_t ftei; }; typedef struct cp_mme_relay_t cp_mme_relay_t; /** MME handle for RX. */ struct cp_mme_rx_t { /** pointer to the received MME. */ u8 *p_mme; /** pointer to the MME's fragments. */ blk_t *p_frag; /** Pointer to the current frag. */ blk_t *p_frag_current; /** MMType the type of MME. */ uint mmtype; /** size of the MME (including header). */ uint length; /** Peer information. */ cp_mme_peer_t peer; /** Payload encryption. */ cp_mme_peks_t peks; /** Protocol run information if present. */ cp_secu_protocol_run_t prun; /** \TODO use the correct bitstream. */ bitstream_t bitstream; /** Data used by the CL. */ void *cl_data; /** CP context used by the destructor of the MME_rx_t message. */ cp_t *cp; /** IV or UUID. */ cp_key_t iv_uuid; /** Relay information. */ cp_mme_relay_t relay; }; typedef struct cp_mme_rx_t cp_mme_rx_t; /** MME handle for TX. */ struct cp_mme_tx_t { /** pointer to the Tx buffer. */ u8 *p_mme; /** size of the mme (including header). */ uint length; /** true if the message is encapsulated in cc_relay. */ bool relay; /** Peer information. */ cp_mme_peer_t peer; /** Payload encryption. */ cp_mme_peks_t peks; /** Protocol run information if present. */ cp_secu_protocol_run_t prun; /** \TODO use the correct bitstream. */ bitstream_t bitstream; /** CP context used by the destructor of the MME_tx_t message. */ cp_t *cp; /** Offset of the payload. */ uint payload_offset; /** RF Len. */ uint rf_len; /** IV or UUID. */ cp_key_t iv_uuid; }; typedef struct cp_mme_tx_t cp_mme_tx_t; /** Construct a cp_mme_peer_t for unicast to all STA. */ #define CP_MME_PEER_ALL_STA \ ((cp_mme_peer_t) { .all_sta = true }) /** Construct a cp_mme_peer_t from a MAC address and an optional TEI. */ #define CP_MME_PEER(mac, tei...) \ PASTE_EXPAND (CP_MME_PEER_, PREPROC_NARG (mac, ## tei)) (mac, ## tei) #define CP_MME_PEER_1(mac_) \ CP_MME_PEER_2 (mac_, 0xff) #define CP_MME_PEER_2(mac_, tei_) \ ((cp_mme_peer_t) { .mac = mac_, .vlan_tag = 0, .tei = tei_, \ .all_sta = false }) /** * Compare two cp_mme_peer_t. * \param p1 first structure * \param p2 second structure * \return true if they match. * * This only works for MAC or MAC+TEI peer structures, ignoring VLAN tag and * all_sta flag. */ extern inline bool cp_mme_peer_cmp (cp_mme_peer_t *p1, cp_mme_peer_t *p2) { return p1->mac == p2->mac && p1->tei == p2->tei; } #endif /* cp2_mme_h */