This program uses a permanent virtual circuit (PVC) to make a call. It allocates the circuit, sends some data and then sends a reset. After receiving the reset-confirmation, the program sends some more data. Example Program pvcrcv is designed to receive the data sent by this program.
The following steps outline the pvcxmit program:
/* X.25 Example Program pvcxmit. */
#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 INFO "Hello World" /* Data to be sent. */ #define INFO2 "Goodbye Everyone" /* More data to be sent. */ #define END_OF_TRANS "EOP" /* End-of-transmission indicator: */ /* must be the same as in pvcrcv. */
/******************************************************************************/ /* Function main */ /* Description This program is designed to demonstrate usage of the X.25 */ /* API. */ /* It allocates a permanent virtual circuit, sends some data */ /* and then sends a reset. After receiving the */ /* reset-confirmation, the program sends some more data. */ /* Example Program pvcrcv 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 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_res_struct cb_res; struct cb_link_name_struct cb_link_name; struct cb_data_struct cb_data;
int conn_id; /* Connection identifier to associate with this link.*/ int ctr_id; /* Counter identifier for this link. */ int ctr_num = 1; /* Number of counters in the counter array. */ int rc; /* Return codes from various subroutines. */
/***************************************************************************/ /* 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 {
/**********************************************************************/ /* Now the PVC is available, send some data. */ /**********************************************************************/
cb_data.flags = X25FLG_DATA; cb_data.data_len = strlen(INFO); cb_data.data = INFO; (void)printf("%s: Sending some data...",argv[0]); (void)x25_send(conn_id,&cb_data);
/**********************************************************************/ /* Send a reset. */ /**********************************************************************/ (void)printf("%s: Resetting the circuit...",argv[0]); (void)x25_reset(conn_id,&cb_res);
/**********************************************************************/ /* After sending a reset packet, you must wait for the reset confirm */ /* to arrive. */ /**********************************************************************/ ctr_array[0].flags = X25FLG_CTR_ID; ctr_array[0].flags |= X25FLG_CTR_VALUE; ctr_array[0].ctr_id = ctr_id; (void)x25_ctr_wait(ctr_num,ctr_array);
/***********************************************************************/ /* There is now a message ready to be received. If it is anything */ /* other than the expected reset-confirmation, we: */ /* free the permanent virtual circuit */ /* remove the counter. */ /* terminate the API. */ /**********************************************************************/ (void)x25_receive(&conn_id,&cb_msg); if (cb_msg.msg_type != X25_RESET_CONFIRM) { (void)printf("%s: Did not receive expected reset confirm",argv[0]); (void)x25_pvc_free(conn_id); (void)x25_ctr_remove(ctr_id); (void)x25_term(&cb_link_name); return(1); } (void)printf("%s: Received reset confirm...",argv[0]);
/**********************************************************************/ /* Now send some more data */ /* The last block of data to be sent is the end-of-transmission */ /* indicator specified by END_OF_TRANS. This is understood by the */ /* PVC receiver example program, pvcrcv. */ /**********************************************************************/ cb_data.data_len = strlen(INFO2); cb_data.data = INFO2;
(void)printf("%s: Sending some data...",argv[0]); (void)x25_send(conn_id,&cb_data); (void)printf("%s: Sending last block of data...",argv[0]); cb_data.data_len = strlen(END_OF_TRANS); cb_data.data = END_OF_TRANS; (void)x25_send(conn_id,&cb_data);
/**********************************************************************/ /* 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); }