-
Notifications
You must be signed in to change notification settings - Fork 1
WTP: Getting Started
This tutorial will help you get started with the WTP API.
For the design, details and issues of WTP please refer to other wiki articles.
The first step to use WTP is to create WTP endpoints. For the server (computer) side, we create an instance of the WTPServer
class:
from wtp import WTPServer
# Create WTP server endpoint
server = WTPServer(
antennas=[1],
n_tags_per_report=1,
)
In the demo code shown above, we create a WTP server endpoint that accepts incoming WTP connections through antenna 1 on the RFID reader and receives 1 tag report each time from the reader.
To start the WTP server, call WTPServer.start()
with the IP address and (optionally) the port of the reader:
# Connect to RFID reader and start
server.start("192.168.1.13")
As for the WISP (client) side, we declare the endpoint variable and initialize it with wtp_init()
:
wtp_t client;
//Initialize client WTP endpoint
wtp_init(
&client,
//EPC data memory
epc_data_mem,
//EPC data memory size
EPC_DATA_MEM_SIZE,
//Read memory
read_mem,
//BlockWrite memory
blockwrite_mem,
//Initial sliding window size
64,
//Timeout
10,
//Buffer size for transmit control
200,
//Buffer size for receiving control
200,
//Capacity of sending messages
5,
//Capacity of receiving messages
5
);
The WTP client library provided three hook functions: wtp_before_do_rfid()
, wtp_load_read_mem()
and wtp_handle_blockwrite()
. You need to call these functions when specific RFID event happens:
//Read and BlockWrite flag
bool read_flag = false;
bool blockwrite_flag = false;
//Read callback
void read_callback(void) {
read_flag = true;
}
//BlockWrite callback
void blockwrite_callback(void) {
blockwrite_flag = true;
}
//Register Read and BlockWrite callback
WISP_registerCallback_READ(read_callback);
WISP_registerCallback_BLOCKWRITE(blockwrite_callback);
while (true) {
//Call "wtp_before_do_rfid" before doing RFID
wtp_before_do_rfid(&client);
//Do RFID
WISP_doRFID();
//Call "wtp_load_read_mem" after RFID Read
if (read_flag) {
wtp_load_read_mem(&client);
read_flag = false;
}
//Call "wtp_handle_blockwrite" after RFID BlockWrite
if (blockwrite_flag) {
wtp_handle_blockwrite(&client);
blockwrite_flag = false;
}
}
In theory, we can directly call wtp_load_read_mem()
inside read_callback()
and call wtp_handle_blockwrite()
inside blockwrite_callback()
. But since these two functions aren't optimized and take a long time to run, they can cause the WISP RFID routines to fail, so now we only set up flags inside the Read and BlockWrite callback and call the WTP hook functions outside the WISP RFID routines.
With the client endpoint we already created, the next step is to connect to the server side. This is done with wtp_connect()
:
WIO_CALLBACK(on_connected) {
//Do anything you want after the connection is fully opened
//...
return WIO_OK;
}
//Add connected event callback
wtp_on_event(&client, WTP_EVENT_OPEN, NULL, on_connected);
//Connect to WTP server
wtp_connect(&client);
The demo client code above registers a callback for the connection open event, and then starts to connect to the server side. The event will be triggered when both the upstream and the downstream connection is opened, and the callback will then be invoked.
For the server side, it handles every new incoming WTP connection (or client) through the server connect
event callback:
@server.on("connect")
def on_connect(connection):
# Print WISP ID
print("New client: %d" % connection.wisp_id)
# Do whatever you want with the connection
# ...
Now that a bidirectional connection has been open for both sides, it's time to send and receive data between the WISP and the computer. Let's first send some data from the computer to the WISP:
# Send callback
def send_cb(_):
print("Send succeeded!")
# Send data to WISP
connection.send(b"12345").addCallback(send_cb)
Function WTPConnection.send()
takes a bytes-like object and sends its content to the WISP side. Because the sending process is asynchronous, it returns a Twisted Deferred object that will be resolved when the client side reports that the whole message is fully sent.
To receive the message at the WISP side, we use wtp_recv()
:
//Received bytes counter
uint16_t n_recv_bytes = 0;
WIO_CALLBACK(on_recv) {
//Received data is wrapped inside a WIO buffer
wio_buf_t* buf = (wio_buf_t*)result;
//Update counter
n_recv_bytes += buf->size;
return WIO_OK;
}
//Receive data from server
wtp_recv(&client, NULL, on_recv);
The process is similar when we send data from WISP to computer, except we use wtp_send()
at the client side and WTPConnection.recv()
at the server side:
WIO_CALLBACK(on_sent) {
//Do whatever you want here after the data is sent
//...
return WIO_OK;
}
//Send data to server
wtp_send(&client, "abcde", 5, NULL, on_sent);
# Keeps receiving and printing data from client
def recv_cb(msg_data):
print("Received %s" % msg_data)
connection.recv().addCallback(recv_cb)
# Kick start
connection.recv().addCallback(recv_cb)