Esempio n. 1
0
signed slac_connect (struct session * session) 

{ 
	unsigned group = 0; 
	unsigned total = 0; 
	if (session->NumGroups > SIZEOF (session->AAG)) 
	{ 
		return (slac_debug (session, session->exit, __func__, "Too much data to analyse!")); 
	} 
	if (session->NumGroups > 0) 
	{ 
		char string [512]; 
		while (group < session->NumGroups) 
		{ 
			total += session->AAG [group]; 
			group++; 
		} 
		total /= group; 
		if (total > session->limit) 
		{ 
			char string [512]; 
			slac_debug (session, 0, __func__, "Average attenuation (%u) more than limit (%u) frow %d groups", total, session->limit, group); 
			slac_debug (session, 0, __func__, "%s", HEXSTRING (string, session->AAG)); 
			return (- 1); 
		} 
		if (total > 0) 
		{ 
			slac_debug (session, 0, __func__, "Average attenuation (%u) less than limit (%u) from %d groups", total, session->limit, group); 
			slac_debug (session, 0, __func__, "%s", HEXSTRING (string, session->AAG)); 
			return (0); 
		} 
	} 
	return (slac_debug (session, session->exit, __func__, "Nothing to analyse")); 
} 
signed evse_cm_slac_match (struct session * session, struct channel * channel, struct message * message)

{
	struct cm_slac_match_request * request = (struct cm_slac_match_request *) (message);
	struct cm_slac_match_confirm * confirm = (struct cm_slac_match_confirm *) (message);
	while (readmessage (channel, message, HOMEPLUG_MMV, (CM_SLAC_MATCH | MMTYPE_REQ)) > 0)
	{
		if (! memcmp (session->RunID, request->MatchVarField.RunID, sizeof (session->RunID)))
		{
			slac_debug (session, 0, __func__, "<-- CM_SLAC_MATCH.REQ");
			memcpy (session->PEV_ID, request->MatchVarField.PEV_ID, sizeof (session->PEV_ID));
			memcpy (session->PEV_MAC, request->MatchVarField.PEV_MAC, sizeof (session->PEV_MAC));
			memcpy (session->RunID, request->MatchVarField.RunID, sizeof (session->RunID));

#if SLAC_DEBUG

			if (_anyset (session->flags, SLAC_VERBOSE))
			{
				char string [256];
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.APPLICATION_TYPE %d", request->APPLICATION_TYPE);
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.SECURITY_TYPE %d", request->SECURITY_TYPE);
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.MVFLength %d", LE16TOH (request->MVFLength));
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.PEV_ID %s", HEXSTRING (string, request->MatchVarField.PEV_ID));
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.PEV_MAC %s", HEXSTRING (string, request->MatchVarField.PEV_MAC));
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.EVSE_ID %s", HEXSTRING (string, request->MatchVarField.EVSE_ID));
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.EVSE_MAC %s", HEXSTRING (string, request->MatchVarField.EVSE_MAC));
				slac_debug (session, 0, __func__, "CM_SLAC_MATCH.REQ.RunID %s", HEXSTRING (string, request->MatchVarField.RunID));
			}

#endif

			slac_debug (session, 0, __func__, "--> CM_SLAC_MATCH.CNF");
			memset (message, 0, sizeof (* message));
			EthernetHeader (& confirm->ethernet, session->PEV_MAC, channel->host, channel->type);
			HomePlugHeader1 (& confirm->homeplug, HOMEPLUG_MMV, (CM_SLAC_MATCH | MMTYPE_CNF));
			confirm->APPLICATION_TYPE = session->APPLICATION_TYPE;
			confirm->SECURITY_TYPE = session->SECURITY_TYPE;
			confirm->MVFLength = HTOLE16 (sizeof (confirm->MatchVarField));
			memcpy (confirm->MatchVarField.PEV_ID, session->PEV_ID, sizeof (confirm->MatchVarField.PEV_ID));
			memcpy (confirm->MatchVarField.PEV_MAC, session->PEV_MAC, sizeof (confirm->MatchVarField.PEV_MAC));
			memcpy (confirm->MatchVarField.EVSE_ID, session->EVSE_ID, sizeof (confirm->MatchVarField.EVSE_ID));
			memcpy (confirm->MatchVarField.EVSE_MAC, session->EVSE_MAC, sizeof (confirm->MatchVarField.EVSE_MAC));
			memcpy (confirm->MatchVarField.RunID, session->RunID, sizeof (confirm->MatchVarField.RunID));
			memcpy (confirm->MatchVarField.NID, session->NID, sizeof (confirm->MatchVarField.NID));
			memcpy (confirm->MatchVarField.NMK, session->NMK, sizeof (confirm->MatchVarField.NMK));
			if (sendmessage (channel, message, sizeof (* confirm)) <= 0)
			{
				return (slac_debug (session, 1, __func__, CHANNEL_CANTSEND));
			}
			return (0);
		}
	}
	return (slac_debug (session, session->exit, __func__, "<-- CM_SLAC_MATCH.REQ ?"));
}
signed evse_cm_atten_char (struct session * session, struct channel * channel, struct message * message)

{
	struct cm_atten_char_indicate * indicate = (struct cm_atten_char_indicate *) (message);
	struct cm_atten_char_response * response = (struct cm_atten_char_response *) (message);
	slac_debug (session, 0, __func__, "--> CM_ATTEN_CHAR.IND");
	memset (message, 0, sizeof (* message));
	EthernetHeader (& indicate->ethernet, session->PEV_MAC, channel->host, channel->type);
	HomePlugHeader1 (& indicate->homeplug, HOMEPLUG_MMV, (CM_ATTEN_CHAR | MMTYPE_IND));
	indicate->APPLICATION_TYPE = session->APPLICATION_TYPE;
	indicate->SECURITY_TYPE = session->SECURITY_TYPE;
	memcpy (indicate->ACVarField.SOURCE_ADDRESS, session->PEV_MAC, sizeof (indicate->ACVarField.SOURCE_ADDRESS));
	memcpy (indicate->ACVarField.RunID, session->RunID, sizeof (indicate->ACVarField.RunID));
	memset (indicate->ACVarField.SOURCE_ID, 0, sizeof (indicate->ACVarField.SOURCE_ID));
	memset (indicate->ACVarField.RESP_ID, 0, sizeof (indicate->ACVarField.RESP_ID));
	indicate->ACVarField.NUM_SOUNDS = session->sounds;
	indicate->ACVarField.ATTEN_PROFILE.NumGroups = session->NumGroups;
	memcpy (indicate->ACVarField.ATTEN_PROFILE.AAG, session->AAG, session->NumGroups);
	if (sendmessage (channel, message, sizeof (* indicate)) <= 0)
	{
		return (slac_debug (session, 1, __func__, CHANNEL_CANTSEND));
	}
	if (readmessage (channel, message, HOMEPLUG_MMV, (CM_ATTEN_CHAR | MMTYPE_RSP)) > 0)
	{
		if (! memcmp (session->RunID, response->ACVarField.RunID, sizeof (session->RunID)))
		{
			slac_debug (session, 0, __func__, "<-- CM_ATTEN_CHAR.RSP");

#if SLAC_DEBUG

			if (_anyset (session->flags, SLAC_VERBOSE))
			{
				char string [256];
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.APPLICATION_TYPE %d", response->APPLICATION_TYPE);
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.SECURITY_TYPE %d", response->SECURITY_TYPE);
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.ACVarfield.SOURCE_ADDRESS %s", HEXSTRING (string, response->ACVarField.SOURCE_ADDRESS));
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.ACVarFIeld.RunID %s", HEXSTRING (string, response->ACVarField.RunID));
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.ACVarField.SOURCE_ID %s", HEXSTRING (string, response->ACVarField.SOURCE_ID));
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.ACVarField.RESP_ID %s", HEXSTRING (string, response->ACVarField.RESP_ID));
				slac_debug (session, 0, __func__, "CM_ATTEN_CHAR.RSP.ACVarField.Result %d", response->ACVarField.Result);
			}

#endif

			return (0);
		}
	}
	return (slac_debug (session, session->exit, __func__, "<-- CM_ATTEN_CHAR.RSP ?"));
}
signed evse_cm_start_atten_char (struct session * session, struct channel * channel, struct message * message) 

{ 
	struct cm_start_atten_char_indicate * indicate = (struct cm_start_atten_char_indicate *) (message); 
	if (readmessage (channel, message, HOMEPLUG_MMV, (CM_START_ATTEN_CHAR | MMTYPE_IND)) > 0) 
	{ 
		if (! memcmp (session->RunID, indicate->ACVarField.RunID, sizeof (session->RunID))) 
		{ 
			slac_debug (session, 0, __func__, "<-- CM_START_ATTEN_CHAR.IND"); 

#if SLAC_DEBUG

			if (_anyset (session->flags, SLAC_VERBOSE)) 
			{ 
				char string [256]; 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.APPLICATION_TYPE %d", indicate->APPLICATION_TYPE); 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.SECURITY_TYPE %d", indicate->SECURITY_TYPE); 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.ACVarField.NUM_SOUNDS %d", indicate->ACVarField.NUM_SOUNDS); 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.ACVarField.TIME_OUT %d", indicate->ACVarField.TIME_OUT); 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.ACVarField.RESP_TYPE %d", indicate->ACVarField.RESP_TYPE); 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.ACVarField.FORWARDING_STA %s", HEXSTRING (string, indicate->ACVarField.FORWARDING_STA)); 
				slac_debug (session, 0, __func__, "CM_START_ATTEN_CHAR.IND.ACVarField.RunID %s", HEXSTRING (string, indicate->ACVarField.RunID)); 
			} 

#endif

			if (indicate->APPLICATION_TYPE != session->APPLICATION_TYPE) 
			{ 
				slac_debug (session, session->exit, __func__, "%s: APPLICATION_TYPE", __func__); 
			} 
			if (indicate->SECURITY_TYPE != session->SECURITY_TYPE) 
			{ 
				slac_debug (session, session->exit, __func__, "%s: SECURITY_TYPE", __func__); 
			} 
			session->NUM_SOUNDS = indicate->ACVarField.NUM_SOUNDS; 
			session->TIME_OUT = indicate->ACVarField.TIME_OUT; 
			if (indicate->ACVarField.RESP_TYPE != session->RESP_TYPE) 
			{ 
				slac_debug (session, session->exit, __func__, "%s: RESP_TYPE", __func__); 
			} 
			memcpy (session->FORWARDING_STA, indicate->ACVarField.FORWARDING_STA, sizeof (session->FORWARDING_STA)); 
			return (0); 
		} 
	} 
	return (slac_debug (session, session->exit, __func__, "CM_START_ATTEN_CHAR.IND ?")); 
} 
signed evse_cm_mnbc_sound (struct session * session, struct channel * channel, struct message * message)

{
	struct timeval ts;
	struct timeval tc;
	signed timer = 100 * session->TIME_OUT;
	unsigned AAG [SLAC_GROUPS];
	unsigned sounds = 0;
	ssize_t length;
	session->sounds = 0;
	memset (AAG, 0, sizeof (AAG));
	memset (session->AAG, 0, sizeof (session->AAG));
	if (gettimeofday (& ts, NULL) == - 1)
	{
		slac_debug (session, 1, __func__, CANT_START_TIMER);
	}
	while ((length = readpacket (channel, message, sizeof (* message))) >= 0)
	{
		struct homeplug * homeplug = (struct homeplug *) (message);
		if (! length)
		{
		}
		else if (ntohs (homeplug->ethernet.MTYPE) != ETH_P_HPAV)
		{
			slac_debug (session, session->exit, __func__, "bad MTYPE");
		}
		else if (homeplug->homeplug.MMV != HOMEPLUG_MMV)
		{
			slac_debug (session, session->exit, __func__, "bad MMV");
		}
		else if (LE16TOH (homeplug->homeplug.MMTYPE) == (CM_MNBC_SOUND | MMTYPE_IND))
		{
			struct cm_mnbc_sound_indicate * indicate = (struct cm_mnbc_sound_indicate *) (message);
			if (! memcmp (session->RunID, indicate->MSVarField.RunID, sizeof (session->RunID)))
			{
				slac_debug (session, 0, __func__, "<-- CM_MNBC_SOUND.IND (%d)", sounds);

#if SLAC_DEBUG

				if (_anyset (session->flags, SLAC_VERBOSE))
				{
					char string [256];
					slac_debug (session, 0, __func__, "CM_MNBC_SOUND.IND.APPLICATION_TYPE %d", indicate->APPLICATION_TYPE);
					slac_debug (session, 0, __func__, "CM_MNBC_SOUND.IND.SECURITY_TYPE %d", indicate->SECURITY_TYPE);
					slac_debug (session, 0, __func__, "CM_MNBC_SOUND.IND.MSVarField.SenderID %s", HEXSTRING (string, indicate->MSVarField.SenderID));
					slac_debug (session, 0, __func__, "CM_MNBC_SOUND.IND.MSVarField.Count %d", indicate->MSVarField.CNT);
					slac_debug (session, 0, __func__, "CM_MNBC_SOUND.IND.MSVarField.RunID %s", HEXSTRING (string, indicate->MSVarField.RunID));
					slac_debug (session, 0, __func__, "CM_MNBC_SOUND.IND.MSVarField.RND %s", HEXSTRING (string, indicate->MSVarField.RND));
				}

#endif

				if (memcmp (session->PEV_MAC, indicate->ethernet.OSA, sizeof (session->PEV_MAC)))
				{
					slac_debug (session, session->exit, __func__, "Unexpected OSA");
				}
				sounds++;
			}
		}
		else if (LE16TOH (homeplug->homeplug.MMTYPE) == (CM_ATTEN_PROFILE | MMTYPE_IND))
		{
			struct cm_atten_profile_indicate * indicate = (struct cm_atten_profile_indicate *) (message);
			if (! memcmp (session->PEV_MAC, indicate->PEV_MAC, sizeof (session->PEV_MAC)))
			{
				slac_debug (session, 0, __func__, "<-- CM_ATTEN_PROFILE.IND (%d)", session->sounds);

#if SLAC_DEBUG

				if (_anyset (session->flags, SLAC_VERBOSE))
				{
					char string [256];
					slac_debug (session, 0, __func__, "CM_ATTEN_PROFILE.PEV_MAC %s", HEXSTRING (string, indicate->PEV_MAC));
					slac_debug (session, 0, __func__, "CM_ATTEN_PROFILE.NumGroups %d", indicate->NumGroups);
					slac_debug (session, 0, __func__, "CM_ATTEN_PROFILE.AAG %s", hexstring (string, sizeof (string), indicate->AAG, indicate->NumGroups));
				}

#endif

				for (session->NumGroups = 0; session->NumGroups < indicate->NumGroups; session->NumGroups++)
				{
					AAG [session->NumGroups] += indicate->AAG [session->NumGroups];
				}
				session->NumGroups = indicate->NumGroups;
				session->sounds++;
			}
		}
		if (gettimeofday (& tc, NULL) == - 1)
		{
			slac_debug (session, 1, __func__, CANT_RESET_TIMER);
		}
		if ((MILLISECONDS (ts, tc) < timer) && (session->sounds < session->NUM_SOUNDS))
		{
			continue;
		}
		if (session->sounds > 0)
		{
			for (session->NumGroups = 0; session->NumGroups < SLAC_GROUPS; ++ session->NumGroups)
			{
				session->AAG [session->NumGroups] = AAG [session->NumGroups] / session->sounds;
			}
		}
		return (0);
	}
	return (slac_debug (session, session->exit, __func__, "Sound timeout"));
}
Esempio n. 6
0
signed pev_cm_slac_param (struct session * session, struct channel * channel, struct message * message) 

{ 
	extern byte const broadcast [ETHER_ADDR_LEN]; 
	struct cm_slac_param_request * request = (struct cm_slac_param_request *) (message); 
	struct cm_slac_param_confirm * confirm = (struct cm_slac_param_confirm *) (message); 
	slac_debug (session, 0, __func__, "--> CM_SLAC_PARAM.REQ"); 
	memset (message, 0, sizeof (* message)); 
	EthernetHeader (& request->ethernet, broadcast, channel->host, channel->type); 
	HomePlugHeader1 (& request->homeplug, HOMEPLUG_MMV, (CM_SLAC_PARAM | MMTYPE_REQ)); 
	request->APPLICATION_TYPE = session->APPLICATION_TYPE; 
	request->SECURITY_TYPE = session->SECURITY_TYPE; 
	memcpy (request->RunID, session->RunID, sizeof (request->RunID)); 
	request->CipherSuite [0] = HTOLE16 ((uint16_t) (session->counter)); 
	if (sendmessage (channel, message, (ETHER_MIN_LEN - ETHER_CRC_LEN)) <= 0) 
	{ 
		return (slac_debug (session, 1, __func__, CHANNEL_CANTSEND)); 
	} 
	while (readmessage (channel, message, HOMEPLUG_MMV, (CM_SLAC_PARAM | MMTYPE_CNF)) > 0) 
	{ 
		if (! memcmp (session->RunID, confirm->RunID, sizeof (session->RunID))) 
		{ 
			slac_debug (session, 0, __func__, "<-- CM_SLAC_PARAM.CNF"); 
			if (confirm->APPLICATION_TYPE != session->APPLICATION_TYPE) 
			{ 
				slac_debug (session, session->exit, __func__, "Unexpected APPLICATION_TYPE"); 
			} 
			if (confirm->SECURITY_TYPE != session->SECURITY_TYPE) 
			{ 
				slac_debug (session, session->exit, __func__, "Unexpected SECURITY_TYPE"); 
			} 
			if (_anyset (session->flags, SLAC_COMPARE)) 
			{ 
				if (LE16TOH (confirm->CipherSuite) != (uint16_t) (session->counter)) 
				{ 
					slac_debug (session, session->exit, __func__, "session->counter mismatch! PEV=(%d) EVSE=(%d)", LE16TOH (confirm->CipherSuite), session->counter); 
				} 
			} 

#if SLAC_DEBUG

			if (_anyset (session->flags, SLAC_VERBOSE)) 
			{ 
				char string [256]; 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.MSOUND_TARGET %s", HEXSTRING (string, confirm->MSOUND_TARGET)); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.NUM_SOUNDS %d", confirm->NUM_SOUNDS); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.TIME_OUT %d", confirm->TIME_OUT); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.RESP_TYPE %d", confirm->RESP_TYPE); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.FORWARDING_STA %s", HEXSTRING (string, confirm->FORWARDING_STA)); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.APPLICATION_TYPE %d", confirm->APPLICATION_TYPE); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.SECURITY_TYPE %d", confirm->SECURITY_TYPE); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.RunID %s", HEXSTRING (string, confirm->RunID)); 
				slac_debug (session, 0, __func__, "CM_SLAC_PARAM.CNF.CipherSuite %d", confirm->CipherSuite); 
			} 

#endif

			memcpy (session->FORWARDING_STA, confirm->FORWARDING_STA, sizeof (session->FORWARDING_STA)); 
			memcpy (session->MSOUND_TARGET, confirm->MSOUND_TARGET, sizeof (session->MSOUND_TARGET)); 
			session->NUM_SOUNDS = confirm->NUM_SOUNDS; 
			session->TIME_OUT = confirm->TIME_OUT; 
			session->RESP_TYPE = confirm->RESP_TYPE; 
			return (0); 
		} 
	} 
	return (slac_debug (session, 0, __func__, "<-- CM_SLAC_PARAM.CNF ?")); 
} 
Esempio n. 7
0
signed pev_cm_set_key (struct session * session, struct channel * channel, struct message * message)

{

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

	struct __packed cm_set_key_request
	{
		struct ethernet_hdr ethernet;
		struct homeplug_fmi homeplug;
		uint8_t KEYTYPE;
		uint32_t MYNOUNCE;
		uint32_t YOURNOUNCE;
		uint8_t PID;
		uint16_t PRN;
		uint8_t PMN;
		uint8_t CCOCAP;
		uint8_t NID [SLAC_NID_LEN];
		uint8_t NEWEKS;
		uint8_t NEWKEY [SLAC_NMK_LEN];
		uint8_t RSVD [3];
	}
	* request = (struct cm_set_key_request *) (message);
	struct __packed cm_set_key_confirm
	{
		struct ethernet_hdr ethernet;
		struct homeplug_fmi homeplug;
		uint8_t RESULT;
		uint32_t MYNOUNCE;
		uint32_t YOURNOUNCE;
		uint8_t PID;
		uint16_t PRN;
		uint8_t PMN;
		uint8_t CCOCAP;
		uint8_t RSVD [27];
	}
	* confirm = (struct cm_set_key_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	memset (message, 0, sizeof (* message));
	slac_debug (session, 0, __func__, "--> CM_SET_KEY.REQ");
	EthernetHeader (& request->ethernet, channel->peer, channel->host, channel->type);
	HomePlugHeader1 (& request->homeplug, HOMEPLUG_MMV, (CM_SET_KEY | MMTYPE_REQ));
	request->KEYTYPE = SLAC_CM_SETKEY_KEYTYPE;
	memset (& request->MYNOUNCE, 0xAA, sizeof (request->MYNOUNCE));
	memset (& request->YOURNOUNCE, 0x00, sizeof (request->YOURNOUNCE));
	request->PID = SLAC_CM_SETKEY_PID;
	request->PRN = HTOLE16 (SLAC_CM_SETKEY_PRN);
	request->PMN = SLAC_CM_SETKEY_PMN;
	request->CCOCAP = SLAC_CM_SETKEY_CCO;
	memcpy (request->NID, session->NID, sizeof (request->NID));
	request->NEWEKS = SLAC_CM_SETKEY_EKS;
	memcpy (request->NEWKEY, session->NMK, sizeof (request->NEWKEY));

#if SLAC_DEBUG

	if (_anyset (session->flags, SLAC_VERBOSE))
	{
		char string [1024];
		slac_debug (session, 0, __func__, "CM_SET_KEY.KEYTYPE %d", request->KEYTYPE);
		slac_debug (session, 0, __func__, "CM_SET_KEY.MYNOUNCE %s", hexstring (string, sizeof (string), & request->MYNOUNCE, sizeof (request->MYNOUNCE)));
		slac_debug (session, 0, __func__, "CM_SET_KEY.YOURNOUNCE %s", hexstring (string, sizeof (string), & request->YOURNOUNCE, sizeof (request->MYNOUNCE)));
		slac_debug (session, 0, __func__, "CM_SET_KEY.PID %d", request->PID);
		slac_debug (session, 0, __func__, "CM_SET_KEY.PRN %d", LE32TOH (request->PRN));
		slac_debug (session, 0, __func__, "CM_SET_KEY.PMN %d", request->PMN);
		slac_debug (session, 0, __func__, "CM_SET_KEY.CCoCAP %d", request->CCOCAP);
		slac_debug (session, 0, __func__, "CM_SET_KEY.NID %s", HEXSTRING (string, request->NID));
		slac_debug (session, 0, __func__, "CM_SET_KEY.NEWEKS %d", request->NEWEKS);
		slac_debug (session, 0, __func__, "CM_SET_KEY.NEWKEY %s", HEXSTRING (string, request->NEWKEY));
	}

#endif

	if (sendpacket (channel, request, sizeof (* request)) <= 0)
	{
		return (slac_debug (session, 1, __func__, CHANNEL_CANTSEND));
	}
	while (readpacket (channel, confirm, sizeof (* confirm)) > 0)
	{
		if (ntohs (confirm->ethernet.MTYPE) != ETH_P_HPAV)
		{
			slac_debug (session, session->exit, __func__, "Ignore MTYPE 0x%04X", htons (confirm->ethernet.MTYPE));
			continue;
		}
		if (confirm->homeplug.MMV != HOMEPLUG_MMV)
		{
			slac_debug (session, session->exit, __func__, "Ignore MMV 0x%02X", confirm->homeplug.MMV);
			continue;
		}
		if (LE32TOH (confirm->homeplug.MMTYPE) != (CM_SET_KEY | MMTYPE_CNF))
		{
			slac_debug (session, session->exit, __func__, "Ignore MMTYPE 0x%04X", LE32TOH (confirm->homeplug.MMTYPE));
			continue;
		}
		slac_debug (session, 0, __func__, "<-- CM_SET_KEY.CNF");
		if (! confirm->RESULT)
		{
			return (slac_debug (session, session->exit, __func__, "Can't set keys"));
		}

#if SLAC_DEBUG

		if (_anyset (session->flags, SLAC_VERBOSE))
		{
			char string [1024];
			slac_debug (session, 0, __func__, "CM_SET_KEY.RESULT %d", confirm->RESULT);
			slac_debug (session, 0, __func__, "CM_SET_KEY.MYNOUNCE %s", hexstring (string, sizeof (string), & confirm->MYNOUNCE, sizeof (confirm->MYNOUNCE)));
			slac_debug (session, 0, __func__, "CM_SET_KEY.YOURNOUNCE %s", hexstring (string, sizeof (string), & confirm->YOURNOUNCE, sizeof (confirm->MYNOUNCE)));
			slac_debug (session, 0, __func__, "CM_SET_KEY.PID %d", confirm->PID);
			slac_debug (session, 0, __func__, "CM_SET_KEY.PRN %d", LE32TOH (confirm->PRN));
			slac_debug (session, 0, __func__, "CM_SET_KEY.PMN %d", confirm->PMN);
			slac_debug (session, 0, __func__, "CM_SET_KEY.CCoCAP %d", confirm->CCOCAP);
		}

#endif

		return (0);
	}
	return (slac_debug (session, session->exit, __func__, "<-- CM_SET_KEY.CNF ?"));
}