00001
00002
00003
00004
00005 #include "vxWorks.h"
00006 #include "stdioLib.h"
00007 #include "socket.h"
00008 #include "in.h"
00009 #include "sigLib.h"
00010 #include "taskLib.h"
00011
00012 #include "vxw_proto.h"
00013
00014 #define SERVER_NUM 2200
00015 #define ARGUMENT_BUFFER_SIZE 16384
00016
00017 extern char *sysSymTbl;
00018
00019 static int error_code;
00020
00021
00022
00023 void protocol_error(x)
00024 int x;
00025 { printf("VxWs protocol error %d\n",x);
00026 error_code=x; }
00027
00028 static getint(type, s)
00029 enum argument_type type;
00030 register FILE *s;
00031 { register int ival=0;
00032 switch(type) {
00033 A_LONG: ival=(getc(s)<<24)+(getc(s)<<16);
00034 A_SHORT: ival+=(getc(s)<<8);
00035 A_CHAR: return(ival+getc(s));}
00036 }
00037
00038 static double getfloat(type, s)
00039 enum argument_type type;
00040 register FILE *s;
00041 { double dval=0.0;
00042 number_union nu;
00043 switch(type) {
00044 case A_FLOAT: nu.i.ival1=getw(s); return(nu.f.fval1);
00045 case A_DOUBLE: nu.i.ival1=getw(s); nu.i.ival2=getw(s); return(nu.dval);
00046 }}
00047
00048 static getlength(s)
00049 FILE *s;
00050 { int len;
00051 len=getc(s);
00052 if (len & 0x80) {
00053 if (len & 0x40)
00054 return(((len & 0x3f)<<24) + (getc(s)<<16) + (getc(s)<<8) + getc(s));
00055 else return(((len & 0x7f)<<8) + getc(s)); }
00056 else return(len);}
00057
00058 static int getvector(s,vmem,index,bufsize)
00059 register FILE *s;
00060 register unsigned char *vmem;
00061 register int index;
00062 int bufsize;
00063 { register int i,length;
00064 length=getlength(s);
00065 if (index+length >= bufsize-100) {
00066 protocol_error(3);
00067 for (i=0; i<length; i++) getc(s);
00068 return(index);}
00069 for (i=0; i<length; i++) vmem[index++]=getc(s);
00070 i=4-(length % 4);
00071 while (i-- >0) vmem[index++] =0;
00072 return(index);}
00073
00074 int findsymbol(s)
00075 char *s;
00076 { int stat, entry, entry_type;
00077 if (symFindByName(sysSymTbl, s, &entry, &entry_type) == OK) return(entry);
00078 else return(ERROR);}
00079
00080 static int getsymbol(s)
00081 register FILE *s;
00082 { char symstr[256];
00083 register int i,len;
00084 int stat, entry, entry_type;
00085
00086 len=getlength(s);
00087 for (i=0; i<len; i++) symstr[i+1]=getc(s);
00088 symstr[len+1]=0;
00089 stat=symFindByName(sysSymTbl, &symstr[1], &entry, &entry_type);
00090 if (stat==ERROR) {
00091 symstr[0]='_';
00092 stat=symFindByName(sysSymTbl, symstr, &entry, &entry_type);
00093 if (stat==ERROR) return(ERROR);}
00094 return(entry);}
00095
00096 int call_vxw(fd)
00097 int fd;
00098 { FILE *s, *ws;
00099 int bufsize, running=1, callee, tid, result_type;
00100 int nextfree, i, j, len;
00101 int (*ifunc)();
00102 double (*ffunc)();
00103 double f;
00104 enum argument_type type;
00105 long cargv[32];
00106 number_union nu;
00107 unsigned char *ip, *vmem;
00108
00109 if ((s=fdopen(fd,"r"))==NULL) { printf("cannot fdopen read\n"); exit(2);}
00110 if ((ws=fdopen(fd,"w"))==NULL) { printf("cannot fdopen write\n"); exit(2);}
00111
00112 tid=taskIdSelf();
00113 taskVarAdd(tid, &error_code);
00114 bufsize=getw(s);
00115 vmem = malloc(bufsize);
00116 if (malloc==NULL) { protocol_error(7); return(7);}
00117
00118 printf("VxWserv v1.0 started with %d byte buffer\n", bufsize);
00119
00120 while (running) {
00121 nextfree=i=j=0; error_code=0;
00122 type=getc(s);
00123 if (type==EOF) { protocol_error(5); break;}
00124 if (type==A_SYMBOL) {
00125 callee=getsymbol(s);
00126 if (callee==ERROR) protocol_error(1); }
00127 else if (type==A_LONG) callee=getw(s);
00128 else protocol_error(2);
00129
00130
00131
00132 type=getc(s);
00133 while (type!=A_END) {
00134 if (j>=32) protocol_error(5);
00135 switch(type) {
00136 case A_CHAR: cargv[i++]=getc(s); break;
00137 case A_SHORT: cargv[i++]=(getc(s)<<8) + getc(s); break;
00138 case A_LONG: cargv[i++]=getw(s); break;
00139 case A_FLOAT: len=getw(s); nu.i.ival1=len;
00140 nu.dval=nu.f.fval1;
00141 cargv[i++]=nu.i.ival1; cargv[i++]=nu.i.ival2;
00142 break;
00143 case A_SYMBOL: cargv[i++]=getsymbol(s); break;
00144 case A_VECTOR: cargv[i++]= &vmem[nextfree];
00145 nextfree=getvector(s,vmem,nextfree,bufsize);
00146 break;
00147 default: protocol_error(4); break; }
00148 j++;
00149 type=getc(s);
00150 if (type==EOF) protocol_error(6);
00151 }
00152
00153 result_type=getc(s);
00154
00155
00156 putc(error_code, ws);
00157 if (error_code==5) break;
00158
00159 if (error_code!=0) { }
00160 else if (result_type==A_FLOAT || result_type==A_DOUBLE) {
00161 ffunc=callee;
00162 if (j<=8)
00163 f=(*ffunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00164 cargv[4],cargv[5],cargv[6],cargv[7]);
00165 else if (j<=32)
00166 f=(*ffunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00167 cargv[4],cargv[5],cargv[6],cargv[7],
00168 cargv[8],cargv[9],cargv[10],cargv[11],
00169 cargv[12],cargv[13],cargv[14],cargv[15],
00170 cargv[16],cargv[17],cargv[18],cargv[19],
00171 cargv[20],cargv[21],cargv[22],cargv[23],
00172 cargv[24],cargv[25],cargv[26],cargv[27],
00173 cargv[28],cargv[29],cargv[30],cargv[31]);
00174
00175 nu.f.fval1=f;
00176 putw(nu.i.ival1, ws);}
00177 else {
00178 ifunc=callee;
00179 if (j<8)
00180 i=(*ifunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00181 cargv[4],cargv[5],cargv[6],cargv[7]);
00182 else if (j<=32)
00183 i=(*ifunc)(cargv[0],cargv[1],cargv[2],cargv[3],
00184 cargv[4],cargv[5],cargv[6],cargv[7],
00185 cargv[8],cargv[9],cargv[10],cargv[11],
00186 cargv[12],cargv[13],cargv[14],cargv[15],
00187 cargv[16],cargv[17],cargv[18],cargv[19],
00188 cargv[20],cargv[21],cargv[22],cargv[23],
00189 cargv[24],cargv[25],cargv[26],cargv[27],
00190 cargv[28],cargv[29],cargv[30],cargv[31]);
00191
00192 if (result_type==A_CHAR || result_type==A_SHORT || result_type==A_LONG)
00193 putw(i,ws);
00194 else if (result_type==A_VECTOR) {
00195 len=getlength(s); ip=(unsigned char *) i;
00196 for (j=0; j<len; j++) { putc(*ip, ws); ip++;}
00197 }
00198 }
00199 fflush(ws);}
00200
00201 fclose(s); free(vmem);
00202 printf("connection closed\n"); }
00203
00204
00205
00206
00207 static int sock;
00208
00209 int spawn_vxw(fd)
00210 int fd;
00211 { char taskname[16];
00212 int stat,entry,entry_type;
00213 static int task_id=1;
00214 unsigned char option,priority;
00215
00216 read(fd, &priority,1);
00217 read(fd, &option, 1);
00218 sprintf(taskname,"VxWs_%d",task_id++);
00219 stat=taskSpawn(taskname, priority, option, 3000,call_vxw,fd);
00220 if (stat==ERROR) { printf("cannot spawn\n"); return(ERROR); }
00221 else return(OK);}
00222
00223 static void abort(sig)
00224 int sig;
00225 { printf("vxwserv aborting\n");
00226 close(sock);
00227 exit(sig);}
00228
00229 vxwserv ()
00230 { int snew;
00231 struct sockaddr_in serverAddr;
00232 struct sockaddr_in clientAddr;
00233 int client_len;
00234 int connection_count=0;
00235 unsigned char special;
00236 SIGVEC sigabort;
00237
00238 sigabort.sv_handler = abort;
00239 sigabort.sv_mask = !SIGMASK(SIGINT);
00240 sigabort.sv_flags= 0;
00241 sigvec(SIGINT, &sigabort, 0);
00242
00243
00244
00245
00246 bzero (&serverAddr, sizeof (serverAddr));
00247 bzero (&clientAddr, sizeof (clientAddr));
00248
00249 sock = socket (AF_INET, SOCK_STREAM, 0);
00250 if (sock == ERROR) exit (1);
00251 else printf("listening on socket %d\n",sock);
00252
00253
00254 serverAddr.sin_family = AF_INET;
00255 serverAddr.sin_port = SERVER_NUM;
00256
00257 while (bind (sock, (SOCKADDR *)&serverAddr, sizeof(serverAddr))==ERROR) {
00258 printf ("bind failed, errno = %d\n", errnoGet());
00259 serverAddr.sin_port++; }
00260 printf ("port %d is bound.\n", serverAddr.sin_port);
00261
00262 if (listen (sock, 2) == ERROR) {
00263 printf ("listen failed\n");
00264 close (sock);
00265 exit (1);}
00266
00267
00268 while (1) {
00269 client_len = sizeof (clientAddr);
00270 snew = accept (sock, (SOCKADDR *)&clientAddr, &client_len);
00271 if (snew==ERROR) { printf("accept failed\n"); close(sock); break;}
00272 printf("CLIENT accepted: sock=%d port=%d family=%d addr=%lx\n",
00273 snew,
00274 clientAddr.sin_port, clientAddr.sin_family,
00275 clientAddr.sin_addr.s_addr);
00276 connection_count++ ;
00277 read(snew, &special, 1);
00278 if (spawn_vxw(snew)==ERROR)
00279 { printf("spawn failed\n"); } ;
00280 }
00281 printf ("totally %d connections established\n",connection_count);
00282 close (sock); }