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