CardReader status event should return the ATR

- Of the inserted card.
- Refactoring of the code that creates a Buffer instance into a
  separate function.
- Update the example and README
- It fixes bug #2
This commit is contained in:
Santiago Gimeno
2013-07-04 22:50:18 +02:00
parent c98f7bc2de
commit 3f2a1b5e4e
5 changed files with 42 additions and 18 deletions

View File

@@ -33,11 +33,11 @@ Example
reader.on('status', function(status) {
console.log('Status(', this.name, '):', status);
/* check what has changed */
var changes = this.status ^ status;
var changes = this.state ^ status.state;
if (changes) {
if ((changes & this.SCARD_STATE_EMPTY) && (status & this.SCARD_STATE_EMPTY)) {
if ((changes & this.SCARD_STATE_EMPTY) && (status.state & this.SCARD_STATE_EMPTY)) {
console.log("card removed");/* card removed */
} else if ((changes & this.SCARD_STATE_PRESENT) && (status & this.SCARD_STATE_PRESENT)) {
} else if ((changes & this.SCARD_STATE_PRESENT) && (status.state & this.SCARD_STATE_PRESENT)) {
console.log("card inserted");/* card inserted */
}
}

View File

@@ -12,11 +12,11 @@ pcsc.on('reader', function(reader) {
reader.on('status', function(status) {
console.log('Status(', this.name, '):', status);
/* check what has changed */
var changes = this.status ^ status;
var changes = this.state ^ status.state;
if (changes) {
if ((changes & this.SCARD_STATE_EMPTY) && (status & this.SCARD_STATE_EMPTY)) {
if ((changes & this.SCARD_STATE_EMPTY) && (status.state & this.SCARD_STATE_EMPTY)) {
console.log("card removed");/* card removed */
} else if ((changes & this.SCARD_STATE_PRESENT) && (status & this.SCARD_STATE_PRESENT)) {
} else if ((changes & this.SCARD_STATE_PRESENT) && (status.state & this.SCARD_STATE_PRESENT)) {
console.log("card inserted");/* card inserted */
}
}

View File

@@ -36,12 +36,17 @@ module.exports = function() {
var r = new CardReader(name);
readers_aux.push(r);
p.emit('reader', r);
r.get_status(function(e, status) {
r.get_status(function(e, state, atr) {
if (e) {
r.emit('error', e);
} else {
var status = { state : state };
if (atr) {
status.atr = atr;
}
r.emit('status', status);
r.status = status;
r.state = state;
}
});
}

View File

@@ -225,10 +225,11 @@ void CardReader::HandleReaderStatusChange(uv_async_t *handle, int status) {
}
if (ar->result == SCARD_S_SUCCESS) {
const unsigned argc = 2;
const unsigned argc = 3;
Handle<Value> argv[argc] = {
Undefined(), // argument
Integer::New(ar->status)
Integer::New(ar->status),
CreateBufferInstance(reinterpret_cast<char*>(ar->atr), ar->atrlen)
};
PerformCallback(async_baton->reader->handle_, async_baton->callback, argc, argv);
@@ -264,6 +265,8 @@ void* CardReader::HandlerFunction(void* arg) {
result = SCardGetStatusChange(reader->m_status_card_context, INFINITE, &card_reader_state, 1);
async_baton->async_result->result = result;
async_baton->async_result->status = card_reader_state.dwEventState;
memcpy(async_baton->async_result->atr, card_reader_state.rgbAtr, card_reader_state.cbAtr);
async_baton->async_result->atrlen = card_reader_state.cbAtr;
uv_async_send(&async_baton->async);
card_reader_state.dwCurrentState = card_reader_state.dwEventState;
}
@@ -433,16 +436,9 @@ void CardReader::AfterTransmit(uv_work_t* req) {
PerformCallback(baton->reader->handle_, baton->callback, argc, argv);
} else {
const unsigned argc = 2;
// get Buffer from global scope.
Local<Object> global = v8::Context::GetCurrent()->Global();
Local<Value> bv = global->Get(String::NewSymbol("Buffer"));
assert(bv->IsFunction());
Local<Function> b = Local<Function>::Cast(bv);
Handle<Value> argv1[3] = { Buffer::New(reinterpret_cast<char*>(tr->data), tr->len)->handle_, Integer::New(tr->len) , Integer::New(0) };
Handle<Object> instance = b->NewInstance(3, argv1);
Handle<Value> argv[argc] = {
Local<Value>::New(Null()),
instance
CreateBufferInstance(reinterpret_cast<char*>(tr->data), tr->len)
};
PerformCallback(baton->reader->handle_, baton->callback, argc, argv);
@@ -468,3 +464,22 @@ void CardReader::CloseCallback(uv_handle_t *handle) {
SCardReleaseContext(async_baton->reader->m_status_card_context);
delete async_baton;
}
Handle<Value> CardReader::CreateBufferInstance(char* data, unsigned long size) {
if (size == 0) {
return Undefined();
}
// get Buffer from global scope.
Local<Object> global = Context::GetCurrent()->Global();
Local<Value> bv = global->Get(String::NewSymbol("Buffer"));
assert(bv->IsFunction());
Local<Function> b = Local<Function>::Cast(bv);
Handle<Value> argv[3] = {
Buffer::New(data, size)->handle_,
Integer::New(size),
Integer::New(0)
};
return b->NewInstance(3, argv);
}

View File

@@ -41,6 +41,8 @@ class CardReader: public node::ObjectWrap {
struct AsyncResult {
LONG result;
unsigned long status;
unsigned char atr[MAX_ATR_SIZE];
unsigned long atrlen;
bool do_exit;
};
@@ -80,6 +82,8 @@ class CardReader: public node::ObjectWrap {
static void AfterTransmit(uv_work_t* req);
static void CloseCallback(uv_handle_t *handle);
static v8::Handle<v8::Value> CreateBufferInstance(char* data, unsigned long size);
private:
SCARDCONTEXT m_card_context;