Exemple #1
0
static void function (struct channel * channel, void * memory, ssize_t extent)

{
	struct ether_header * frame = (struct ether_header *)(memory);
	unsigned length;
	while ((length = (unsigned)(hexload (memory, extent, stdin))) > 0)
	{
		if (length < (ETHER_MIN_LEN - ETHER_CRC_LEN))
		{
			error (1, ENOTSUP, "Frame size of %d is less than %d bytes", length, (ETHER_MIN_LEN - ETHER_CRC_LEN));
		}
		if (length > (ETHER_MAX_LEN - ETHER_CRC_LEN))
		{
			error (1, ENOTSUP, "Frame size of %d is more than %d bytes", length, (ETHER_MAX_LEN - ETHER_CRC_LEN));
		}
		if (_anyset (channel->flags, CHANNEL_UPDATE_TARGET))
		{
			memcpy (frame->ether_dhost, channel->peer, sizeof (frame->ether_dhost));
		}
		if (_anyset (channel->flags, CHANNEL_UPDATE_SOURCE))
		{
			memcpy (frame->ether_shost, channel->host, sizeof (frame->ether_shost));
		}
		sendpacket (channel, memory, length);
		if (_anyset (channel->flags, CHANNEL_LISTEN))
		{
			while (readpacket (channel, memory, extent) > 0);
		}
	}
	return;
}
Exemple #2
0
static void function (LIST * list, regexp * regex, flag_t flags)

{
	char const * string;
	if (_anyset (flags, WHOM_B_USR))
	{
		struct passwd * passwd;
		while ((passwd = getpwent ()))
		{
			string = regexspan (regex, passwd->pw_name);
			if ((string) && (! * string))
			{
				listinsert (list, passwd->pw_name);
			}
		}
	}
	if (_anyset (flags, WHOM_B_GRP))
	{
		struct group * group;
		while ((group = getgrent ()))
		{
			string = regexspan (regex, group->gr_name);
			if ((string) && (! * string))
			{
				listinsert (list, group->gr_name);
			}
		}
	}
	return;
}
Exemple #3
0
static void function (char const * colors [], unsigned count, flag_t flags) 

{ 
	if (_anyset (flags, (OFFSET_HTML | OFFSET_PAGE))) 
	{ 
		html (colors, count, flags); 
	} 
	else if (_anyset (flags, (OFFSET_TEXT))) 
	{ 
		tabs (flags); 
	} 
	else if (_anyset (flags, (OFFSET_EFSU))) 
	{ 
		efsu (flags); 
	} 
	else if (_anyset (flags, (OFFSET_FOLD))) 
	{ 
		fold (flags); 
	} 
	else if (_anyset (flags, (OFFSET_ZERO))) 
	{ 
		zero (flags); 
	} 
	else 
	{ 
		text (flags); 
	} 
	return; 
} 
Exemple #4
0
void manager (struct plc * plc, signed count, signed pause)

{
	while (count--)
	{
		if (_anyset (plc->flags, PLC_VERSION))
		{
			VersionInfo1 (plc);
		}
		if (_anyset (plc->flags, PLC_LOCAL_TRAFFIC))
		{
			Traffic1 (plc);
		}
		if (_anyset (plc->flags, PLC_NETWORK_TRAFFIC))
		{
			NetworkTraffic1 (plc);
		}
		if (_anyset (plc->flags, PLC_NETWORK))
		{
			PhyRates1 (plc);
		}
		if (_anyset (plc->flags, PLC_RESET_DEVICE))
		{
			ResetDevice (plc);
		}
		sleep (pause);
	}
	return;
}
int detect (struct serial *s, struct serial_mode *serial_mode, flag_t flags)

{
	static int rate [] =
	{
		115200,
		9600,
		460800,
		230400,
		57600,
		38400,
		19200,
		4800,
		2400,
		600,
		300,
		50
	};
	static int parity [] =
	{
		UART_NOPARITY,
		UART_EVENPARITY,
		UART_ODDPARITY
	};
	size_t i;
	size_t j;
	unsigned current;
	unsigned total;
	total = 2 * 2 * 3 * (sizeof (rate) / sizeof (int));
	current = 0;
	for (serial_mode->stop_bits = 1; serial_mode->stop_bits <= 2; ++serial_mode->stop_bits)
	{
		for (serial_mode->data_bits = 8; serial_mode->data_bits >= 7; --serial_mode->data_bits)
		{
			for (i = 0; i < sizeof (parity) / sizeof (int); ++i)
			{
				serial_mode->parity = parity [i];
				for (j = 0; j < sizeof (rate) / sizeof (int); ++j)
				{
					serial_mode->baud_rate = rate [j];
					++current;
					if (!_anyset (flags, INT6KDETECT_QUIET))
					{
						printf ("\rTesting mode: %03u/%03u (%.01f%%)...", current, total, current * 100.0 / total);
						fflush (stdout);
					}
					if (!try_serial_mode (s, serial_mode, flags))
					{
						if (!_anyset (flags, INT6KDETECT_QUIET)) printf ("\n");
						return (0);
					}
				}
			}
		}
	}
	if (!_anyset (flags, INT6KDETECT_QUIET)) printf ("\n");
	return (-1);
}
Exemple #6
0
static void testfile (FIND * find, FIND * home, flag_t flags)

{
	if (lstat (find->fullname, & find->statinfo))
	{
		error (0, errno, FILE_CANTSTAT, find->fullname);
		return;
	}
	if (S_ISDIR (find->statinfo.st_mode))
	{
		char const * filename = find->filename;
		if (* filename == '.')
		{
			filename++;
		}
		if (* filename == '.')
		{
			filename++;
		}
		if (* filename == (char) (0))
		{
			return;
		}
		if (_anyset (find->flagword, FIND_B_RECURSE))
		{
			findfile (find, home, flags);
		}
		if (_anyset (find->flagword, FIND_B_DIR))
		{
			function (find, home, flags);
		}
		return;
	}
	if (S_ISLNK (find->statinfo.st_mode))
	{
		if (_anyset (find->flagword, FIND_B_LNK))
		{
			function (find, home, flags);
		}
		return;
	}
	if (S_ISREG (find->statinfo.st_mode))
	{
		if (_anyset (find->flagword, FIND_B_REG))
		{
			function (find, home, flags);
		}
		return;
	}
	return;
}
Exemple #7
0
ssize_t sendpacket (struct channel const * channel, void * memory, ssize_t extent) 

{
	if (_anyset (channel->flags, CHANNEL_VERBOSE)) 
	{
		hexdump (memory, 0, extent, stdout);
	}

#if defined (__linux__)

	extent = sendto (channel->fd, memory, extent, 0, (struct sockaddr *) (0), (socklen_t) (0));

#elif defined (__APPLE__) || defined (__OpenBSD__)

	extent = write (channel->fd, memory, extent);

#elif defined (WINPCAP) || defined (LIBPCAP)

	if (pcap_sendpacket (channel->socket, (byte *)(memory), extent)) 
	{
		extent = -1;
	}

#else
#error "Unknown Environment"
#endif

	return (extent);
}
Exemple #8
0
int main (int argc, char const * argv []) 

{ 
	static char const * optv [] = 
	{ 
		"c:w:x", 
		PUTOPTV_S_FILTER, 
		"extend FORTRAN style comment bars", 
		"c c\tcomments start with character c [" LITERAL (FBAR_START) "]", 
		"w n\tbar width is (n) [" LITERAL (FBAR_WIDTH) "]", 
		"x\tmake file executable", 
		(char const *) (0)
	}; 
	flag_t flags = (flag_t) (0); 
	size_t length = _LINESIZE; 
	size_t width = FBAR_WIDTH; 
	char start = FBAR_START; 
	char space = FBAR_SPACE; 
	signed c; 
	while (~ (c = getoptv (argc, argv, optv))) 
	{ 
		switch (c) 
		{ 
		case 'c': 
			start = (char) (* optarg); 
			break; 
		case 'x': 
			_setbits (flags, FBAR_EXECUTE); 
			break; 
		case 'w': 
			width = uintspec (optarg, 0, length); 
			break; 
		default: 
			break; 
		} 
	} 
	argc -= optind; 
	argv += optind; 
	if (!argc) 
	{ 
		function (start, space, width, length, flags); 
	} 
	while ((argc) && (* argv)) 
	{ 
		if (vfopen (* argv)) 
		{ 
			function (start, space, width, length, flags); 
			if (_anyset (flags, FBAR_EXECUTE)) 
			{ 
				if (chmod (* argv, 0755)) 
				{ 
					error (0, errno, "can't chmod %s", * argv); 
				} 
			} 
		} 
		argc--; 
		argv++; 
	} 
	exit (0); 
} 
Exemple #9
0
static void invoke_handler (signed count, size_t length, flag_t flags) 

{ 
	char const * fields [count]; 
	char buffer [length]; 
	printf ("# ===\n# call package program handler;\n# ---\n\n"); 
	while (getfields (fields, count, buffer, length)) 
	{ 
		if (_anyset (flags, OWRT_ONELINE)) 
		{ 
			printf ("$(eval $(call %s \\\n", fields [OWRT_HANDLER]); 
			printf ("\t,%s \\\n", fields [OWRT_LIBRARY]); 
			printf ("\t,%s \\\n", fields [OWRT_PROGRAM]); 
			printf ("\t,'%s' \\\n", fields [OWRT_TITLE]); 
			printf ("\t,'%s' \\\n", fields [OWRT_SUMMARY]); 
			printf ("))\n"); 
		} 
		else 
		{ 
			printf ("$(eval $(call %s", fields [OWRT_HANDLER]); 
			printf (",%s", fields [OWRT_LIBRARY]); 
			printf (",%s", fields [OWRT_PROGRAM]); 
			printf (",'%s'", fields [OWRT_TITLE]); 
			printf (",'%s'", fields [OWRT_SUMMARY]); 
			printf ("))\n"); 
		} 
	} 
	printf ("\n"); 
	return; 
} 
static void manager (struct uart * uart)

{
	if (_anyset (uart->flags, UART_WAKE))
	{
		at_wake (uart);
	}
	if (_anyset (uart->flags, UART_COMMAND))
	{
		at_command (uart);
	}
	if (_anyset (uart->flags, UART_ATBR))
	{
		atbr (uart);
	}
	return;
}
Exemple #11
0
void readcommand (struct _file_ * port, flag_t flags)

{
	extern struct command command;
	ssize_t tmp;

#if defined (WIN32)

	PAUSE (250);
	memset (&command, 0, sizeof (command));
	tmp = read (port->file, command.buffer, sizeof (command.buffer));
	if (tmp < 0)
	{
		error (1, errno, "Bad response from %s", port->name);
	}
	if (tmp == 0)
	{
		error (1, errno, "No response from %s", port->name);
	}
	command.length = tmp;

#else

	struct timeval tv;
	fd_set rfd;
	memset (&command, 0, sizeof (command));
	while (!strchr (command.buffer, '\r'))
	{
		tv.tv_sec = 1;
		tv.tv_usec = 0;
		FD_ZERO (&rfd);
		FD_SET (port->file, &rfd);
		if (select (port->file + 1, &rfd, NULL, NULL, &tv) != 1)
		{
			error (1, errno, "Read timeout");
		}
		tmp = read (port->file, command.buffer + command.length, sizeof (command.buffer) - command.length - 1);
		if (tmp < 0)
		{
			error (1, errno, "Could not read %s", port->name);
		}
		command.length += tmp;
		command.buffer [command.length] = '\0';
	}

#endif

	if (_anyset (flags, UART_VERBOSE))
	{
		write (STDERR_FILENO, command.buffer, command.length);
		write (STDERR_FILENO, "\n", sizeof (char));
	}
	if (!memcmp (command.buffer, "ERROR", 5))
	{
		error (1, ECANCELED, "Device refused request");
	}
	return;
}
static signed nvmimage2 (void const * memory, size_t extent, char const * filename, flag_t flags)

{
	struct nvm_header1 * nvm_header;
	unsigned module = 0;
	uint32_t offset = 0;
	do
	{
		nvm_header = (struct nvm_header1 *)((char *)(memory) + offset);
		if (LE32TOH (nvm_header->HEADERVERSION) != 0x60000000)
		{
			if (_allclr (flags, NVM_SILENCE))
			{
				error (0, errno, NVM_HDR_VERSION, filename, module);
			}
			return (-1);
		}
		if (checksum32 (nvm_header, sizeof (* nvm_header), 0))
		{
			if (_allclr (flags, NVM_SILENCE))
			{
				error (0, errno, NVM_HDR_CHECKSUM, filename, module);
			}
			return (-1);
		}
		offset += sizeof (* nvm_header);
		extent -= sizeof (* nvm_header);
		if (_anyset (flags, NVM_VERBOSE))
		{
			printf ("------- %s (%d) -------\n", filename, module);
			nvmpeek1 (nvm_header);
		}
		if (LE32TOH (nvm_header->IMAGETYPE) == NVM_IMAGE_FIRMWARE)
		{
			firmware (filename, module, (char *)(memory) + offset, 0x70, flags);
		}
		if (checksum32 ((char *)(memory) + offset, LE32TOH (nvm_header->IMAGELENGTH), nvm_header->IMAGECHECKSUM))
		{
			if (_allclr (flags, NVM_SILENCE))
			{
				error (0, errno, NVM_IMG_CHECKSUM, filename, module);
			}
			return (-1);
		}
		offset += LE32TOH (nvm_header->IMAGELENGTH);
		extent -= LE32TOH (nvm_header->IMAGELENGTH);
		module++;
	}
	while (nvm_header->NEXTHEADER);
	if (extent)
	{
		if (_allclr (flags, NVM_SILENCE))
		{
			error (0, errno, NVM_HDR_LINK, filename, module);
		}
	}
	return ((signed)(extent));
}
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 ?"));
}
int try_serial_mode (struct serial *s, struct serial_mode *serial_mode, flag_t flags)

{
	if (set_serial (s, serial_mode) == -1)
	{
		error (0, 0, "could not set serial_mode");
		return (-1);
	}
	if (!_anyset (flags, INT6KDETECT_CMD_MODE)) wakeup (s);
	at_cmd (s);
	return (at_cmd (s));
}
Exemple #15
0
void manager (struct plc * plc, signed count, signed pause) 

{
	while (count--) 
	{
		if (_anyset (plc->flags, PLC_ANALYSE)) 
		{
			Topology2 (plc);
		}
		if (_anyset (plc->flags, PLC_NETWORK)) 
		{
			NetworkInformation2 (plc);
		}
		if (_anyset (plc->flags, PLC_LINK_STATS)) 
		{
			LinkStatistics (plc);
		}
		sleep (pause);
	}
	return;
}
Exemple #16
0
static void assemble (flag_t flags) 

{
	extern signed c;
	c = mygetc ();
	while (c != EOF) 
	{
		if (isspace (c)) 
		{
			do 
			{
				c = mygetc ();
			}
			while (isspace (c));
			continue;
		}
		if ((c == '#') || (c == ';')) 
		{
			do 
			{
				c = mygetc ();
			}
			while (nobreak (c));
			continue;
		}
		phy = integer (16);
		reg = integer (16);
		data = integer (16);
		mask = integer (16);
		instr = MDIO16_INSTR (1, 1, phy, reg, 2);
		write (STDOUT_FILENO, &instr, sizeof (instr));
		data = HTOLE16 (data & 0xFFFF);
		write (STDOUT_FILENO, &data, sizeof (data));
		mask = HTOLE16 (mask & 0xFFFF);
		write (STDOUT_FILENO, &mask, sizeof (mask));
		count++;
		if (_anyset (flags, MDIO_VERBOSE)) 
		{
			fprintf (stderr, "INSTR=0x%04X DATA=0x%04X MASK=0x%04X\n", instr, data, mask);
		}
		if ((c == ';') || (c == EOF)) 
		{
			c = mygetc ();
			continue;
		}
		if (_allclr (flags, MDIO_SILENCE)) 
		{
			error (1, 0, "Illegal character or missing terminator: line %d col %d", row, col);
		}
	}
	return;
}
Exemple #17
0
int main (int argc, char const * argv [])

{
	static char const * optv [] =
	{
		"f:qv",
		"pib-file [pib-file] [...]",
		"Qualcomm Atheros PLC Parameter File Editor",
		"f f\txmlfile is (f)",
		"q\tquiet",
		"v\tverbose",
		(char const *) (0)
	};
	struct node * node = (struct node *)(0);
	flag_t flags = (flag_t)(0);
	signed c;
	optind = 1;
	while ((c = getoptv (argc, argv, optv)) != -1)
	{
		switch (c)
		{
		case 'f':
			node = xmlopen (optarg);
			break;
		case 'm':
			_setbits (flags, PIB_MANIFEST);
			break;
		case 'q':
			_setbits (flags, PIB_SILENCE);
			break;
		case 'v':
			_setbits (flags, PIB_VERBOSE);
			break;
		default:
			break;
		}
	}
	argc -= optind;
	argv += optind;
	while ((argc) && (* argv))
	{
		function (* argv, node);
		argc--;
		argv++;
	}
	if (_anyset (flags, PIB_VERBOSE))
	{
		xmltree (node);
	}
	xmlfree (node);
	return (0);
}
static void firmware (char const * filename, unsigned module, char const * memory, unsigned offset, flag_t flags)

{
	if (_anyset (flags, NVM_FIRMWARE))
	{
		if ((* memory > 0x20) && (* memory < 0x7f))
		{
			printf ("%s (%d) %s\n", filename, module, memory);
		}
		else
		{
			printf ("%s (%d) %s\n", filename, module, memory + offset);
		}
		return;
	}
	if (_anyset (flags, NVM_IDENTITY))
	{
		char * vector [16];
		char buffer [256];
		if ((* memory > 0x20) && (* memory < 0x7f))
		{
			strncpy (buffer, memory, sizeof (buffer));
		}
		else
		{
			strncpy (buffer, memory + offset, sizeof (buffer));
		}
		string2vector (vector, buffer, '-');
		printf ("%s ", vector [HARDWARE]);
		printf ("%04d ", atoi (vector [BUILD]));
		printf ("%s ", vector [DATE]);
		printf ("%s.", vector [VER]);
		printf ("%s ", vector [REV]);
		printf ("%s (%d)\n", filename, module);
		return;
	}
	return;
}
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 ?"));
}
Exemple #20
0
void sendcommand (struct _file_ * port, flag_t flags)

{
	extern struct command command;
	if (_anyset (flags, UART_VERBOSE))
	{
		write (STDERR_FILENO, command.buffer, command.length);
		write (STDERR_FILENO, "\n", sizeof (char));
	}
	if (write (port->file, command.buffer, command.length) != (signed)(command.length))
	{
		error (1, errno, "Can't write to %s", port->name);
	}
	clearcommand ();
	return;
}
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 ?")); 
} 
Exemple #22
0
int ihpapi_UpdateDevice (uint8_t sa [], uint8_t da [], ihpapi_hostActionRequest_t type) 

{
	extern struct SeqCB scb;
	TxInfo *tcb = &scb.tcb;
	tcb->txok = false;
	if (_anyset (scb.flags, scbFlag_bsy)) 
	{
		errno = EBUSY;
		return (-1);
	}
	memset (&scb, 0, sizeof (scb));
	switch (type) 
	{
	case IHPAPI_HAR_UPLOAD_FW:
		_setbits (scb.flags, scbFlag_FW);
		tcb->RDMDBLKR.MODULEID = MACSW_MODID;
		tcb->RDMDBLKR.LENGTH = ihtons(sizeof (NVMBlockHeader));
		break;
	case IHPAPI_HAR_UPLOAD_FWnPB:
		_setbits (scb.flags, scbFlag_FW | scbFlag_PB);
		tcb->RDMDBLKR.MODULEID = MACSW_MODID;
		tcb->RDMDBLKR.LENGTH = ihtons(sizeof (NVMBlockHeader));
		break;
	case IHPAPI_HAR_UPLOAD_PB:
		_setbits (scb.flags, scbFlag_PB);
		tcb->RDMDBLKR.MODULEID = PIB_MODID;
		tcb->RDMDBLKR.LENGTH = ihtons(MAX_MODULE_TX_LENGTH);
		break;
	default:
		errno = EINVAL;
		return (-1);
	}
	_setbits (scb.flags, scbFlag_flash);
	scb.opcode = IHPAPI_OPCODE_UPDATE_DEVICE;
	scb.action = type;
	tcb->txok = true;
	memcpy (tcb->ODA, da, IHPAPI_ETHER_ADDR_LEN);
	memcpy (tcb->OSA, sa, IHPAPI_ETHER_ADDR_LEN);
	tcb->MMTYPE = VS_RD_MOD | MMTYPE_REQ;
	tcb->hdrlen = sizeof (tcb->RDMDBLKR);
	tcb->RDMDBLKR.OFFSET = 0;
	return (0);
}
Exemple #23
0
static void function (struct channel * channel, flag_t flags) 

{
	struct message message;
	signed length;
	while ((length = readpacket (channel, &message, sizeof (message))) >= 0) 
	{
		if (!length) 
		{
			continue;
		}
		if (_allclr (flags, HPAV_SILENCE)) 
		{
			MMEPeek (&message, length, stdout);
		}
		if (_anyset (flags, HPAV_VERBOSE)) 
		{
			hexdump (&message, 0, length, stdout);
		}
	}
	return;
}
Exemple #24
0
static void function (struct _find_ * find, struct _find_ * home, flag_t flags)

{
	char buffer [BUFSIZ];
	signed length;
	if (! match (find->filename, find->wildcard))
	{
		return;
	}
	strcpy (home->filename, find->filename);
	makepath (home->fullname, home->pathname, home->filename);
	if ((find->fd = open (find->fullname, O_RDONLY)) == -1)
	{
		error (0, errno, FILE_CANTOPEN, find->fullname);
		return;
	}
	if ((home->fd = open (home->fullname, O_CREAT | O_WRONLY, find->statinfo.st_mode)) == -1)
	{
		error (0, errno, FILE_CANTOPEN, home->fullname);
		close (find->fd);
		return;
	}
	if (_anyset (flags, IMPORT_VERBOSE))
	{
		printf ("%s\n", find->fullname);
	}
	while ((length = read (find->fd, buffer, sizeof (buffer))) > 0)
	{
		if (write (home->fd, buffer, length) < length)
		{
			error (0, errno, FILE_CANTSAVE, home->fullname);
			break;
		}
	}
	close (home->fd);
	close (find->fd);
	return;
}
Exemple #25
0
static void function (char const * filename, signed index, flag_t flags) 

{
	uint32_t version;
	struct _file_ file = 
	{
		-1,
		filename
	};
	if (_anyset (flags, NVM_VERBOSE)) 
	{
		error (0, 0, "%s", file.name);
	}
	if ((file.file = open (file.name, O_BINARY|O_RDONLY)) == -1) 
	{
		error (1, errno, FILE_CANTOPEN, file.name);
	}
	if (read (file.file, &version, sizeof (version)) != sizeof (version)) 
	{
		error (1, errno, FILE_CANTREAD, file.name);
	}
	if (lseek (file.file, 0, SEEK_SET)) 
	{
		error (1, errno, FILE_CANTHOME, file.name);
	}
	if (LE32TOH (version) == 0x60000000) 
	{
		function1 (&file, index, flags);
	}
	else 
	{
		function2 (&file, index, flags);
	}
	close (file.file);
	return;
}
Exemple #26
0
int main (int argc, const char * argv [])

{
	extern struct channel channel;
	static const char *optv [] =
	{
		"C:i:eFN:p:P:qt:vx",
		"-C file -P file -N file",
		"Atheros Powerline Device Flash Utility for INT6300",
		"C f\twrite CFG file to device using VS_SET_SDRAM",
		"e\tredirect stderr messages to stdout",

#if defined (WINPCAP) || defined (LIBPCAP)

		"i n\thost interface number [2]",

#else

		"i s\thost interface name [" CHANNEL_ETHDEVICE "]",

#endif

		"F[F]\tflash [force] NVRAM after firmware start using VS_MOD_NVM",
		"N f\twrite NVM file to device using VS_WR_MEM",
		"P f\twrite PIB file to device using VS_WR_MEM",
		"q\tquiet mode",

#if defined (WINPCAP) || defined (LIBPCAP)

		"t n\tread capture time is (n) milliseconds [50]",

#else

		"t n\tread timeout is (n) milliseconds [50]",

#endif

		"v\tverbose mode",
		"x\texit on error",
		(const char *) (0)
	};

#include "../plc/plc.c"

	char firmware [PLC_VERSION_STRING];
	signed c;
	if (getenv (PLCDEVICE))
	{

#if defined (WINPCAP) || defined (LIBPCAP)

		channel.ifindex = atoi (getenv (PLCDEVICE));

#else

		channel.ifname = strdup (getenv (PLCDEVICE));

#endif

	}
	optind = 1;
	opterr = 1;
	while ((c = getoptv (argc, argv, optv)) != -1)
	{
		switch ((char) (c))
		{
		case 'i':

#if defined (WINPCAP) || defined (LIBPCAP)

			channel.ifindex = atoi (optarg);

#else

			channel.ifname = optarg;

#endif

			break;
		case 'q':
			_setbits (channel.flags, CHANNEL_SILENCE);
			break;
		case 't':
			channel.timeout = (unsigned)(uintspec (optarg, 0, UINT_MAX));
			break;
		case 'v':
			_setbits (channel.flags, CHANNEL_VERBOSE);
			break;
		}
	}
	openchannel (&channel);
	desuid ();
	optind = 1;
	opterr = 1;
	while ((c = getoptv (argc, argv, optv)) != -1)
	{
		switch ((char) (c))
		{
		case 'C':
			if (!checkfilename (optarg))
			{
				error (1, EINVAL, "%s", optarg);
			}
			if ((plc.CFG.file = open (optarg, O_BINARY|O_RDONLY)) == -1)
			{
				error (1, errno, "%s", optarg);
			}
			if (sdramfile (plc.CFG.file, optarg, plc.flags))
			{
				error (1, ECANCELED, "CFG file %s is corrupt", optarg);
			}
			_setbits (plc.flags, PLC_SDRAM_CONFIG);
			plc.CFG.name = optarg;
			break;
		case 'e':
			dup2 (STDOUT_FILENO, STDERR_FILENO);
			break;
		case 'F':
			_setbits (plc.module, PLC_MODULE_NVM_PIB);
			if (_anyset (plc.flags, PLC_FLASH_DEVICE))
			{
				_setbits (plc.module, VS_MODULE_FORCE);
			}
			_setbits (plc.flags, PLC_FLASH_DEVICE);
			break;
		case 'N':
			if (!checkfilename (optarg))
			{
				error (1, EINVAL, "%s", optarg);
			}
			if ((plc.NVM.file = open (optarg, O_BINARY|O_RDONLY)) == -1)
			{
				error (1, errno, "%s", optarg);
			}
			plc.NVM.name = optarg;
			if (nvmfile1 (&plc.NVM))
			{
				error (1, errno, "Bad firmware file: %s", plc.NVM.name);
			}
			_setbits (plc.flags, PLC_WRITE_MAC);
			break;
		case 'P':
			if (!checkfilename (optarg))
			{
				error (1, EINVAL, "%s", optarg);
			}
			if ((plc.PIB.file = open (optarg, O_BINARY|O_RDONLY)) == -1)
			{
				error (1, errno, "%s", optarg);
			}
			plc.PIB.name = optarg;
			if (pibfile1 (&plc.PIB))
			{
				error (1, errno, "Bad parameter file: %s", plc.PIB.name);
			}
			_setbits (plc.flags, PLC_WRITE_PIB);
			break;
		case 'q':
			_setbits (plc.flags, PLC_SILENCE);
			break;
		case 'v':
			_setbits (plc.flags, PLC_VERBOSE);
			break;
		case 'x':
			_setbits (plc.flags, PLC_BAILOUT);
			break;
		default:
			break;
		}
	}
	argc -= optind;
	argv += optind;
	if (argc)
	{
		error (1, ECANCELED, "Too many arguments");
	}
	if (plc.CFG.file == -1)
	{
		error (1, ECANCELED, "No CFG file specified");
	}
	if (plc.PIB.file == -1)
	{
		error (1, ECANCELED, "No PIB file specified");
	}
	if (plc.NVM.file == -1)
	{
		error (1, ECANCELED, "No NVM file specified");
	}
	if (!(plc.message = malloc (sizeof (struct message))))
	{
		error (1, errno, PLC_NOMEMORY);
	}
	if (WaitForStart (&plc, firmware, sizeof (firmware)))
	{
		Failure (&plc, "Device must be connected");
		return (-1);
	}
	if (plc.hardwareID > CHIPSET_INT6300)
	{
		Failure (&plc, "Device must be %s or earlier; try using int6kboot.", chipsetname (CHIPSET_INT6300));
		return (-1);
	}
	if (strcmp (firmware, "BootLoader"))
	{
		Failure (&plc, "Bootloader must be running");
		return (-1);
	}
	if (!StartDevice1 (&plc))
	{
		if (_anyset (plc.flags, PLC_FLASH_DEVICE))
		{
			UpgradeDevice1 (&plc);
		}
	}
	free (plc.message);
	closechannel (&channel);
	exit (0);
}
Exemple #27
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);
}
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 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 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"));
}