Home › Forums › Ask the Flomies › How to set piccPowerOnWithTimeout with 30 seconds?
Tagged: ACR35, Concurrency, FloJack
-
AuthorPosts
-
February 9, 2015 at 9:28 pm #42782
Test Environment: ACR35 + iPhone 5 + Mifare classic 1K card
After reset reader, I use following code to read PICC ATR with timeout 30 seconds.
- (void) readPiccAtr { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ if (![_reader piccPowerOnWithTimeout:30 cardType:143]) { NSLog(@"request queue failed."); } else { NSLog(@"request queue successfully."); } }); } - (void)reader:(ACRAudioJackReader *)reader didSendPiccAtr:(const uint8_t *)atr length:(NSUInteger)length { NSLog(@"read apr successfully"); }
Unfortunately the timeout can’t be above 5 seconds. So I have to call piccPowerOnWithTimeout every 5 seconds in loop as below.
for(int i=0;i<6;i++){ NSLog(@"Trying %d...", i); [self readPiccAtr]; sleep(5); } - (void) readPiccAtr { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ if (![_reader piccPowerOnWithTimeout:5 cardType:143]) { NSLog(@"request queue failed."); } else { NSLog(@"request queue successfully."); } }); } - (void)reader:(ACRAudioJackReader *)reader didSendPiccAtr:(const uint8_t *)atr length:(NSUInteger)length { NSLog(@"read apr successfully"); }
Above codes are not stable. If put Mifare classic 1K card on reader when call readPiccAtr method for the first time, it always read apr successfully, and also read it successfully every time calling readPiccAtr in loop. However, if I don’t put card on reader until call readPiccAtr 2nd time or 3rd time, it can’t often read apr.
Please advise how to fix this issue. Thanks.
February 9, 2015 at 10:47 pm #42794Hi Tomson, your problem is related to concurrency. If you sleep the thread that instantiates the
ACRAudioJackReader
object, then thedidSendPiccAtr
callback won’t fire since the audio data events aren’t properly queued. When you have the card in the field initially, the callback is able to fire before entering sleep letting the chain work smoothly. When you sleep the responses are corrupted by periodic keep-alive messages on the audio interface. Read up on the iOS Concurrency Programming Guide to resolve your problem.February 10, 2015 at 4:14 am #42835Hi Richard, thanks for your prompt reply. I understand it is concurrency issue, would you please provide sample codes to resolve this problem? Thanks again.
February 11, 2015 at 4:22 am #43022scripts is modified as below, not sure if it is correct. it calls piccPowerOnWithTimeout in main queue (reader is instantiated and reset in main queue as well), and calls NSCondition waitUntilDate with 5 seconds timeout in global queue.
NSCondition *_responseCondition; ... dispatch_async(dispatch_get_main_queue(), ^{ [self readPiccAtr]; }); ... - (void) readPiccAtr { if (![_reader piccPowerOnWithTimeout:5 cardType:143]) { NSLog(@"request queue failed."); } else { NSLog(@"request queue successfully."); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [_responseCondition lock]; if (![_responseCondition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:5]]) { NSLog(@"5 seconds timeout.... picc power on again..."); dispatch_async(dispatch_get_main_queue(), ^{ [self readPiccAtr]; }); } [_responseCondition unlock]; }); } } - (void)reader:(ACRAudioJackReader *)reader didSendPiccAtr:(const uint8_t *)atr length:(NSUInteger)length { NSLog(@"read apr successfully"); [_responseCondition lock]; [_responseCondition signal]; [_responseCondition unlock]; }
The performance looks little better, but sometimes the didSendPiccAtr callback doesn’t fire. Any tip? Thanks.
February 11, 2015 at 7:09 am #43045Hi Tomson, that’s awesome progress. We are working on improving this performance on our soon to be released SDK that will provide a turnkey interface for developers like yourself. It will include over 6 months of investigation, optimization, and testing that makes the FloJack much more reliable and effective to use. Features included in this months’ release are:
- Optimized polling engine.
- Scan notification audio routing
- Type 2 read/write data block (with authentication support)
- NDEF parser
- Cordova Plugin for cross platform support
February 22, 2015 at 8:21 pm #45330Noted with thanks. I am looking forward to the new release. Hope it can support piccPowerOnWithTimeout with 30 seconds.
It would be great if adding callback param to piccPowerOnWithTimeout as below.
– (BOOL)piccPowerOnWithTimeout:(NSUInteger)timeout cardType (NSUInteger)cardType completion:(void (^)(void))completion;February 23, 2015 at 5:44 am #45403Hi Tomson, I’m curious as to why you want a
completion
callback registration with this method? The point of thepiccPowerOnWithTimeout
method is to hold the PICC (NFC tag) in reset so that it kicks off an ATR (Answer To Reset) response. The ATR is then handled by thedidSendPiccAtr
callback. This would be equivalent to yourcompletion
callback request and would cause a conflict. In other words,didSendPiccAtr
is callback functionality I think you’re looking for.February 23, 2015 at 10:22 pm #45531Sorry Richard, my mistake. Actually I want to say timeout callback
– (BOOL)piccPowerOnWithTimeout:(NSUInteger)timeout cardType (NSUInteger)cardType onTimeout:(void (^)(void))timeoutCallback;
February 24, 2015 at 1:40 pm #45653I see what you’re asking for but I’m not sure it’s necessary. You can easily set up an OS timer to fire after for each
timeout
period rather than pushing the requirement onto the API. Read up on the iOS Concurrency Programming Guide for more on the topic. -
AuthorPosts
You must be logged in to reply to this topic.