|
|
1.1 root 1: /* pingpong.c - listen and call out at the same time */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/others/pingpong/RCS/pingpong.c,v 7.0 89/11/23 22:01:11 mrose Rel $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/others/pingpong/RCS/pingpong.c,v 7.0 89/11/23 22:01:11 mrose Rel $
9: *
10: *
11: * $Log: pingpong.c,v $
12: * Revision 7.0 89/11/23 22:01:11 mrose
13: * Release 6.0
14: *
15: */
16:
17: /*
18: * NOTICE
19: *
20: * Acquisition, use, and distribution of this module and related
21: * materials are subject to the restrictions of a license agreement.
22: * Consult the Preface in the User's Manual for the full terms of
23: * this agreement.
24: *
25: */
26:
27: #include <stdio.h>
28: #include <isode/isoaddrs.h>
29: #include <isode/tsap.h>
30:
31: struct PSAPaddr * pingaddr;
32: struct PSAPaddr * pongaddr;
33: int cn_state = NOTOK;
34: int cn_sd = NOTOK;
35:
36: fd_set wfds, rfds;
37: int nfds = 0;
38: int doneit = 0;
39: int retry = 1;
40:
41: main (argc,argv)
42: int argc;
43: char ** argv;
44: {
45:
46: do_args (argc,argv);
47:
48: start_listener ();
49:
50: printf ("Started to listen\n");
51:
52: ping_address ();
53:
54: wait_for_result ();
55:
56: printf ("Got Result\n");
57:
58: stop_nicely ();
59: }
60:
61: do_args (argc,argv)
62: int argc;
63: char ** argv;
64: {
65: char * myname;
66:
67: if (myname = rindex (argv[0], '/'))
68: myname++;
69: if (myname == NULL || *myname == NULL)
70: myname = argv[0];
71:
72: if (argc != 3) {
73: (void) fprintf (stderr,"Usage pingpong listen_address call_address\n");
74: exit (-1);
75: }
76:
77: isodetailor (myname, 0);
78:
79: if ((pongaddr = str2paddr (argv[1])) == NULLPA) {
80: (void) fprintf (stderr,"Invalid listen address %s\n", argv[1]);
81: exit (-1);
82: }
83:
84: if ((pingaddr = str2paddr (argv[2])) == NULLPA) {
85: (void) fprintf (stderr,"Invalid call address %s\n", argv[2]);
86: exit (-1);
87: }
88: }
89:
90:
91: start_listener ()
92: {
93: struct TSAPdisconnect td_s;
94: struct TSAPdisconnect * td = &(td_s);
95:
96: if(TNetListen(&pongaddr->pa_addr.sa_addr, td) == NOTOK) {
97: ts_advise ("TNetListen", td);
98: exit (-2);
99: }
100: }
101:
102: ping_address ()
103: {
104: struct TSAPstart tss;
105: register struct TSAPstart *ts = &tss;
106: struct TSAPdisconnect tds;
107: register struct TSAPdisconnect *td = &tds;
108: struct TSAPconnect tcs;
109: struct TSAPconnect *tc = &tcs;
110:
111: cn_state = TAsynConnRequest (NULLTA, &pingaddr->pa_addr.sa_addr, 0,
112: NULLCP, ts -> ts_cc, &ts -> ts_qos,
113: tc, td, 1);
114:
115: cn_sd = tc -> tc_sd;
116: printf ("Starting ping on %d state ", cn_sd);
117: updatemask ();
118: if (cn_state == NOTOK)
119: ts_advise ("TAsynConnRequest", td);
120: else
121: retry = 0;
122: }
123:
124:
125: wait_for_result ()
126: {
127: int vecp = 0;
128: char *vec[4];
129: int i;
130: struct TSAPdisconnect td_s;
131: struct TSAPdisconnect *td = &td_s;
132: struct TSAPconnect tcs;
133: struct TSAPconnect *tc = &tcs;
134: struct TSAPstart tss;
135: struct TSAPstart *ts = &tss;
136: fd_set ifds, ofds;
137:
138: for (;;) {
139:
140: ifds = rfds;
141: ofds = wfds;
142: printf ("TNetAccept nfds=%d rfds=0x%x wfds=0x%x\n", nfds,
143: rfds.fds_bits[0], wfds.fds_bits[0]);
144: if(TNetAccept(&vecp, vec, nfds, &ifds, &ofds, NULLFD,
145: NOTOK, td) == NOTOK)
146: {
147: ts_advise ("TNetAccept failed", td);
148: exit (-3);
149: }
150: if (retry)
151: ping_address ();
152:
153: if (vecp > 0) {
154: if (TInit (vecp, vec, ts, td) == NOTOK) {
155: ts_advise ("TInit failed failed", td);
156: exit (-1);
157: }
158: if (TConnResponse (ts->ts_sd, NULLTA, 0, NULLCP, 0,
159: &tc -> tc_qos, td) == NOTOK) {
160: ts_advise ("TConnResponse", td);
161: exit (-1);
162: }
163: printf ("Connection accepted on %d\n", ts -> ts_sd);
164: FD_SET (ts -> ts_sd, &rfds);
165: if (ts -> ts_sd >= nfds)
166: nfds = ts -> ts_sd + 1;
167: }
168:
169: for (i = 0; i < nfds; i++) {
170: if (FD_ISSET (i, &ofds) || FD_ISSET (i, &ifds)) {
171: if (i == cn_sd)
172: progress_connection ();
173: else {
174: if (sink_data (i) != OK) {
175: FD_CLR (i, &rfds);
176: if (doneit ++ > 0)
177: return;
178: }
179:
180: }
181: }
182: }
183: if (cn_state == DONE) {
184: if (doneit ++ > 0)
185: return;
186: cn_state = NOTOK;
187: }
188: }
189: }
190:
191: sink_data (sd)
192: int sd;
193: {
194: struct TSAPdisconnect tds;
195: struct TSAPdisconnect *td = &tds;
196: struct TSAPdata txs, *tx = &txs;
197:
198: if (TReadRequest (sd, tx, OK, td) == NOTOK) {
199: if (td -> td_reason = DR_NORMAL)
200: ts_advise ("Normal disconnection", td);
201: else ts_advise ("TReadRequest", td);
202: return NOTOK;
203: }
204: TXFREE (tx);
205: return OK;
206: }
207:
208: progress_connection ()
209: {
210: struct TSAPdisconnect td_s;
211: struct TSAPdisconnect *td = &td_s;
212: struct TSAPconnect tcs;
213: struct TSAPconnect *tc = &tcs;
214:
215: switch(cn_state)
216: {
217: case CONNECTING_1:
218: printf ("CONNECTING_1 -> ");
219: cn_state = TAsynRetryRequest(cn_sd,tc,td);
220: if (cn_state == NOTOK)
221: ts_advise ("\nTAsynRetryRequest", td);
222: updatemask ();
223: break;
224: case CONNECTING_2:
225: printf ("CONNECTING_2 -> ");
226: cn_state = TAsynRetryRequest(cn_sd,tc,td);
227: if (cn_state == NOTOK)
228: ts_advise ("\nTAsynRetryRequest", td);
229: updatemask();
230: break;
231: case NOTOK:
232: printf ("NOTOK\n");
233: updatemask ();
234: break;
235: case DONE:
236: printf ("DONE->");
237: updatemask ();
238: break;
239: default:
240: printf ("cn_state weird\n");
241: exit (-4);
242: }
243: }
244:
245: stop_nicely ()
246: {
247: struct TSAPdisconnect td_s;
248: struct TSAPdisconnect * td = &(td_s);
249:
250: (void) TNetClose (&pongaddr->pa_addr.sa_addr, td);
251: }
252:
253:
254: updatemask ()
255: {
256: struct TSAPdisconnect td_s;
257: struct TSAPdisconnect * td = &(td_s);
258:
259: if (cn_sd != NOTOK) {
260: FD_CLR (cn_sd, &rfds);
261: FD_CLR (cn_sd, &wfds);
262: if (cn_sd >= nfds)
263: nfds = cn_sd + 1;
264: }
265: switch (cn_state) {
266: case NOTOK:
267: printf ("NOTOK\n");
268: break;
269:
270: default:
271: printf ("weird!\n");
272: break;
273:
274: case CONNECTING_1:
275: printf ("CONNECTING_1\n");
276: FD_SET (cn_sd, &wfds);
277: break;
278:
279: case CONNECTING_2:
280: printf ("CONNECTING_2\n");
281: FD_SET (cn_sd, &rfds);
282: break;
283: case DONE:
284: printf ("DONE\n");
285: (void) TDiscRequest (cn_sd, NULLCP, 0, td);
286: cn_sd = NOTOK;
287: printf ("Disconnect sent\n");
288: break;
289: }
290: }
291:
292: ts_advise (str, td)
293: char *str;
294: struct TSAPdisconnect *td;
295: {
296: if (td -> td_cc > 0)
297: printf ("%s : %s [%*.*s]\n", str, TErrString (td -> td_reason),
298: td -> td_cc, td -> td_cc, td -> td_data);
299: else printf ("%s : %s\n", str, TErrString (td -> td_reason));
300: }
301:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.