This example program uses a switched virtual circuit (SVC) to make a call and transmit data, as follows. Example program svcrcv is designed to receive the data sent by this program.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <NLchar.h> #include <x25sdefs.h>
#define LINK_NAME "x25s0" /* Name of X.25 port. */ #define CALLING_ADDR "54321" /* Calling Network User Address */ #define CALLED_ADDR "1234502" /* Called Network User Address */ #define SAMPLE_NAME "IBMSAMP" /* A name in the X.25 routing list.*/ #define INFO "Hello World" #define INFO2 "Goodbye Everyone"
/*****************************************************************************/ /* Function main */ /* Description This program is designed to demonstrate usage of the X.25 */ /* API. It makes a call, transmits some data, and then clears */ /* the call. */ /* Example program svcrcv is designed to receive the data sent */ /* by this program. */ /* Note that, in a production program, you should check the */ * return code from each subroutine call and take appropriate */ /* action. */ /* Return 0 if successful */ /* 1 if error occurs */ /*****************************************************************************/
int main(
  int argc,
  char *argv[])
{
  int conn_id;        /* Connection identifier,                              */
                      /*  to identify the call once it is made.               */
  int ctr_id;         /* Counter identifier to be associated with the call.  */
  int rc;             /* Used for return codes.                               */
  int ctr_num = 1;    /* The number of counters in counter array.             */  
/*****************************************************************************/ /* The following structures are defined in the x25sdefs.h file. */ /*****************************************************************************/
struct cb_msg_struct cb_msg; struct cb_link_name_struct cb_link_name; struct ctr_array_struct ctr_array[1]; struct cb_call_struct cb_call; struct cb_clear_struct cb_clear; struct cb_data_struct cb_data;
/***************************************************************************/ /* Initialize the API for access to a link. */ /***************************************************************************/
  cb_link_name.flags = X25FLG_LINK_NAME;
  cb_link_name.link_name = LINK_NAME;
  rc = x25_init<(&cb_link_name);                                                  
  if (rc < 0)
  {
    (void)printf("%s: x25_init failed : x25_errno = %d errno = %d\n",
                argv[0],x25_errno,errno);
    return(1);
  }
  else
  {  
/************************************************************************/ /* Get a counter to be used to notify us of incoming messages. */ /************************************************************************/ ctr_id = x25_ctr_get();
/************************************************************************/ /* Set the flags in the cb_call structure to indicate which fields * /* have been filled in. The fields which this program sets */ /* are the calling and called addresses, and the link on which to call. */ /* The D-bit field must also be set, as there will be a data packet */ /* sent later which sets the D-bit. */ /************************************************************************/
cb_call.flags = X25FLG_LINK_NAME; /* Set flag for using linkname. */ cb_call.link_name = LINK_NAME; cb_call.flags |= X25FLG_CALLING_ADDR; /* Set flag for calling address. */ cb_call.calling_addr = CALLING_ADDR; cb_call.flags |= X25FLG_CALLED_ADDR; /* Set flag for called address. */ cb_call.called_addr = CALLED_ADDR;
cb_call.flags |= X25FLG_D_BIT; /* Set flag for D-bit. */ /* Now that cb_call structure has been set up, make the call. */ /* The return code is the connection identifier, which will be used to */ /* refer to this call later. */
    conn_id = x25_call(&cb_call,ctr_id);                                       
    if (conn_id == -1)
    {
      (void)printf("%s: x25_call failed : x25_errno = %d errno = %d\n",
                  argv[0],x25_errno,errno);
      return(1);
    }
    else
      (void)printf("%s: Placed outgoing call\n",argv[0]); 
/************************************************************************/ /* After making the call, prepare for either a call-connected or a */ /* clear-indication message to arrive: */ /* wait for the counter value to change indicating an incoming message. */ /* (If there were more than one counter in the array, you would have to */ /* test the counter identifier to see which one had been incremented. */ /* In this case there is only one, so we do not have to do this.) */ /************************************************************************/
ctr_array[0].flags = X25FLG_CTR_ID; ctr_array[0].flags |= X25FLG_CTR_VALUE; ctr_array[0].ctr_id = ctr_id; ctr_array[0].ctr_value = 0; (void)x25_ctr_wait(ctr_num,ctr_array);
/* Receive the call-clear or call-connected packet. */ (void)x25_receive(&conn_id,&cb_msg);
/************************************************************************/ /* If the incoming message shows that the call has been connected, */ /* send some data<. */ /************************************************************************/
    if (cb_msg.msg_type == X25_CALL_CONNECTED)
    {
      cb_data.flags = X25FLG_DATA;
      cb_data.data_len = strlen(INFO);
      cb_data.data = INFO;
      (void)x25_send(conn_id,&cb_data);
      (void)printf("%s: Data sent\n",argv[0]); 
/**********************************************************************/ /* Send some more data but this time with the D bit set. This */ /* requires the receiver to send an acknowledgement to this data, */ /* so we have to wait for the acknowledgment to arrive. */ /**********************************************************************/
      cb_data.flags = X25FLG_DATA;
      cb_data.flags |= X25FLG_D_BIT;
      cb_data.data_len = strlen(INFO2);
      cb_data.data = INFO2;
      (void)x25_send(conn_id,&cb_data);
      (void)printf("%s: Data sent\n",argv[0]);
      /* Wait for and receive acknowledgement                               */
      (void)x25_ctr_wait(ctr_num,ctr_array);  
      (void)x25_receive(&conn_id,&cb_msg);   
 
      if (cb_msg.msg_type == X25_DATA_ACK)
        (void)printf("%s: Data has been acknowledged.\n",argv[0]);
      else
        (void)printf("%s: Unexpected packet received.\n",argv[0]);     
/**********************************************************************/ /* Clear the call now that transmission is completed. */ /**********************************************************************/
      cb_clear.flags = X25FLG_CAUSE;
      cb_clear.flags |= X25FLG_DIAGNOSTIC;
      cb_clear.cause = 0;            /* The CCITT code for DTE-originated   */
      cb_clear.diagnostic = 0;       /* No further information              */
 
      (void)printf("%s: Clearing the call.",argv[0]);
      
      /* The x25_call_clear function can return information from the clear  */
      /* confirmation packet. However, this isn't required here, so set the */
      /* third parameter to NULL.                                           */
      
      (void)x25_call_clear(conn_id,&cb_clear,(struct cb_msg_struct *)NULL);
    }    
/************************************************************************/ /* If the message received was a clear-indication, */ /* print out a message before terminating the program. */ /************************************************************************/
    else if (cb_msg.msg_type == X25_CLEAR_INDICATION)
    {
      (void)printf("%s: Call cleared. Cause = 0x%02x Diagnostic = 0x%02x\n",
        argv[0], cb_msg.msg_point.cb_clear->cause,
        cb_msg.msg_point.cb_clear->diagnostic);
    } 
/************************************************************************/ /* Finally, tidy up by removing the counter and terminating the API. */ /************************************************************************/
(void)x25_ctr_remove(ctr_id); (void)x25_term(&cb_link_name); } return(0); }