    /*====================================================================*
     *
     *   Copyright (c) 2013 Qualcomm Atheros, Inc.
     *
     *   All rights reserved.
     *
     *   Redistribution and use in source and binary forms, with or
     *   without modification, are permitted (subject to the limitations
     *   in the disclaimer below) provided that the following conditions
     *   are met:
     *
     *   * Redistributions of source code must retain the above copyright
     *     notice, this list of conditions and the following disclaimer.
     *
     *   * Redistributions in binary form must reproduce the above
     *     copyright notice, this list of conditions and the following
     *     disclaimer in the documentation and/or other materials
     *     provided with the distribution.
     *
     *   * Neither the name of Qualcomm Atheros nor the names of
     *     its contributors may be used to endorse or promote products
     *     derived from this software without specific prior written
     *     permission.
     *
     *   NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
     *   GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE
     *   COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
     *   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     *   PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
     *   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     *   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     *   OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     *--------------------------------------------------------------------*/

    /*====================================================================*
     *
     *   slac.h -
     *
     *   this file contains defintions for the HomePlug Green PHY SLAC
     *   protocol;
     *
     *--------------------------------------------------------------------*/

    #ifndef SLAC_HEADER
    #define SLAC_HEADER

    /*====================================================================*
     *   system header files;
     *--------------------------------------------------------------------*/

    #include <stdint.h>

    /*====================================================================*
     *   custom header files;
     *--------------------------------------------------------------------*/

    #include "../tools/types.h"
    #include "../tools/endian.h"
    #include "../ether/ether.h"
    #include "../mme/mme.h"

    /*====================================================================*
     *   constants;
     *--------------------------------------------------------------------*/

    #define SLAC_DEBUG 1

    /*
     * The following two constants control whether or not the PEV or EVSE
     * change AVLN on SLAC protocol cycle; The recommended setting is PEV
     * changes with each pass and the EVSE does not;
     */

    #define SLAC_AVLN_PEV 1
    #define SLAC_AVLN_EVSE 0

    #define SLAC_APPLICATION_PEV_EVSE 0x00

    #define SLAC_SECURITY_NONE 0x00
    #define SLAC_SECURITY_PUBLIC_KEY 0x01

    #define SLAC_RUNID_LEN 8
    #define SLAC_UNIQUE_ID_LEN 17
    #define SLAC_RND_LEN 16
    #define SLAC_NID_LEN 7
    #define SLAC_NMK_LEN 16

    #define SLAC_MSOUNDS 8
    #define SLAC_TIMETOSOUND 8
    #define SLAC_TIMEOUT 1000
    #define SLAC_APPLICATION_TYPE 0
    #define SLAC_SECURITY_TYPE 0
    #define SLAC_RESPONSE_TYPE 0
    #define SLAC_MSOUND_TARGET "FF:FF:FF:FF:FF:FF"
    #define SLAC_FORWARD_STATION "00:00:00:00:00:00"
    #define SLAC_GROUPS 58

    #define SLAC_LIMIT 40
    #define SLAC_PAUSE 20
    #define SLAC_SETTLETIME 10
    #define SLAC_CHARGETIME 2
    #define SLAC_FLAGS 0

    #define SLAC_SILENCE (1 << 0)
    #define SLAC_VERBOSE (1 << 1)
    #define SLAC_SESSION (1 << 2)
    #define SLAC_COMPARE (1 << 3)

    #define SLAC_CM_SETKEY_KEYTYPE 0x01
    #define SLAC_CM_SETKEY_PID 0x02
    #define SLAC_CM_SETKEY_PRN 0x00
    #define SLAC_CM_SETKEY_PMN 0x00
    #define SLAC_CM_SETKEY_CCO 0x00
    #define SLAC_CM_SETKEY_EKS 0x01

    /*====================================================================*
     *   messages;
     *--------------------------------------------------------------------*/

    #ifndef __GNUC__
    #pragma pack (push,1)
    #endif

    typedef struct __packed session

    {
    	struct session * next;
    	struct session * prev;
    	byte RunID [SLAC_RUNID_LEN];
    	byte APPLICATION_TYPE;
    	byte SECURITY_TYPE;
    	byte RESP_TYPE;
    	byte NUM_SOUNDS;
    	byte TIME_OUT;
    	byte AAG [SLAC_GROUPS];
    	byte NumGroups;
    	byte MSOUND_TARGET [ETHER_ADDR_LEN];
    	byte FORWARDING_STA [ETHER_ADDR_LEN];
    	byte PEV_ID [SLAC_UNIQUE_ID_LEN];
    	byte PEV_MAC [ETHER_ADDR_LEN];
    	byte EVSE_ID [SLAC_UNIQUE_ID_LEN];
    	byte EVSE_MAC [ETHER_ADDR_LEN];
    	byte RND [SLAC_RND_LEN];
    	byte NMK [SLAC_NMK_LEN];
    	byte NID [SLAC_NID_LEN];
    	byte original_nmk [SLAC_NMK_LEN];
    	byte original_nid [SLAC_NID_LEN];
    	unsigned state;
    	unsigned sounds;
    	unsigned limit;
    	unsigned pause;
    	unsigned chargetime;
    	unsigned settletime;
    	unsigned counter;
    	unsigned flags;
    	signed exit;
    }

    session;
    typedef struct __packed cm_sta_identity_request

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    }

    cm_sta_identity_request;
    typedef struct __packed cm_sta_identity_confirm

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    	uint8_t GREEN_PHY_CAPABILITY;
    	uint8_t POWER_SAVE_CAPABILITY;
    	uint8_t GREEN_PHY_PREFERRED_ALLOCATION_CAPABILITY;
    	uint8_t REPEATING_AND_ROUTING_CAPABILITY;
    	uint8_t HOMEPLUG_AV_VERSION;
    	uint8_t EFL;
    	uint8_t EF [1];
    }

    cm_sta_identity_confirm;
    typedef struct __packed cm_slac_param_request

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    	uint8_t APPLICATION_TYPE;
    	uint8_t SECURITY_TYPE;
    	uint8_t RunID [SLAC_RUNID_LEN];
    	uint8_t CipherSuiteSetSize;
    	uint16_t CipherSuite [1];
    }

    cm_slac_param_request;
    typedef struct __packed cm_slac_param_confirm

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    	uint8_t MSOUND_TARGET [ETHER_ADDR_LEN];
    	uint8_t NUM_SOUNDS;
    	uint8_t TIME_OUT;
    	uint8_t RESP_TYPE;
    	uint8_t FORWARDING_STA [ETHER_ADDR_LEN];
    	uint8_t APPLICATION_TYPE;
    	uint8_t SECURITY_TYPE;
    	uint8_t RunID [SLAC_RUNID_LEN];
    	uint16_t CipherSuite;
    }

    cm_slac_param_confirm;
    typedef struct __packed cm_start_atten_char_indicate

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    	uint8_t APPLICATION_TYPE;
    	uint8_t SECURITY_TYPE;
    	struct __packed
    	{
    		uint8_t NUM_SOUNDS;
    		uint8_t TIME_OUT;
    		uint8_t RESP_TYPE;
    		uint8_t FORWARDING_STA [ETHER_ADDR_LEN];
    		uint8_t RunID [SLAC_RUNID_LEN];
    	}
    	ACVarField;
    }

    cm_start_atten_char_indicate;
    typedef struct __packed cm_start_atten_char_response

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    }

    cm_start_atten_char_response;
    typedef struct __packed cm_atten_char_indicate

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    	uint8_t APPLICATION_TYPE;
    	uint8_t SECURITY_TYPE;
    	struct __packed
    	{
    		uint8_t SOURCE_ADDRESS [ETHER_ADDR_LEN];
    		uint8_t RunID [SLAC_RUNID_LEN];
    		uint8_t SOURCE_ID [SLAC_UNIQUE_ID_LEN];
    		uint8_t RESP_ID [SLAC_UNIQUE_ID_LEN];
    		uint8_t NUM_SOUNDS;
    		struct __packed
    		{
    			uint8_t NumGroups;
    			uint8_t AAG [255];
    		}
    		ATTEN_PROFILE;
    	}
    	ACVarField;
    }

    cm_atten_char_indicate;
    typedef struct __packed cm_atten_char_response

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    	uint8_t APPLICATION_TYPE;
    	uint8_t SECURITY_TYPE;
    	struct __packed
    	{
    		uint8_t SOURCE_ADDRESS [ETHER_ADDR_LEN];
    		uint8_t RunID [SLAC_RUNID_LEN];
    		uint8_t SOURCE_ID [SLAC_UNIQUE_ID_LEN];
    		uint8_t RESP_ID [SLAC_UNIQUE_ID_LEN];
    		uint8_t Result;
    	}
    	ACVarField;
    }

    cm_atten_char_response;
    typedef struct __packed cm_mnbc_sound_indicate

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    	uint8_t APPLICATION_TYPE;
    	uint8_t SECURITY_TYPE;
    	struct __packed
    	{
    		uint8_t SenderID [SLAC_UNIQUE_ID_LEN];
    		uint8_t CNT;
    		uint8_t RunID [SLAC_RUNID_LEN];
    		uint8_t RSVD [8];
    		uint8_t RND [SLAC_RND_LEN];
    	}
    	MSVarField;
    }

    cm_mnbc_sound_indcate;
    typedef struct __packed cm_validate_request

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    	uint8_t SignalType;
    	struct __packed
    	{
    		uint8_t Timer;
    		uint8_t Result;
    	}
    	VRVarField;
    }

    cm_validate_request;
    typedef struct __packed cm_validate_confirm

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    	uint8_t SignalType;
    	struct __packed
    	{
    		uint8_t ToggleNum;
    		uint8_t Result;
    	}
    	VCVarField;
    }

    cm_validate_confirm;
    typedef struct __packed cm_slac_match_request

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    	uint8_t APPLICATION_TYPE;
    	uint8_t SECURITY_TYPE;
    	uint16_t MVFLength;
    	struct __packed
    	{
    		uint8_t PEV_ID [SLAC_UNIQUE_ID_LEN];
    		uint8_t PEV_MAC [ETHER_ADDR_LEN];
    		uint8_t EVSE_ID [SLAC_UNIQUE_ID_LEN];
    		uint8_t EVSE_MAC [ETHER_ADDR_LEN];
    		uint8_t RunID [SLAC_RUNID_LEN];
    		uint8_t RSVD [8];
    	}
    	MatchVarField;
    }

    cm_slac_match_request;
    typedef struct __packed cm_slac_match_confirm

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    	uint8_t APPLICATION_TYPE;
    	uint8_t SECURITY_TYPE;
    	uint16_t MVFLength;
    	struct __packed
    	{
    		uint8_t PEV_ID [SLAC_UNIQUE_ID_LEN];
    		uint8_t PEV_MAC [ETHER_ADDR_LEN];
    		uint8_t EVSE_ID [SLAC_UNIQUE_ID_LEN];
    		uint8_t EVSE_MAC [ETHER_ADDR_LEN];
    		uint8_t RunID [SLAC_RUNID_LEN];
    		uint8_t RSVD1 [8];
    		uint8_t NID [SLAC_NID_LEN];
    		uint8_t RSVD2;
    		uint8_t NMK [SLAC_NMK_LEN];
    	}
    	MatchVarField;
    }

    cm_slac_match_confirm;
    typedef struct __packed cm_atten_profile_indicate

    {
    	struct ethernet_hdr ethernet;
    	struct homeplug_fmi homeplug;
    	uint8_t PEV_MAC [ETHER_ADDR_LEN];
    	uint8_t NumGroups;
    	uint8_t RSVD;
    	uint8_t AAG [255];
    }

    cm_atten_profile_indicate;

    #ifndef __GNUC__
    #pragma pack (pop)
    #endif

    /*====================================================================*
     *   functions;
     *--------------------------------------------------------------------*/

    signed pev_cm_slac_param (struct session *, struct channel *, struct message *);
    signed pev_cm_start_atten_char (struct session *, struct channel *, struct message *);
    signed pev_cm_atten_char (struct session *, struct channel *, struct message *);
    signed pev_cm_mnbc_sound (struct session *, struct channel *, struct message *);
    signed pev_cm_slac_match (struct session *, struct channel *, struct message *);
    signed pev_cm_set_key (struct session *, struct channel *, struct message *);
    signed evse_cm_slac_param (struct session *, struct channel *, struct message *);
    signed evse_cm_start_atten_char (struct session *, struct channel *, struct message *);
    signed evse_cm_atten_char (struct session *, struct channel *, struct message *);
    signed evse_cm_mnbc_sound (struct session *, struct channel *, struct message *);
    signed evse_cm_slac_match (struct session *, struct channel *, struct message *);
    signed evse_cm_set_key (struct session *, struct channel *, struct message *);
    signed slac_connect (struct session *);
    void slac_session (struct session *);
    void slac_structs ();
    signed slac_debug (struct session * session, signed status, char const * string, char const * format, ...);

    /*====================================================================*
     *
     *--------------------------------------------------------------------*/

    #endif

[PREV] [HOME] [NEXT]