#ifndef _ecif_c #define _ecif_c #ifdef __cplusplus extern "C" { #endif #include "ecif.h" typedef struct ecinterfacevalues { pthread_t serverthread; int run; char servicename[42]; char envname[42]; int initport; SOCKNR sock; SOCKNR serversock; } ecinterfacevalues; ecinterfacevalues ecif = { NULL, 0, "elcam", "ELCAMPORT", 23500, INVALID_SOCKET, INVALID_SOCKET }; void elcamtcpshutdown( void ) { struct linger lin; if( ecif.sock == INVALID_SOCKET ){ return; } shutdown(ecif.sock,2); lin.l_onoff = 1; lin.l_linger = 0; setsockopt(ecif.sock,SOL_SOCKET,SO_LINGER,&lin,sizeof(lin)); ecif.sock = INVALID_SOCKET; } void elcamtcpshutdownserver( void ) { struct linger lin; if(ecif.serversock == INVALID_SOCKET){ return; } elcamtcpshutdown(); shutdown(ecif.serversock,2); lin.l_onoff = 1; lin.l_linger = 0; setsockopt(ecif.serversock,SOL_SOCKET,SO_LINGER,&lin,sizeof(lin)); ecif.serversock = INVALID_SOCKET; } void elcamtcpserverstop ( void ) { int ct = 0; if(! ecif.run){ return; } elcamtcpshutdownserver(); while( ecif.run ){ if(ct > 3 ){ break; } sleep(1); ct++; } ecif.run = 0; } void tcpecif_fillstate( void ) { tcpecif.run = run; tcpecif.active = 0; tcpecif.flag = 0; tcpecif.strategy = cfg.strategy; tcpecif.correct = 0; if( run && threaded_grab_busy && threaded_work_busy ){ if(correctactive){ if(correctresult == 1){ tcpecif.active = 1; tcpecif.correct = 1; } else if(correctresult == 2){ tcpecif.active = 1; tcpecif.left = cv.left; tcpecif.right = cv.right; tcpecif.up = cv.up; tcpecif.down = cv.down; } } } } /* in tcpecif are the incoming values; The same will be go back after function, with perhaps changed values. Only command TCPECIFCMD_ENDALL does not send anything back, all other sends back the same buffer. */ int elcamtcpserverwork( void ) { switch( tcpecif.cmd ){ case TCPECIFCMD_GETSTATE: tcpecif_fillstate(); break; case TCPECIFCMD_START: if( (! run ) && (! threaded_work_busy ) && (! threaded_grab_busy ) ){ ethread = NULL; if(pthread_create(ðread, NULL, (void *)&threaded_grabbing, NULL) != 0 ){ fprintf(stderr,"\nCannot create grabbing thread\n"); tcpecif.run = 0; break; } } tcpecif_fillstate(); break; case TCPECIFCMD_STOP: run = 0; tcpecif_fillstate(); break; case TCPECIFCMD_NOP: break; case TCPECIFCMD_ENDALL: return(0); break; } return(1); } void elcamtcpserverloop ( char *data ) { fd_set rfds; struct timeval tv; int retval; int addrlen; struct sockaddr_in IPaddr; SOCKNR sock; int len; ecif.run = 1; while( ecif.run && ( ecif.serversock != INVALID_SOCKET ) ) { elcamtcpshutdown(); sock = INVALID_SOCKET; FD_ZERO(&rfds); FD_SET(ecif.serversock,&rfds); retval = select(ecif.serversock + 1,&rfds,NULL,NULL,&tv); FD_ZERO(&rfds); if(retval <= 0 ){ continue; } addrlen = sizeof(IPaddr); sock = accept(ecif.serversock,(struct sockaddr *)&IPaddr,&addrlen); if(sock == INVALID_SOCKET){ continue; } ecif.sock = sock; len = recv( sock,(void *) &tcpecif, sizeof( tcpecif ),0); if(len < 0 ){ continue; } if( ! elcamtcpserverwork( ) ) { run = 0; break; } len = send(sock,( void *)&tcpecif,sizeof( tcpecif ) ,0); if(len < 0 ){ ;/*this should be an error */ } } elcamtcpshutdownserver(); ecif.run = 0; } int elcamtcpserverstart ( int usethread ) { char *p; struct servent *serv_ptr; SOCKNR sock; int opt; int rsize,ssize; struct protoent *proto; struct sockaddr_in IPaddr; unsigned long IPAddr; if(ecif.run){ return(1); } ecif.serversock = INVALID_SOCKET; ecif.sock = INVALID_SOCKET; if( ecif.initport == -1 ) { if(strlen( ecif.envname ) > 0 ){ if( ( p = getenv(ecif.envname)) ) { ecif.initport = atoi( p ); } else { if( strlen( ecif.servicename ) > 0 ) { if( ( serv_ptr = getservbyname(ecif.servicename, "tcp")) ) { ecif.initport = ntohs( serv_ptr->s_port ); } } } } } if( ecif.initport <= 0 ){ fprintf( stderr, "Cannot get valid tcp-port\n"); return(0); } proto = getprotobyname("tcp"); if(proto == NULL){ return(0); } sock = socket( AF_INET, SOCK_STREAM, proto->p_proto); if( sock == INVALID_SOCKET ) { return(0); } ecif.serversock = sock; opt = 1; if( setsockopt( sock, SOL_SOCKET, SO_REUSEADDR, ( char *)&opt,sizeof(opt)) != 0 ) { elcamtcpshutdownserver(); return(0); } rsize = 1024; if(setsockopt( sock, SOL_SOCKET, SO_RCVBUF, ( char *)&rsize,sizeof(rsize)) != 0 ) { elcamtcpshutdownserver(); return(0); } ssize = 1024; if(setsockopt( sock, SOL_SOCKET, SO_SNDBUF, ( char *)&ssize,sizeof(ssize)) != 0 ) { elcamtcpshutdownserver(); return(0); } (void)bzero(&IPaddr,sizeof(IPaddr)); IPaddr.sin_family = AF_INET; IPaddr.sin_addr.s_addr = INADDR_ANY; IPaddr.sin_port = (unsigned short) htons((unsigned short)ecif.initport); if(bind(sock,(struct sockaddr *)&IPaddr,(int)sizeof(IPaddr)) != 0) { elcamtcpshutdownserver(); return(0); } if(listen(sock,5) != 0) { elcamtcpshutdownserver(); return(0); } if(usethread){ if( pthread_create( &ecif.serverthread, NULL, (void *)&elcamtcpserverloop, NULL ) != 0 ){ elcamtcpshutdownserver(); return( 0 ); } return( 1 ); } elcamtcpserverloop( NULL ); return( 1 ); } #ifdef __cplusplus } #endif #endif /*_ecif_c*/