Commit | Line | Data |
---|---|---|
dd8036b5 C |
1 | /* |
2 | * this is the example use of rosap taken from the manual | |
3 | */ | |
4 | #include <stdio.h> | |
5 | #include "generic.h" | |
6 | #include <isode/rtsap.h> | |
7 | #include <isode/rosap.h> | |
8 | ||
9 | #define error fprintf | |
10 | ||
11 | int ros_indication(); | |
12 | ||
13 | static FILE *dfp; | |
14 | main(argc, argv, envp) | |
15 | int argc; | |
16 | char **argv, **envp; | |
17 | { | |
18 | int result, sd; | |
19 | int res; | |
20 | ||
21 | struct RtSAPstart rtss; | |
22 | register struct RtSAPstart *rts = &rtss; | |
23 | struct RtSAPindication rtis; | |
24 | register struct RtSAPindication *rti = &rtis; | |
25 | register struct AcSAPstart *acs = &rts->rts_start; | |
26 | register struct PSAPstart *ps = &acs->acs_start; | |
27 | register struct RtSAPabort *rta = &rti -> rti_abort; | |
28 | struct RoSAPindication rois; | |
29 | register struct RoSAPindication *roi = &rois; | |
30 | register struct RoSAPpreject *rop = &roi->roi_preject; | |
31 | ||
32 | dfp = freopen("/dev/console", "w", stdout); | |
33 | fprintf(dfp, "Got to here\n"); | |
34 | ||
35 | if (RtBInit(argc, argv, rts, rti) == NOTOK) | |
36 | fprintf(dfp, "initialisation fails: %s", | |
37 | RtErrString(rta->rta_reason)); | |
38 | ||
39 | sd = rts->rts_sd; | |
40 | RTSFREE(rts); | |
41 | ||
42 | /* would have read command line arguments here */ | |
43 | ||
44 | if (RtBeginResponse(sd, RTS_ACCEPT, NULLPE, rti) == NOTOK) | |
45 | fprintf(dfp, "RT-OPEN.RESPONSE: %s", | |
46 | RtErrString(rti->rti_abort.rta_reason)); | |
47 | ||
48 | if (RoSetService (sd, RoRtService, &rois) == NOTOK) | |
49 | fprintf(dfp, "RoSetService: %s", RoErrString (rop -> rop_reason)); | |
50 | ||
51 | #ifdef SHOW_BUG | |
52 | if (RoSetIndications(sd, ros_indication, roi) == NOTOK) | |
53 | fprintf(stderr, "RoSetIndications: %s", RoErrString(rop->rop_reason)); | |
54 | ||
55 | for(;;) | |
56 | pause(); | |
57 | #else | |
58 | fprintf(dfp, "Got to here\n"); | |
59 | for (;;) { | |
60 | switch (res = RoWaitRequest(sd, NOTOK, roi)) { | |
61 | case NOTOK: | |
62 | fprintf(dfp,"RoWaitRequest: %s\n", RoErrString(rop->rop_reason)); | |
63 | exit(1); | |
64 | ||
65 | case OK: | |
66 | fprintf(dfp, "got a request %d\n", res); | |
67 | ros_indication(sd, roi); | |
68 | break; | |
69 | ||
70 | case DONE: | |
71 | fprintf(dfp, "Done\n"); | |
72 | ros_indication(sd, roi); | |
73 | exit(0); /* should never get to here */ | |
74 | } | |
75 | } | |
76 | #endif | |
77 | } | |
78 | /* | |
79 | * Request/Reply loop of ROS server. Called when data arrives like a signal | |
80 | * routine | |
81 | */ | |
82 | static int | |
83 | ros_indication(sd, roi) | |
84 | int sd; | |
85 | register struct RoSAPindication *roi; | |
86 | { | |
87 | ||
88 | fprintf(dfp, "ros_indication got called\n"); | |
89 | switch (roi->roi_type) { | |
90 | case ROI_INVOKE: | |
91 | ros_invoke(sd, &roi->roi_invoke); | |
92 | break; | |
93 | ||
94 | case ROI_RESULT: | |
95 | ros_result(sd, &roi->roi_result); | |
96 | break; | |
97 | ||
98 | case ROI_ERROR: | |
99 | ros_error(sd, &roi->roi_error); | |
100 | break; | |
101 | ||
102 | ||
103 | case ROI_UREJECT: | |
104 | ros_ureject(sd, &roi->roi_ureject); | |
105 | break; | |
106 | ||
107 | case ROI_PREJECT: | |
108 | ros_preject(sd, &roi->roi_preject); | |
109 | break; | |
110 | ||
111 | case ROI_FINISH: | |
112 | ros_finish(sd, &roi->roi_finish); | |
113 | break; | |
114 | ||
115 | case ROI_END: | |
116 | ros_end(sd, &roi->roi_end); | |
117 | break; | |
118 | ||
119 | default: | |
120 | fprintf(dfp, "unknown indication type=%d", roi->roi_type); | |
121 | } | |
122 | } | |
123 | ||
124 | extern int OP1(); | |
125 | ||
126 | ||
127 | ||
128 | /* OPERATIONS are numbered APDU_OPx, where each is a unique integer. Further, | |
129 | APDU_UNKNOWN is used as a tag different than any valid operation. | |
130 | ||
131 | ERRORS are numbered ERROR_xyz, where each is a unique integer. | |
132 | ERROR_MISTYPED is used to signal an argument error to an operation. | |
133 | Further, ERROR_UNKNOWN is used as a tag to indicate that the operation | |
134 | succeeded. | |
135 | ||
136 | Finally, note that rox -> rox_args is updated in place by these routines. | |
137 | If the routine returns ERROR_UNKNOWN, then rox_args contains the results | |
138 | of the operation. If the routine returns ERROR_MISTYPED, then rox_args is | |
139 | untouched. Otherwise, if the routine returns any other value, then | |
140 | rox_args contains the parameters of the error which occurred. Obviously, | |
141 | each routine calls ROXFREE prior to setting rox_args to a new value. | |
142 | */ | |
143 | ||
144 | static struct dispatch { | |
145 | int ds_operation; | |
146 | IFP ds_vector; | |
147 | } dispatches[] = { | |
148 | APDU_OP1, OP1, | |
149 | APDU_ERR, OP1, | |
150 | APDU_URJ, OP1, | |
151 | ||
152 | /* APDU_OPn, OPn, */ | |
153 | ||
154 | APDU_UNKNOWN | |
155 | }; | |
156 | ||
157 | ||
158 | static int ros_invoke (sd, rox) | |
159 | int sd; | |
160 | register struct RoSAPinvoke *rox; | |
161 | { | |
162 | int result; | |
163 | register struct dispatch *ds; | |
164 | struct RoSAPindication rois; | |
165 | register struct RoSAPindication *roi = &rois; | |
166 | register struct RoSAPpreject *rop = &roi -> roi_preject; | |
167 | ||
168 | for (ds = dispatches; ds -> ds_operation != APDU_UNKNOWN; ds++) | |
169 | if (ds -> ds_operation == rox -> rox_op) | |
170 | break; | |
171 | ||
172 | if (ds -> ds_operation == APDU_UNKNOWN) { | |
173 | if (RoURejectRequest (sd, &rox -> rox_id, ROS_IP_UNRECOG, | |
174 | ROS_NOPRIO, roi) == NOTOK) | |
175 | error (dfp, "RO-U-REJECT.REQUEST: %s", RoErrString (rop -> rop_reason)); | |
176 | goto out; | |
177 | } | |
178 | ||
179 | if (rox -> rox_nolinked == 0) { | |
180 | if (RoURejectRequest (sd, &rox -> rox_id, ROS_IP_LINKED, | |
181 | ROS_NOPRIO, roi) == NOTOK) | |
182 | error (dfp, "RO-U-REJECT.REQUEST: %s", RoErrString (rop -> rop_reason)); | |
183 | goto out; | |
184 | } | |
185 | ||
186 | switch (result = (*ds -> ds_vector) (rox)) { | |
187 | case ERROR_UNKNOWN: | |
188 | if (RoResultRequest (sd, rox -> rox_id, rox -> rox_op, | |
189 | rox -> rox_args, ROS_NOPRIO, roi) == NOTOK) | |
190 | error (dfp, "RO-RESULT.REQUEST: %s", | |
191 | RoErrString (rop -> rop_reason)); | |
192 | break; | |
193 | ||
194 | default: | |
195 | if (RoErrorRequest (sd, rox -> rox_id, result, rox -> rox_args, | |
196 | ROS_NOPRIO, roi) == NOTOK) | |
197 | error (dfp, "RO-ERROR.REQUEST: %s", | |
198 | RoErrString (rop -> rop_reason)); | |
199 | break; | |
200 | ||
201 | case ERROR_MISTYPED: | |
202 | if (RoURejectRequest (sd, &rox -> rox_id, ROS_IP_MISTYPED, | |
203 | ROS_NOPRIO, roi) == NOTOK) | |
204 | error (dfp, "RO-U-REJECT.REQUEST: %s", | |
205 | RoErrString (rop -> rop_reason)); | |
206 | break; | |
207 | } | |
208 | ||
209 | out: ; | |
210 | ROXFREE (rox); | |
211 | } | |
212 | ||
213 | ||
214 | static int ros_result (sd, ror) | |
215 | int sd; | |
216 | register struct RoSAPresult *ror; | |
217 | { | |
218 | struct RoSAPindication rois; | |
219 | register struct RoSAPindication *roi = &rois; | |
220 | register struct RoSAPpreject *rop = &roi -> roi_preject; | |
221 | ||
222 | if (RoURejectRequest (sd, &ror -> ror_id, ROS_RRP_UNRECOG, ROS_NOPRIO, roi) | |
223 | == NOTOK) | |
224 | error (dfp, "RO-U-REJECT.REQUEST: %s", RoErrString (rop -> rop_reason)); | |
225 | ||
226 | RORFREE (ror); | |
227 | } | |
228 | ||
229 | ||
230 | static int ros_error (sd, roe) | |
231 | int sd; | |
232 | register struct RoSAPerror *roe; | |
233 | { | |
234 | struct RoSAPindication rois; | |
235 | register struct RoSAPindication *roi = &rois; | |
236 | register struct RoSAPpreject *rop = &roi -> roi_preject; | |
237 | ||
238 | if (RoURejectRequest (sd, &roe -> roe_id, ROS_REP_UNRECOG, ROS_NOPRIO, roi) | |
239 | == NOTOK) | |
240 | error (dfp, "RO-U-REJECT.REQUEST: %s", RoErrString (rop -> rop_reason)); | |
241 | ||
242 | ROEFREE (roe); | |
243 | } | |
244 | ||
245 | ||
246 | static int ros_ureject (sd, rou) | |
247 | int sd; | |
248 | register struct RoSAPureject *rou; | |
249 | { | |
250 | /* handle rejection here... */ | |
251 | } | |
252 | ||
253 | ||
254 | static int ros_preject (sd, rop) | |
255 | int sd; | |
256 | register struct RoSAPpreject *rop; | |
257 | { | |
258 | if (ROS_FATAL (rop -> rop_reason)) | |
259 | error (dfp, "RO-REJECT-P.INDICATION: %s", RoErrString (rop -> rop_reason)); | |
260 | ||
261 | /* handle temporary failure here... */ | |
262 | } | |
263 | ||
264 | static int ros_finish (sd, acf) | |
265 | int sd; | |
266 | struct AcSAPfinish *acf; | |
267 | { | |
268 | struct AcSAPindication acis; | |
269 | register struct AcSAPabort *aca = &acis.aci_abort; | |
270 | struct RtSAPindication rtis; | |
271 | ||
272 | ACFFREE (acf); | |
273 | if (RtCloseResponse(sd, ACR_NORMAL, NULLPE, &rtis) == NOTOK) { | |
274 | fprintf(dfp, "RtWaitRequest:RT-CLOSE.RESPONSE: %s\n", | |
275 | RtErrString (rtis.rti_abort.rta_reason)); | |
276 | exit(9); | |
277 | } | |
278 | ||
279 | ||
280 | error (dfp, "association released"); | |
281 | ||
282 | exit(0); | |
283 | } | |
284 | ||
285 | static int | |
286 | ros_end(sd, roe) | |
287 | int sd; | |
288 | struct RoSAPend *roe; | |
289 | { | |
290 | struct RtSAPindication rtis; | |
291 | ||
292 | if (RtEndResponse(sd, &rtis) == NOTOK) { | |
293 | fprintf(dfp, "RT-END.RESPONSE: failed: %s\n", | |
294 | RtErrString(rtis.rti_abort.rta_reason)); | |
295 | exit(6); | |
296 | } | |
297 | ||
298 | exit(0); | |
299 | } | |
300 | OP1(rox) | |
301 | register struct RoSAPinvoke *rox; | |
302 | { | |
303 | fprintf(dfp, "Invocation\nid %d", rox->rox_id); | |
304 | if (!rox->rox_nolinked) | |
305 | fprintf(dfp, " linked to %d", rox->rox_linkid); | |
306 | fprintf(dfp, " operation %d\n", rox->rox_op); | |
307 | /* print the pe */ | |
308 | ||
309 | switch (rox->rox_op) { | |
310 | case APDU_OP1: | |
311 | return (ERROR_UNKNOWN); | |
312 | ||
313 | case APDU_ERR: | |
314 | return (ERROR_ERROR); | |
315 | ||
316 | case APDU_URJ: | |
317 | return (ERROR_MISTYPED); | |
318 | ||
319 | default: | |
320 | fprintf(dfp, "\nunknown operation %d\n", rox->rox_op); | |
321 | } | |
322 | return (ERROR_ERROR); | |
323 | } |