Receiving Data on an ATM Socket SVC Server Example Program

This section describes the procedure of receiving data on an ATM socket SVC server example program.

This program must be compiled with the -D_BSD and -lbsd options. For example, use the cc prog.c -o prog -D_BSD -lbsd command.


/*
 * ATM Sockets SVC Server Example
 *
 * This program listens for and accepts an SVC and receives data on it.
 *
 */
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/ndd_var.h>
#include <sys/atmsock.h>
#define BUFF_SIZE       8192
char    buff[BUFF_SIZE];
main(argc, argv)
        int argc;
        char *argv[];
{
   int                     s;          // Socket file descriptor
   int                     new_s;      // Socket returned by accept
   int                     error;      // Function return code
   int                     i;
   sockaddr_ndd_atm_t      addr;       // ATM Socket Address
   unsigned long           size;       // Size of socket argument
   aal_parm_t              aal_parm;   // AAL parameters
   blli_t                  blli[3];    // Broadband Lower Layer Info
   traffic_des_t           traffic;    // Traffic Descriptor
   bearer_t                bearer;     // Broadband Bearer Capability
   cause_t                 cause;      // Cause of failure
   // Create a socket in the AF_NDD domain of type SOCK_CONN_DGRAM
   // and NDD_PROT_ATM protocol.
   s = socket(AF_NDD, SOCK_CONN_DGRAM, NDD_PROT_ATM);
   if (s == -1) {
      perror("socket");
      exit(-1);
   }
   // The bind command associates this socket with a particular
   // ATM device, as specified by addr.sndd_atm_nddname.
   addr.sndd_atm_len = sizeof(addr);
   addr.sndd_atm_family = AF_NDD;
   strcpy( addr.sndd_atm_nddname, "atm0" );  // The name of the ATM device
                                             // which is to be used.
   error = bind( s, (struct sockaddr *)&addr, sizeof(addr) );
   if (error) {
      perror("bind");
      exit(-1);
   } /* endif */
   // Although up to 3 BLLIs may be specified by the calling side,
   // the listening side may only specify one.
   bzero(blli, sizeof(blli_t) );
   blli[0].length = sizeof(blli_t);
   blli[1].length = 0;
   blli[2].length = 0;
   // If a call arrives that matches these two parameters, it will
   // be given to this application.
   blli[0].L2_prot = CM_L2_PROT_USER;
   blli[0].L2_info = 1;
   // Fields that are not used must be set to NOT_SPECIFIED_B (byte)
   blli[0].L2_mode = NOT_SPECIFIED_B;
   blli[0].L2_win_size = NOT_SPECIFIED_B;
   blli[0].L3_prot = NOT_SPECIFIED_B;
   blli[0].L3_mode = NOT_SPECIFIED_B;
   blli[0].L3_def_pkt_size = NOT_SPECIFIED_B;
   blli[0].L3_pkt_win_size = NOT_SPECIFIED_B;
   blli[0].L3_info = NOT_SPECIFIED_B;
   blli[0].ipi = NOT_SPECIFIED_B;
   blli[0].snap_oui[0] = NOT_SPECIFIED_B;
   blli[0].snap_oui[1] = NOT_SPECIFIED_B;
   blli[0].snap_oui[2] = NOT_SPECIFIED_B;
   blli[0].snap_pid[0] = NOT_SPECIFIED_B;
   blli[0].snap_pid[1] = NOT_SPECIFIED_B;
   error = setsockopt( s, 0, SO_ATM_BLLI, (void *)&blli,
                       sizeof(blli) );
   if (error) {
      perror("setsockopt SO_ATM_BLLI");
      exit(-1);
   } /* endif */
   // Query and print out the ATM address of this station.  The
   // client application will need it.
   bzero( &addr, sizeof(addr));
   size = sizeof(addr);
   error = getsockname( s, (struct sockaddr *)&addr, &size );
   if (error) {
      perror("getsockname");
      exit(-1);
   } /* endif */
   printf("My ATM address: ");
   for (i=0; i<20; i++) {
     printf("%X.", addr.sndd_atm_addr.number.addr[i]);
   } /* endfor */
   printf("\n");
   // Although up to 3 BLLIs may be specified by the calling side,
   // the listening side may only specify one.
 bzero(blli, sizeof(blli_t) );
   blli[0].length = sizeof(blli_t);
   blli[1].length = 0;
   blli[2].length = 0;
   // If a call arrives that matches these two parameters, it will
   // be given to this application.
   blli[0].L2_prot = CM_L2_PROT_USER;
   blli[0].L2_info = 1;
   // Fields that are not used must be set to NOT_SPECIFIED_B (byte)
   blli[0].L2_mode = NOT_SPECIFIED_B;
   blli[0].L2_win_size = NOT_SPECIFIED_B;
   blli[0].L3_prot = NOT_SPECIFIED_B;
   blli[0].L3_mode = NOT_SPECIFIED_B;
   blli[0].L3_def_pkt_size = NOT_SPECIFIED_B;
   blli[0].L3_pkt_win_size = NOT_SPECIFIED_B;
   blli[0].L3_info = NOT_SPECIFIED_B;
   blli[0].ipi = NOT_SPECIFIED_B;
   blli[0].snap_oui[0] = NOT_SPECIFIED_B;
   blli[0].snap_oui[1] = NOT_SPECIFIED_B;
   blli[0].snap_oui[2] = NOT_SPECIFIED_B;
   blli[0].snap_pid[0] = NOT_SPECIFIED_B;
   blli[0].snap_pid[1] = NOT_SPECIFIED_B;
   error = setsockopt( s, 0, SO_ATM_BLLI, (void *)&blli,
                       sizeof(blli) );
   if (error) {
      perror("setsockopt SO_ATM_BLLI");
      exit(-1);
   } /* endif */
   // Query and print out the ATM address of this station.  The
   // client application will need it.
   bzero( &addr, sizeof(addr));
   size = sizeof(addr);
   error = getsockname( s, (struct sockaddr *)&addr, &size );
   if (error) {
      perror("getsockname");
      exit(-1);
   } /* endif */
   bzero( &addr, sizeof(addr));
   size = sizeof(addr);
   error = getsockname( s, (struct sockaddr *)&addr, &size );
   if (error) {
      perror("getsockname");
      exit(-1);
   } /* endif */
   // The listen call enables this socket to receive incoming call
   // that match its BLLI.
   error = listen( s, 10 );
   if (error) {
      // Listen will fail if the station is not connected to
      // an ATM switch.
      perror("listen");
      exit(-1);
   } /* endif */
   size = sizeof(addr);
   // The accept will return a new socket of an incoming call
   // for this socket, or sleep until one arrives.
   new_s = accept( s, (struct sockaddr *)&addr, &size );
   if (new_s == -1) {
      perror("accept");
      exit(-1);
   } /* endif */
   // In order for the connection to be fully established, the
   // SO_ATM_ACCEPT setsockopt call must be issued.  An application
   // may query the parameters first with getsockopt before deciding
   // to fully establish this connection and change some parameters.
   // If no parameters are to be changed the third parameter may
   // be NULL, otherwise it points to a indaccept_ie structure.
   error = setsockopt( new_s, 0, SO_ATM_ACCEPT, NULL, 0 );
   if (error) {
     perror("setsockopt ACCEPT");
     exit(-1);
   } /* endif */
   while (1) {
      error = recv( new_s, buff, BUFF_SIZE, 0 );
      if (error == -1) {
         // If a recv fails, the cause structure may contain useful
         // information for determining the reason of the failure.
         // The connection might have been closed by the other party,
         // or the physical network might have been disconnected.
         // See the ATM UNI 3.0 for a description of the cause values.
         // If the send failed for some other reason, the errno will
         // indicate this.
         perror("recv");
         size = sizeof(cause_t);
         error = getsockopt(new_s, 0, SO_ATM_CAUSE,
                           (void *)&cause, &size);
         if (error) {
            perror("SO_ATM_CAUSE");
         } else {
            printf("cause = %d\n", cause.cause );
         } /* endif */
         exit(-1);
      } else {
         printf("received %d bytes\n", error);
      } /* endif */
   }
}