Revision ef78cec5
Added by Hamish Coleman over 16 years ago
- ID ef78cec51377482c28fe862f1927b9f2bde50a63
wconsd.c | ||
---|---|---|
|
||
int debug_mode = 0;
|
||
|
||
#define MAXCONNECTIONS 8
|
||
|
||
struct connection {
|
||
int connected;
|
||
int menuactive;
|
||
HANDLE menuThread;
|
||
SOCKET net;
|
||
HANDLE netThread;
|
||
HANDLE serial;
|
||
HANDLE serialThread;
|
||
int net_bytes_rx;
|
||
int net_bytes_tx;
|
||
};
|
||
struct connection connection[MAXCONNECTIONS];
|
||
|
||
/*
|
||
* output from OutputDebugStringA can be seen using sysinternals debugview
|
||
* http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx
|
||
... | ... | |
*specificError=WSAGetLastError();
|
||
return 9;
|
||
}
|
||
#ifndef MS_WINDOWS
|
||
{
|
||
int one=1;
|
||
setsockopt(ls,SOL_SOCKET,SO_REUSEADDR,(void*)&one,sizeof(one));
|
||
}
|
||
#endif
|
||
if (bind(ls,(struct sockaddr *)&sin,sizeof(sin))==SOCKET_ERROR) {
|
||
*specificError=WSAGetLastError();
|
||
dprintf(1,"wconsd: wconsd_init: failed to bind socket\n");
|
||
return 10;
|
||
}
|
||
if (listen(ls,1)==SOCKET_ERROR) {
|
||
... | ... | |
return 0;
|
||
}
|
||
|
||
DWORD WINAPI thread_new_connection(LPVOID lpParam) {
|
||
HANDLE netThread=NULL, comThread=NULL;
|
||
|
||
// run the menu to ask the user questions
|
||
run_menu();
|
||
|
||
// they must have opened the com port, so start the threads
|
||
PurgeComm(hCom,PURGE_RXCLEAR|PURGE_RXABORT);
|
||
netThread=CreateThread(NULL,0,wconsd_net_to_com,NULL,0,NULL);
|
||
comThread=CreateThread(NULL,0,wconsd_com_to_net,NULL,0,NULL);
|
||
|
||
return 0;
|
||
}
|
||
|
||
static void wconsd_main(void)
|
||
{
|
||
HANDLE wait_array[3];
|
||
... | ... | |
HANDLE netThread=NULL, comThread=NULL;
|
||
long zero;
|
||
|
||
struct sockaddr_in sa;
|
||
int salen;
|
||
|
||
int i;
|
||
|
||
/* clear out any bogus data in the connections table */
|
||
for (i=0;i<MAXCONNECTIONS;i++) {
|
||
connection[i].connected = 0;
|
||
}
|
||
|
||
/* Main loop: wait for a connection, service it, repeat
|
||
* until signalled that the service is terminating */
|
||
wait_array[0]=stopEvent;
|
||
... | ... | |
o=WaitForMultipleObjects(3,wait_array,FALSE,INFINITE);
|
||
|
||
switch (o-WAIT_OBJECT_0) {
|
||
case 0:
|
||
case 0: /* stopEvent */
|
||
run=FALSE;
|
||
ResetEvent(stopEvent);
|
||
break;
|
||
case 1: /* There is an incoming connection */
|
||
case 1: /* listenSocketEvent */
|
||
/* There is an incoming connection */
|
||
WSAResetEvent(listenSocketEvent);
|
||
as=accept(ls,NULL,NULL);
|
||
|
||
dprintf(1,"wconsd: accepted new connection\n");
|
||
|
||
if (as!=INVALID_SOCKET) {
|
||
if (cs!=INVALID_SOCKET) {
|
||
/* Close down the existing connection and let the new one through */
|
||
SetEvent(threadTermEvent);
|
||
shutdown(cs,SD_BOTH);
|
||
WaitForSingleObject(netThread,INFINITE);
|
||
WaitForSingleObject(comThread,INFINITE);
|
||
CloseHandle(netThread);
|
||
CloseHandle(comThread);
|
||
closesocket(cs);
|
||
ResetEvent(connectionCloseEvent);
|
||
ResetEvent(threadTermEvent);
|
||
}
|
||
cs=as;
|
||
zero=0;
|
||
ioctlsocket(cs,FIONBIO,&zero);
|
||
salen = sizeof(sa);
|
||
as=accept(ls,(struct sockaddr*)&sa,&salen);
|
||
|
||
if (as==INVALID_SOCKET) {
|
||
break;
|
||
}
|
||
|
||
// run the menu to ask the user questions
|
||
run_menu();
|
||
dprintf(1,"wconsd: new connection from %08x\n",
|
||
sa.sin_addr.s_addr);
|
||
|
||
// they must have opened the com port, so start the threads
|
||
PurgeComm(hCom,PURGE_RXCLEAR|PURGE_RXABORT);
|
||
netThread=CreateThread(NULL,0,wconsd_net_to_com,NULL,0,NULL);
|
||
comThread=CreateThread(NULL,0,wconsd_com_to_net,NULL,0,NULL);
|
||
/* search for an empty connection slot */
|
||
i=0;
|
||
while(connection[i].connected && i<MAXCONNECTIONS) {
|
||
i++;
|
||
}
|
||
if (i==MAXCONNECTIONS) {
|
||
dprintf(1,"wconsd: connection table overflow\n");
|
||
/* FIXME - properly reject the incoming connection */
|
||
/* for now, just close the socket */
|
||
closesocket(as);
|
||
break;
|
||
}
|
||
connection[i].connected=1;
|
||
connection[i].menuactive=1;
|
||
connection[i].menuThread=NULL;
|
||
connection[i].net=as;
|
||
connection[i].netThread=NULL;
|
||
connection[i].serial=INVALID_HANDLE_VALUE;
|
||
connection[i].serialThread=NULL;
|
||
connection[i].net_bytes_rx=0;
|
||
connection[i].net_bytes_tx=0;
|
||
|
||
dprintf(1,"wconsd: accepted connection id %i\n",i);
|
||
|
||
|
||
/* we successfully accepted the connection */
|
||
|
||
if (cs!=INVALID_SOCKET) {
|
||
/* There is an existing connected socket */
|
||
/* Close down the existing connection and let the new one through */
|
||
SetEvent(threadTermEvent);
|
||
shutdown(cs,SD_BOTH);
|
||
WaitForSingleObject(netThread,INFINITE);
|
||
WaitForSingleObject(comThread,INFINITE);
|
||
CloseHandle(netThread);
|
||
CloseHandle(comThread);
|
||
closesocket(cs);
|
||
ResetEvent(connectionCloseEvent);
|
||
ResetEvent(threadTermEvent);
|
||
}
|
||
cs=as;
|
||
zero=0;
|
||
ioctlsocket(cs,FIONBIO,&zero);
|
||
|
||
connection[i].menuThread = CreateThread(NULL,0,thread_new_connection,&connection[i],0,NULL);
|
||
|
||
break;
|
||
case 2: /* The data connection has been broken */
|
||
case 2: /* connectionCloseEvent*/
|
||
/* The data connection has been broken */
|
||
dprintf(1,"wconsd: connection closed\n");
|
||
SetEvent(threadTermEvent);
|
||
WaitForSingleObject(netThread,INFINITE);
|
||
... | ... | |
printf("wconsd: Console Application Mode (version %s)\n",VERSION);
|
||
r=wconsd_init(argc,argv,&err);
|
||
if (r!=0) {
|
||
printf("wconsd: debug: init failed, return code %d [%d]\n",r, err);
|
||
printf("wconsd: wconsd_init failed, return code %d [%d]\n",r, err);
|
||
return 1;
|
||
}
|
||
wconsd_main();
|
Also available in: Unified diff
Start to implement a connection table
This change is only half baked as I still have not altered the rest of the
threads to use the new connection table. Nor have I updated the event
signalling model to take into account the existance of multiple connections.