home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / IE3802.ZIP / IEEE8022 / DLCSAMPO.C < prev    next >
Text File  |  1991-12-12  |  20KB  |  493 lines

  1. /******************************************************************************
  2. *                                                                             *
  3. *   Module name :     DLCSAMPL                                                *
  4. *                                                                             *
  5. *   Function :        Demo program for 802.2 interface of the LAN             *
  6. *                                                                             *
  7. *   Usage :           DLCSAMPL   {SEND       Netaddress=123456789abc          *
  8. *                                            [Adapter={0│1} ]     }           *
  9. *                                                                             *
  10. *                                {RECV       [Adapter={0│1} ]     }           *
  11. *                                                                             *
  12. *                                {DISP       [Adapter={0│1} ]     }           *
  13. *                                                                             *
  14. *                                defaults: Adapter=0                          *
  15. *                                                                             *
  16. *                                note that the remote address MUST            *
  17. *                                be supplied with the SEND option.            *
  18. *                                                                             *
  19. *                     DLCSAMPL   ?                                            *
  20. *                                                                             *
  21. *   Return codes :    0    if successful                                      *
  22. *                     1    if a parameter was bad and/or Help was given       *
  23. *                     x    if an NCB fails the ncb.retcode is returned        *
  24. *                                                                             *
  25. *                                                                             *
  26. *                                                                             *
  27. *                                                                             *
  28. *******************************************************************************/
  29. #define INCL_DOSSEMAPHORES
  30. #define INCL_16
  31.  
  32. #include <stdio.h>
  33. #ifndef E32TO16
  34. #include <dos.h>
  35. #endif
  36. #include <ctype.h>
  37.  
  38. #include <OS2.H>
  39.  
  40. /* Include programming language support declarations    */
  41. #include "lan_7_c.h"   /* general typedefs */
  42. #include "lan_1_c.h"   /* DLC defines      */
  43. #include "lan_2_c.h"   /* misc definitions */
  44. #include "lan_3_c.h"   /* CCB structures   */
  45. #include "lan_6_c.h"   /* ACSLAN external definitions */
  46.  
  47. /* Include sample program declarations   */
  48. #include "dlcerror.h"
  49. #include "dlcgblv.h"
  50. #include "dlcintf.h"
  51. #include "dirintf.h"
  52.  
  53. #ifdef E32TO16
  54. dword ReceiveSem, WorkSem;
  55. #else
  56. HSYSSEM ReceiveSem, WorkSem;
  57. #endif
  58.  
  59. main(argc,argv)
  60. int argc;
  61. char *argv[];
  62. {
  63.         /*------------------------------------------------------------+
  64.         │  Set the default parameters and initial values              │
  65.         +------------------------------------------------------------*/
  66.         dword semrc;
  67.  
  68.         Mode = SEND;
  69.         Lana = 0;
  70.         memset( RmtAddr, 0, 6);
  71.  
  72.         if ( GrabArgs( argc, argv ) )  {
  73.                 Help();
  74.                 exit(1);
  75.         }
  76.         else if (Mode == SEND && RmtAddr[0] == 0) {
  77.                 puts( ">> Remote network adapter address required for SEND" );
  78.                 Terminate( " ",0 );
  79.         }
  80.  
  81.         printf( "\nDLC Sample Program Started in %s mode.",
  82.                 (Mode == SEND ? "SEND" : (Mode == RECV ? "RECEIVE" : "DISP")));
  83.  
  84.         /*------------------------------------------------------------+
  85.         │  Create System Semaphores for use by the DLC code           │
  86.         │  System Semaphores are required because they are posted at  │
  87.         │  the device driver level.                                   │
  88.         +------------------------------------------------------------*/
  89.  
  90. #ifdef E32TO16
  91.         DosCreateSem(CSEM_PUBLIC,(void *)&WorkSem,"\\SEM\\DLCSAMPO\\WORKSEM");
  92.         if(Mode==RECV)
  93.           {
  94.           DosCreateSem(CSEM_PUBLIC,(void *)&ReceiveSem,"\\SEM\\DLCSAMPO\\RECEIVE");
  95.           } /* end else */
  96. #else
  97.         DosCreateSem(CSEM_PUBLIC, &WorkSem,"\\SEM\\DLCSAMPO\\WORKSEM");
  98.         if(Mode==RECV)
  99.           {
  100.           DosCreateSem(CSEM_PUBLIC, &ReceiveSem,"\\SEM\\DLCSAMPO\\RECEIVE");
  101.           } /* end else */
  102. #endif
  103.  
  104.         /*------------------------------------------------------------+
  105.         │  See that the adapter is initialized and open and make sure │
  106.         │  the user isn't trying to get us to talk to ourselves.      │
  107.         +------------------------------------------------------------*/
  108.  
  109.         LanaInit();
  110.         if (Mode == DISP)  {
  111.  
  112.                 printf( "\nThe lan adapter %u address is  ", Lana);
  113.                 for( i=0; i<6; ++i)
  114.                         printf( "%02X", LclAddr[i] );
  115.                 printf( ".\n" );
  116.                 exit(0);
  117.         }
  118.  
  119.         if (memcmp(LclAddr,RmtAddr,6) == 0) {
  120.                 printf( "\n>> This program cannot talk to itself" );
  121.                 Terminate( " ",0);
  122.         }
  123.  
  124.         /*------------------------------------------------------------+
  125.         │  Open our special SAP                                       │
  126.         +------------------------------------------------------------*/
  127.         printf( "Opening our SAP..." );
  128.         if(dlc_open_sap( &workccb, Lana, Mode==SEND?SendSap:RecvSap,WorkSem,Yes))
  129.            Terminate( "DLC_OPEN_SAP", workccb.ccb.ccb_retcode);
  130.         else {
  131.            Sapid = workccb.pt.open_sap.station_id;
  132.            puts( "ok" );
  133.            }
  134.  
  135.  
  136.         if (Mode == SEND) {
  137.                 /*----------------------------------------------------+
  138.                 │  If we're the SENDer, we now open a link station    │
  139.                 │  and do a dlc_connect.                              │
  140.                 +----------------------------------------------------*/
  141.  
  142.                 printf( "Opening the link station ..." );
  143.                 if(dlc_open_station( &workccb, Lana, Sapid, RmtAddr ,RecvSap,WorkSem,Yes))
  144.                     Terminate( "DLC_OPEN_STATION", workccb.ccb.ccb_retcode);
  145.                 else
  146.                     puts( "ok" );
  147.  
  148.                 Stationid = workccb.pt.open_station.link_station_id;
  149.  
  150.                 printf( "Connecting the link station ..." );
  151.  
  152.                 if(dlc_connect_station( &workccb, Lana, Stationid, RoutingInfo,WorkSem,Yes ))
  153.                    Terminate( "DLC_CONNECT_STATION", workccb.ccb.ccb_retcode);
  154.                 else
  155.                    puts( "ok" );
  156.  
  157.                 /*----------------------------------------------------+
  158.                 │  Next, we send our test data to the other station   │
  159.                 +----------------------------------------------------*/
  160.  
  161.                 msglen = strlen(message);
  162.  
  163.                 printf( "\nSending the message: <%s> ...", message );
  164.                 if(dlc_transmit_I_frame( &workccb, Lana, message, msglen,
  165.                                       ZEROADDRESS, (word) 0, Stationid,RecvSap,
  166.                                       WorkSem,Yes))
  167.                   Terminate( "DLC_TRANSMIT_I_FRAME", workccb.ccb.ccb_retcode);
  168.                 else
  169.                   puts( "ok" );
  170.  
  171.         }
  172.  
  173.         else {  /* Mode is RECV */
  174.  
  175.                 /*----------------------------------------------------+
  176.                 │  If we're the RECeiVer, we must wait for a DLC      │
  177.                 │  status change to tell us a link station has been   │
  178.                 │  opened.                                            │
  179.                 +----------------------------------------------------*/
  180.                 printf( "\nWaiting on DLC status change..." );
  181.                 dlc_status_read ( &workccb, Lana, Sapid,WorkSem,Yes);
  182.  
  183.                 dsp = &workccb.pt.read.status_tbl;
  184.                 if (dsp->reg_ax == LLC_SABME_RCV_STN_OPENED )
  185.                      {
  186.                      Stationid = dsp->stationid;
  187.                      printf( "\n=> DLC_STAT_CHANGE: 0x%04x", dsp->reg_ax);
  188.                      printf( "\nLink Station Opened.");
  189.                      }
  190.                 else
  191.                      {
  192.                      printf ("\nDLC_STAT_CHANGE code not as expected");
  193.                      printf ("\nEvent code = %x expected %x",dsp->reg_ax,
  194.                                                 LLC_SABME_RCV_STN_OPENED);
  195.                      exit(0);
  196.                      }
  197.  
  198.                 /*----------------------------------------------------+
  199.                 │  Next we start a receive for messages coming        │
  200.                 │  to this new link station.
  201.                 +----------------------------------------------------*/
  202.                 printf( "\nStarting a receive on the new link station ..." );
  203.                 receive( &rcvccb, Lana, Stationid,ReceiveSem,No);
  204.                 retcode = rcvccb.ccb.ccb_retcode;
  205.                 if (retcode != 0xFF)
  206.                         Terminate( "RECEIVE", retcode);
  207.                 else
  208.                         puts( "ok" );
  209.  
  210.  
  211.                 /*----------------------------------------------------+
  212.                 │  Finally We must complete the connection by issuing │
  213.                 │  a DLC_CONNECT_STATION CCB ourselves.               │
  214.                 +----------------------------------------------------*/
  215.                 printf( "Connecting the link station ..." );
  216.                 if(dlc_connect_station( &workccb, Lana, Stationid, RoutingInfo,WorkSem,Yes))
  217.                   Terminate( "DLC_CONNECT_STATION", workccb.ccb.ccb_retcode);
  218.                 else
  219.                    puts( "ok" );
  220.  
  221.                 /*----------------------------------------------------+
  222.                 │  Now the link has been established, so we wait for  │
  223.                 │  a received message.
  224.                 +----------------------------------------------------*/
  225. #ifdef E32TO16
  226.                 semrc = passemwait(ReceiveSem);
  227. #else
  228.                 DosSemWait(ReceiveSem,-1L);
  229. #endif
  230.                 if ((retcode=rcvccb.ccb.ccb_retcode) != 0x00)
  231.                       Terminate( "RECEIVE", retcode);
  232.  
  233.                 else  {
  234.                         printf( "\n=> Message received: ");
  235.                         rbptr = (struct receive_not_contiguous *) rcvccb.pt.receive.first_buffer;
  236. #ifdef E32TO16
  237.                         data_add.address = (char *)rbptr;
  238. #else
  239.                         data_add.address = (dword) rbptr;
  240. #endif
  241.                         data_add.part.offset = rbptr->user_offset;
  242. #ifdef E32TO16
  243.                         dataptr = data_add.address;
  244. #else
  245.                         dataptr = (char *) data_add.address;
  246. #endif
  247.                         for( i=0; i<rbptr->length_in_buffer; ++i)
  248.                                 printf( "%c", *dataptr++ );
  249.                         printf( "\n");
  250.                 }
  251.         }
  252.  
  253.         /*------------------------------------------------------------+
  254.         │  That's all, so we reset the whole SAP, thereby closing all │
  255.         │  its open link stations and freeing its resources.          │
  256.         +------------------------------------------------------------*/
  257.         printf( "\nDoing DLC_RESET ..." );
  258.         dlc_reset( &workccb, Lana, Sapid ,WorkSem,No);
  259.  
  260.         if (workccb.ccb.ccb_retcode)
  261.                 Terminate( "DLC_RESET", workccb.ccb.ccb_retcode);
  262.         else
  263.                 puts( "ok" );
  264.  
  265.         printf( "DLC Sample Program Completed.%c\n", BELL_CHAR );
  266.  
  267.         exit(0);
  268. }
  269.  
  270. /**********************************************************************/
  271. /*
  272. **  LanaInit    Initialize and open the adapter.
  273. **
  274. */
  275.  
  276. LanaInit()
  277. {
  278.         byte openrc;
  279.         /*--------------------------------------------------------------------+
  280.         │   dir_initialize the adapter                                        │
  281.         +--------------------------------------------------------------------*/
  282.         printf( "\nInitializing the adapter ..." );
  283.         dir_initialize( &workccb, Lana ,WorkSem,No);
  284.  
  285.         if (workccb.ccb.ccb_retcode == LLC_INVALID_SYS_KEYCODE)
  286.                 {
  287.                 printf( "\nDIR_INITIALIZE failed because your System Key in the LAN config file");
  288.                 printf( "\nwas not 'CFB0' which this sample program uses.  Everything should");
  289.                 printf( "\nstill work since the initialize is optional on OS/2.\n");
  290.                 }
  291.         else if (workccb.ccb.ccb_retcode)
  292.                 Terminate( "DIR_INITIALIZE", workccb.ccb.ccb_retcode);
  293.         else
  294.                 puts( "ok" );
  295.  
  296.         /*--------------------------------------------------------------------+
  297.         │   dir_open the adapter with mostly default parameters               │
  298.         │   If we're the receiver, we ring the bell when this CCB completes   │
  299.         │   to signal that the sender program should be started.              │
  300.         +--------------------------------------------------------------------*/
  301.  
  302.         printf( "Opening the adapter ..." );
  303.         dir_openadapter(&workccb,Lana,ProductId ,WorkSem,Yes);
  304.  
  305.         openrc = workccb.ccb.ccb_retcode;
  306.         if (openrc)
  307.                 Terminate( "DIR_OPEN", openrc);
  308.         else
  309.                 printf( "ok%c\n",(Mode==RECV? BELL_CHAR : ' '));
  310.         ApplId = workccb.ccb.ccb_appl_id;
  311.  
  312.         /* get our adapter's address */
  313.         dir_status( &workccb, Lana ,WorkSem,Yes);
  314.         if (workccb.ccb.ccb_retcode)
  315.                 Terminate( "DIR_STATUS", workccb.ccb.ccb_retcode);
  316.  
  317.         memcpy (LclAddr,workccb.pt.status.node_address,6);
  318. }
  319.  
  320.  
  321. /**********************************************************************/
  322. /*
  323. **  GrabArgs    Parses the command line arguments.  The first letters
  324. **              of each possible parameter keyword are sufficient to
  325. **              identify the parameter.
  326. **
  327. **              Accepts the standard argc,argv parameters
  328. **
  329. **              Modifies the global variables Mode, Lana, and NetAddr
  330. **              if successful, or produces an error message and exits.
  331. */
  332.  
  333. GrabArgs( argc, argv )
  334. int argc;
  335. char *argv[];
  336. {
  337.         char *cp, *strchr();
  338.         byte i;
  339.  
  340.  
  341.         while( --argc )  {
  342.  
  343.                 cp = *++argv;
  344.  
  345.                 switch( toupper(*cp) )  {
  346.  
  347.                         case 'S':       Mode = SEND;
  348.                                         break;
  349.  
  350.                         case 'R':       Mode = RECV;
  351.                                         break;
  352.  
  353.                         case 'D':       Mode = DISP;
  354.                                         break;
  355.  
  356.                         case 'A':       cp = strchr( cp, '=' );
  357.                                         if (! *cp)
  358.                                             Terminate("Bad adapter number", 0);
  359.                                         if (*++cp == '0')
  360.                                             Lana = 0;
  361.                                         else if (*cp == '1')
  362.                                             Lana = 1;
  363.                                         else
  364.                                             Terminate("Bad adapter number", 0);
  365.                                         break;
  366.  
  367.                         case 'N':       cp = strchr( cp, '=' );
  368.                                         if (! *cp)
  369.                                             Terminate("Bad remote network address", 0);
  370.  
  371.                                         for (++cp,i=0; isxdigit(*cp) && i<12; ++cp, ++i)
  372.                                             RmtAddr[i/2] = (RmtAddr[i/2] << 4) +
  373.                                                            (isdigit(*cp) ? (*cp-'0')
  374.                                                                          : (toupper(*cp)-'A'+10));
  375.  
  376.                                         if (i<12)
  377.                                             Terminate("Bad remote network address", 0);
  378.  
  379.                                         break;
  380.  
  381.                         case '?':       return 1;
  382.  
  383.                         default:        printf( ">>Extraneous input on command line: %s\n",
  384.                                                  cp );
  385.                                         Terminate( " ", 0);
  386.                                         break;
  387.                 }
  388.  
  389.         }
  390.  
  391.         return 0;
  392. }
  393.  
  394. /**********************************************************************/
  395. /*
  396. **  Help        Displays directions for running this demo program
  397. */
  398.  
  399. Help()
  400. {
  401.         puts( " " );
  402.         puts( " DLCSAMPL   {SEND       Netaddress=123456789abc  ");
  403.         puts( "                        [Adapter={0│1} ]     }   ");
  404.         puts( "                                                 ");
  405.         puts( "            {RECV       [Adapter={0│1} ]     }   ");
  406.         puts( "                                                 ");
  407.         puts( "            {DISP       [Adapter={0│1} ]     }   ");
  408.         puts( "                                                 ");
  409.         puts( "            defaults: Adapter=0                  ");
  410.         puts( "                                                 ");
  411.         puts( "            Note that the remote address MUST    ");
  412.         puts( "            be supplied with the SEND option.    ");
  413.         puts( "            This value can be obtained by running");
  414.         puts( "                                                 ");
  415.         puts( "                DLCSAMPL DISP [Adapter={0│1}]    ");
  416.         puts( "                                                 ");
  417.         puts( "            on the remote PC.                    ");
  418.         puts( " ");
  419.  
  420. }
  421.  
  422. /**********************************************************************/
  423. /*
  424. **  Terminate    Produce a formatted error message and
  425. **              terminate the program
  426. **
  427. **              Accepts a character string holding the failed action
  428. **              and an byte holding the return code.
  429. **
  430. **              DOES NOT RETURN
  431. */
  432.  
  433. #define BELL_CHAR       '\007'
  434.  
  435. Terminate( message, code )
  436. byte *message;
  437. byte code;
  438. {
  439.         char *TableLookUp();
  440.  
  441.         if (code)
  442.                 printf( "\n\n>> Error during %s: \n>>   %s%c\n",
  443.                         message, TableLookUp(DLCErrorMsgs,code), BELL_CHAR );
  444.         else    {
  445.                 printf( ">> %s\n", message);
  446.                 Help();
  447.                 code=1;
  448.         }
  449.  
  450.         exit(code);
  451. }
  452.  
  453. /*****************************************************************************/
  454. /*
  455. **  TableLookUp This function scans a code table for a specified value,
  456. **              and returns a text string which can be used as a message.
  457. */
  458.  
  459. char *TableLookUp(table, key)
  460. struct CodeTable *table;
  461. unsigned char key;
  462. {
  463.         while (table->label && table->code!=key) table++;
  464.         if (table->label) return(table->label);
  465.         else return(" <unknown> ");
  466. }
  467.  
  468. /*---------------------------------------------------------------------*
  469. * passemwait
  470. * This routine passes a seg16 parameter to DosSemWait
  471. *---------------------------------------------------------------------*/
  472. #ifdef E32TO16
  473. int passemwait(sem)
  474. HSYSSEM _Seg16 sem;
  475. {
  476.                 DosSemWait(sem,-1L);
  477.                 return(0);
  478. }
  479. #endif
  480.  
  481. /*---------------------------------------------------------------------*
  482. * pass_ccb()
  483. * This routine passes a CCB to the Adapter Handler.
  484. *---------------------------------------------------------------------*/
  485.  
  486. int pass_ccb(ccb)
  487. char * ccb;
  488. {
  489. address Bad_CCB_Ptr;
  490.  
  491. return (ACSLAN(ccb,(address)&Bad_CCB_Ptr));
  492. }
  493.