Sending Data on an ATM Socket SVC Client Example Program

This section describes the procedure for sending data on an ATM socket SVC client 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 Client Example
 *
 * This program opens a opens an best effort SVC and sends 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                     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
   int                     o[20];      // Temorary variable for ATM
                                       // address
   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) {          // Socket either returns the file descriptor
      perror("socket");    // or a -1 to indicate an error.
      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) {         // An error from bind would indicate the
      perror("bind");   // requested ATM device is not available.
      exit(-1);         // Check smitty devices.
   } /* endif */
   // Set the AAL parameters.
   // See the ATM UNI 3.0 for valid combinations.
   bzero( aal_parm, sizeof(aal_parm_t) );
   aal_parm.length = sizeof(aal_5_t);
   aal_parm.aal_type = CM_AAL_5;
   aal_parm.aal_info.aal5.fwd_max_sdu_size = 9188;
   aal_parm.aal_info.aal5.bak_max_sdu_size = 9188;
   aal_parm.aal_info.aal5.mode = CM_MESSAGE_MODE;
   aal_parm.aal_info.aal5.sscs_type = CM_NULL_SSCS;
   error = setsockopt( s, 0, SO_ATM_AAL_PARM, (void *)&aal_parm,
                       sizeof(aal_parm_t) );
   if (error) {
      perror("setsockopt SO_AAL_PARM");
      exit(-1);
   } /* endif */
   // Up to three BLLI may be specified in the setup message.
   // If a BLLI contains valid information, its length must be
   // set to sizeof(blli_t).  Otherwise set its length to 0.
   bzero(blli, sizeof(blli_t) * 3);
   blli[0].length = sizeof(blli_t); // Only use the first BLLI
   blli[1].length = 0;
   blli[2].length = 0;
   // This call will be delivered to the application that is
   // listening for calls that match these two parameters.
   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;
   blli[1].length = 0; /* sizeof(blli_t); */
   blli[2].length = 0;
   error = setsockopt( s, 0, SO_ATM_BLLI, (void *)&blli,
                       sizeof(blli) );
   if (error) {
      perror("setsockopt SO_ATM_BLLI");
      exit(-1);
   } /* endif */
   // Set the Traffic Descriptor
   // See the ATM UNI 3.0 for valid settings.
   bzero( traffic, sizeof(traffic_des_t) );
   // Here we specify a 25 Mbps best effort connection.  Best effort
   // indicates that the adapter should not enforce the transmission
   // rate.  Note that the minimum rate will be depend on what
   // best effort rate queues have bet configured for the ATM adapter.
   // See SMIT for details.
   traffic.best_effort = TRUE;         // No rate enforcement
   traffic.fwd_peakrate_lp = 25000;    // Kbps
   traffic.bak_peakrate_lp = 25000;    // Kbps
   traffic.tagging_bak = FALSE;
   traffic.tagging_fwd = FALSE;
   // Fields that are not used must be set to NOT_SPECIFIED_L (long)
   traffic.fwd_peakrate_hp = NOT_SPECIFIED_L;
   traffic.bak_peakrate_hp = NOT_SPECIFIED_L;
   traffic.fwd_sus_rate_hp = NOT_SPECIFIED_L;
   traffic.bak_sus_rate_hp = NOT_SPECIFIED_L;
   traffic.fwd_sus_rate_lp = NOT_SPECIFIED_L;
   traffic.bak_sus_rate_lp = NOT_SPECIFIED_L;
   traffic.fwd_bur_size_hp = NOT_SPECIFIED_L;
   traffic.bak_bur_size_hp = NOT_SPECIFIED_L;
   traffic.fwd_bur_size_lp = NOT_SPECIFIED_L;
   traffic.bak_bur_size_lp = NOT_SPECIFIED_L;
   error = setsockopt( s, 0, SO_ATM_TRAFFIC_DES, (void *)&traffic,
                       sizeof(traffic_des_t) ); 
   if (error) {
      perror("set traffic");
      exit(-1);
   } /* endif */
  // Set the Broadband Bearer Capability
   // See the UNI 3.0 for valid combinations
   bearer.bearer_class = CM_CLASS_C;
   bearer.traffic_type = NOT_SPECIFIED_B;
   bearer.timing = NOT_SPECIFIED_B;
   bearer.clipping = CM_NOT_SUSCEPTIBLE;
   bearer.connection_cfg = CM_CON_CFG_PTP;
   error = setsockopt( s, 0, SO_ATM_BEARER, (void *)&bearer,
                       sizeof(bearer_t) );
   if (error) {
      perror("set bearer");
      exit(-1);
   } /* endif */
   printf("Input ATM address to be called:\n");
   i = scanf( "%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x.%x",
               &o[0], &o[1], &o[2], &o[3], &o[4],
               &o[5], &o[6], &o[7], &o[8], &o[9],
               &o[10], &o[11], &o[12], &o[13], &o[14],
               &o[15], &o[16], &o[17], &o[18], &o[19] );
   if (i != 20) {
      printf("invalid atm address\n");
      exit(-1);
   }
   for (i=0; i<20; i++) {
     addr.sndd_atm_addr.number.addr[i] = o[i];
   } /* endfor */
   addr.sndd_atm_addr.length = ATM_ADDR_LEN;
   addr.sndd_atm_addr.type = CM_INTL_ADDR_TYPE;
   addr.sndd_atm_addr.plan_id = CM_NSAP;
   addr.sndd_atm_addr.pres_ind = NOT_SPECIFIED_B;
   addr.sndd_atm_addr.screening = NOT_SPECIFIED_B;
   addr.sndd_atm_vc_type = CONN_SVC;
   error = connect( s, (struct sockaddr *)&addr, sizeof(addr) );
   if (error) {
      perror("connect");
      // If a connect fails, the cause structure may contain useful
      // information for determining the reason of the failure.
      // See the ATM UNI 3.0 for a description of the cause values.
      size = sizeof(cause_t);
      error = getsockopt(s, 0, SO_ATM_CAUSE, (void *)&cause, &size);
      if (error) {
         perror("SO_ATM_CAUSE");
      } else {
         printf("cause = %d\n", cause.cause );
      } /* endif */
      exit(-1);
   } /* endif */
   while (1) {
      error = send( s, buff, BUFF_SIZE, 0 );
      if (error == -1) {
         // If a send 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("send");
         size = sizeof(cause_t);
         error = getsockopt(s, 0, SO_ATM_CAUSE, (void *)&cause, &size);
         if (error) {
            perror("SO_ATM_CAUSE");
         } else {
            printf("cause = %d\n", cause.cause );
         }
         exit(-1);
      } else {
         printf("sent %d bytes\n", error );
      }
      sleep(1);
   }
}