|
|
1.1 root 1: #include <stdio.h>
2: #include <ctype.h>
3: #include <isode/rtsap.h>
4:
5: #include "support.h"
6:
7: /*
8: * General routines useful for supporting the tests of rtsap library routines
9: */
10:
11: extern int fnx_s(), fnx_r();
12: extern FILE *errfp; /* where to send our error messages */
13:
14: #define TIMEOUT 40 /* seconds to wait for a transfer */
15:
16: #define PE_SIZE 3 /* size to build pe's for testing transfer */
17: /*
18: * perform the given operation
19: */
20: oper(sd, operation)
21: int sd;
22: int operation; /* to be performed */
23: {
24: struct RtSAPindication rtis;
25: struct AcSAPrelease acr;
26: PE data;
27:
28: fprintf(errfp, "oper %d\n", operation);
29: switch (operation) {
30: case SIMP_SEND:
31: data = mkpelist(PE_SIZE);
32: if (RtTransferRequest(sd, data, TIMEOUT, &rtis) == NOTOK) {
33: fprintf(errfp, "SIMP_SEND:RT-TRANSFER.REQUEST: %s\n",
34: RtErrString (rtis.rti_abort.rta_reason));
35: exit(1);
36: }
37: pe_free(data);
38: break;
39:
40: case CPLX_SEND:
41: if (RtSetDownTrans(sd, fnx_s, &rtis) == NOTOK) {
42: fprintf(errfp, "CPLX_SEND:RtSetDown: %s\n", /* Can never happen */
43: RtErrString (rtis.rti_abort.rta_reason));
44: exit(3);
45: }
46: if (RtTransferRequest(sd, NULLPE, TIMEOUT, &rtis) == NOTOK) {
47: fprintf(errfp, "CPLX_SEND:failed: %s\n",
48: RtErrString (rtis.rti_abort.rta_reason));
49: exit(1);
50: }
51: fprintf(errfp, "CPLX_SEND:done\n");
52: break;
53:
54: case CPLX_RCV:
55: if (RtSetUpTrans(sd, fnx_r, &rtis) == NOTOK) {
56: fprintf(errfp, "CPLX_RCV:RtSetDown: %s\n", /* Can never happen */
57: RtErrString (rtis.rti_abort.rta_reason));
58: exit(3);
59: }
60: do {
61: if (RtWaitRequest(sd, TIMEOUT, &rtis) == NOTOK) {
62: fprintf(errfp, "CPLX_RCV:failed: %s\n",
63: RtErrString (rtis.rti_abort.rta_reason));
64: exit(1);
65: }
66: if (rtis.rti_type == RTI_CLOSE || rtis.rti_type == RTI_FINISH
67: || rtis.rti_type == RTI_ABORT) {
68: fprintf(errfp, "Unexpected end\n");
69: exit(3);
70: }
71:
72: } while (rtis.rti_type != RTI_TRANSFER);
73: fprintf(errfp, "CPLX_RCV:done\n");
74: break;
75:
76: case SIMP_RCV:
77: case RCV_PLS:
78: case RCV_GIVE:
79: case RCV_ABRT:
80: case RCV_FINISH:
81: case RCV_CLOSE:
82: fprintf(errfp, "RtWaitRequest\n");
83: if (RtWaitRequest(sd, TIMEOUT, &rtis) == NOTOK) {
84: fprintf(errfp, "RtWaitRequest: %s\n",
85: RtErrString (rtis.rti_abort.rta_reason));
86: exit(1);
87: }
88: switch (rtis.rti_type) {
89: case RTI_TURN:
90: if (operation != RCV_GIVE && operation != RCV_PLS)
91: break;
92: if (rtis.rti_turn.rtu_please && operation != RCV_PLS) {
93: fprintf(errfp, "Unexpected RT-TURN-GIVE.INDICATION\n");
94: exit(4);
95: }
96: if (!rtis.rti_turn.rtu_please && operation == RCV_PLS) {
97: fprintf(errfp, "Unexpected RT-TURN-PLEASE.INDICATION\n");
98: exit(5);
99: }
100: return;
101:
102: case RTI_TRANSFER:
103: if (operation != SIMP_RCV)
104: break;
105: data = mkpelist(PE_SIZE);
106: if (pe_cmp(data, rtis.rti_transfer.rtt_data))
107: fprintf(errfp, "oper:RTI_TRANSFER: data does not match\n");
108: RTTFREE(&rtis.rti_transfer);
109: pe_free(data);
110: return;
111:
112: case RTI_ABORT:
113: if (operation != RCV_ABRT || operation != RCV_CLOSE)
114: break;
115: if (rtis.rti_abort.rta_peer)
116: fprintf(errfp, "RT-U-ABORT.INDICATION: %s\n",
117: RtErrString (rtis.rti_abort.rta_reason));
118: else
119: fprintf(errfp, "RT-P-ABORT.INDICATION: %s\n",
120: RtErrString (rtis.rti_abort.rta_reason));
121: return;
122:
123: case RTI_CLOSE:
124: break;
125:
126: case RTI_FINISH:
127: if (operation != RCV_CLOSE)
128: break;
129: if (RtCloseResponse(sd, ACR_NORMAL, NULLPE, &rtis) == NOTOK) {
130: fprintf(errfp, "RtWaitRequest:RT-CLOSE.RESPONSE: %s\n",
131: RtErrString (rtis.rti_abort.rta_reason));
132: exit(9);
133: }
134: return;
135: }
136: fprintf(errfp, "RtWaitRequest:unexpected indication %d received\n",
137: rtis.rti_type);
138: break;
139:
140: case SEND_PLS:
141: if (RtPTurnRequest(sd, 0, &rtis) == NOTOK) {
142: fprintf(errfp, "SEND_PLS:RT-PLEASE-TURN.REQUEST: %s\n",
143: RtErrString (rtis.rti_abort.rta_reason));
144: exit(6);
145: }
146: break;
147:
148: case SEND_GIVE:
149: if (RtGTurnRequest(sd, &rtis) == NOTOK) {
150: fprintf(errfp, "SEND_GIVE:RT-GIVE-TURN.REQUEST: %s\n",
151: RtErrString (rtis.rti_abort.rta_reason));
152: exit(7);
153: }
154: break;
155:
156: case SEND_CLOSE:
157: if (RtCloseRequest (sd, ACF_NORMAL, NULLPE, &acr, &rtis) == NOTOK)
158: fprintf (errfp, "RT-CLOSE.REQUEST: %s\n",
159: RtErrString (rtis.rti_abort.rta_reason));
160: return;
161:
162: case SEND_ABRT:
163: data = mkpelist(PE_SIZE);
164: if (RtUAbortRequest(sd, data, &rtis) == NOTOK)
165: fprintf (errfp, "RT-CLOSE.REQUEST: %s\n",
166: RtErrString (rtis.rti_abort.rta_reason));
167: return;
168:
169: default:
170: fprintf(errfp, "oper:unknown operation %d\n", operation);
171:
172: }
173: }
174:
175:
176: #define MKMASK 0x7
177: #define MKSHIFT 6
178: /*
179: * Generate a randomish list of PElement s for use as ANY or SET OF ANY ....
180: */
181: PE
182: mkpelist(i)
183: int i;
184: {
185: PE pe, fpe = NULL;
186:
187: fpe = pe_alloc(PE_CLASS_PRIV, PE_FORM_CONS, i);
188: while (i > 0) {
189: pe = mkpe(i);
190: pe->pe_next = fpe->pe_cons;
191: fpe->pe_cons = pe;
192: i--;
193: }
194: return (fpe);
195: }
196:
197: /*
198: * generate a randomish PElement
199: */
200: PE
201: mkpe(i)
202: {
203: int id, class;
204: PE pe;
205:
206: id = i * i + 1;
207: class = PE_CLASS_PRIV;
208: switch ((i*i >> MKSHIFT) & MKMASK) {
209: case 5:
210: case 0:
211: pe = flag2prim(i & 0x1, class, id);
212: break;
213:
214: case 6:
215: case 1:
216: pe = num2prim(i, class, id);
217: break;
218:
219: case 7:
220: case 2:
221: pe = str2prim("mkpelist:testdata", 17, class, id);
222: break;
223:
224: case 3:
225: pe = strb2bitstr("\021\0245\375\0124", 4, class, id);
226: break;
227:
228: case 4:
229: pe = mkpelist(i - 1);
230: break;
231:
232: default:
233: fprintf(errfp, "mkpe:internal error %d case not handled\n",
234: (i*i >> MKSHIFT) & MKMASK);
235: exit(2);
236: }
237:
238: return (pe);
239: }
240:
241: #define MAXCNT 3 /* How many increments of data to send */
242: #define DATASIZE 1035 /* Size of maximum increment */
243: /*
244: * function which is called to incrementally send data
245: */
246: fnx_s(sd, base, len, size, ack, ssn, rti)
247: int sd;
248: char **base;
249: int *len, size;
250: long ack, ssn;
251: struct RtSAPindication *rti;
252: {
253: static int cnt = MAXCNT;
254:
255: if (base == NULLVP) { /* RT-PLEASE.INDICATION */
256: fprintf(errfp, "fnx_s: RT-PLEASE.INDICATION ignored\n");
257: return (OK);
258: }
259: fprintf(errfp, "fnx_s: cnt = %d size = %d ack = %d ssn = %d\n",
260: cnt, size, ack, ssn);
261: if (cnt > 0) { /* Send some data */
262: if (size < 0) {
263: fprintf(errfp, "fnx_s: bad value for size %d error\n", size);
264: return rtsaplose(rti, RTS_TRANSFER, NULLCP,
265: "fnx_s called with bad value for size");
266: }
267: if (size == 0) { /* Have to do all at once transfer */
268: cnt = MAXCNT;
269: }
270: if (DATASIZE < size)
271: size = DATASIZE;
272: if ((*base = malloc(size)) == NULL) {
273: fprintf(errfp, "fnx_s: malloc failed on size %d\n", size);
274: return rtsaplose(rti, RTS_TRANSFER, NULLCP, "malloc failed");
275: }
276: fill(*base, size);
277: *len = size;
278: cnt--;
279: } else {
280: cnt = MAXCNT;
281: *len = 0;
282: }
283: return (OK);
284: }
285:
286: static char *SSAPact_names[] = {
287: "START.INDICATION", "RESUME.INDICATION", "INTERRUPT.INDICATION",
288: "INTERRUPT.CONFIRMATION", "DISCARD.INDICATION", "DISCARD.CONFIRMATION",
289: "END.INDICATION", "END.CONFIRMATION",
290: };
291:
292: /* Number of entries */
293: #define NENTRIES(x) (sizeof (x)/sizeof ((x)[0]))
294: /*
295: * function called by rtsap library to handle the incremental reception
296: * of data.
297: */
298: fnx_r(sd, event, addr, rti)
299: int sd;
300: int event;
301: caddr_t addr;
302: struct RtSAPindication *rti;
303: {
304: struct qbuf *qb;
305: struct SSAPactivity *pa;
306: int len;
307: char *p;
308: int place;
309:
310: switch (event) {
311: case SI_DATA:
312: qb = (struct qbuf *)addr;
313: len = qb->qb_len;
314: fprintf(errfp, "fnx_r: %d octets of data arrived\n", len);
315: /* just assume it works - doesn't mention error conditions in the manual */
316: p = qb2str(qb);
317: if ((place = chk(p, len)) >= 0)
318: fprintf(errfp, "fnx_r: data failed check at octet %d\n", place);
319: break;
320:
321: case SI_SYNC:
322: fprintf(errfp, "fnx_r: S-MINOR-SYNC.INDICATION ignored\n");
323: break;
324:
325: case SI_ACTIVITY:
326: pa = (struct SSAPactivity *) addr;
327: if (pa->sv_type >= NENTRIES(SSAPact_names) || pa->sv_type < 0)
328: fprintf(errfp, "fnx_r: S-ACTIVITY of unknown type!\n");
329: else
330: fprintf(errfp, "fnx_r: S-ACTIVITY-%s\n", SSAPact_names[pa->sv_type]);
331: break;
332:
333: case SI_REPORT:
334: fprintf(errfp, "fnx_r: S-U-EXCEPTION-REPORT.INDICATION\n");
335: break;
336:
337: default:
338: fprintf(errfp, "fnx_r: unknown event received %d\n", event);
339: return rtsaplose(rti, RTS_TRANSFER, NULLCP, "fnx_r:Unknown event");
340: }
341:
342: return (OK);
343: }
344:
345: /*
346: * Fill a piece of memory with some data which has a pattern
347: */
348: fill(data, len)
349: char *data;
350: int len;
351: {
352: while (len-- > 0) {
353: *data++ = len & 0xff;
354: }
355: }
356:
357: /*
358: * check that data is filled as per fill routine. Return the place where it
359: * fails otherwise -1 if it doesn't
360: */
361: chk(data, len)
362: char *data;
363: int len;
364: {
365: int i;
366:
367: i = 0;
368: while (len-- > 0) {
369: if ((*data++ & 0xff) != (len & 0xff))
370: return (i);
371: i++;
372: }
373: return (-1);
374: }
375:
376: /*
377: * Dump a bunch of hex digits printing out those that are printable
378: * Print out a given length of octets as hex (with the ASCII characters
379: * given if they have any
380: */
381: fpclen(fp, s, len)
382: register FILE *fp;
383: register char *s;
384: register int len;
385: {
386: register int cnt = 0;
387:
388: while (len-- > 0) {
389: if (cnt % 8 == 0)
390: fprintf(fp, "\n%d:", cnt/8 + 1);
391: if (isprint(*s&0x7f))
392: fprintf(fp, "\t%02x(%c)", *s&0xff, *s&0x7f);
393: else
394: fprintf(fp, "\t%02x", *s&0xff);
395: s++;
396: cnt++;
397: }
398: fputc('\n', fp);
399: }
400:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.