X-Git-Url: http://lists.indexdata.com/cgi-bin?a=blobdiff_plain;f=ir-tcl.c;h=1772c666e7c7d82e9a6f2891971f6e63d97723d8;hb=6ccc7b22a020d9dde824656655e4e6a920e6abc3;hp=738394835b003e894e88bd00980e6cecd73441f0;hpb=ce0d0464e54cf6bed96cd32b7a99514beacd3989;p=ir-tcl-moved-to-github.git diff --git a/ir-tcl.c b/ir-tcl.c index 7383948..1772c66 100644 --- a/ir-tcl.c +++ b/ir-tcl.c @@ -5,7 +5,21 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: ir-tcl.c,v $ - * Revision 1.68 1996-01-04 11:05:22 adam + * Revision 1.72 1996-01-19 17:45:34 quinn + * Added debugging output + * + * Revision 1.71 1996/01/19 16:22:38 adam + * New method: apduDump - returns information about last incoming APDU. + * + * Revision 1.70 1996/01/10 09:18:34 adam + * PDU specific callbacks implemented: initRespnse, searchResponse, + * presentResponse and scanResponse. + * Bug fix in the command line shell (tclmain.c) - discovered on OSF/1. + * + * Revision 1.69 1996/01/04 16:12:12 adam + * Setting PDUType renamed to eventType. + * + * Revision 1.68 1996/01/04 11:05:22 adam * New setting: PDUType - returns type of last PDU returned from the target. * Fixed a bug in configure/Makefile. * @@ -243,6 +257,7 @@ #include #include +#include #ifdef WINDOWS #include #else @@ -601,7 +616,7 @@ static int do_init_request (void *obj, Tcl_Interp *interp, req->implementationVersion = p->implementationVersion; req->userInformationField = 0; - return ir_tcl_send_APDU (interp, p, apdu, "init", argv[0]); + return ir_tcl_send_APDU (interp, p, apdu, "init", *argv); } /* @@ -676,6 +691,54 @@ static int do_options (void *obj, Tcl_Interp *interp, } /* + * do_apduInfo: Get APDU information + */ +static int do_apduInfo (void *obj, Tcl_Interp *interp, int argc, char **argv) +{ + char buf[16]; + FILE *apduf; + IrTcl_Obj *p = obj; + + if (argc <= 0) + return TCL_OK; + sprintf (buf, "%d", p->apduLen); + Tcl_AppendElement (interp, buf); + sprintf (buf, "%d", p->apduOffset); + Tcl_AppendElement (interp, buf); + if (!p->buf_in) + { + Tcl_AppendElement (interp, ""); + return TCL_OK; + } + apduf = fopen ("apdu.tmp", "w"); + if (!apduf) + { + Tcl_AppendElement (interp, ""); + return TCL_OK; + } + odr_dumpBER (apduf, p->buf_in, p->apduLen); + fclose (apduf); + if (!(apduf = fopen ("apdu.tmp", "r"))) + Tcl_AppendElement (interp, ""); + else + { + int c; + + Tcl_AppendResult (interp, " {", NULL); + while ((c = getc (apduf)) != EOF) + { + buf[0] = c; + buf[1] = '\0'; + Tcl_AppendResult (interp, buf, NULL); + } + fclose (apduf); + Tcl_AppendResult (interp, "}", NULL); + } + unlink ("apdu.tmp"); + return TCL_OK; +} + +/* * do_failInfo: Get fail information */ static int do_failInfo (void *obj, Tcl_Interp *interp, int argc, char **argv) @@ -997,7 +1060,8 @@ static int do_connect (void *obj, Tcl_Interp *interp, do_disconnect (p, NULL, 2, NULL); return TCL_ERROR; } - p->pduType = "connect"; + logf(LOG_DEBUG, "cs_connect() returned %d", r); + p->eventType = "connect"; ir_select_add (cs_fileno (p->cs_link), p); if (r == 1) { @@ -1027,7 +1091,7 @@ static int do_disconnect (void *obj, Tcl_Interp *interp, if (argc == 0) { p->state = IR_TCL_R_Idle; - p->pduType = NULL; + p->eventType = NULL; p->hostname = NULL; p->cs_link = NULL; return TCL_OK; @@ -1042,6 +1106,7 @@ static int do_disconnect (void *obj, Tcl_Interp *interp, odr_reset (p->odr_in); assert (p->cs_link); + logf(LOG_DEBUG, "Closing connection"); cs_close (p->cs_link); p->cs_link = NULL; @@ -1102,19 +1167,19 @@ static int do_logLevel (void *o, Tcl_Interp *interp, /* - * do_pduType: Return type of last PDU received + * do_eventType: Return type of last event */ -static int do_pduType (void *obj, Tcl_Interp *interp, - int argc, char **argv) +static int do_eventType (void *obj, Tcl_Interp *interp, + int argc, char **argv) { IrTcl_Obj *p = obj; if (argc <= 0) { - p->pduType = NULL; + p->eventType = NULL; return TCL_OK; } - Tcl_AppendElement (interp, p->pduType ? p->pduType : ""); + Tcl_AppendElement (interp, p->eventType ? p->eventType : ""); return TCL_OK; } @@ -1178,6 +1243,34 @@ static int do_failback (void *obj, Tcl_Interp *interp, } /* + * do_initResponse: add init response handler + */ +static int do_initResponse (void *obj, Tcl_Interp *interp, + int argc, char **argv) +{ + IrTcl_Obj *p = obj; + + if (argc == 0) + { + p->initResponse = NULL; + return TCL_OK; + } + else if (argc == -1) + return ir_tcl_strdel (interp, &p->initResponse); + if (argc == 3) + { + free (p->initResponse); + if (argv[2][0]) + { + if (ir_tcl_strdup (interp, &p->initResponse, argv[2]) == TCL_ERROR) + return TCL_ERROR; + } + else + p->initResponse = NULL; + } + return TCL_OK; +} +/* * do_protocol: Set/get protocol method on IR object */ static int do_protocol (void *o, Tcl_Interp *interp, int argc, char **argv) @@ -1529,9 +1622,10 @@ static IrTcl_Method ir_method_tab[] = { { 1, "protocol", do_protocol }, { 0, "failback", do_failback }, { 0, "failInfo", do_failInfo }, +{ 0, "apduInfo", do_apduInfo }, { 0, "logLevel", do_logLevel }, -{ 0, "PDUType", do_pduType }, +{ 0, "eventType", do_eventType }, { 1, "connect", do_connect }, { 0, "protocolVersion", do_protocolVersion }, { 1, "preferredMessageSize", do_preferredMessageSize }, @@ -1549,7 +1643,9 @@ static IrTcl_Method ir_method_tab[] = { { 0, "initResult", do_initResult }, { 0, "disconnect", do_disconnect }, { 0, "callback", do_callback }, +{ 0, "initResponse", do_initResponse }, { 0, "triggerResourceControl", do_triggerResourceControl }, +{ 0, "initResponse", do_initResponse }, { 0, NULL, NULL} }; @@ -1818,7 +1914,67 @@ static int do_search (void *o, Tcl_Interp *interp, int argc, char **argv) interp->result = "unknown query method"; return TCL_ERROR; } - return ir_tcl_send_APDU (interp, p, apdu, "search", argv[0]); + return ir_tcl_send_APDU (interp, p, apdu, "search", *argv); +} + +/* + * do_searchResponse: add search response handler + */ +static int do_searchResponse (void *o, Tcl_Interp *interp, + int argc, char **argv) +{ + IrTcl_SetObj *obj = o; + + if (argc == 0) + { + obj->searchResponse = NULL; + return TCL_OK; + } + else if (argc == -1) + return ir_tcl_strdel (interp, &obj->searchResponse); + if (argc == 3) + { + free (obj->searchResponse); + if (argv[2][0]) + { + if (ir_tcl_strdup (interp, &obj->searchResponse, argv[2]) + == TCL_ERROR) + return TCL_ERROR; + } + else + obj->searchResponse = NULL; + } + return TCL_OK; +} + +/* + * do_presentResponse: add present response handler + */ +static int do_presentResponse (void *o, Tcl_Interp *interp, + int argc, char **argv) +{ + IrTcl_SetObj *obj = o; + + if (argc == 0) + { + obj->presentResponse = NULL; + return TCL_OK; + } + else if (argc == -1) + return ir_tcl_strdel (interp, &obj->presentResponse); + if (argc == 3) + { + free (obj->presentResponse); + if (argv[2][0]) + { + if (ir_tcl_strdup (interp, &obj->presentResponse, argv[2]) + == TCL_ERROR) + return TCL_ERROR; + } + else + obj->presentResponse = NULL; + } + return TCL_OK; } /* @@ -2307,7 +2463,7 @@ static int do_present (void *o, Tcl_Interp *interp, int argc, char **argv) } else req->recordComposition = NULL; - return ir_tcl_send_APDU (interp, p, apdu, "present", argv[0]); + return ir_tcl_send_APDU (interp, p, apdu, "present", *argv); } /* @@ -2353,6 +2509,8 @@ static int do_loadFile (void *o, Tcl_Interp *interp, static IrTcl_Method ir_set_method_tab[] = { { 0, "search", do_search }, + { 0, "searchResponse", do_searchResponse }, + { 0, "presentResponse", do_presentResponse }, { 0, "searchStatus", do_searchStatus }, { 0, "presentStatus", do_presentStatus }, { 0, "nextResultSetPosition", do_nextResultSetPosition }, @@ -2581,7 +2739,37 @@ static int do_scan (void *o, Tcl_Interp *interp, int argc, char **argv) logf (LOG_DEBUG, "preferredPositionInResponse=%d", *req->preferredPositionInResponse); - return ir_tcl_send_APDU (interp, p, apdu, "scan", argv[0]); + return ir_tcl_send_APDU (interp, p, apdu, "scan", *argv); +} + +/* + * do_scanResponse: add scan response handler + */ +static int do_scanResponse (void *o, Tcl_Interp *interp, + int argc, char **argv) +{ + IrTcl_ScanObj *obj = o; + + if (argc == 0) + { + obj->scanResponse = NULL; + return TCL_OK; + } + else if (argc == -1) + return ir_tcl_strdel (interp, &obj->scanResponse); + if (argc == 3) + { + free (obj->scanResponse); + if (argv[2][0]) + { + if (ir_tcl_strdup (interp, &obj->scanResponse, argv[2]) + == TCL_ERROR) + return TCL_ERROR; + } + else + obj->scanResponse = NULL; + } + return TCL_OK; } /* @@ -2730,6 +2918,7 @@ static int do_scanLine (void *obj, Tcl_Interp *interp, int argc, char **argv) static IrTcl_Method ir_scan_method_tab[] = { { 0, "scan", do_scan }, + { 0, "scanResponse", do_scanResponse }, { 0, "stepSize", do_stepSize }, { 0, "numberOfTermsRequested", do_numberOfTermsRequested }, { 0, "preferredPositionInResponse", do_preferredPositionInResponse }, @@ -3154,9 +3343,12 @@ void ir_select_read (ClientData clientData) IrTcl_Request *rq; char *object_name; Tcl_CmdInfo cmd_info; + const char *apdu_call; + logf(LOG_DEBUG, "Read handler"); if (p->state == IR_TCL_R_Connecting) { + logf(LOG_DEBUG, "Connect handler"); r = cs_rcvconnect (p->cs_link); if (r == 1) { @@ -3206,23 +3398,31 @@ void ir_select_read (ClientData clientData) return; } if (r == 1) + { + logf(LOG_DEBUG, "PDU Fraction read"); return ; + } /* got complete APDU. Now decode */ + p->apduLen = r; + p->apduOffset = -1; odr_setbuf (p->odr_in, p->buf_in, r, 0); - logf (LOG_DEBUG, "cs_get ok, got %d", r); + logf (LOG_DEBUG, "cs_get ok, total size %d", r); if (!z_APDU (p->odr_in, &apdu, 0)) { - logf (LOG_DEBUG, "%s", odr_errmsg (odr_geterror (p->odr_in))); + logf (LOG_DEBUG, "cs_get failed: %s", + odr_errmsg (odr_geterror (p->odr_in))); do_disconnect (p, NULL, 2, NULL); if (p->failback) { p->failInfo = IR_TCL_FAIL_IN_APDU; + p->apduOffset = odr_offset (p->odr_in); IrTcl_eval (p->interp, p->failback); } /* release ir object now if failback deleted it */ ir_obj_delete (p); return; } + logf(LOG_DEBUG, "Decoded ok"); /* handle APDU and invoke callback */ rq = p->request_queue; if (!rq) @@ -3232,28 +3432,36 @@ void ir_select_read (ClientData clientData) } object_name = rq->object_name; logf (LOG_DEBUG, "getCommandInfo (%s)", object_name); + apdu_call = NULL; if (Tcl_GetCommandInfo (p->interp, object_name, &cmd_info)) { switch(apdu->which) { case Z_APDU_initResponse: - p->pduType = "init"; + p->eventType = "init"; ir_initResponse (p, apdu->u.initResponse); + apdu_call = p->initResponse; break; case Z_APDU_searchResponse: - p->pduType = "search"; + p->eventType = "search"; ir_searchResponse (p, apdu->u.searchResponse, (IrTcl_SetObj *) cmd_info.clientData); + apdu_call = ((IrTcl_SetObj *) + cmd_info.clientData)->searchResponse; break; case Z_APDU_presentResponse: - p->pduType = "present"; + p->eventType = "present"; ir_presentResponse (p, apdu->u.presentResponse, (IrTcl_SetObj *) cmd_info.clientData); + apdu_call = ((IrTcl_SetObj *) + cmd_info.clientData)->presentResponse; break; case Z_APDU_scanResponse: - p->pduType = "scan"; + p->eventType = "scan"; ir_scanResponse (p, apdu->u.scanResponse, (IrTcl_ScanObj *) cmd_info.clientData); + apdu_call = ((IrTcl_ScanObj *) + cmd_info.clientData)->scanResponse; break; default: logf (LOG_WARN, "Received unknown APDU type (%d)", @@ -3269,8 +3477,10 @@ void ir_select_read (ClientData clientData) } p->request_queue = rq->next; p->state = IR_TCL_R_Idle; - - if (rq->callback) + + if (apdu_call) + IrTcl_eval (p->interp, apdu_call); + else if (rq->callback) IrTcl_eval (p->interp, rq->callback); free (rq->buf_out); free (rq->callback); @@ -3297,9 +3507,10 @@ void ir_select_write (ClientData clientData) int r; IrTcl_Request *rq; - logf (LOG_DEBUG, "In write handler"); + logf (LOG_DEBUG, "Write handler"); if (p->state == IR_TCL_R_Connecting) { + logf(LOG_DEBUG, "Connect handler"); r = cs_rcvconnect (p->cs_link); if (r == 1) return; @@ -3327,7 +3538,7 @@ void ir_select_write (ClientData clientData) assert (rq); if ((r=cs_put (p->cs_link, rq->buf_out, rq->len_out)) < 0) { - logf (LOG_DEBUG, "select write fail"); + logf (LOG_DEBUG, "cs_put write fail"); if (p->failback) { p->failInfo = IR_TCL_FAIL_WRITE; @@ -3339,6 +3550,7 @@ void ir_select_write (ClientData clientData) } else if (r == 0) /* remove select bit */ { + logf(LOG_DEBUG, "Write completed"); p->state = IR_TCL_R_Waiting; ir_select_remove_write (cs_fileno (p->cs_link), p); free (rq->buf_out);