00001
00002
00003
00004
00005
00006
00007 #include <ccid.h>
00008 #include <ccid-spec.h>
00009 #include <Python.h>
00010 #include <structmember.h>
00011 #include "py_ccid.h"
00012
00013 static ccidev_t get_dev(struct cp_dev *dev)
00014 {
00015 if ( dev->dev )
00016 return dev->dev;
00017 else
00018 return dev->owner->list[dev->idx];
00019 }
00020
00021 static PyObject *cp_dev_bus(struct cp_dev *self, PyObject *args)
00022 {
00023 ccidev_t dev = get_dev(self);
00024 return PyInt_FromLong(ccid_device_bus(dev));
00025 }
00026
00027 static PyObject *cp_dev_addr(struct cp_dev *self, PyObject *args)
00028 {
00029 ccidev_t dev = get_dev(self);
00030 return PyInt_FromLong(ccid_device_addr(dev));
00031 }
00032
00033 static int cp_dev_init(struct cp_dev *self, PyObject *args, PyObject *kwds)
00034 {
00035 int bus, addr;
00036 ccidev_t dev;
00037
00038 if ( !PyArg_ParseTuple(args, "ii", &bus, &addr) )
00039 return -1;
00040
00041 dev = ccid_device(bus, addr);
00042 if ( NULL == dev ) {
00043 PyErr_SetString(PyExc_IOError, "Not a valid CCID device");
00044 return -1;
00045 }
00046
00047 self->dev = dev;
00048 self->owner = NULL;
00049 return 0;
00050 }
00051
00052 static void cp_dev_dealloc(struct cp_dev *self)
00053 {
00054 if ( self->owner )
00055 Py_DECREF(self->owner);
00056 self->ob_type->tp_free((PyObject*)self);
00057 }
00058
00059 static PyMethodDef cp_dev_methods[] = {
00060 {"bus", (PyCFunction)cp_dev_bus, METH_NOARGS,
00061 "xfr.bus()\n"
00062 "Retrieves bus number of device."},
00063 {"addr", (PyCFunction)cp_dev_addr, METH_NOARGS,
00064 "xfr.addr()\n"
00065 "Retrieves USB device address."},
00066 {NULL, }
00067 };
00068
00069 static PyTypeObject dev_pytype = {
00070 PyObject_HEAD_INIT(NULL)
00071 .tp_name = "ccid.dev",
00072 .tp_basicsize = sizeof(struct cp_dev),
00073 .tp_flags = Py_TPFLAGS_DEFAULT,
00074 .tp_new = PyType_GenericNew,
00075 .tp_init = (initproc)cp_dev_init,
00076 .tp_dealloc = (destructor)cp_dev_dealloc,
00077 .tp_methods = cp_dev_methods,
00078 .tp_doc = "CCI device list entry",
00079 };
00080
00081 static int cp_devlist_init(struct cp_devlist *self, PyObject *args,
00082 PyObject *kwds)
00083 {
00084 self->list = ccid_get_device_list(&self->nmemb);
00085 return 0;
00086 }
00087
00088 static void cp_devlist_dealloc(struct cp_devlist *self)
00089 {
00090 ccid_free_device_list(self->list);
00091 self->ob_type->tp_free((PyObject*)self);
00092 }
00093
00094 static Py_ssize_t devlist_len(struct cp_devlist *self)
00095 {
00096 return self->nmemb;
00097 }
00098
00099 static PyObject *devlist_get(struct cp_devlist *self, Py_ssize_t i)
00100 {
00101 struct cp_dev *dev;
00102
00103 if ( i >= self->nmemb )
00104 return NULL;
00105
00106 dev = (struct cp_dev*)_PyObject_New(&dev_pytype);
00107 if ( dev ) {
00108 Py_INCREF(self);
00109 dev->owner = self;
00110 dev->idx = i;
00111 dev->dev = NULL;
00112 }
00113 return (PyObject *)dev;
00114 }
00115
00116 static PySequenceMethods devlist_seq = {
00117 .sq_length = (lenfunc)devlist_len,
00118 .sq_item = (ssizeargfunc)devlist_get,
00119 };
00120
00121 static PyTypeObject devlist_pytype = {
00122 PyObject_HEAD_INIT(NULL)
00123 .tp_name = "ccid.devlist",
00124 .tp_basicsize = sizeof(struct cp_devlist),
00125 .tp_flags = Py_TPFLAGS_DEFAULT,
00126 .tp_new = PyType_GenericNew,
00127 .tp_init = (initproc)cp_devlist_init,
00128 .tp_dealloc = (destructor)cp_devlist_dealloc,
00129 .tp_as_sequence = &devlist_seq,
00130 .tp_doc = "CCI device list",
00131 };
00132
00133
00134 static int cp_xfr_init(struct cp_xfr *self, PyObject *args, PyObject *kwds)
00135 {
00136 int tx, rx;
00137
00138 if ( !PyArg_ParseTuple(args, "ii", &tx, &rx) )
00139 return -1;
00140
00141 self->xfr = xfr_alloc(tx, rx);
00142 if ( NULL == self->xfr ) {
00143 PyErr_SetString(PyExc_MemoryError, "Allocating buffer");
00144 return -1;
00145 }
00146
00147 return 0;
00148 }
00149
00150 static void cp_xfr_dealloc(struct cp_xfr *self)
00151 {
00152 xfr_free(self->xfr);
00153 self->ob_type->tp_free((PyObject*)self);
00154 }
00155
00156 static PyObject *cp_xfr_reset(struct cp_xfr *self, PyObject *args)
00157 {
00158 xfr_reset(self->xfr);
00159 Py_INCREF(Py_None);
00160 return Py_None;
00161 }
00162
00163 static PyObject *cp_xfr_byte(struct cp_xfr *self, PyObject *args)
00164 {
00165 uint8_t byte;
00166
00167 if ( !PyArg_ParseTuple(args, "b", &byte) )
00168 return NULL;
00169
00170 if ( !xfr_tx_byte(self->xfr, byte) ) {
00171 PyErr_SetString(PyExc_MemoryError, "TX buffer overflow");
00172 return NULL;
00173 }
00174
00175 Py_INCREF(Py_None);
00176 return Py_None;
00177 }
00178
00179 static PyObject *cp_xfr_str(struct cp_xfr *self, PyObject *args)
00180 {
00181 const uint8_t *str;
00182 int len;
00183
00184 if ( !PyArg_ParseTuple(args, "s#", &str, &len) )
00185 return NULL;
00186
00187 if ( !xfr_tx_buf(self->xfr, str, len) ) {
00188 PyErr_SetString(PyExc_MemoryError, "TX buffer overflow");
00189 return NULL;
00190 }
00191
00192 Py_INCREF(Py_None);
00193 return Py_None;
00194 }
00195
00196 static PyObject *cp_xfr_sw1(struct cp_xfr *self, PyObject *args)
00197 {
00198 return PyInt_FromLong(xfr_rx_sw1(self->xfr));
00199 }
00200
00201 static PyObject *cp_xfr_sw2(struct cp_xfr *self, PyObject *args)
00202 {
00203 return PyInt_FromLong(xfr_rx_sw2(self->xfr));
00204 }
00205
00206 static PyObject *cp_xfr_data(struct cp_xfr *self, PyObject *args)
00207 {
00208 const uint8_t *str;
00209 size_t len;
00210
00211 str = xfr_rx_data(self->xfr, &len);
00212 if ( NULL == str ) {
00213 PyErr_SetString(PyExc_ValueError, "RX buffer underflow");
00214 return NULL;
00215 }
00216 return Py_BuildValue("s#", str, (int)len);
00217 }
00218
00219 static PyMethodDef cp_xfr_methods[] = {
00220 {"reset", (PyCFunction)cp_xfr_reset, METH_NOARGS,
00221 "xfr.reset()\n"
00222 "Reset transmit and receive buffers."},
00223 {"tx_byte", (PyCFunction)cp_xfr_byte, METH_VARARGS,
00224 "xfr.tx_byte()\n"
00225 "Push a byte to the transmit buffer."},
00226 {"tx_str", (PyCFunction)cp_xfr_str, METH_VARARGS,
00227 "xfr.tx_str()\n"
00228 "Push a string to the transmit buffer."},
00229 {"rx_sw1", (PyCFunction)cp_xfr_sw1, METH_NOARGS,
00230 "xfr.rx_sw1()\n"
00231 "Retrieve SW1 status word."},
00232 {"rx_sw2", (PyCFunction)cp_xfr_sw2, METH_NOARGS,
00233 "xfr.rx_sw1()\n"
00234 "Retrieve SW2 status word."},
00235 {"rx_data", (PyCFunction)cp_xfr_data, METH_NOARGS,
00236 "xfr.rx_data()\n"
00237 "Return receive buffer data."},
00238 {NULL,}
00239 };
00240
00241 static PyTypeObject xfr_pytype = {
00242 PyObject_HEAD_INIT(NULL)
00243 .tp_name = "ccid.xfr",
00244 .tp_basicsize = sizeof(struct cp_xfr),
00245 .tp_flags = Py_TPFLAGS_DEFAULT,
00246 .tp_new = PyType_GenericNew,
00247 .tp_methods = cp_xfr_methods,
00248 .tp_init = (initproc)cp_xfr_init,
00249 .tp_dealloc = (destructor)cp_xfr_dealloc,
00250 .tp_doc = "CCI transfer buffer",
00251 };
00252
00253
00254 static PyObject *cp_chipcard_transact(struct cp_chipcard *self, PyObject *args)
00255 {
00256 struct cp_xfr *xfr;
00257
00258 if ( NULL == self->slot ) {
00259 PyErr_SetString(PyExc_ValueError, "Bad slot");
00260 return NULL;
00261 }
00262
00263 if ( !PyArg_ParseTuple(args, "O", &xfr) )
00264 return NULL;
00265
00266 if ( xfr->ob_type != &xfr_pytype ) {
00267 PyErr_SetString(PyExc_TypeError, "Not an xfr object");
00268 return NULL;
00269 }
00270
00271 if ( !chipcard_transact(self->slot, xfr->xfr) ) {
00272 PyErr_SetString(PyExc_IOError, "Transaction error");
00273 return NULL;
00274 }
00275
00276 return PyInt_FromLong(xfr_rx_sw1(xfr->xfr));
00277 }
00278
00279 static PyObject *cp_chipcard_wait(struct cp_chipcard *self, PyObject *args)
00280 {
00281 if ( NULL == self->slot ) {
00282 PyErr_SetString(PyExc_ValueError, "Bad slot");
00283 return NULL;
00284 }
00285
00286 chipcard_wait_for_card(self->slot);
00287
00288 Py_INCREF(Py_None);
00289 return Py_None;
00290 }
00291
00292 static PyObject *cp_chipcard_status(struct cp_chipcard *self, PyObject *args)
00293 {
00294 if ( NULL == self->slot ) {
00295 PyErr_SetString(PyExc_ValueError, "Bad slot");
00296 return NULL;
00297 }
00298
00299 return PyInt_FromLong(chipcard_status(self->slot));
00300 }
00301
00302 static PyObject *cp_chipcard_clock(struct cp_chipcard *self, PyObject *args)
00303 {
00304 long ret;
00305
00306 if ( NULL == self->slot ) {
00307 PyErr_SetString(PyExc_ValueError, "Bad slot");
00308 return NULL;
00309 }
00310
00311 ret = chipcard_slot_status(self->slot);
00312 if ( ret == CHIPCARD_CLOCK_ERR ) {
00313 PyErr_SetString(PyExc_IOError, "Transaction error");
00314 return NULL;
00315 }
00316
00317 return PyInt_FromLong(ret);
00318 }
00319
00320 static PyObject *cp_chipcard_on(struct cp_chipcard *self, PyObject *args)
00321 {
00322 int voltage = CHIPCARD_AUTO_VOLTAGE;
00323 const uint8_t *ptr;
00324 size_t atr_len;
00325
00326 if ( NULL == self->slot ) {
00327 PyErr_SetString(PyExc_ValueError, "Bad slot");
00328 return NULL;
00329 }
00330
00331 if ( !PyArg_ParseTuple(args, "|i", &voltage) )
00332 return NULL;
00333
00334 if ( voltage < 0 || voltage > CHIPCARD_1_8V ) {
00335 PyErr_SetString(PyExc_ValueError, "Bad voltage ID");
00336 return NULL;
00337 }
00338
00339 ptr = chipcard_slot_on(self->slot, voltage, &atr_len);
00340 if ( NULL == ptr ) {
00341 PyErr_SetString(PyExc_IOError, "Transaction error");
00342 return NULL;
00343 }
00344
00345 return Py_BuildValue("s#", ptr, (int)atr_len);
00346 }
00347
00348 static PyObject *cp_chipcard_off(struct cp_chipcard *self, PyObject *args)
00349 {
00350 if ( NULL == self->slot ) {
00351 PyErr_SetString(PyExc_ValueError, "Bad slot");
00352 return NULL;
00353 }
00354
00355 if ( !chipcard_slot_off(self->slot) ) {
00356 PyErr_SetString(PyExc_IOError, "Transaction error");
00357 return NULL;
00358 }
00359
00360 Py_INCREF(Py_None);
00361 return Py_None;
00362 }
00363
00364 static PyMethodDef cp_chipcard_methods[] = {
00365 {"wait_for_card", (PyCFunction)cp_chipcard_wait, METH_NOARGS,
00366 "slot.wait_for_card()\n"
00367 "Sleep until the end of time, or until a card is inserted."
00368 "whichever comes soonest."},
00369 {"status", (PyCFunction)cp_chipcard_status, METH_NOARGS,
00370 "slot.status()\n"
00371 "Get status of the slot."},
00372 {"clock_status", (PyCFunction)cp_chipcard_clock, METH_NOARGS,
00373 "slot.status()\n"
00374 "Get chip card clock status."},
00375 {"on", (PyCFunction)cp_chipcard_on, METH_VARARGS,
00376 "slotchipcard.on(voltage=CHIPCARD_AUTO_VOLTAGE)\n"
00377 "Power on card and retrieve ATR."},
00378 {"off", (PyCFunction)cp_chipcard_off, METH_NOARGS,
00379 "slot.off()\n"
00380 "Power off card."},
00381 {"transact", (PyCFunction)cp_chipcard_transact, METH_VARARGS,
00382 "slot.transact(xfr) - chipcard transaction."},
00383 {NULL, }
00384 };
00385
00386 static void cp_chipcard_dealloc(struct cp_chipcard *self)
00387 {
00388 if ( self->owner ) {
00389 Py_DECREF(self->owner);
00390 }
00391
00392 self->ob_type->tp_free((PyObject*)self);
00393 }
00394
00395 static PyTypeObject chipcard_pytype = {
00396 PyObject_HEAD_INIT(NULL)
00397 .tp_name = "ccid.chipcard",
00398 .tp_basicsize = sizeof(struct cp_chipcard),
00399 .tp_flags = Py_TPFLAGS_DEFAULT,
00400 .tp_new = PyType_GenericNew,
00401 .tp_methods = cp_chipcard_methods,
00402 .tp_dealloc = (destructor)cp_chipcard_dealloc,
00403 .tp_doc = "CCI device slot",
00404 };
00405
00406
00407 static PyObject *cci_get(struct cp_cci *self, Py_ssize_t i)
00408 {
00409 struct cp_chipcard *cc;
00410
00411 cc = (struct cp_chipcard*)_PyObject_New(&chipcard_pytype);
00412 if ( NULL == cc ) {
00413 PyErr_SetString(PyExc_MemoryError, "Allocating chipcard");
00414 return NULL;
00415 }
00416
00417 cc->owner = (PyObject *)self;
00418 cc->slot = cci_get_slot(self->dev, i);
00419 if ( NULL == cc->slot) {
00420 _PyObject_Del(cc);
00421 PyErr_SetString(PyExc_ValueError, "Bad slot number\n");
00422 return NULL;
00423 }
00424
00425 Py_INCREF(cc->owner);
00426 return (PyObject *)cc;
00427 }
00428
00429 static int cp_cci_init(struct cp_cci *self, PyObject *args, PyObject *kwds)
00430 {
00431 const char *trace = NULL;
00432 struct cp_dev *cpd;
00433 ccidev_t dev;
00434
00435 if ( !PyArg_ParseTuple(args, "O|z", &cpd, &trace) )
00436 return -1;
00437
00438 if ( cpd->ob_type != &dev_pytype ) {
00439 PyErr_SetString(PyExc_TypeError, "Expected valid cci.dev");
00440 return -1;
00441 }
00442
00443 dev = get_dev(cpd);
00444
00445 self->dev = cci_probe(dev, trace);
00446 if ( NULL == self->dev ) {
00447 PyErr_SetString(PyExc_IOError, "cci_probe() failed");
00448 return -1;
00449 }
00450
00451 return 0;
00452 }
00453
00454 static void cp_cci_dealloc(struct cp_cci *self)
00455 {
00456 cci_close(self->dev);
00457 self->ob_type->tp_free((PyObject*)self);
00458 }
00459
00460 static Py_ssize_t cci_len(struct cp_cci *self)
00461 {
00462 return cci_slots(self->dev);
00463 }
00464
00465 static PyObject *cp_log(struct cp_cci *self, PyObject *args)
00466 {
00467 const char *str;
00468
00469 if ( !PyArg_ParseTuple(args, "s", &str) )
00470 return NULL;
00471
00472 cci_log(self->dev, "%s", str);
00473
00474 Py_INCREF(Py_None);
00475 return Py_None;
00476 }
00477
00478 static PyMethodDef cp_cci_methods[] = {
00479 {"log",(PyCFunction)cp_log, METH_VARARGS,
00480 "cci.log(string) - Log some text to the tracefile"},
00481 {NULL, }
00482 };
00483
00484 static PySequenceMethods cci_seq = {
00485 .sq_length = (lenfunc)cci_len,
00486 .sq_item = (ssizeargfunc)cci_get,
00487 };
00488
00489 static PyTypeObject cci_pytype = {
00490 PyObject_HEAD_INIT(NULL)
00491 .tp_name = "ccid.cci",
00492 .tp_basicsize = sizeof(struct cp_cci),
00493 .tp_flags = Py_TPFLAGS_DEFAULT,
00494 .tp_new = PyType_GenericNew,
00495 .tp_init = (initproc)cp_cci_init,
00496 .tp_dealloc = (destructor)cp_cci_dealloc,
00497 .tp_as_sequence = &cci_seq,
00498 .tp_methods = cp_cci_methods,
00499 .tp_doc = "CCI device",
00500 };
00501
00502 static PyObject *cp_hex_dump(PyObject *self, PyObject *args)
00503 {
00504 const uint8_t *ptr;
00505 int len, llen = 16;
00506 if ( !PyArg_ParseTuple(args, "s#|i", &ptr, &len, &llen) )
00507 return NULL;
00508 hex_dump(ptr, len, llen);
00509 Py_INCREF(Py_None);
00510 return Py_None;
00511 }
00512
00513 static PyObject *cp_ber_dump(PyObject *self, PyObject *args)
00514 {
00515 const uint8_t *ptr;
00516 int len;
00517 if ( !PyArg_ParseTuple(args, "s#", &ptr, &len) )
00518 return NULL;
00519 ber_dump(ptr, len, 1);
00520 Py_INCREF(Py_None);
00521 return Py_None;
00522 }
00523
00524 static PyMethodDef methods[] = {
00525 {"hex_dump", cp_hex_dump, METH_VARARGS,
00526 "hex_dump(string, len=16) - hex dump."},
00527 {"ber_dump", cp_ber_dump, METH_VARARGS,
00528 "ber_dump(string) - dump BER TLV tags."},
00529 {NULL, }
00530 };
00531
00532 #define _INT_CONST(m, c) PyModule_AddIntConstant(m, #c, c)
00533 PyMODINIT_FUNC initccid(void)
00534 {
00535 PyObject *m;
00536
00537 if ( PyType_Ready(&dev_pytype) < 0 )
00538 return;
00539 if ( PyType_Ready(&devlist_pytype) < 0 )
00540 return;
00541 if ( PyType_Ready(&xfr_pytype) < 0 )
00542 return;
00543 if ( PyType_Ready(&chipcard_pytype) < 0 )
00544 return;
00545 if ( PyType_Ready(&cci_pytype) < 0 )
00546 return;
00547
00548 m = Py_InitModule3("ccid", methods, "USB Chip Card Interface Driver");
00549 if ( NULL == m )
00550 return;
00551
00552 _INT_CONST(m, CHIPCARD_ACTIVE);
00553 _INT_CONST(m, CHIPCARD_PRESENT);
00554 _INT_CONST(m, CHIPCARD_NOT_PRESENT);
00555
00556 _INT_CONST(m, CHIPCARD_CLOCK_START);
00557 _INT_CONST(m, CHIPCARD_CLOCK_STOP_L);
00558 _INT_CONST(m, CHIPCARD_CLOCK_STOP_H);
00559 _INT_CONST(m, CHIPCARD_CLOCK_STOP_L);
00560
00561 _INT_CONST(m, CHIPCARD_AUTO_VOLTAGE);
00562 _INT_CONST(m, CHIPCARD_5V);
00563 _INT_CONST(m, CHIPCARD_3V);
00564 _INT_CONST(m, CHIPCARD_1_8V);
00565
00566 Py_INCREF(&xfr_pytype);
00567 PyModule_AddObject(m, "xfr", (PyObject *)&xfr_pytype);
00568
00569 Py_INCREF(&chipcard_pytype);
00570 PyModule_AddObject(m, "slot", (PyObject *)&chipcard_pytype);
00571
00572 Py_INCREF(&cci_pytype);
00573 PyModule_AddObject(m, "cci", (PyObject *)&cci_pytype);
00574
00575 Py_INCREF(&dev_pytype);
00576 PyModule_AddObject(m, "dev", (PyObject *)&dev_pytype);
00577
00578 Py_INCREF(&devlist_pytype);
00579 PyModule_AddObject(m, "devlist", (PyObject *)&devlist_pytype);
00580 }