Reading ISO 15693 tags on iOS13 - ios13

I'm implementing new feature in my app that should allow users to scan NFC tags. I've got some tags for testing that NFCTagReaderSession finds as ISO 15693 tags. I'm able to find and connect to a it, however, when I try to read data stored on a tag using
-readMultipleBlocksWithRequestFlags:blockRange:completionHandler:
mehod, it reports no error and always returns empty (zero-filled) data. I tried to change request flags etc., but no matter what I do, it always returns zero-ed data. Tag itself is OK as when I scan it with external BT reader it finds its value OK. I'm doing following after connecting a tag:
- (void)readISO15693Tag:(id)tag {
[tag getSystemInfoWithRequestFlag:(RequestFlagHighDataRate) completionHandler:^(NSInteger dsfid, NSInteger afi, NSInteger blockSize, NSInteger blockCount, NSInteger icReference, NSError * _Nullable error) {
if(!error) {
/// This prints "DSFId: 0, AFI: 0, Block size: 4, Block count: 28, IC Reference: 1"
NSLog(#"DSFId: %ld, AFI: %ld, Block size: %ld, Block count: %ld, IC Reference: %ld", (long)dsfid, afi,blockSize, blockCount, icReference);
NSRange blockRange = NSMakeRange(0, blockCount);
[tag readMultipleBlocksWithRequestFlags:RequestFlagHighDataRate blockRange:blockRange completionHandler:^(NSArray * _Nonnull dataBlocks, NSError * _Nullable error) {
NSMutableData *response = [NSMutableData data];
for(NSData *blockData in dataBlocks) {
[response appendData:blockData];
}
if(response.length > 0) {
NSData *rawData = [response subdataWithRange:NSMakeRange(1, (response.length - 1))];
/// Prints Received data: {length = 111, bytes = 0x00000000 00000000 00000000 00000000 ... 00000000 00000000 }
NSLog(#"Received data: %#", rawData);
}
}];
}
}];
}
}];
}
}];
}
I've got no clue what can be wrong with it. Did anybody have similar issue?
Thanks
Matt

Ok, I've figured it out. I was simply confused that external RFID scanner returns some data while I can see empty data returned by - readMultipleBlocksWithRequestFlags:... method. It turned out that the RFID scanner simply returns tag's UID, it actually does not read tag contents. The tag I'm trying to read IS actually empty.
So this question can be safely ignored.
Best
Matt

Related

Error in http syntax error in arduino code

The function below describes a set of values from adruino shield and uno board using gps module.
I receive some errors perhaps it is in the syntax. Please ignore the line in which the error has been pointed out. I don't want people to get scared seeing a large coding.
void send_HTTP(){
uint8_t answer=0;
// Initializes HTTP service
answer = sendATcommand("AT+HTTPINIT", "OK", 10000);
if (answer == 1)
{
// Sets CID parameter
answer = sendATcommand("AT+HTTPPARA=\"CID\",1", "OK", 5000);
if (answer == 1)
{
// Sets url
sprintf(aux_str, "AT+HTTPPARA=\"URL\",\"http://%s/demo_sim908.php?", url);// line number :459
Serial.print(aux_str);
sprintf(frame, "visor=false&latitude=%s&longitude=%s&altitude=%s&time=%s&satellites=%s&speedOTG=%s&course=%s",
latitude, longitude, altitude, date, satellites, speedOTG, course); // line number : 460
Serial.print(frame);
answer = sendATcommand("\"", "OK", 5000);
if (answer == 1)
{
// Starts GET action
answer = sendATcommand("AT+HTTPACTION=0", "+HTTPACTION:0,200", 30000);
if (answer == 1)
{
Serial.println(F("Done!"));
}
else
{
Serial.println(F("Error getting url"));
}
}
else
{
Serial.println(F("Error setting the url"));
}
}
else
{
Serial.println(F("Error setting the CID"));
}
}
else
{
Serial.println(F("Error initializating"));
}
sendATcommand("AT+HTTPTERM", "OK", 5000);
}
And I get the following errors.
Arduino: 1.7.5 (Windows 8.1), Board: "Arduino Uno"
sketch_aug22e.ino:459:13: error: missing terminating " character
sketch_aug22e.ino: In function 'void send_HTTP()':
sketch_aug22e.ino:460:34: error: expected ')' before ';' token
Error compiling.
This report would have more information with
"Show verbose output during compilation"
enabled in File > Preferences.
You have an uneven number of quotation marks in line 459:
sprintf(aux_str, "AT+HTTPPARA=\"URL\",\"http://%s/demo_sim908.php?", url);
which is confusing the compiler.
It's hard to say without knowing exactly what you want to do but if you are printing 3 separate strings then it may be that you do not want to 'ESC' the third string - e.g.:
sprintf(aux_str, "AT+HTTPPARA=\"URL\"", "http://%s/demo_sim908.php?", url);
or alternatively if you are just trying to print two strings and the 'comma' before http is just part of the string then you might just have needed to close that 'ESCed' URL:
sprintf(aux_str, "AT+HTTPPARA=\"URL\",http://%s/demo_sim908.php?\", url);

QT socket does no read all data

I want to read the data through socket in Qt. I am using QBytearray to store the data. Actually server sends 4095 bytes in a single stretch, but in the QT client side I am receiving in different chunks because of my application design.
void Dialog::on_pushButton_clicked()
{
socket=new QTcpSocket(this);
socket->connectToHost("172.17.0.1",5000);
if(socket->waitForConnected(-1))
qDebug()<<"Connected";
Read_data();
}
void Dialog::Read_data()
{
QString filename(QString("%1/%2.bin").arg(path,device));
qDebug()<<"filename"<<filename;
QFile fileobj(filename);
int cmd,file_size,percentage_completed;
if(!fileobj.open(QFile::WriteOnly | QFile::Text))
{
qDebug()<<"Cannot open file for writting";
return;
}
QTextStream out(&fileobj);
while(1)
{
socket->waitForReadyRead(-1);
byteArray=socket->read(4);
qDebug()<<"size of bytearray"<<byteArray.size();
length=0xffff & ((byteArray[3]<<8)|(0x00ff & byteArray[2]));
int rem;
byteArray=socket->read(length);
while(byteArray.size()!=length)
{
rem=length-byteArray.size();
byteArray.append( socket->read(rem));
}
fileobj.write(byteArray);
fileobj.flush();
byteArray.clear();
}
}
server code:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/ioctl.h>
#include<mtd/mtd-user.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <arpa/inet.h>
#include<math.h>
#include <netinet/tcp.h>
static int msb,lsb,size,listenfd = 0, connfd = 0,len;
main()
{
struct sockaddr_in serv_addr;
serverlen=sizeof(serv_addr);
listenfd = socket(AF_INET, SOCK_STREAM, 0);
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(5000);
if(bind(listenfd,(struct sockaddr*)&serv_addr, sizeof(serv_addr))<0)
{
perror("\n Error in binding");
exit(1);
}
size=100000;
listen(listenfd, 1);
fd=fopen(new.bin,"r");
len=4089;
while(1)
{
buff[0]=25;
buff[1]=2;
buff[2]=60;
buff[3]=47;
n=fread(buff+4,1,length, fd);
buff[len+4]=5;
buff[len+5]='\n';
if(n>0)
sent_bytes=send(connfd,buff,n+6,0);
size =size-len;
if(size==0)
break;
}
}
If I execute the code in localhost(127.0.0.1) I can receive the data fully. The problem arises only when I connect to different host IP. Kindly help me in this regard
EDIT 1:
The problem is when bytesAvailable() returns the maximum bytes I am waiting for waitForReadyRead() times out. It works fine if the bytesAvailable() is less than as expected. Does bytesAvailable() allocate any buffer annoyed by this behaviour.
while(1)
{
while(socket->bytesAvailable()<4)
{
if (!socket->waitForReadyRead())
{
qDebug() << "waitForReadyRead() timed out";
return;
}
}
byteArray=socket->read(4);
length=0xffff & ((byteArray[3]<<8)|(0x00ff & byteArray[2]));
int rem_bytes=length+2;
qDebug()<<"bytes available"<<socket->bytesAvailable();
while(socket->bytesAvailable()<=rem_bytes)
{
qDebug()<<"reading";
if (!socket->waitForReadyRead(10000))//times out here if bytesAvailable() == rem_bytes but executes well in other cases
{
qDebug() << "waitForReadyRead() timed out";
return;
}
qDebug()<<"ready";
byteArray.append(socket->read(rem_bytes));
qDebug()<<"size of bytearray"<<byteArray.size();
if(byteArray.size()==length+2)
{
for(int j=0;j<length;j++)
newarray.append(byteArray[j]);
fileobj.write(newarray);
fileobj.flush();
newarray.clear();
byteArray.clear();
break;
}
else
{
rem_bytes -=byteArray.size();
}
}
Send();
}
I have tried by sending different data sizes cannot figure it out why?. Please provide me a solution pointing where I have gone wrong
Your problem stems from your misunderstanding of how TCP works.
When data is transmitted from a sender, it is broken into packets and then each packet is transmitted one by one until all the data has finished sending. If packets go missing, they are re-transmitted until either they reach their destination, or a timeout is reached.
As an added complication, each packet might follow various routes before arriving at the destination. The receiver has the task of acknowledging to the sender that packets have been received and then making sure that the packets are joined back together in the correct order.
For this reason, the longer the network route, the greater the chance of getting a delay in getting the data re-assembled. This is what you've been experiencing with your localhost versus networked-computer tests.
The IP stack on your computer does not wait for the complete data to arrive before passing it to your application but it will pause if it's missing a packet in sequence.
e.g. If you have 10 packets and packet 4 arrives last, the IP stack will pass the data to your application in two sets: 1-2-3, [[wait for 4 to arrive]], 4-5-6-7-8-9-10.
For this reason, when waitForReadyRead() returns true, you cannot expect that all your data has arrived, you must always check how many bytes have been actually received.
There are two places in your code where you wait for data. The first thing you wait for is a four-byte number to tell you how much data has been sent. Even though it's highly likely that you will have received all four bytes, it's good practice to check.
while(socket.bytesAvailable() < 4){
if (!socket.waitForReadyRead()) { // timeout after 30 second, by default
qDebug() << "waitForReadyRead() timed out";
return;
}
}
byteArray=socket->read(4);
qDebug()<<"size of bytearray"<<byteArray.size();
length=0xffff & ((byteArray[3]<<8)|(0x00ff & byteArray[2]));
The next thing you need to do is keep cycling through a wait-read-wait-read loop until all your data has arrived, each time keeping track of how many bytes you still expect to receive.
int bytesRemaining = length;
while(socket->bytesAvailable() < bytesRemaining){
if (!socket->waitForReadyRead()){
qDebug() "waitForReadyRead() timed out";
return;
}
// calling read() with the bytesRemaining argument will not guarantee
// that you will receive all the data. It only means that you will
// receive AT MOST bytesRemaining bytes.
byteArray = socket->read(bytesRemaining);
bytesRemaining -= byteArray.size();
fileobj.write(byteArray);
fileobj.flush();
}
All this said, you should not use the blocking API in your main thread or your GUI could freeze up. I suggest either using the asynchronous API, or create a worker thread to handle the downloading (and use the blocking API in the worker thread).
To see examples of how to use the two different APIs, looking in the documentation for the Fortune Client Example and the Blocking Fortune Client Example.
EDIT:
My apologies, there's a bug in the code above that doesn't take an number of possibilities into account, most importantly, if all data has already been received, and the end game once all data has finally arrived.
The following one-line change should clear that up:
Change
while(socket->bytesAvailable() < bytesRemaining){
To
while (bytesRemaining > 0) {
So you are saying that waitForReadyRead() returns false regardless of the time given once your the buffer has all 3000 expected bytes. What other behavior would you want? Perhaps you need rethink the trigger logic here. Many TCP/IP app protocols have some sort of frame start detection logic they combine with the required message size to then trigger processing. This lets them cope with widely different package sizes that the intermediate networks will impose, as well as truncated/partial messages. Once you have it working, connect to it by way of your cell phone and you will get different set of packet fragmentation examples to test with.

How can I send a simple HTTP request with a lwIP stack?

Please move/close this if the question isn't relevant.
Core: Cortex-M4
Microprocessor: TI TM4C1294NCPDT.
IP Stack: lwIP 1.4.1
I am using this microprocessor to do some data logging, and I want to send some information to a separate web server via a HTTP request in the form of:
http://123.456.789.012:8800/process.php?data1=foo&data2=bar&time=1234568789
and I want the processor to be able to see the response header (i.e if it was 200 OK or something went wrong) - it does not have to do display/recieve the actual content.
lwIP has a http server for the microprocessor, but I'm after the opposite (microprocessor is the client).
I am not sure how packets correlate to request/response headers, so I'm not sure how I'm meant to actually send/recieve information.
This ended up being pretty simple to implement, forgot to update this question.
I pretty much followed the instructions given on this site, which is the Raw/TCP 'documentation'.
Basically, The HTTP request is encoded in TCP packets, so to send data to my PHP server, I sent an HTTP request using TCP packets (lwIP does all the work).
The HTTP packet I want to send looks like this:
HEAD /process.php?data1=12&data2=5 HTTP/1.0
Host: mywebsite.com
To "translate" this to text which is understood by an HTTP server, you have to add "\r\n" carriage return/newline in your code. So it looks like this:
char *string = "HEAD /process.php?data1=12&data2=5 HTTP/1.0\r\nHost: mywebsite.com\r\n\r\n ";
Note that the end has two lots of "\r\n"
You can use GET or HEAD, but because I didn't care about HTML site my PHP server returned, I used HEAD (it returns a 200 OK on success, or a different code on failure).
The lwIP raw/tcp works on callbacks. You basically set up all the callback functions, then push the data you want to a TCP buffer (in this case, the TCP string specified above), and then you tell lwIP to send the packet.
Function to set up a TCP connection (this function is directly called by my application every time I want to send a TCP packet):
void tcp_setup(void)
{
uint32_t data = 0xdeadbeef;
/* create an ip */
struct ip_addr ip;
IP4_ADDR(&ip, 110,777,888,999); //IP of my PHP server
/* create the control block */
testpcb = tcp_new(); //testpcb is a global struct tcp_pcb
// as defined by lwIP
/* dummy data to pass to callbacks*/
tcp_arg(testpcb, &data);
/* register callbacks with the pcb */
tcp_err(testpcb, tcpErrorHandler);
tcp_recv(testpcb, tcpRecvCallback);
tcp_sent(testpcb, tcpSendCallback);
/* now connect */
tcp_connect(testpcb, &ip, 80, connectCallback);
}
Once a connection to my PHP server is established, the 'connectCallback' function is called by lwIP:
/* connection established callback, err is unused and only return 0 */
err_t connectCallback(void *arg, struct tcp_pcb *tpcb, err_t err)
{
UARTprintf("Connection Established.\n");
UARTprintf("Now sending a packet\n");
tcp_send_packet();
return 0;
}
This function calls the actual function tcp_send_packet() which sends the HTTP request, as follows:
uint32_t tcp_send_packet(void)
{
char *string = "HEAD /process.php?data1=12&data2=5 HTTP/1.0\r\nHost: mywebsite.com\r\n\r\n ";
uint32_t len = strlen(string);
/* push to buffer */
error = tcp_write(testpcb, string, strlen(string), TCP_WRITE_FLAG_COPY);
if (error) {
UARTprintf("ERROR: Code: %d (tcp_send_packet :: tcp_write)\n", error);
return 1;
}
/* now send */
error = tcp_output(testpcb);
if (error) {
UARTprintf("ERROR: Code: %d (tcp_send_packet :: tcp_output)\n", error);
return 1;
}
return 0;
}
Once the TCP packet has been sent (this is all need if you want to "hope for the best" and don't care if the data actually sent), the PHP server return a TCP packet (with a 200 OK, etc. and the HTML code if you used GET instead of HEAD). This code can be read and verified in the following code:
err_t tcpRecvCallback(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err)
{
UARTprintf("Data recieved.\n");
if (p == NULL) {
UARTprintf("The remote host closed the connection.\n");
UARTprintf("Now I'm closing the connection.\n");
tcp_close_con();
return ERR_ABRT;
} else {
UARTprintf("Number of pbufs %d\n", pbuf_clen(p));
UARTprintf("Contents of pbuf %s\n", (char *)p->payload);
}
return 0;
}
p->payload contains the actual "200 OK", etc. information. Hopefully this helps someone.
I have left out some error checking in my code above to simplify the answer.
Take a look at the HTTP example in Wikipedia. The client will send the GET and HOST lines. The server will respond with many lines for a response. The first line will have the response code.
I managed to create an HTTP client for raspberry pi Pico W using the example here.
It uses the httpc_get_file or httpc_get_file_dns functions from the sdk.
However, that example is incomplete since it has a memory leak.
You will need to free the memory taken by the struct pbuf *hdr in the headers function and struct pbuf *p in the body function with respectively pbuf_free(hdr); and pbuf_free(p);
Without those modifications, it will stop working after about 20 calls (probably depends on the size of the response).

CocaAsyncSocket losing UDP packets, Possible iOS 7/iPad issue?

I am currently on XCode 5.0 and working on an iOS 7 sample application which uses CocoaAyncSocket library. In this application, the "sender controller" sends UDP messages on 255.255.255.255 on port 4000 for a "receiver controller" to handle and print out. The "sender controller" has a for loop that broadcasts a message 200 times. Using Wireshark (filtering on udp.port == 4000), of the 200 packets, 0 of them were lost, which is great! In this environment, everything works great, and the "receiver controller" prints out all the messages.
But now when I move the application an actual iPad (iPad MD328LL/A 16GB, Wi-Fi 3rd Generation iOS 7), some of the packets are lost. Of the 200, about 60% - 65% of the packets are picked up by WireShark and make it to the "receiver controller". I am not quite sure if its the library (which I don't think since it works perfectly with the simulator) or and iOS 7/iPad that is causing the packet loss issue.
Code:
// Sender Controller
#interface ViewController ()
{
GCDAsyncUdpSocket *udpSocket;
}
#end
- (void)viewDidLoad
{
[super viewDidLoad];
if (udpSocket == nil)
{
[self setupSocket];
}
// ...
}
// set ups socket
- (void)setupSocket
{
// Initialize
udpSocket = [[GCDAsyncUdpSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
// Enable Broadcast
[udpSocket enableBroadcast:YES error:nil];
NSError *error = nil;
// Bind to port
if (![udpSocket bindToPort:0 error:&error])
{
[self logError:FORMAT(#"Error binding: %#", error)];
return;
}
if (![udpSocket beginReceiving:&error])
{
[self logError:FORMAT(#"Error receiving: %#", error)];
return;
}
[self logInfo:#"Ready"];
}
// ...
// Click event
- (IBAction)send:(id)sender
{
// Format message
NSData *data = [msg dataUsingEncoding:NSUTF8StringEncoding];
// Broadcast message 200 times
for (int i = 0 ; i < 200; i++) {
[udpSocket sendData:data toHost:host port:port withTimeout:-1 tag:0];
}
}
I know that in this scenario these messages are being sent at a fast rate and it would be highly unlikely for a user to send 200 broadcasts like this. I also understand that UDP is cheap and there is a chance of the occasional malformed or lost packets, but at the rate of 40%... that seems rather high to me.
If anybody has any suggestion/experience with this or any useful information, it would be greatly appreciated
Thanks in advance!

unable to read tcp/ip headers

i am getting this error:‘struct iphdr’ has no member named ‘ip_ttl’
same for other members too but not for protocol feild
what is the solution to it?and y does it happen?
PS:I saw this on various forums but couldn't get why is it able to access ipHeader->protocol and not others
Assuming you're using Linux, try taking a look at /usr/include/linux/ip.h. That header file defines the structure:
struct iphdr {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 ihl:4,
version:4;
#elif defined (__BIG_ENDIAN_BITFIELD)
__u8 version:4,
ihl:4;
#else
#error "Please fix <asm/byteorder.h>"
#endif
__u8 tos;
__be16 tot_len;
__be16 id;
__be16 frag_off;
__u8 ttl;
__u8 protocol;
__sum16 check;
__be32 saddr;
__be32 daddr;
/*The options start here. */
};
As you can see, the name of the field is ttl, not ip_ttl.

Resources