signed RemoteHosts (struct plc * plc)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_sw_ver_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
	}
	* request = (struct vs_sw_ver_request *) (message);
	struct __packed vs_sw_ver_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint32_t NUMDEVICES;
		struct __packed
		{
			uint8_t MACADDRESS [ETHER_ADDR_LEN];
			uint8_t ENUMID;
		}
		DEVICE [1];
	}
	* confirm = (struct vs_sw_ver_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Request Enumeration ID Table");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_EM_ID_TABLE | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_EM_ID_TABLE | MMTYPE_CNF)) > 0)
	{
		unsigned count = LE32TOH (confirm->NUMDEVICES);
		if (confirm->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			continue;
		}
		while (count--)
		{
			hexout (confirm->DEVICE [count].MACADDRESS, ETHER_ADDR_LEN, ':', count? ' ': '\n', stdout);
		}
	}
	return (0);
}
static signed DefaultVLANIDs (struct plc * plc, struct item list [], unsigned items)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_forward_config_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t RESERVED1;
		uint8_t MREQUEST;
		uint8_t MVERSION;
		uint32_t RESERVED2;
		uint16_t VLANID;
		uint16_t RESERVED3;
	}
	* request = (struct vs_forward_config_request *) (message);
	struct __packed vs_forward_config_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t RESERVED1;
		uint8_t RESULTCODE;
		uint8_t OPERATION;
		uint8_t MVERSION;
		uint32_t RESERVED2;
	}
	* confirm = (struct vs_forward_config_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_FORWARD_CONFIG | MMTYPE_REQ));
	request->MREQUEST = PLCFWD_SET;
	request->MVERSION = PLCFWD_VER;
	request->VLANID = HTOLE16 (list [0].VLANID [0]);
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_FORWARD_CONFIG | MMTYPE_CNF)) > 0)
	{
		if (confirm->RESULTCODE)
		{
			Failure (plc, PLC_WONTDOIT);
			continue;
		}
	}
	return (0);
}
Exemple #3
0
static signed mod_conn (struct plc * plc, uint8_t TYPE, uint16_t CID) 

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_mod_conn_req 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint32_t REQ_ID;
		uint32_t RSVD;
		uint16_t CID;
		uint8_t MOD_CTRL;
	}
	* request = (struct vs_mod_conn_req *)(message);
	struct __packed vs_mod_conn_cnf 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint32_t REQ_ID;
		uint8_t MSTATUS;
		uint16_t ERR_REC_CODE;
		uint32_t RSVD;
		uint16_t CID;
	}
	* confirm = (struct vs_mod_conn_cnf *)(message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "COQOS modify connection");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, HOMEPLUG_MTYPE);
	QualcommHeader (&request->qualcomm, 0, (VS_MOD_CONN | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	request->MOD_CTRL = TYPE;
	request->CID = CID;
	if (SendMME (plc) <= 0) 
	{
		error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_MOD_CONN | MMTYPE_CNF)) > 0) 
	{
		if (confirm->MSTATUS) 
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		Confirm (plc, "%s connection %04X", (TYPE == ACTION_SPND)? "Suspended": "Resumed", CID);
	}
	return (0);
}
signed rel_conn (struct plc * plc, uint16_t CID)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_rel_conn_req
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint32_t REQ_ID;
		uint32_t RSVD;
		uint16_t CID;
	}
	* request = (struct vs_rel_conn_req *)(message);
	struct __packed vs_rel_conn_cnf
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint32_t REQ_ID;
		uint8_t MSTATUS;
		uint16_t ERR_REC_CODE;
		uint32_t RSVD;
	}
	* confirm = (struct vs_rel_conn_cnf *)(message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Release COQOS connection");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_CONN_REL | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	request->CID = CID;
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_CONN_REL | MMTYPE_CNF)) > 0)
	{
		if (confirm->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		Confirm (plc, "Released %04X", CID);
	}
	return (0);
}
Exemple #5
0
signed Flash (struct int6k * int6k) 

{
	struct channel * channel = (struct channel *)(int6k->channel);
	struct message * message = (struct message *)(int6k->message);

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

	struct __packed vs_mod_nvm_request 
	{
		struct header_eth ethernet;
		struct header_int intellon;
		uint8_t MODULEID;
	}
	* request = (struct vs_mod_nvm_request *) (message);
	struct __packed vs_mod_nvm_confirm 
	{
		struct header_eth ethernet;
		struct header_int intellon;
		uint8_t MSTATUS;
		uint8_t MODULEID;
	}
	* confirm = (struct vs_mod_nvm_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (int6k, "Flash NVRAM");
	memset (message, 0, sizeof (struct message));
	EthernetHeader (&message->ethernet, channel->peer, channel->host);
	IntellonHeader (&message->intellon, (VS_MOD_NVM | MMTYPE_REQ));
	int6k->packetsize = ETHER_MIN_LEN;
	request->MODULEID = int6k->modulecode;
	if (SendMME (int6k) <= 0) 
	{
		error ((int6k->flags & INT6K_BAILOUT), ECANCELED, INT6K_CANTSEND);
		return (-1);
	}
	if (ReadMME (int6k, (VS_MOD_NVM | MMTYPE_CNF)) <= 0) 
	{
		error ((int6k->flags & INT6K_BAILOUT), ECANCELED, INT6K_CANTREAD);
		return (-1);
	}
	if (confirm->MSTATUS) 
	{
		Failure (int6k, INT6K_WONTDOIT);
		return (-1);
	}
	Confirm (int6k, "Flashing ...");
	return (0);
}
Exemple #6
0
signed Classification (struct plc * plc, struct MMERule * rule) 

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_classification_request 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		struct MMERule rule;
	}
	* request = (struct vs_classification_request *)(message);
	struct __packed vs_classification_confirm 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint8_t MSTATUS;
	}
	* confirm = (struct vs_classification_confirm *)(message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Set Classification Rules");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_CLASSIFICATION | MMTYPE_REQ));
	plc->packetsize = sizeof (struct vs_classification_request);
	memcpy (&request->rule, rule, sizeof (request->rule));
	if (SendMME (plc) <= 0) 
	{
		error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	if (ReadMME (plc, 0, (VS_CLASSIFICATION | MMTYPE_CNF)) <= 0) 
	{
		error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTREAD);
		return (-1);
	}
	if (confirm->MSTATUS) 
	{
		Failure (plc, PLC_WONTDOIT);
		return (-1);
	}
	Confirm (plc, "Setting ...");
	return (0);
}
Exemple #7
0
signed FlashNVM (struct plc * plc) 

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_mod_nvm_request 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint8_t MODULEID;
	}
	* request = (struct vs_mod_nvm_request *) (message);
	struct __packed vs_mod_nvm_confirm 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint8_t MSTATUS;
		uint8_t MODULEID;
	}
	* confirm = (struct vs_mod_nvm_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Flash device");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_MOD_NVM | MMTYPE_REQ));
	request->MODULEID = plc->module;
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	if (SendMME (plc) <= 0) 
	{
		error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	if (ReadMME (plc, 0, (VS_MOD_NVM | MMTYPE_CNF)) <= 0) 
	{
		error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTREAD);
		return (-1);
	}
	if (confirm->MSTATUS) 
	{
		Failure (plc, PLC_WONTDOIT);
		return (-1);
	}
	return (0);
}
signed HostActionIndicate (struct plc * plc)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_host_action_ind
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MACTION;
		uint8_t MAJOR_VERSION;
		uint8_t MINOR_VERSION;
	}
	* indicate = (struct vs_host_action_ind *) (message);
	struct __packed vs_host_action_rsp
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
	}
	* response = (struct vs_host_action_rsp *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Start Host Action");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&indicate->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&indicate->qualcomm, 0, (VS_HOST_ACTION | MMTYPE_IND));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	indicate->MACTION = plc->action;
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_HOST_ACTION | MMTYPE_RSP)) > 0)
	{
		if (response->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			continue;
		}
		Confirm (plc, "Start.");
	}
	return (0);
}
Exemple #9
0
signed VersionInfo (struct int6k * int6k) 

{
	extern const char * chipset [CHIPSETS+1];
	struct channel * channel = (struct channel *)(int6k->channel);
	struct message * message = (struct message *)(int6k->message);

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

	struct __packed vs_sw_ver_confirm 
	{
		struct header_eth ethernet;
		struct header_int intellon;
		uint8_t MSTATUS;
		uint8_t MDEVICEID;
		uint8_t MVERLENGTH;
		char MVERSION [INT6K_VERSTRING];
		uint8_t UPGRADEABLE;
		uint32_t MCOOKIE;
	}
	* confirm = (struct vs_sw_ver_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (int6k, "Request Version Information");
	memset (message, 0, sizeof (struct message));
	EthernetHeader (&message->ethernet, channel->peer, channel->host);
	IntellonHeader (&message->intellon, (VS_SW_VER | MMTYPE_REQ));
	int6k->packetsize = ETHER_MIN_LEN;
	if (SendMME (int6k) <= 0) 
	{
		error ((int6k->flags & INT6K_BAILOUT), ECANCELED, INT6K_CANTSEND);
		return (-1);
	}
	while (ReadMME (int6k, (VS_SW_VER | MMTYPE_CNF)) > 0) 
	{
		if (confirm->MSTATUS) 
		{
			Failure (int6k, INT6K_WONTDOIT);
			continue;
		}
		if (confirm->MDEVICEID > CHIPSETS) 
		{
			confirm->MDEVICEID = 0x00;
		}
		Display (int6k, "%s %s", chipset [confirm->MDEVICEID], confirm->MVERSION);
	}
	return (0);
}
Exemple #10
0
signed VersionInfo1 (struct plc * plc) 

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_sw_ver_request 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
	}
	* request = (struct vs_sw_ver_request *) (message);
	struct __packed vs_sw_ver_confirm 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint8_t MSTATUS;
		uint8_t MDEVICEID;
		uint8_t MVERLENGTH;
		char MVERSION [PLC_VERSION_STRING];
	}
	* confirm = (struct vs_sw_ver_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Request Version Information");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_SW_VER | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	if (SendMME (plc) <= 0) 
	{
		error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_SW_VER | MMTYPE_CNF)) > 0) 
	{
		if (confirm->MSTATUS) 
		{
			Failure (plc, PLC_WONTDOIT);
			continue;
		}
		chipset (confirm);
		Display (plc, "%s %s", chipsetname (confirm->MDEVICEID), confirm->MVERSION);
	}
	return (0);
}
Exemple #11
0
signed Antiphon (struct plc * plc, byte source [], byte target []) 

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_fr_lbk_request 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint8_t DURATION;
		uint8_t RESERVED;
		uint16_t LENGTH;
		uint8_t PACKET [1038];
	}
	* request = (struct vs_fr_lbk_request *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	if (_allclr (plc->flags, PLC_SILENCE)) 
	{
		char sourcename [ETHER_ADDR_LEN * 3];
		char targetname [ETHER_ADDR_LEN * 3];
		hexdecode (source, ETHER_ADDR_LEN, sourcename, sizeof (sourcename));
		hexdecode (target, ETHER_ADDR_LEN, targetname, sizeof (targetname));
		fprintf (stderr, "%s %s %s\n", channel->ifname, sourcename, targetname);
	}
	memset (message, 0, sizeof (* message));
	EthernetHeader (&message->ethernet, source, channel->host, HOMEPLUG_MTYPE);
	QualcommHeader (&message->qualcomm, 0, (VS_FR_LBK | MMTYPE_REQ));
	request->DURATION = plc->timer;
	request->LENGTH = HTOLE16 (sizeof (request->PACKET));
	memset (request->PACKET, 0xA5, sizeof (request->PACKET));
	EthernetHeader (request->PACKET, target, source, ETHERTYPE_IP);
	plc->packetsize = sizeof (* request);
	if (SendMME (plc) <= 0) 
	{
		error (1, errno, CHANNEL_CANTSEND);
	}
	if (ReadMME (plc, 0, (VS_FR_LBK | MMTYPE_CNF)) <= 0) 
	{
		error (1, errno, CHANNEL_CANTREAD);
	}
	sleep (plc->timer);
	return (0);
}
signed FactoryDefaults (struct plc * plc)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_fac_defaults_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
	}
	* request = (struct vs_fac_defaults_request *) (message);
	struct __packed vs_fac_defaults_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
	}
	* confirm = (struct vs_fac_defaults_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Restore Factory Defaults");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_FAC_DEFAULTS | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_FAC_DEFAULTS | MMTYPE_CNF)) > 0)
	{
		if (confirm->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			continue;
		}
		Confirm (plc, "Restoring ...");
	}
	return (0);
}
signed PLCNetworkInfo (struct plc * plc)

{
	signed status;
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_sw_ver_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint8_t MDEVICEID;
		uint8_t MVERLENGTH;
		char MVERSION [PLC_VERSION_STRING];
	}
	* request = (struct vs_sw_ver_request *) (message);
	struct __packed vs_sw_ver_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint8_t MDEVICEID;
		uint8_t MVERLENGTH;
		char MVERSION [PLC_VERSION_STRING];
	}
	* confirm = (struct vs_sw_ver_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_SW_VER | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	if (ReadMME (plc, 0, (VS_SW_VER | MMTYPE_CNF)) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
		return (-1);
	}
	if (confirm->MSTATUS)
	{
		Failure (plc, "Device will not start");
		return (-1);
	}
	chipset (confirm);
	if ((plc->hardwareID = confirm->MDEVICEID) < CHIPSET_AR7400)
	{
		status = NetInfo1 (plc);
	}
	else
	{
		status = NetInfo2 (plc);
	}
	return (status);
}
signed EmulateHost (struct plc * plc)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);
	static char const * actions [] =
	{
		"start device",
		"store firmware",
		"store parameters",
		"update host",
		"config memory",
		"restore defaults",
		"unknown"
	};

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

	struct __packed vs_host_action_ind
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MACTION;
		uint8_t MAJOR_VERSION;
		uint8_t MINOR_VERSION;
	}
	* indicate = (struct vs_host_action_ind *) (message);

#if 0

	struct __packed vs_host_action_rsp
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
	}
	* response = (struct vs_host_action_rsp *) (message);

#endif

#ifndef __GNUC__
#pragma pack (pop)
#endif

	struct nvm_header1 nvm_header;
	struct pib_header pib_header;
	uint32_t offset;
	char const * PIB = plc->PIB.name;
	char const * NVM = plc->NVM.name;
	signed timer = channel->timeout;
	signed status = 0;
	Request (plc, "Waiting for Host Action");
	while (1)
	{
		channel->timeout = plc->timer;
		status = ReadMME (plc, 0, (VS_HOST_ACTION | MMTYPE_IND));
		channel->timeout = timer;
		if (status < 0)
		{
			break;
		}
		if (status > 0)
		{
			printf ("\n");
			if (indicate->MACTION < (sizeof (actions) / sizeof (char const *)))
			{
				Confirm (plc, "Host Action Request is (%d) %s.", indicate->MACTION, actions [indicate->MACTION]);
			}
			else
			{
				error (0, ENOTSUP, "Host Action 0x%0X", indicate->MACTION);
				continue;
			}
			memcpy (channel->peer, indicate->ethernet.OSA, sizeof (channel->peer));
			channel->timeout = timer;
			if (indicate->MACTION == 0x00)
			{
				unsigned module = 0;
				char firmware [PLC_VERSION_STRING];
				if (HostActionResponse (plc))
				{
					return (-1);
				}
				if (lseek (plc->PIB.file, 0, SEEK_SET))
				{
					error (1, errno, FILE_CANTHOME, plc->PIB.name);
				}
				if (read (plc->PIB.file, &pib_header, sizeof (pib_header)) != sizeof (pib_header))
				{
					error (1, errno, FILE_CANTREAD, plc->PIB.name);
				}
				if (lseek (plc->PIB.file, 0, SEEK_SET))
				{
					error (1, errno, FILE_CANTHOME, plc->PIB.name);
				}
				if (BE16TOH (*(uint16_t *)(&pib_header)) < 0x0305)
				{
					offset = LEGACY_PIBOFFSET;
				}
				else if (BE16TOH (*(uint16_t *)(&pib_header)) < 0x0500)
				{
					offset = INT6x00_PIBOFFSET;
				}
				else
				{
					offset = AR7x00_PIBOFFSET;
				}
				if (WriteMEM (plc, &plc->PIB, 0, offset, LE16TOH (pib_header.PIBLENGTH)))
				{
					return (-1);
				}
				if (lseek (plc->NVM.file, 0, SEEK_SET))
				{
					error (1, errno, FILE_CANTHOME, plc->NVM.name);
				}
				if (read (plc->NVM.file, &nvm_header, sizeof (nvm_header)) != sizeof (nvm_header))
				{
					error (1, errno, FILE_CANTREAD, plc->NVM.name);
				}
				while (nvm_header.NEXTHEADER)
				{
					lseek (plc->NVM.file, LE32TOH (nvm_header.NEXTHEADER), SEEK_SET);
					if (read (plc->NVM.file, &nvm_header, sizeof (nvm_header)) != sizeof (nvm_header))
					{
						error (1, errno, FILE_CANTREAD, plc->NVM.name);
					}
					module++;
				}
				if (WriteFirmware1 (plc, module, &nvm_header))
				{
					return (-1);
				}
				if (StartFirmware1 (plc, module, &nvm_header))
				{
					return (-1);
				}
				if (WaitForStart (plc, firmware, sizeof (firmware)))
				{
					return (-1);
				}
				if (_anyset (plc->flags, PLC_FLASH_DEVICE))
				{
					if (WriteNVM (plc))
					{
						return (-1);
					}
					if (WritePIB (plc))
					{
						return (-1);
					}
					if (FlashNVM (plc))
					{
						return (-1);
					}
				}
				continue;
			}
			if (indicate->MACTION == 0x01)
			{
				if (HostActionResponse (plc))
				{
					return (-1);
				}
				close (plc->NVM.file);
				if (ReadFirmware1 (plc))
				{
					return (-1);
				}
				if ((plc->NVM.file = open (plc->NVM.name = plc->nvm.name, O_BINARY|O_RDONLY)) == -1)
				{
					error (1, errno, "%s", plc->NVM.name);
				}
				if (ResetDevice (plc))
				{
					return (-1);
				}
				continue;
			}
			if (indicate->MACTION == 0x02)
			{
				if (HostActionResponse (plc))
				{
					return (-1);
				}
				close (plc->PIB.file);
				if (ReadParameters1 (plc))
				{
					return (-1);
				}
				if ((plc->PIB.file = open (plc->PIB.name = plc->pib.name, O_BINARY|O_RDONLY)) == -1)
				{
					error (1, errno, "%s", plc->PIB.name);
				}
				if (ResetDevice (plc))
				{
					return (-1);
				}
				continue;
			}
			if (indicate->MACTION == 0x03)
			{
				if (HostActionResponse (plc))
				{
					return (-1);
				}
				close (plc->NVM.file);
				if (ReadFirmware1 (plc))
				{
					return (-1);
				}
				if ((plc->NVM.file = open (plc->NVM.name = plc->nvm.name, O_BINARY|O_RDONLY)) == -1)
				{
					error (1, errno, "%s", plc->NVM.name);
				}
				close (plc->PIB.file);
				if (ReadParameters1 (plc))
				{
					return (-1);
				}
				if ((plc->PIB.file = open (plc->PIB.name = plc->pib.name, O_BINARY|O_RDONLY)) == -1)
				{
					error (1, errno, "%s", plc->PIB.name);
				}
				if (ResetDevice (plc))
				{
					return (-1);
				}
				continue;
			}
			if (indicate->MACTION == 0x04)
			{

#if 0

/*
 *	Due to an omission in the INT6300 BootLoader, responding to this VS_HOST_ACTION
 *      indication will suppress subsequent VS_HOST_ACTION messages and the device will
 *     	not request firmware and parameters; this may be corrected on the INT6400;
 */

				if (HostActionResponse (plc))
				{
					return (-1);
				}

#endif

				if (WriteCFG (plc))
				{
					return (-1);
				}

/*
 *	At this point, one could download firmware and parameters without waiting for
 *	further  requests from the device; however, we elect to wait for them since it
 *	is 'good form'; a device should send code 0x00 within 10 seconds of this one;
 */

				continue;
			}
			if (indicate->MACTION == 0x05)
			{
				if (HostActionResponse (plc))
				{
					return (-1);
				}
				close (plc->NVM.file);
				if ((plc->NVM.file = open (plc->NVM.name = NVM, O_BINARY|O_RDONLY)) == -1)
				{
					error (1, errno, "%s", plc->NVM.name);
				}
				close (plc->PIB.file);
				if ((plc->PIB.file = open (plc->PIB.name = PIB, O_BINARY|O_RDONLY)) == -1)
				{
					error (1, errno, "%s", plc->PIB.name);
				}
				if (ResetDevice (plc))
				{
					return (-1);
				}
				continue;
			}
			error (0, ENOSYS, "Host Action 0x%0X", indicate->MACTION);
		}
	}
	return (0);
}
signed MDUTrafficStats (struct plc * plc, uint8_t command, uint8_t session, uint8_t slave)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_mdu_station_stats_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t COMMAND;
		uint8_t SESSION;
		uint32_t SLAVE_BITMAP [8];
	}
	* request = (struct vs_mdu_station_stats_request *) (message);
	struct __packed vs_mdu_traffic_master_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t COMMAND;
		uint8_t SESSION;
		uint16_t RESERVED;
		uint8_t NUM_SLAVES;
		uint8_t NUM_SLAVES_LEFT;
		uint16_t STATS_LEN;
		struct station_stats STATS [1];
	}
	* master_confirm = (struct vs_mdu_traffic_master_confirm *) (message);
	struct __packed vs_mdu_traffic_slave_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t COMMAND;
		uint8_t SESSION;
		uint16_t STATS_LEN;
		struct station_stats STATS [1];
	}
	* slave_confirm = (struct vs_mdu_traffic_slave_confirm *) (message);

#if 1

	struct __packed vs_eth_hardware_stats_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t COMMAND;
		uint8_t SESSION;
		uint8_t CHIPTYPE;
		uint8_t STATUS;
		uint16_t STATS_LEN;
		struct ethernet_stats STATS [1];
	}
	* ether_confirm = (struct vs_eth_hardware_stats_confirm *) (message);

#endif

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Request MDU Traffic Statistics (1)");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_MDU_TRAFFIC_STATS | MMTYPE_REQ));
	request->COMMAND = command;
	request->SESSION = session;
	set32bitmap (request->SLAVE_BITMAP, slave);
	plc->packetsize = sizeof (* request);
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_MDU_TRAFFIC_STATS | MMTYPE_CNF)) > 0)
	{
		if ((request->COMMAND > 0x00) && (request->COMMAND < 0x0020))
		{
			struct station_stats * stats;
			unsigned count;
			if (_anyset (request->COMMAND, MASTER_TX_RX | SLAVE_TX_RX))
			{
				stats = master_confirm->STATS;
				count = LE16TOH (master_confirm->STATS_LEN);
			}
			else
			{
				stats = slave_confirm->STATS;
				count = LE16TOH (slave_confirm->STATS_LEN);
			}
			while (count >= sizeof (struct station_stats))
			{
				StationStats (plc, stats++);
				count -= sizeof (struct station_stats);
			}
			continue;
		}
		if ((request->COMMAND >= 0x20) && (request->COMMAND < 0x24))
		{
			EthernetStats (plc, ether_confirm->STATS);
			continue;
		}
		if ((request->COMMAND >= 0x24) && (request->COMMAND < 0x28))
		{
			EthernetStats (plc, ether_confirm->STATS);
			continue;
		}
		if ((request->COMMAND >= 0x28) && (request->COMMAND < 0x32))
		{
			EthernetStats (plc, ether_confirm->STATS);
			continue;
		}
	}
	return (0);
}
signed WriteFirmware1 (struct plc * plc, unsigned module, const struct nvm_header1 * nvm_header)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_wr_mem_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint32_t MOFFSET;
		uint32_t MLENGTH;
		uint8_t BUFFER [PLC_RECORD_SIZE];
	}
	* request = (struct vs_wr_mem_request *) (message);
	struct __packed vs_wr_mem_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint32_t MOFFSET;
		uint32_t MLENGTH;
	}
	* confirm = (struct vs_wr_mem_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	uint32_t length = PLC_RECORD_SIZE;
	uint32_t offset = LE32TOH (nvm_header->IMAGEADDRESS);
	uint32_t extent = LE32TOH (nvm_header->IMAGELENGTH);
	Request (plc, "Write %s (%d) (%08X:%d)", plc->NVM.name, module, offset, extent);
	while (extent)
	{
		memset (message, 0, sizeof (* message));
		EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
		QualcommHeader (&request->qualcomm, 0, (VS_WR_MEM | MMTYPE_REQ));
		if (length > extent)
		{
			length = extent;
		}
		if (read (plc->NVM.file, request->BUFFER, length) != (signed)(length))
		{
			error (1, errno, FILE_CANTREAD, plc->NVM.name);
		}
		request->MLENGTH = HTOLE32 (length);
		request->MOFFSET = HTOLE32 (offset);
		plc->packetsize = sizeof (* request);
		if (SendMME (plc) <= 0)
		{
			error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
			return (-1);
		}
		if (ReadMME (plc, 0, (VS_WR_MEM | MMTYPE_CNF)) <= 0)
		{
			error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
			return (-1);
		}
		if (confirm->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		if (LE32TOH (confirm->MLENGTH) != length)
		{
			error (PLC_EXIT (plc), 0, PLC_ERR_LENGTH);
			return (-1);
		}
		if (LE32TOH (confirm->MOFFSET) != offset)
		{
			error (PLC_EXIT (plc), 0, PLC_ERR_OFFSET);
			return (-1);
		}
		offset += length;
		extent -= length;
	}
	return (0);
}
Exemple #17
0
signed WaitForStart (struct plc * plc, char string [], size_t length) 

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);
	struct timeval ts;
	struct timeval tc;
	unsigned timer = 0;

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

	struct __packed vs_sw_ver_request 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint8_t MSTATUS;
		uint8_t MDEVICEID;
		uint8_t MVERLENGTH;
		char MVERSION [PLC_VERSION_STRING];
	}
	* request = (struct vs_sw_ver_request *) (message);
	struct __packed vs_sw_ver_confirm 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint8_t MSTATUS;
		uint8_t MDEVICEID;
		uint8_t MVERLENGTH;
		char MVERSION [PLC_VERSION_STRING];
	}
	* confirm = (struct vs_sw_ver_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Allow %d seconds for Start", plc->timer);
	if (gettimeofday (&ts, NULL) == -1) 
	{
		error (1, errno, CANT_START_TIMER);
	}
	for (timer = 0; timer < plc->timer; timer = SECONDS (ts, tc)) 
	{
		memset (message, 0, sizeof (* message));
		EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
		QualcommHeader (&request->qualcomm, 0, (VS_SW_VER | MMTYPE_REQ));
		plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
		if (SendMME (plc) <= 0) 
		{
			error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND);
			return (-1);
		}
		if (ReadMME (plc, 0, (VS_SW_VER | MMTYPE_CNF)) < 0) 
		{
			error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTREAD);
			return (-1);
		}
		if (gettimeofday (&tc, NULL) == -1) 
		{
			error (1, errno, CANT_RESET_TIMER);
		}
		if (plc->packetsize) 
		{
			if (confirm->MSTATUS) 
			{
				Failure (plc, PLC_WONTDOIT);
				return (-1);
			}
			if (_allset (plc->flags, (PLC_WAITFORSTART | PLC_ANALYSE))) 
			{
				Confirm (plc, "Waited %d seconds for Start", timer);
			}
			strncpy (string, confirm->MVERSION, length);
			return (0);
		}
	}
	if (_allset (plc->flags, (PLC_WAITFORSTART | PLC_ANALYSE))) 
	{
		Confirm (plc, "Waited %d seconds for Start", timer);
	}
	return (-1);
}
Exemple #18
0
signed SetNMK (struct plc * plc)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_set_key_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t EKS;
		uint8_t NMK [HPAVKEY_NMK_LEN];
		uint8_t PEKS;
		uint8_t RDA [ETHER_ADDR_LEN];
		uint8_t DAK [HPAVKEY_DAK_LEN];
	}
	* request = (struct vs_set_key_request *) (message);
	struct __packed vs_set_key_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
	}
	* confirm = (struct vs_set_key_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_SET_KEY | MMTYPE_REQ));
	plc->packetsize = sizeof (struct vs_set_key_request);
	request->EKS = 0x01;
	memcpy (request->NMK, plc->NMK, sizeof (request->NMK));
	if (_anyset (plc->flags, PLC_SETREMOTEKEY))
	{
		Request (plc, "Set Remote Network Membership Key");
		memcpy (request->RDA, plc->RDA, sizeof (request->RDA));
		memcpy (request->DAK, plc->DAK, sizeof (request->DAK));
		request->PEKS = 0x00;
	}
	else
	{
		Request (plc, "Set Local Network Membership Key");
		memset (request->RDA, 0, sizeof (request->RDA));
		memset (request->DAK, 0, sizeof (request->DAK));
		request->PEKS = 0x0F;
	}
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	if (ReadMME (plc, 0, (VS_SET_KEY | MMTYPE_CNF)) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
		return (-1);
	}
	if (confirm->MSTATUS)
	{
		Failure (plc, PLC_WONTDOIT);
		return (-1);
	}
	Confirm (plc, "Setting ...");
	return (0);
}
Exemple #19
0
signed ModuleWrite (struct plc * plc, struct _file_ * file, unsigned index, struct vs_module_spec * vs_module_spec) 

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_module_operation_write_request 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint32_t RESERVED;
		uint8_t NUM_OP_DATA;
		struct __packed 
		{
			uint16_t MOD_OP;
			uint16_t MOD_OP_DATA_LEN;
			uint32_t MOD_OP_RSVD;
			uint32_t MOD_OP_SESSION_ID;
			uint8_t MODULE_IDX;
			uint16_t MODULE_ID;
			uint16_t MODULE_SUB_ID;
			uint16_t MODULE_LENGTH;
			uint32_t MODULE_OFFSET;
		}
		MODULE_SPEC;
		uint8_t MODULE_DATA [PLC_MODULE_SIZE];
	}
	* request = (struct vs_module_operation_write_request *)(message);
	struct __packed vs_module_operation_write_confirm 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint16_t MSTATUS;
		uint16_t ERR_REC_CODE;
		uint32_t RESERVED;
		uint8_t NUM_OP_DATA;
		struct __packed 
		{
			uint16_t MOD_OP;
			uint16_t MOD_OP_DATA_LEN;
			uint32_t MOD_OP_RSVD;
			uint32_t MOD_OP_SESSION_ID;
			uint8_t MODULE_IDX;
			uint16_t MODULE_ID;
			uint16_t MODULE_SUB_ID;
			uint16_t MODULE_LENGTH;
			uint32_t MODULE_OFFSET;
		}
		MODULE_SPEC;
	}
	* confirm = (struct vs_module_operation_write_confirm *)(message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	unsigned timeout = channel->timeout;
	uint16_t length = PLC_MODULE_SIZE;
	uint32_t extent = vs_module_spec->MODULE_LENGTH;
	uint32_t offset = 0;
	Request (plc, "Flash %s", file->name);
	while (extent) 
	{
		memset (message, 0, sizeof (* message));
		EthernetHeader (&request->ethernet, channel->peer, channel->host, HOMEPLUG_MTYPE);
		QualcommHeader (&request->qualcomm, 0, (VS_MODULE_OPERATION | MMTYPE_REQ));
		plc->packetsize = sizeof (struct vs_module_operation_write_request);
		if (length > extent) 
		{
			length = extent;
		}
		if (read (file->file, request->MODULE_DATA, length) != length) 
		{
			error (1, errno, FILE_CANTREAD, file->name);
		}
		request->NUM_OP_DATA = 1;
		request->MODULE_SPEC.MOD_OP = HTOLE16 (PLC_MOD_OP_WRITE_MODULE);
		request->MODULE_SPEC.MOD_OP_DATA_LEN = HTOLE16 (sizeof (request->MODULE_SPEC) + sizeof (request->MODULE_DATA));
		request->MODULE_SPEC.MOD_OP_SESSION_ID = HTOLE32 (plc->cookie);
		request->MODULE_SPEC.MODULE_IDX = index;
		request->MODULE_SPEC.MODULE_ID = HTOLE16 (vs_module_spec->MODULE_ID);
		request->MODULE_SPEC.MODULE_SUB_ID = HTOLE16 (vs_module_spec->MODULE_SUB_ID);
		request->MODULE_SPEC.MODULE_LENGTH = HTOLE16 (length);
		request->MODULE_SPEC.MODULE_OFFSET = HTOLE32 (offset);

#if 0

		fprintf (stderr, "RESERVED 0x%08X\n", LE32TOH (request->RESERVED));
		fprintf (stderr, "NUM_OP_DATA %d\n", request->NUM_OP_DATA);
		fprintf (stderr, "MOD_OP 0x%02X\n", LE16TOH (request->MODULE_SPEC.MOD_OP));
		fprintf (stderr, "MOD_OP_DATA_LEN %d\n", LE16TOH (request->MODULE_SPEC.MOD_OP_DATA_LEN));
		fprintf (stderr, "RESERVED 0x%08X\n", LE32TOH (request->MODULE_SPEC.MOD_OP_RSVD));
		fprintf (stderr, "MODULE_ID 0x%04X\n", LE16TOH (request->MODULE_SPEC.MODULE_ID));
		fprintf (stderr, "MODULE_SUB_ID 0x%04X\n", LE16TOH (request->MODULE_SPEC.MODULE_SUB_ID));
		fprintf (stderr, "MODULE_LENGTH %d\n", LE16TOH (request->MODULE_SPEC.MODULE_LENGTH));
		fprintf (stderr, "MODULE_OFFSET 0x%08X\n", LE32TOH (request->MODULE_SPEC.MODULE_OFFSET));

#endif

		if (SendMME (plc) <= 0) 
		{
			error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND);
			return (-1);
		}
		channel->timeout = PLC_MODULE_WRITE_TIMEOUT;
		if (ReadMME (plc, 0, (VS_MODULE_OPERATION | MMTYPE_CNF)) <= 0) 
		{
			error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTREAD);
			channel->timeout = timeout;
			return (-1);
		}
		channel->timeout = timeout;

#if 0

		fprintf (stderr, "MSTATUS 0x%04X\n", LE16TOH (confirm->MSTATUS));
		fprintf (stderr, "ERROR_REC_CODE %d\n", LE16TOH (confirm->ERR_REC_CODE));
		fprintf (stderr, "RESERVED 0x%08X\n", LE32TOH (confirm->RESERVED));
		fprintf (stderr, "NUM_OP_DATA %d\n", confirm->NUM_OP_DATA);
		fprintf (stderr, "MOD_OP 0x%02X\n", LE16TOH (request->MODULE_SPEC.MOD_OP));
		fprintf (stderr, "MOD_OP_DATA_LEN %d\n", LE16TOH (confirm->MODULE_SPEC.MOD_OP_DATA_LEN));
		fprintf (stderr, "RESERVED 0x%08X\n", LE32TOH (confirm->MODULE_SPEC.MOD_OP_RSVD));
		fprintf (stderr, "MODULE_ID 0x%04X\n", LE16TOH (confirm->MODULE_SPEC.MODULE_ID));
		fprintf (stderr, "MODULE_SUB_ID 0x%04X\n", LE16TOH (confirm->MODULE_SPEC.MODULE_SUB_ID));
		fprintf (stderr, "MODULE_LENGTH %d\n", LE16TOH (confirm->MODULE_SPEC.MODULE_LENGTH));
		fprintf (stderr, "MODULE_OFFSET 0x%08X\n", LE32TOH (request->MODULE_SPEC.MODULE_OFFSET));

#endif

		if (confirm->MSTATUS) 
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		if (LE16TOH (confirm->MODULE_SPEC.MODULE_LENGTH) != length) 
		{
			error ((plc->flags & PLC_BAILOUT), 0, PLC_ERR_LENGTH);
			return (-1);
		}
		if (LE32TOH (confirm->MODULE_SPEC.MODULE_OFFSET) != offset) 
		{
			error ((plc->flags & PLC_BAILOUT), 0, PLC_ERR_OFFSET);
			return (-1);
		}
		extent -= length;
		offset += length;
	}
	return (0);
}
static signed Diagnostics (struct plc * plc)

{
	char version [PLC_VERSION_STRING];
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_sw_ver_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint8_t MDEVICEID;
		uint8_t MVERLENGTH;
		char MVERSION [PLC_VERSION_STRING];
	}
	* request = (struct vs_sw_ver_request *) (message);
	struct __packed vs_sw_ver_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint8_t MDEVICEID;
		uint8_t MVERLENGTH;
		char MVERSION [PLC_VERSION_STRING];
	}
	* confirm = (struct vs_sw_ver_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_SW_VER | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	if (ReadMME (plc, 0, (VS_SW_VER | MMTYPE_CNF)) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
		return (-1);
	}
	if (confirm->MSTATUS)
	{
		Failure (plc, PLC_WONTDOIT);
		return (-1);
	}
	memcpy (version, confirm->MVERSION, sizeof (version));
	if (plc->action == INT6KLOG_FMT_XML)
	{
		printf ("<?xml version='1.0' encoding='utf-8' standalone='yes'?>");
		printf ("<Diagnostics>");
		PrintWatchdogReport (plc, version);
		PrintCheckpointReport (plc, version);
		printf ("</Diagnostics>\n");
		return (0);
	}
	if (plc->action == INT6KLOG_FMT_RAW)
	{
		PrintRawWatchdogReport (plc);
		return (0);
	}
	return (0);
}
static signed PrintCheckpointReport (struct plc * plc, char const * version)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_cp_rpt_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint16_t SESSIONID;
		uint8_t CLR;
	}
	* request = (struct vs_cp_rpt_request *) (message);
	struct __packed vs_cp_rpt_ind
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint8_t MAJORVERSION;
		uint8_t MINORVERSION;
		uint8_t RESERVED [14];
		uint16_t SESSIONID;
		uint32_t TOTALBUFFERSIZE;
		uint32_t BLOCKOFFSET;
		uint32_t BYTEINDEXOFNEXTPOSITION;
		uint8_t NUMPARTS;
		uint8_t CURPART;
		uint16_t RDATALENGTH;
		uint8_t RDATAOFFSET;
		uint8_t RDATA [1];
	}
	* indicate = (struct vs_cp_rpt_ind *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_CP_RPT | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	request->SESSIONID = HTOLE16 (plc->cookie);
	request->CLR = plc->readaction;
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	printf ("<CheckpointReport>");
	do
	{
		if (ReadMME (plc, 0, (VS_CP_RPT | MMTYPE_IND)) <= 0)
		{
			error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
			return (-1);
		}
		if (_anyset (indicate->MSTATUS, MSTATUS_STATUS))
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		printf ("<Packet>");
		printf ("<Version>%s</Version>", version);
		printf ("<Status>0</Status>");
		printf ("<MajorVersionBit>%d</MajorVersionBit>", indicate->MSTATUS & MSTATUS_MAJORVERSION? 1:0);
		printf ("<BufferIsLocked>%d</BufferIsLocked>", indicate->MSTATUS & MSTATUS_BUFFERISLOCKED? 1:0);
		printf ("<AutoLockOnResetIsOn>%d</AutoLockOnResetIsOn>", indicate->MSTATUS & MSTATUS_AUTOLOCKONRESET? 1:0);
		printf ("<UnsolicitedUpdatesIsOn>%d</UnsolicitedUpdatesIsOn>", indicate->MSTATUS & MSTATUS_UNSOLICITEDUPDATES? 1:0);
		printf ("<Unsolicited>%d</Unsolicited>", indicate->MSTATUS & MSTATUS_UNSOLICITED? 1:0);
		printf ("<MajorVersion>%d</MajorVersion>", indicate->MAJORVERSION);
		printf ("<MinorVersion>%d</MinorVersion>", indicate->MINORVERSION);
		printf ("<Reserved1>0</Reserved1>");
		printf ("<Reserved2>0</Reserved2>");
		printf ("<Reserved3>0</Reserved3>");
		printf ("<Reserved4>0</Reserved4>");
		printf ("<SessionId>1</SessionId>");
		printf ("<TotalBufferSize>%d</TotalBufferSize>", LE32TOH (indicate->TOTALBUFFERSIZE));
		printf ("<BlockOffset>%d</BlockOffset>", LE32TOH (indicate->BLOCKOFFSET));
		printf ("<ByteIndexOfNextPos>%d</ByteIndexOfNextPos>", LE32TOH (indicate->BYTEINDEXOFNEXTPOSITION));
		printf ("<NumParts>%d</NumParts>", indicate->NUMPARTS);
		printf ("<CurPart>%d</CurPart>", indicate->CURPART);
		printf ("<RDataLength>%d</RDataLength>", LE16TOH (indicate->RDATALENGTH));
		printf ("<RDataOffset>%d</RDataOffset>", indicate->RDATAOFFSET);
		printf ("<RData>");
		b64dump (indicate->RDATA + indicate->RDATAOFFSET, LE16TOH (indicate->RDATALENGTH), 0, stdout);
		printf ("</RData>");
		printf ("</Packet>");
	}
	while (indicate->CURPART < indicate->NUMPARTS);
	printf ("</CheckpointReport>");
	return (0);
}
static signed PrintWatchdogReport (struct plc * plc, char const * version)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_wd_rpt_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint16_t SESSIONID;
		uint8_t CLR;
	}
	* request = (struct vs_wd_rpt_request *) (message);
	struct __packed vs_wd_rpt_ind
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint16_t SESSIONID;
		uint8_t NUMPARTS;
		uint8_t CURPART;
		uint16_t RDATALENGTH;
		uint8_t RDATAOFFSET;
		uint8_t RDATA [1];
	}
	* indicate = (struct vs_wd_rpt_ind *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_WD_RPT | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	request->SESSIONID = HTOLE16 (plc->cookie);
	request->CLR = plc->readaction;
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	printf ("<WatchdogReport>");
	do
	{
		if (ReadMME (plc, 0, (VS_WD_RPT | MMTYPE_IND)) < 0)
		{
			error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
			return (-1);
		}
		if (indicate->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		printf ("<Packet>");
		printf ("<Version>%s</Version>", version);
		printf ("<OUI>%s</OUI>", "00B052");
		printf ("<Status>0</Status>");
		printf ("<SessionId>0</SessionId>");
		printf ("<NumParts>%d</NumParts>", indicate->NUMPARTS);
		printf ("<CurPart>%d</CurPart>", indicate->CURPART);
		printf ("<DataLength>%d</DataLength>", LE16TOH (indicate->RDATALENGTH));
		printf ("<DataOffset>%d</DataOffset>", indicate->RDATAOFFSET);
		printf ("<Data>");
		b64dump (indicate->RDATA + indicate->RDATAOFFSET, LE16TOH (indicate->RDATALENGTH) - indicate->RDATAOFFSET, 0, stdout);
		printf ("</Data>");
		printf ("</Packet>");
	}
	while (indicate->CURPART < indicate->NUMPARTS);
	printf ("</WatchdogReport>");
	return (0);
}
static signed PrintRawWatchdogReport (struct plc * plc)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_wd_rpt_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint16_t SESSIONID;
		uint8_t CLR;
	}
	* request = (struct vs_wd_rpt_request *) (message);
	struct __packed vs_wd_rpt_indicate
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint16_t SESSIONID;
		uint8_t NUMPARTS;
		uint8_t CURPART;
		uint16_t RDATALENGTH;
		uint8_t RDATAOFFSET;
		uint8_t RDATA [1];
	}
	* indicate = (struct vs_wd_rpt_indicate *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_WD_RPT | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	request->SESSIONID = HTOLE16 (plc->cookie);
	request->CLR = plc->readaction;
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	do
	{
		printf ("%d %d\n", LE16TOH (indicate->RDATALENGTH), indicate->RDATAOFFSET);
		if (ReadMME (plc, 0, (VS_WD_RPT | MMTYPE_IND)) <= 0)
		{
			error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
			return (-1);
		}
		printf ("%d %d\n", LE16TOH (indicate->RDATALENGTH), indicate->RDATAOFFSET);
		if (indicate->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		printf ("%d %d\n", LE16TOH (indicate->RDATALENGTH), indicate->RDATAOFFSET);
		write (STDOUT_FILENO, indicate->RDATA + indicate->RDATAOFFSET, LE16TOH (indicate->RDATALENGTH) - indicate->RDATAOFFSET);
	}
	while (indicate->CURPART < indicate->NUMPARTS);
	return (0);
}
signed WriteExecuteFirmware1 (struct plc * plc, unsigned module, const struct nvm_header1 * nvm_header) 

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_write_execute_request 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint32_t CLIENT_SESSION_ID;
		uint32_t SERVER_SESSION_ID;
		uint32_t FLAGS;
		uint8_t ALLOWED_MEM_TYPES [8];
		uint32_t TOTAL_LENGTH;
		uint32_t CURR_PART_LENGTH;
		uint32_t CURR_PART_OFFSET;
		uint32_t START_ADDR;
		uint32_t CHECKSUM;
		uint8_t RESERVED2 [8];
		uint8_t IMAGE [PLC_MODULE_SIZE];
	}
	* request = (struct vs_write_execute_request *) (message);
	struct __packed vs_write_execute_confirm 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint32_t MSTATUS;
		uint32_t CLIENT_SESSION_ID;
		uint32_t SERVER_SESSION_ID;
		uint32_t FLAGS;
		uint8_t ALLOWED_MEM_TYPES [8];
		uint32_t TOTAL_LENGTH;
		uint32_t CURR_PART_LENGTH;
		uint32_t CURR_PART_OFFSET;
		uint32_t START_ADDR;
		uint32_t CHECKSUM;
		uint8_t RESERVED2 [8];
		uint32_t CURR_PART_ABSOLUTE_ADDR;
		uint32_t ABSOLUTE_START_ADDR;
	}
	* confirm = (struct vs_write_execute_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	unsigned action = PLC_MODULE_ABSOLUTE;
	uint32_t length = PLC_MODULE_SIZE;
	uint32_t offset = LE32TOH (nvm_header->IMAGEADDRESS);
	uint32_t extent = LE32TOH (nvm_header->IMAGELENGTH);
	Request (plc, "Write %s (%d) (%08X:%d)", plc->NVM.name, module, offset, extent);
	while (extent) 
	{
		memset (message, 0, sizeof (* message));
		EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
		QualcommHeader (&request->qualcomm, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_REQ));
		if (length > extent) 
		{
			Request (plc, "Start %s (%d) (%08X)", plc->NVM.name, module, LE32TOH (nvm_header->ENTRYPOINT));
			length = extent;
			action |= PLC_MODULE_EXECUTE;
		}
		if (read (plc->NVM.file, request->IMAGE, length) != (signed)(length)) 
		{
			error (1, errno, FILE_CANTREAD, plc->NVM.name);
		}
		request->CLIENT_SESSION_ID = HTOLE32 (plc->cookie);
		request->SERVER_SESSION_ID = HTOLE32 (0);
		request->FLAGS = HTOLE32 (action);
		request->ALLOWED_MEM_TYPES [0] = 1;
		request->TOTAL_LENGTH = nvm_header->IMAGELENGTH;
		request->CURR_PART_LENGTH = HTOLE32 (length);
		request->CURR_PART_OFFSET = HTOLE32 (offset);
		request->START_ADDR = nvm_header->ENTRYPOINT;
		request->CHECKSUM = nvm_header->IMAGECHECKSUM;
		plc->packetsize = sizeof (* request);
		if (SendMME (plc) <= 0) 
		{
			error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND);
			return (-1);
		}
		if (ReadMME (plc, 0, (VS_WRITE_AND_EXECUTE_APPLET | MMTYPE_CNF)) <= 0) 
		{
			error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTREAD);
			return (-1);
		}
		if (confirm->MSTATUS) 
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		if (LE32TOH (confirm->CURR_PART_LENGTH) != length) 
		{
			error ((plc->flags & PLC_BAILOUT), 0, PLC_ERR_LENGTH);
			return (-1);
		}
		if (LE32TOH (confirm->CURR_PART_OFFSET) != offset) 
		{
			error ((plc->flags & PLC_BAILOUT), 0, PLC_ERR_OFFSET);
			return (-1);
		}
		offset += length;
		extent -= length;
	}
	return (0);
}
signed Identity1 (struct plc * plc)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_rd_mod_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MODULEID;
		uint8_t MACCESS;
		uint16_t MLENGTH;
		uint32_t MOFFSET;
		uint8_t MSECRET [16];
	}
	* request = (struct vs_rd_mod_request *) (message);
	struct __packed vs_rd_mod_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint8_t RES [3];
		uint8_t MODULEID;
		uint8_t RESERVED;
		uint16_t MLENGTH;
		uint32_t MOFFSET;
		uint32_t MCHKSUM;
		uint8_t BUFFER [PLC_RECORD_SIZE];
	}
	* confirm = (struct vs_rd_mod_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Device Identity");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_RD_MOD | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	request->MODULEID = VS_MODULE_PIB;
	request->MLENGTH = HTOLE16 (sizeof (confirm->BUFFER));
	request->MOFFSET = HTOLE32 (0);
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_RD_MOD | MMTYPE_CNF)) > 0)
	{
		if (confirm->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			continue;
		}
		Confirm (plc, "-------");
		pibpeek1 (confirm->BUFFER);
	}
	return (0);
}
signed ReadFirmware1 (struct plc * plc)

{
    struct channel * channel = (struct channel *)(plc->channel);
    struct message * message = (struct message *)(plc->message);

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

    struct __packed vs_rd_mod_request
    {
        struct ethernet_hdr ethernet;
        struct qualcomm_hdr qualcomm;
        uint8_t MODULEID;
        uint8_t MACCESS;
        uint16_t MLENGTH;
        uint32_t MOFFSET;
        uint8_t MSECRET [16];
    }
    * request = (struct vs_rd_mod_request *) (message);
    struct __packed vs_rd_mod_confirm
    {
        struct ethernet_hdr ethernet;
        struct qualcomm_hdr qualcomm;
        uint8_t MSTATUS;
        uint8_t RES [3];
        uint8_t MODULEID;
        uint8_t RESERVED;
        uint16_t MLENGTH;
        uint32_t MOFFSET;
        uint32_t CHKSUM;
        uint8_t BUFFER [PLC_RECORD_SIZE];
    }
    * confirm = (struct vs_rd_mod_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

    uint32_t header = 0;
    uint32_t extent = 0;
    uint32_t offset = 0;
    uint16_t length = PLC_RECORD_SIZE;
    Request (plc, "Read Firmware from Device");
    if (lseek (plc->nvm.file, 0, SEEK_SET))
    {
        error (PLC_EXIT (plc), errno, FILE_CANTHOME, plc->nvm.name);
        return (1);
    }
    do
    {
        memset (message, 0, sizeof (* message));
        EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
        QualcommHeader (&request->qualcomm, 0, (VS_RD_MOD | MMTYPE_REQ));
        plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
        request->MODULEID = VS_MODULE_MAC;
        request->MLENGTH = HTOLE16 (length);
        request->MOFFSET = HTOLE32 (offset);
        if (SendMME (plc) <= 0)
        {
            error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
            return (-1);
        }
        if (ReadMME (plc, 0, (VS_RD_MOD | MMTYPE_CNF)) <= 0)
        {
            error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
            return (-1);
        }
        if (confirm->MSTATUS)
        {
            Failure (plc, PLC_WONTDOIT);
            return (-1);
        }
        if (LE16TOH (confirm->MLENGTH) != length)
        {
            error (PLC_EXIT (plc), 0, PLC_ERR_LENGTH);
            return (-1);
        }
        if (LE32TOH (confirm->MOFFSET) != offset)
        {
            error (PLC_EXIT (plc), 0, PLC_ERR_OFFSET);
            return (-1);
        }
        length = LE16TOH (confirm->MLENGTH);
        offset = LE32TOH (confirm->MOFFSET);
        if (checksum32 (confirm->BUFFER, length, confirm->CHKSUM))
        {
            error (PLC_EXIT (plc), ECANCELED, "Bad Packet Checksum");
            return (-1);
        }
        if (offset == extent)
        {
            struct nvm_header1 * nvm_header = (struct nvm_header1 *)(confirm->BUFFER);
            if (checksum32 (nvm_header, sizeof (* nvm_header), 0))
            {
                error (PLC_EXIT (plc), ECANCELED, "Bad Header Checksum");
                return (-1);
            }
            if (LE32TOH (nvm_header->HEADERVERSION) != 0x60000000)
            {
                error (PLC_EXIT (plc), ECANCELED, "Bad Header Version");
                return (-1);
            }
            extent += sizeof (* nvm_header);
            extent += LE32TOH (nvm_header->IMAGELENGTH);
            header = LE32TOH (nvm_header->NEXTHEADER);
        }
        if ((offset + length) > extent)
        {
            length = extent - offset;
        }
        if (lseek (plc->nvm.file, offset, SEEK_SET) != (off_t)(offset))
        {
            error (PLC_EXIT (plc), errno, FILE_CANTSEEK, plc->nvm.name);
            return (-1);
        }
        if (write (plc->nvm.file, confirm->BUFFER, length) != (signed)(length))
        {
            error (PLC_EXIT (plc), errno, FILE_CANTSEEK, plc->nvm.name);
            return (-1);
        }
        offset += length;
        length = 1024;
    }
    while ((header) || (offset < extent));
    Confirm (plc, "Read %s", plc->nvm.name);
    return (0);
}
Exemple #27
0
signed SetProperty (struct plc * plc, struct plcproperty * plcproperty)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_set_property_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint32_t COOKIE;
		uint8_t OPTION;
		uint8_t RESERVED [3];
		uint32_t PROP_VERSION;
		uint32_t PROP_NUMBER;
		uint32_t DATA_LENGTH;
		uint8_t DATA_BUFFER [256];
	}
	* request = (struct vs_set_property_request *) (message);
	struct __packed vs_set_property_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint32_t MSTATUS;
		uint32_t COOKIE;
	}
	* confirm = (struct vs_set_property_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Set Property");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_SET_PROPERTY | MMTYPE_REQ));
	request->COOKIE = HTOLE32 (plc->cookie);
	request->OPTION = plcproperty->PROP_OPTION;
	request->PROP_VERSION = HTOLE32 (plcproperty->PROP_VERSION);
	request->PROP_NUMBER = HTOLE32 (plcproperty->PROP_NUMBER);
	request->DATA_LENGTH = HTOLE32 (plcproperty->DATA_LENGTH);
	memcpy (&request->DATA_BUFFER, &plcproperty->DATA_BUFFER, plcproperty->DATA_LENGTH);
	plc->packetsize = sizeof (* request);
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_SET_PROPERTY | MMTYPE_CNF)) > 0)
	{
		if (confirm->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			continue;
		}
	}
	return (0);
}
static signed con_info (struct plc * plc, uint8_t TYPE, uint16_t CID, uint16_t TOT_BW_USED)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_con_info_req
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t REQ_TYPE;
		uint32_t RSVD;
		uint16_t CSPEC_VER;
		uint16_t CID;
		uint16_t TOT_BW_USED;
	}
	* request = (struct vs_con_info_req *)(message);
	struct __packed vs_con_info_cnf
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t REQ_TYPE;
		uint8_t MSTATUS;
		uint16_t ERR_REC_CODE;
		uint32_t RSVD;
		uint8_t NUM_CONN;
		struct conn_info CONN_INFO [64];
	}
	* confirm = (struct vs_con_info_cnf *)(message);
	struct conn_info * conn_info = (struct conn_info*)(confirm->CONN_INFO);
	struct vs_con_info_cnf * indicate = (struct vs_con_info_cnf *)(message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	int i;
	Request (plc, "COQOS connection information");
	memset (message, 0, sizeof (* message));
	EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
	QualcommHeader (&request->qualcomm, 0, (VS_CONN_INFO | MMTYPE_REQ));
	plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
	request->REQ_TYPE = TYPE;
	request->CID = CID;
	request->TOT_BW_USED = TOT_BW_USED;
	request->CSPEC_VER = 0x01;
	if (SendMME (plc) <= 0)
	{
		error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
		return (-1);
	}
	while (ReadMME (plc, 0, (VS_CONN_INFO | MMTYPE_CNF)) <= 0);
	if (confirm->MSTATUS)
	{
		Failure (plc, "Error requesting information.");
		return (-1);
	}

/* BW exceeded request and "cancel all requests" do not send indicate */

	if ((TYPE == CONTROL_BW) || (TYPE == CONTROL_BWC))
	{
		Confirm (plc, "Success");
		return (0);
	}
	Confirm (plc, "Received confirm, waiting for indicate...");
	while (ReadMME (plc, 0, (VS_CONN_INFO | MMTYPE_IND)) <= 0);
	if (indicate->MSTATUS)
	{
		Failure (plc, "Error requesting information.");
		return (-1);
	}
	printf ("Number of Connections: %d\n", (int)indicate->NUM_CONN);
	conn_info = (struct conn_info *)(indicate->CONN_INFO);
	for (i = 0; i < indicate->NUM_CONN; i++)
	{
		printf ("SNID: %02X ", conn_info->SNID);
		printf ("CID: %04X ", conn_info->CID);
		printf ("STEI: %02X ", conn_info->STEI);
		printf ("DTEI: %02X ", conn_info->DTEI);
		printf ("LLID: %02X ", conn_info->LLID);
		printf ("CSPEC_VERSION: %04X ", conn_info->CSPECVERSION);
		printf ("CONN_CAP: %02d ", conn_info->CONN_CAP);
		printf ("CONN_COQOS_PRIO: %02d ", conn_info->CONN_COQOS_PRIO);
		printf ("CONN_RATE: %d ", conn_info->CONN_RATE);
		printf ("CONN_TTL: %d ", conn_info->CONN_TTL);
		printf ("BW_USED: %d \n", conn_info->BW_USED);
		conn_info++;
	}
	return (0);
}
signed WriteMOD (struct plc * plc, uint8_t module, void const * memory, size_t extent)

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);

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

	struct __packed vs_wr_mod_request
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MODULEID;
		uint8_t MACCESS;
		uint16_t MLENGTH;
		uint32_t MOFFSET;
		uint32_t MCHKSUM;
		uint8_t MBUFFER [PLC_RECORD_SIZE];
	}
	* request = (struct vs_wr_mod_request *) (message);
	struct __packed vs_wr_mod_confirm
	{
		struct ethernet_hdr ethernet;
		struct qualcomm_hdr qualcomm;
		uint8_t MSTATUS;
		uint8_t MODULEID;
		uint8_t MACCESS;
		uint16_t MLENGTH;
		uint32_t MOFFSET;
	}
	* confirm = (struct vs_wr_mod_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	uint32_t length = PLC_RECORD_SIZE;
	uint32_t offset = 0;
	while (extent)
	{
		memset (message, 0, sizeof (* message));
		EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
		QualcommHeader (&request->qualcomm, 0, (VS_WR_MOD | MMTYPE_REQ));
		if (length > extent)
		{
			length = (signed)(extent);
		}
		memcpy (request->MBUFFER, (byte *)(memory) + offset, length);
		request->MODULEID = module;
		request->MACCESS = 0;
		request->MLENGTH = HTOLE16 (length);
		request->MOFFSET = HTOLE32 (offset);
		request->MCHKSUM = checksum32 (request->MBUFFER, length, 0);
		plc->packetsize = sizeof (* request);
		if (SendMME (plc) <= 0)
		{
			error (PLC_EXIT (plc), errno, CHANNEL_CANTSEND);
			return (-1);
		}
		if (ReadMME (plc, 0, (VS_WR_MOD | MMTYPE_CNF)) <= 0)
		{
			error (PLC_EXIT (plc), errno, CHANNEL_CANTREAD);
			return (-1);
		}
		if (confirm->MSTATUS)
		{
			Failure (plc, PLC_WONTDOIT);
			return (-1);
		}
		if (LE16TOH (confirm->MLENGTH) != length)
		{
			error (PLC_EXIT (plc), 0, PLC_ERR_LENGTH);
			return (-1);
		}
		if (LE32TOH (confirm->MOFFSET) != offset)
		{
			error (PLC_EXIT (plc), 0, PLC_ERR_OFFSET);
			return (-1);
		}
		offset += length;
		extent -= length;
	}
	return (0);
}
Exemple #30
0
signed ResetAndWait (struct plc * plc) 

{
	struct channel * channel = (struct channel *)(plc->channel);
	struct message * message = (struct message *)(plc->message);
	struct timeval ts;
	struct timeval tc;
	unsigned timer = 0;

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

	struct __packed vs_rs_dev_request 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
	}
	* request = (struct vs_rs_dev_request *) (message);
	struct __packed vs_rs_dev_confirm 
	{
		struct ethernet_std ethernet;
		struct qualcomm_std qualcomm;
		uint8_t MSTATUS;
	}
	* confirm = (struct vs_rs_dev_confirm *) (message);

#ifndef __GNUC__
#pragma pack (pop)
#endif

	Request (plc, "Reset when Ready");
	if (gettimeofday (&ts, NULL) == -1) 
	{
		error (1, errno, CANT_START_TIMER);
	}
	for (timer = 0; timer < plc->timer; timer = SECONDS (ts, tc)) 
	{
		memset (message, 0, sizeof (* message));
		EthernetHeader (&request->ethernet, channel->peer, channel->host, channel->type);
		QualcommHeader (&request->qualcomm, 0, (VS_RS_DEV | MMTYPE_REQ));
		plc->packetsize = (ETHER_MIN_LEN - ETHER_CRC_LEN);
		if (SendMME (plc) <= 0) 
		{
			error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTSEND);
			return (-1);
		}
		if (ReadMME (plc, 0, (VS_RS_DEV | MMTYPE_CNF)) < 0) 
		{
			error ((plc->flags & PLC_BAILOUT), errno, CHANNEL_CANTREAD);
			return (-1);
		}
		if (gettimeofday (&tc, NULL) == -1) 
		{
			error (1, errno, CANT_RESET_TIMER);
		}
		if (plc->packetsize) 
		{
			if (!confirm->MSTATUS) 
			{
				Confirm (plc, "Resetting ...");
				return (0);
			}
		}
	}
	return (-1);
}