📄 lapb-test.c
字号:
/* * Test routines for LAP-B driver. * * This code may be used for any purpose as long as the author's * copyright is cited in any source code distributed. This code * is also available electronically from the author's web site. * * http://people.ne.mediaone.net/carlson/ppp * * http://www.workingcode.com/ppp * * Copyright 1999 by James Carlson and Working Code */#include <stdio.h>#include <stdlib.h>#include <assert.h>#include "sysdep.h"#include "util.h"#include "ahdlc.h"#include "lapb.h"/* State structure for LAP-B testing */struct session { char *name; /* Session name */ void *state; /* Handle from LAP-B engine */ void *line; /* Handle from AHDLC (if used) */ int seqnum; /* Message number to send */ int doxmit; /* State flag; LAP-B still has frames to send */ int sent; /* Number of messages sent */ int received; /* Number of messages received */ int loses; /* Intentionally dropped data frames */ int tosend; /* Number of messages to send during test */ int errors; /* Mismatched messages received */};static struct session dte,dce;/* Global flag -- dump all data in hex. */static int showdata;/* * Handle downcall from LAP-B. This would normally enable the hardware * transmit-empty interrupt and cause AHDLC to make a transmit upcall * into the LAP-B engine. */voidenable_transmit(void){#ifdef DEBUG_TEST printf("LAP-B requests call to transmit routine.\n");#endif dte.doxmit = dce.doxmit = 1;}/* * Handle LAP-B data reception. Normally, this would go up to the * PPP state machines or do a "wakeup" on a process-level component. * Here, we just fetch the received frames, print them, and check * integrity. */static voidlapb_rcvd(void *state){ struct session *sp = (struct session *)state; int len,snum; octet *bufp,*bp; if (showdata) printf("LAP-B %s received data.\n",sp->name); for (;;) { len = lapb_receive(sp->state,&bufp); if (bufp == NULL) break; sp->received++; /* Note: no terminating NUL byte on message; atoi won't do. */ snum = 0; for (bp = bufp+15; bp < bufp+len; bp++) snum = (snum*10) + (*bp - '0'); if ((bufp[12] ^ sp->name[1]) != ('t' ^ 'c') || snum != sp->received+sp->loses) { printf("ERROR: expected (d%ce,%d) but got (d%ce,%d)\n", sp->name[1]^'t'^'c',sp->received+sp->loses, bufp[12],snum); sp->errors++; } if (showdata) dump_buffer(bufp,len); buffer_release(bufp); }}/* * Handle LAP-B upcall. In a real system, this would dequeue buffers * from a device structure and pass them down to LAP-B transmit. Here * we just fabricate some test packets to send. */static voidlapb_hasroom(void *state){ struct session *sp = (struct session *)state; octet *bp; int retv;#ifdef DEBUG_TEST printf("LAP-B %s has output room.\n",sp->name);#endif for (;;) { if (sp->tosend <= 0) break; sp->seqnum++;#ifdef DEBUG_TEST printf("%s insert message number %d\n",sp->name,sp->seqnum);#endif sp->tosend--; bp = (octet *)buffer_fetch(LAPB_OVERHEAD+20); bp += LAPB_OVERHEAD; sprintf(bp,"hello from %s %d",sp->name,sp->seqnum); sp->sent++; retv = lapb_send(sp->state,bp,strlen(bp)); if (retv) break; }}void interrupts_off(void) {}void interrupts_on(void) {}void wakeup(void *event) {}void sleep(void *event, int level) {}intmain(argc,argv)int argc;char **argv;{ int i,len,useahdlc,dropone,supermode,timertest,queuemode,millisec; octet *bufp,*bufp2; char obuffer[32]; useahdlc = dropone = supermode = timertest = queuemode = 0; while ((i=getopt(argc,argv,"adqrst")) != EOF) switch (i) { case 'a': useahdlc++; break; case 'd': showdata++; break; case 'q': queuemode++; break; case 'r': dropone++; break; case 's': supermode++; break; case 't': timertest++; break; case '?': fprintf(stderr,"Usage:\n\t%s [-adqrst] [dte-count [dce-count]]\n", argv[0]); exit(1); } if (optind < argc) dte.tosend = atoi(argv[optind++]); else dte.tosend = 20; if (optind < argc) dce.tosend = atoi(argv[optind++]); else dce.tosend = 20; if (optind < argc) fprintf(stderr,"Extraneous command line arguments ignored.\n"); /* Create two LAP-B sessions and loop them together. */ if (supermode) dte.state = lapb_create(MODE_SUPER,10,10,0,0,LBF_ISDTE); else dte.state = lapb_create(MODE_BASIC,7,7,0,0,LBF_ISDTE); assert(dte.state != NULL); printf("Allocated DTE state structure %p\n",dte.state); if (supermode) dce.state = lapb_create(MODE_SUPER,10,10,0,0,0); else dce.state = lapb_create(MODE_BASIC,7,7,0,0,0); assert(dce.state != NULL); printf("Allocated DCE state structure %p\n",dce.state); dte.name = "dte"; dce.name = "dce"; dte.doxmit = dce.doxmit = 1; if (useahdlc) { dte.line = ahdlc_create(); ahdlc_handlers(dte.line,dte.state,lapb_input,lapb_transmit); dce.line = ahdlc_create(); ahdlc_handlers(dce.line,dce.state,lapb_input,lapb_transmit); } /* Install received data handlers and initialize */ lapb_handlers(dte.state,&dte,lapb_rcvd,lapb_hasroom); lapb_handlers(dce.state,&dce,lapb_rcvd,lapb_hasroom); if (queuemode) { lapb_hasroom((void *)&dte); lapb_hasroom((void *)&dce); } else { lapb_control(dte.state,1); lapb_control(dce.state,1); } /* Run tests */ for (i = 0; i < 20 || (i < 1000 && (dte.doxmit || dce.doxmit)); i++) { millisec = nextevent();#ifdef DEBUG_TEST if (millisec >= 0) printf("%d milliseconds to next event.\n",millisec);#endif if (timertest) { if (i == 15) { printf("Firing off an event.\n"); timeelapsed(-1); } else timeelapsed(500); } if (dte.doxmit != 0) { if (useahdlc) { len = ahdlc_transmit(dte.line,obuffer,sizeof(obuffer)); if (len > 0) { if (showdata) { printf("Looping back %d characters from DTE to DCE\n", len); dump_buffer(obuffer,len); } ahdlc_receive(dce.line,obuffer,len); } else { if (showdata) printf("LAP-B DTE out of data to send.\n"); dte.doxmit = 0; } } else { /* * Get next frame that the DTE side LAP-B is sending. In a * normal system, this would be done by an AHDLC upcall. */ lapb_transmit(dte.state,&bufp,&len); if (bufp != NULL) { if (showdata) { printf("LAP-B DTE sent frame.\n"); dump_buffer(bufp,len); } if ((dropone && i == 6) || (timertest && i >= 15 && i < 17)) { printf( "Intentionally dropping this one (will cause%s loss).\n", queuemode?"":" no"); if (queuemode) dce.loses++; } else { /* * Note: transmitter must not free buffer, but * receiver does free it. Therefore, for this * test code we have to do a data copy. This will * not happen in real life. */ bufp2 = (octet *)buffer_fetch(len); memcpy(bufp2,bufp,len); /* Send this into the other guy's input */ lapb_input(dce.state,bufp2,len); } } else { if (showdata) printf("LAP-B DTE out of data to send.\n"); dte.doxmit = 0; } } } if (dce.doxmit != 0) { if (useahdlc) { len = ahdlc_transmit(dce.line,obuffer,sizeof(obuffer)); if (len > 0) { if (showdata) { printf("Looping back %d characters from DCE to DTE\n", len); dump_buffer(obuffer,len); } ahdlc_receive(dte.line,obuffer,len); } else { if (showdata) printf("LAP-B DCE out of data to send.\n"); dce.doxmit = 0; } } else { /* Get the next frame from the LAP-B DCE side */ lapb_transmit(dce.state,&bufp,&len); if (bufp != NULL) { if (showdata) { printf("LAP-B DCE sent frame.\n"); dump_buffer(bufp,len); } bufp2 = (octet *)buffer_fetch(len); memcpy(bufp2,bufp,len); /* Send this into the other guy's input */ lapb_input(dte.state,bufp2,len); } else { if (showdata) printf("LAP-B DCE out of data to send.\n"); dce.doxmit = 0; } } } } /* Clean up. */ ahdlc_destroy(dte.line); ahdlc_destroy(dce.line); /* Display the results. */ printf("DTE: %d sent, %d received, %d remain.\n",dte.sent,dte.received, dte.tosend); printf("DCE: %d sent, %d received, %d remain.\n",dce.sent,dce.received, dce.tosend); buffer_status(); if (dte.tosend != 0 || dce.tosend != 0 || dte.errors != 0 || dce.errors != 0 || dte.sent != dce.received+dce.loses || dce.sent != dte.received) printf("ERROR: Some data lost.\n"); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -