[ Previous | Next | Table of Contents | Index | Library Home | Legal | Search ]

Communications Programming Concepts


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 */
   }
}


[ Previous | Next | Table of Contents | Index | Library Home | Legal | Search ]