* this is the example use of rosap taken from the manual
register struct SSAPstart
*ss
= &sss
;
struct SSAPindication sis
;
register struct SSAPindication
*si
= &sis
;
register struct SSAPabort
*sa
= &si
->si_abort
;
struct RoSAPindication rois
;
register struct RoSAPindication
*roi
= &rois
;
register struct RoSAPpreject
*rop
= &roi
->roi_preject
;
dfp
= freopen("/dev/console", "w", stdout
);
fprintf(dfp
, "Got to here\n");
if (SInit(argc
, argv
, ss
, si
) == NOTOK
)
fprintf(dfp
, "initialisation fails: %s", SErrString(sa
->sa_reason
));
/* would have read command line arguments here */
/* This is rather an elegant scheme but there is no point in doing
* all this in line, a function would be more appropriate apart from
* the number of arguments required.
#define dotoken(requires, shift, bit, type) \
if (sss.ss_requirements & requires) \
switch (sss.ss_settings & (ST_MASK << shift)) { \
case ST_CALL_VALUE << shift: \
sss.ss_settings &= ~(ST_MASK << shift); \
sss.ss_settings |= ST_INIT_VALUE << shift; \
fprintf(stderr, "bad token setting for %s (%d)\n", type, \
sss.ss_settings & (ST_MASK << shift)); \
/* expand out the above for each case */
bzero((char *) &ref
, sizeof (ref
));
if (SConnResponse(sd
, ref
, NULLSA
, SC_ACCEPT
, sss
.ss_requirements
,
sss
.ss_settings
, sss
.ss_isn
, NULLCP
, 0, si
) == NOTOK
) {
fprintf(dfp
, "A-ASSOCIATE.RESPONSE: %s",
SErrString(sis
.si_abort
.sa_reason
));
if (RoInit(argc
, argv
, &ross
, &rois
) == NOTOK
) {
fprintf(dfp
, "initialisation fails: %s", RoErrString(rop
->rop_reason
));
if (RoBeginResponse(sd
, ROS_ACCEPT
, NULLPE
, &rois
) == NOTOK
) {
fprintf(dfp
, "RO-BEGIN.RESPONSE fails: %s",
RoErrString(rop
->rop_reason
));
if (RoSetService (sd
, RoSService
, &rois
) == NOTOK
) {
error ("RoSetService: %s", RoErrString (rop
-> rop_reason
));
if (RoSetIndications(sd
, ros_indication
, roi
) == NOTOK
)
fprintf(dfp
, "RoSetIndications: %s", RoErrString(rop
->rop_reason
));
dfp
= freopen("/dev/console", "w", stdout
);
fprintf(dfp
, "Got to here\n");
switch (res
= RoWaitRequest(sd
, NOTOK
, roi
)) {
fprintf(dfp
,"RoWaitRequest: %s\n", RoErrString(rop
->rop_reason
));
fprintf(dfp
, "got a request %d\n", res
);
exit(0); /* should never get to here */
* Request/Reply loop of ROS server. Called when data arrives like a signal
register struct RoSAPindication
*roi
;
fprintf(dfp
, "ros_indication %d\n", roi
->roi_type
);
ros_invoke(sd
, &roi
->roi_invoke
);
ros_result(sd
, &roi
->roi_result
);
ros_error(sd
, &roi
->roi_error
);
ros_ureject(sd
, &roi
->roi_ureject
);
ros_preject(sd
, &roi
->roi_preject
);
ros_finish(sd
, &roi
->roi_finish
);
ros_end(sd
, &roi
->roi_end
);
fprintf(dfp
, "unknown indication type=%d", roi
->roi_type
);
/* OPERATIONS are numbered APDU_OPx, where each is a unique integer. Further,
APDU_UNKNOWN is used as a tag different than any valid operation.
ERRORS are numbered ERROR_xyz, where each is a unique integer.
ERROR_MISTYPED is used to signal an argument error to an operation.
Further, ERROR_UNKNOWN is used as a tag to indicate that the operation
Finally, note that rox -> rox_args is updated in place by these routines.
If the routine returns ERROR_UNKNOWN, then rox_args contains the results
of the operation. If the routine returns ERROR_MISTYPED, then rox_args is
untouched. Otherwise, if the routine returns any other value, then
rox_args contains the parameters of the error which occurred. Obviously,
each routine calls ROXFREE prior to setting rox_args to a new value.
static int ros_invoke (sd
, rox
)
register struct RoSAPinvoke
*rox
;
register struct dispatch
*ds
;
struct RoSAPindication rois
;
register struct RoSAPindication
*roi
= &rois
;
register struct RoSAPpreject
*rop
= &roi
-> roi_preject
;
for (ds
= dispatches
; ds
-> ds_operation
!= APDU_UNKNOWN
; ds
++)
if (ds
-> ds_operation
== rox
-> rox_op
)
if (ds
-> ds_operation
== APDU_UNKNOWN
) {
if (RoURejectRequest (sd
, &rox
-> rox_id
, ROS_IP_UNRECOG
,
ROS_NOPRIO
, roi
) == NOTOK
)
error (dfp
, "RO-U-REJECT.REQUEST: %s", RoErrString (rop
-> rop_reason
));
if (rox
-> rox_nolinked
== 0) {
if (RoURejectRequest (sd
, &rox
-> rox_id
, ROS_IP_LINKED
,
ROS_NOPRIO
, roi
) == NOTOK
)
error (dfp
, "RO-U-REJECT.REQUEST: %s", RoErrString (rop
-> rop_reason
));
switch (result
= (*ds
-> ds_vector
) (rox
)) {
if (RoResultRequest (sd
, rox
-> rox_id
, rox
-> rox_op
,
rox
-> rox_args
, ROS_NOPRIO
, roi
) == NOTOK
)
error (dfp
, "RO-RESULT.REQUEST: %s\n",
RoErrString (rop
-> rop_reason
));
fprintf (dfp
, "RO-RESULT.REQUEST:done\n");
if (RoErrorRequest (sd
, rox
-> rox_id
, result
, rox
-> rox_args
,
ROS_NOPRIO
, roi
) == NOTOK
)
error (dfp
, "RO-ERROR.REQUEST: %s\n",
RoErrString (rop
-> rop_reason
));
if (RoURejectRequest (sd
, &rox
-> rox_id
, ROS_IP_MISTYPED
,
ROS_NOPRIO
, roi
) == NOTOK
)
error (dfp
, "RO-U-REJECT.REQUEST: %s\n",
RoErrString (rop
-> rop_reason
));
static int ros_result (sd
, ror
)
register struct RoSAPresult
*ror
;
struct RoSAPindication rois
;
register struct RoSAPindication
*roi
= &rois
;
register struct RoSAPpreject
*rop
= &roi
-> roi_preject
;
if (RoURejectRequest (sd
, &ror
-> ror_id
, ROS_RRP_UNRECOG
, ROS_NOPRIO
, roi
)
error (dfp
, "RO-U-REJECT.REQUEST: %s", RoErrString (rop
-> rop_reason
));
static int ros_error (sd
, roe
)
register struct RoSAPerror
*roe
;
struct RoSAPindication rois
;
register struct RoSAPindication
*roi
= &rois
;
register struct RoSAPpreject
*rop
= &roi
-> roi_preject
;
if (RoURejectRequest (sd
, &roe
-> roe_id
, ROS_REP_UNRECOG
, ROS_NOPRIO
, roi
)
error (dfp
, "RO-U-REJECT.REQUEST: %s", RoErrString (rop
-> rop_reason
));
static int ros_ureject (sd
, rou
)
register struct RoSAPureject
*rou
;
/* handle rejection here... */
static int ros_preject (sd
, rop
)
register struct RoSAPpreject
*rop
;
if (ROS_FATAL (rop
-> rop_reason
))
error (dfp
, "RO-REJECT-P.INDICATION: %s", RoErrString (rop
-> rop_reason
));
/* handle temporary failure here... */
static int ros_finish (sd
, acf
)
struct AcSAPindication acis
;
register struct AcSAPabort
*aca
= &acis
.aci_abort
;
if (AcRelResponse (sd
, ACS_ACCEPT
, ACR_NORMAL
, NULLPEP
, 0, &acis
) == NOTOK
)
error (dfp
, "A-RELEASE.RESPONSE: %s", AcErrString (aca
-> aca_reason
));
error (dfp
, "association released");
struct SSAPindication sis
;
if (SRelResponse(sd
, SC_ACCEPT
, NULLCP
, 0, &sis
) == NOTOK
) {
fprintf(dfp
, "S-RELEASE.REPONSE: failed: %s\n",
SErrString(sis
.si_abort
.sa_reason
));
struct RoSAPindication rois
;
fprintf(dfp
, "RO-END.RESPONSE:\n");
if (RoEndResponse(sd
, &rois
) == NOTOK
) {
fprintf(dfp
, "RO-END.RESPONSE: failed: %s\n",
RoErrString(rois
.roi_preject
.rop_reason
));
register struct RoSAPinvoke
*rox
;
fprintf(dfp
, "Invocation\nid %d", rox
->rox_id
);
fprintf(dfp
, " linked to %d", rox
->rox_linkid
);
fprintf(dfp
, " operation %d\n", rox
->rox_op
);
fprintf(dfp
, "\nunknown operation %d\n", rox
->rox_op
);