/* Embedded Kermit, main program. */ /* This version for VxWorks, by Airvana, Inc., Chelmsford MA (USA) http://www.airvananet.com, included with EK by permission, Oct 2002. */ #include "vxworks.h" #include "UserTypes.h" #include "Result.h" #include "stdio.h" #include "stat.h" #include "kermit.h" /* Debugging */ #ifdef DEBUG FILE * dp = (FILE *)0; int debug = 1; #endif /* DEBUG */ /* External data */ extern UCHAR o_buf[]; /* Must be defined in io.c */ extern int errno; /* Data global to this module */ static struct k_data k; /* Kermit data structure */ static struct k_response r; /* Kermit response structure */ #ifdef DEBUG int errorrate = 0; /* Simulated error rate */ int seed = 1234; /* Random number generator seed */ #endif /* DEBUG */ int kexit(int status) { pktmode(OFF); /* Restore device */ devclose(); /* Close device */ #ifdef DEBUG if (dp != (FILE *)0) fclose(dp); #endif if (status == FAILURE) return RESULT_E_FAIL; else return RESULT_S_OK; } int kinit(int action, int xmode, int ftype, int parity, int check, int remote, char *path) { int status, rx_len, i, x; char c; UCHAR *inbuf; short r_slot; UCHAR *flist[2]; parity = P_PARITY; /* Set this to desired parity */ status = X_OK; /* Initial kermit status */ #ifdef DEBUG dp = fopen("disk0:/Kermit.dbg", "wb"); if (dp == (FILE *)0) debug = 0; debug = 1; if (debug) fprintf(dp,"SIMULATED ERROR RATE: %d\n",errorrate); if (errorrate) srand(seed); /* Init random error generator */ #endif /* DEBUG */ if (!devopen("dummy")) /* Open the communication device */ return kexit(FAILURE); if (!pktmode(ON)) /* Put it in packet mode */ return kexit(FAILURE); #ifdef DEBUG if (debug) fprintf(dp,"Initializing...\n"); #endif /* DEBUG */ /* THE REAL STUFF IS FROM HERE DOWN */ /* Fill in parameters for this run */ flist[0] = (UCHAR *)path; flist[1] = (UCHAR *)0; k.xfermode = xmode; /* Text/binary automatic/manual */ k.remote = remote; /* Remote vs local */ k.binary = ftype; /* 0 = text, 1 = binary */ k.parity = parity; /* Communications parity */ k.bct = check; /* Block check type */ k.filelist = flist; /* List of files to send (if any) */ /* Fill in the i/o pointers */ k.obuf = o_buf; /* File output buffer */ k.obuflen = OBUFLEN; k.obufpos = 0; /* Fill in function pointers */ k.txd = tx_data; /* for sending packets */ k.openf = openfile; /* for opening output file */ k.writef = writefile; /* for opening output file */ k.closef = closefile; /* for closing output file */ status = kermit(K_INIT, &k, 0, 0, "", &r); #ifdef DEBUG if (debug) fprintf(dp,"status=%d\n",status); #endif /* DEBUG */ if (status == X_ERROR) return kexit(FAILURE); if (action == A_SEND) status = kermit(K_SEND, &k, 0, 0, "", &r); /* Now we read a packet ourselves and call Kermit with it. Normally, Kermit would read its own packets, but in the embedded context, the device must be free to do other things while waiting for a packet to arrive. So the real control program might dispatch to other types of tasks, of which Kermit is only one. But in order to read a packet into Kermit's internal buffer, we have to ask for a buffer address and slot number. */ while (status != X_DONE) { inbuf = getrslot(&k,&r_slot); /* Allocate a window slot */ #ifdef DEBUG if (debug) fprintf(dp,"inbuf=%ld, r_slot=%d\n",inbuf,r_slot); #endif /* DEBUG */ /* Try to read a packet */ /* (inbuf,k.r_maxlen+4,k.r_soh,k.r_eom,k.r_timo,k.parity); */ rx_len = readpkt(inbuf,&k); #ifdef DEBUG if (debug) { fprintf(dp,"rx_len=%d\n",rx_len); if (rx_len > 0) fprintf(dp,"RPKT[%s]\n",&(k.ipktbuf[0][r_slot])); } #endif /* DEBUG */ /* For simplicity, Kermit ACKs the packet immediately after verifying it was received correctly. If, afterwards, the control program fails to handle the data correctly (e.g. can't open file, can't write data, can't close file), then it tells Kermit to send an Error packet next time through the loop. */ if (rx_len < 1) { /* No data was read */ freerslot(&k,r_slot); /* So free the window slot */ if (rx_len < 0) /* If there was a fatal error */ return kexit(FAILURE); /* give up */ } /* Handle the input */ switch (status = kermit(K_RUN, &k, r_slot, rx_len, "", &r)) { case X_OK: continue; /* Keep looping */ case X_DONE: break; /* Finished */ case X_ERROR: return kexit(FAILURE); /* Failed */ } } return kexit(SUCCESS); }