This program uses a permanent virtual circuit (PVC) to make a call. It allocates the circuit, receives data, and is prepared to handle a reset by sending a reset-confirmation packet. Example program pvcxmit is designed to send the data received by this program.
The X.25 program uses the following steps:
/* X.25 Example Program pvcrcv. */
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <x25sdefs.h>
#define LINK_NAME "x25s0" /* Name of X.25 port. */ #define LOG_CHAN_NUM (1) /* PVC logical channel number. */ #define END_OF_TRANS "EOP" /* End-of-transmission indicator; */ /* must be the same as in pvcxmit. */
/*****************************************************************************/ /* Function main */ /* Description This program is designed to demonstrate usage of the X.25 */ /* API. */ /* It allocates a permanent virtual circuit, receives data and */ /* is prepared to handle a reset, by sending a */ /* reset-confirmation. */ /* Example Program pvcxmit is designed to send the data */ /* received 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 otherwise */ /*****************************************************************************/
int main( int argc, char *argv[]) {
/***************************************************************************/ /* The following structures are defined in the x25sdefs.h file. */ /***************************************************************************/ struct ctr_array_struct ctr_array[1]; /* One counter in the array. */ struct cb_msg_struct cb_msg; struct cb_pvc_alloc_struct cb_pvc; struct cb_link_name_struct cb_link_name;
int conn_id; /* Connection identifier to associate with this link.*/ int ctr_id; /* Counter identifier for this link. */ int rc; /* Return codes from various subroutines. */ int ctr_num = 1; /* Number of counters in the counter array. */ int end_tx = 0; /* Whether end of transmission has been reached. */
/***************************************************************************/ /* 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 up flags to show that a link and a channel number are supplied. */ /* Then allocate the permanent virtual circuit for this application. */ /************************************************************************/ cb_pvc.flags = X25FLG_LINK_NAME | X25FLG_LCN; cb_pvc.link_name = LINK_NAME; cb_pvc.lcn = LOG_CHAN_NUM;
conn_id = x25_pvc_alloc(&cb_pvc,ctr_id);
if (conn_id < 0) { (void)printf("%s: x25_pvc_alloc failed : x25_errno = %d errno = %d\n", argv[0],x25_errno,errno); return(1); } else {
/********************************************************************/ /* The PVC link has now been set up and data can be received. */ /* Wait for any message to arrive for this application */ /********************************************************************/
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; do { (void)x25_ctr_wait(ctr_num,ctr_array);
/********************************************************************/ /* Receive the message */ /********************************************************************/ (void)x25_receive(&conn_id,&cb_msg);
/********************************************************************/ /* If a reset-indication message is received, we must */ /* send a reset-confirmation message as soon as possible. */ /********************************************************************/ if (cb_msg.msg_type == X25_RESET_INDICATION) { (void)printf("%s: Received reset indication...",argv[0]); (void)x25_reset_confirm(conn_id); }
/* If data is received, we display it on the screen, unless it is */ /* end-of-transmission indicator specified by END_OF_TRANS. */ else if (cb_msg.msg_type == X25_DATA) { (void)printf("%s: Incoming Data : ",argv[0]); (void)printf("%s\n",cb_msg.msg_point.cb_data->data); if (strcmp(cb_msg.msg_point.cb_data->data,END_OF_TRANS) != 0) { (void)printf("%s",cb_msg.msg_point.cb_data->data); (void)printf("\n"); } else { (void)printf("%s: End of transmission received",argv[0]); end_tx = 1; }
/******************************************************************/ /* The X.25 API allocates memory for information to be returned. */ /* Although there are no memory constraints in this application, */ /* the space is freed when the information has been displayed. */ /******************************************************************/ free((char *)cb_msg.msg_point.cb_data->data); free((char *)cb_msg.msg_point.cb_data); } else { (void)printf("%s: Unexpected packet received",argv[0]); } } while (end_tx == 0);
/**********************************************************************/ /* Free up any resources allocated during the program before ending: */ /* free the permanent virtual circuit */ /* remove the counter */ /* terminate the API. */ /**********************************************************************/ (void)x25_pvc_free(conn_id); (void)x25_ctr_remove(ctr_id); (void)x25_term(&cb_link_name); } } return(0); }