Revision 2d552dd4
Added by Hamish Coleman over 17 years ago
- ID 2d552dd4312cd73d53793f66e96cffcec841fc50
| wconsd.c | ||
|---|---|---|
| #include <stdio.h>
 | ||
| #include <stdlib.h>
 | ||
|  | ||
| #define VERSION "0.2.1"
 | ||
| #define VERSION "0.2.2"
 | ||
|  | ||
| /* Size of buffers for send and receive */
 | ||
| #define BUFSIZE 1024
 | ||
| ... | ... | |
|  | ||
| #define MAXCONNECTIONS	8
 | ||
|  | ||
| int next_connection_id = 0;	/* lifetime unique connection id */
 | ||
| int next_connection_id = 1;	/* lifetime unique connection id */
 | ||
| int next_connection_slot = 0;	/* next slot to look at for new connection */
 | ||
| struct connection {
 | ||
| 	int active;		/* an active entry cannot be reused */
 | ||
| ... | ... | |
| /* close the com port */
 | ||
| void close_com_port(struct connection *conn) {
 | ||
| 	CloseHandle(conn->serial);
 | ||
| 	conn->serial=INVALID_HANDLE_VALUE;
 | ||
| 	conn->serialconnected=0;
 | ||
| }
 | ||
|  | ||
| /*
 | ||
|  * Given an active connection, force close its
 | ||
|  * serial port. waiting for all relevant resources
 | ||
|  */
 | ||
| void close_serial_connection(struct connection *conn) {
 | ||
| 	if (!conn->active) {
 | ||
| 		dprintf(1,"wconsd: closing closed connection %i\n",conn->id);
 | ||
| 		return;
 | ||
| 	}
 | ||
| 	conn->menuactive=1;
 | ||
| 	close_com_port(conn);
 | ||
| 	WaitForSingleObject(conn->serialThread,INFINITE);
 | ||
| 	CloseHandle(conn->serialThread);
 | ||
| 	conn->serialThread=NULL;
 | ||
| }
 | ||
|  | ||
|  | ||
| /* Initialise wconsd: open a listening socket and the COM port, and
 | ||
|  * create lots of event objects. */
 | ||
| ... | ... | |
| 	dprintf(1,"wconsd[%i]: start wconsd_net_to_com\n",conn->id);
 | ||
|  | ||
| 	o.hEvent = writeEvent;
 | ||
| 	while (conn->netconnected) {
 | ||
| 	while (conn->netconnected && conn->serialconnected) {
 | ||
| 		/* There's a bug in some versions of Windows which leads
 | ||
| 		 * to recv() returning -1 and indicating error WSAEWOULDBLOCK,
 | ||
| 		 * even on a blocking socket. This select() is here to work
 | ||
| ... | ... | |
| 		"\r\n"
 | ||
| 		"NOTE: these commands will change in the next version\r\n\n"
 | ||
| 		"available commands:\r\n\n"
 | ||
| 		"  port, speed, data, parity, stop\r\n"
 | ||
| 		"  help, status, copyright\r\n"
 | ||
| 		"  open, close, autoclose\r\n"
 | ||
| 		"  show_conn_table\r\n"
 | ||
| 		"  port speed data parity stop\r\n"
 | ||
| 		"  help status copyright\r\n"
 | ||
| 		"  open close autoclose\r\n"
 | ||
| 		"  show_conn_table kill_conn\r\n"
 | ||
| 		"  quit\r\n");
 | ||
| }
 | ||
|  | ||
| ... | ... | |
| 	return atoi(p);
 | ||
| }
 | ||
|  | ||
| int process_menu_line(struct connection*conn, char *line) {
 | ||
| void process_menu_line(struct connection*conn, char *line) {
 | ||
| 	char *command;
 | ||
| 	char *parameter1;
 | ||
|  | ||
| ... | ... | |
| 			netprintf(conn,"\r\n\n");
 | ||
| 			/* signal to quit the menu */
 | ||
| 			conn->menuactive=0;
 | ||
| 			/* and return still running */
 | ||
| 			return 1;
 | ||
| 			return;
 | ||
| 		}
 | ||
|  | ||
| 		if (!open_com_port(conn,&errcode)) {
 | ||
| 			netprintf(conn,"\r\n\n");
 | ||
| 			// signal to quit the menu
 | ||
| 			conn->menuactive=0;
 | ||
| 			/* and return still running */
 | ||
| 			return 1;
 | ||
| 			return;
 | ||
| 		} else {
 | ||
| 			netprintf(conn,"error: cannot open port\r\n\n");
 | ||
| 		}
 | ||
| 	} else if (!strcmp(command, "close")) {			// close
 | ||
| 		close_com_port(conn);
 | ||
| 		close_serial_connection(conn);
 | ||
| 		netprintf(conn,"info: actual com port closed\r\n\n");
 | ||
| 	} else if (!strcmp(command, "autoclose")) {		// autoclose
 | ||
| 		if (!strcmp(parameter1, "true") || !strcmp(parameter1, "1") || !strcmp(parameter1, "yes")) {
 | ||
| ... | ... | |
| 		closesocket(conn->net);
 | ||
| 		conn->net=INVALID_SOCKET;
 | ||
| 		conn->netconnected=0;
 | ||
| 		/* and return not running */
 | ||
| 		return 0;
 | ||
| 		return;
 | ||
| 	} else if (!strcmp(command, "show_conn_table")) {
 | ||
| 		int i;
 | ||
| 		netprintf(conn,
 | ||
| ... | ... | |
| 				connection[i].net_bytes_rx, connection[i].net_bytes_tx
 | ||
| 				);
 | ||
| 		}
 | ||
| 	} else if (!strcmp(command, "kill_conn")) {
 | ||
| 		int connid = check_atoi(parameter1,0,conn,"must specify a connection id\r\n");
 | ||
| 		if (connid==0 || connid>next_connection_id) {
 | ||
| 			netprintf(conn,"Connection ID %i out of range\r\n",connid);
 | ||
| 			return;
 | ||
| 		}
 | ||
|  | ||
| 		int i=0;
 | ||
| 		while(connection[i].id!=connid && i<MAXCONNECTIONS) {
 | ||
| 			i++;
 | ||
| 		}
 | ||
| 		if (i>=MAXCONNECTIONS) {
 | ||
| 			netprintf(conn,"Connection ID %i not found\r\n",connid);
 | ||
| 			return;
 | ||
| 		}
 | ||
|  | ||
| 		close_serial_connection(&connection[i]);
 | ||
| 		netprintf(conn,"Connection ID %i serial port closed\r\n",connid);
 | ||
| 	} else {
 | ||
| 		/* other, unknown commands */
 | ||
| 		netprintf(conn,"debug: line='%s', command='%s'\r\n\n",line,command);
 | ||
| 	}
 | ||
| 	/* return still running */
 | ||
| 	return 1;
 | ||
| }
 | ||
|  | ||
| int run_menu(struct connection * conn) {
 | ||
| void run_menu(struct connection * conn) {
 | ||
| 	unsigned char buf[BUFSIZE+5];	/* ensure there is room for our kludge telnet options */
 | ||
| 	unsigned char line[MAXLEN];
 | ||
| 	DWORD size, linelen=0;
 | ||
| ... | ... | |
| 			closesocket(conn->net);
 | ||
| 			conn->net=INVALID_SOCKET;
 | ||
| 			conn->netconnected=0;
 | ||
| 			return 0; /* signal running=0 */
 | ||
| 			return;
 | ||
| 		}
 | ||
| 		if (size==SOCKET_ERROR) {
 | ||
| 			dprintf(1,"wconsd[%i]: socket error\n",conn->id);
 | ||
| ... | ... | |
| 					netprintf(conn,"\r\n");
 | ||
|  | ||
| 				if (linelen!=0) {
 | ||
| 					int running;
 | ||
| 					line[linelen]=0;	// ensure string is terminated
 | ||
|  | ||
| 					running = process_menu_line(conn,(char*)line);
 | ||
| 					process_menu_line(conn,(char*)line);
 | ||
| 					if (!conn->menuactive) {
 | ||
| 						/* exiting the menu.. */
 | ||
| 						return running;
 | ||
| 						return;
 | ||
| 					}
 | ||
| 				}
 | ||
|  | ||
| ... | ... | |
| 	}
 | ||
|  | ||
| 	/* not reached */
 | ||
| 	return 0;
 | ||
| }
 | ||
|  | ||
| DWORD WINAPI thread_new_connection(LPVOID lpParam) {
 | ||
| ... | ... | |
| 	shutdown(conn->net,SD_BOTH);
 | ||
| 	closesocket(conn->net);
 | ||
|  | ||
| 	close_com_port(conn);
 | ||
| 	WaitForSingleObject(conn->serialThread,INFINITE);
 | ||
| 	CloseHandle(conn->serialThread);
 | ||
| 	close_serial_connection(conn);
 | ||
|  | ||
| 	conn->active=0;
 | ||
|  | ||
Also available in: Unified diff
Implement the ability to kill existing connections
This is a new command to force quit any current serial connection