Proxy is defined as
"...the agency, function, or office of a deputy who acts as a substitute for another"
and this is exactly what this program does. Proxy is the piece of software which any other software communicates with in order to communicate with the hardware. It is the middle-man between the CC430 serial UART and network interface from which other software applications can communicate with. Providing this layer of abstraction greatly simplifies any application development.
Proxy works on the premise of spinning up a thread which has the sole purpose of querying every “port” (0-255) of the Faraday radio to see if new data is available. This is called the UART Worker. Upon data being available, the thread will receive the data and place it into a buffer queue. This queue is 100 packets long and is a FIFO resulting in old data being popped off if no user is requesting data. The same occurs in reverse with data posted to Proxy using the HTTP POST method.
A flask server runs in the main process which provides a RESTful interface for the Proxy. When the RESTful interface is queried with a GET request the thread-safe queue will pop off packets for the requested Faraday “port” from the left . This data is served to the user in a JSON dictionary. If the RESTful interface received a POST request to send data to Faraday then the flask server will place the packet onto the queue from the right. Every 10ms the UART Worker checks to see if there is any data for any port in the transmit queue. If present, this data is immediately sent to Faraday via USB UART.
Checks the proxy queue for the specified port. If packets are present in the queue they are returned as a JSON dictionary as an HTTP response. Additionally, the POST method will add packets to the POST queue which are sent to Faraday on a periodic basis. Invalid parameters are responded with appropriate HTTP responses and relevant warning messages.
Before Proxy can connect to any radio hardware, it needs to be configured using the proxy.ini
file with your callsign and the serial port.
- Navigate to the
Proxy
folder - Create a copy of
proxy.sample.ini
and rename the new fileproxy.ini
- Open
proxy.ini
in a text editor and update the requested information noted byREPLACEME
Configuring Proxy consists of changing three parameters for basic use:CALLSIGN
, NODEID
and COM
. These will let Telemetry properly query Proxy to obtain the correct telemetry data.
[UNIT0]
: Unit 0 Proxy configuration values sectionCALLSIGN
: Callsign to associate with radio on this USB portNODEID
: Node ID of radio connected on this USB portCOM
: COM/serial Port associated with the radio connected
Proxy is able to save all data in BASE64 format to a SQLite database for future playback. This is extremely helpful if raw UART data is desired as BASE64 can be converted into binary. Additionally, it enabled replays of events and use of software without the need for hardware in "Test Mode".
Open proxy.ini
and configure the following in addition to the Basic Configuration above:
[DATABASE]
FILENAME=log.db
: Filename of Proxy log to be created
[PROXY]
LOG=1
: Enable Proxy logging mode (boolean)UNITS=1
: Number of UART units to log
Now, when you run Proxy
it will log to the database in the background while you are free to use software normally. You can stop Proxy normally without issue.
With a SQLite log file, one can play it back as if hardware is connected. To do so please disable logging mode and edit the following proxy.ini
configuration items:
[TESTDATABASE]
FILENAME=examplelogs/2017-04-20-01.db
: Proxy log file to play in test mode. Example log provided in examplelogs/ folder.
[PROXY]
TESTMODE=1
: Enable payback test modeTESTRATE=1
: Set rate in Hz to read each row of database backTESTCALLSIGN=KB1LQC
: Set callsign to appear as Proxy connected Faraday radioTESTNODEID=2
: Set nodeid to appear as Proxy connected Faraday radio
Once properly configured and logging mode is disabled in proxy.ini
then running Proxy
normally will result in the log file being read into Proxy
at the indicated rate. It will not repeat once the end of the file is reached.
import requests
# Simple GET request putting response into variable r
# Port 5 is the telemetry port of Faraday so we will receive three telemetry packets
payload = {'callsign': 'kb1lqd','nodeid': 22,'port':5,'limit': 3}
r = requests.get('http://localhost:8000/',params=payload)
# Printing text response from Proxy
print(r.text)
# Printing with requests built-in JSON decoder
for item in r.json():
print item, '\n'
Printing text response from Python sample GET call:
[
{
"data": "AwBhS0IxTFFEBXsDBhZLQjFMUUQFewMGFggAAAACANAHMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAHYAkuCBAIDAfaB9cHtwAAACQLJwAAHCAAAAAAAAAAAAAAAAAAAAAAAAAAAABOxBIs"
},
{
"data": "AwBhS0IxTFFEAADDBhZLQjFMUUSxAAAGFgkAAAACANAHMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAHYAktCBEIDQfaB9cHugAAACMLLAAAHCAAAAAAAAAAAAAAAAAAAAAAAE7EAACXIxNd"
},
{
"data": "AwBhS0IxTFFEBXsDBhZLQjFMUUQAAMMGFgoAAAACANAHMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAHYAksCBAICwfaB9UHtwAAACMLLwAAHCAAAAAAAAAAAAAAAAAAAAAAAAAATsQAABJw"
}
]
Printing output of requests built-in JSON decoder from Python Sample GET Call:
{u'data': u'AwBhS0IxTFFEBXsDBhZLQjFMUUQFewMGFggAAAACANAHMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAHYAkuCBAIDAfaB9cHtwAAACQLJwAAHCAAAAAAAAAAAAAAAAAAAAAAAAAAAABOxBIs'}
{u'data': u'AwBhS0IxTFFEAADDBhZLQjFMUUSxAAAGFgkAAAACANAHMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAHYAktCBEIDQfaB9cHugAAACMLLAAAHCAAAAAAAAAAAAAAAAAAAAAAAE7EAACXIxNd'}
{u'data': u'AwBhS0IxTFFEBXsDBhZLQjFMUUQAAMMGFgoAAAACANAHMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAHYAksCBAICwfaB9UHtwAAACMLLwAAHCAAAAAAAAAAAAAAAAAAAAAAAAAATsQAABJw'}
Port 8000 of localhost (127.0.0.1) hosts the flask server where Proxy is exposed
GET
| POST
- Required
Callsign
= [String]NodeID
= [Integer]Port
= [Integer]- Optional
Limit
= [Integer]
When making a POST request Proxy expects to receive JSON data in the body with an object containing a string “data” and value being an array of BASE64 encoded strings each 164 characters long. The header of the POST request must specify the content type as application/json
. Only a data array of 100 packets is accepted.
Code: 200 OK
Content: [{"data": "<164 Characters of BASE64>"},{"data": "<164 Characters of BASE64>"},...]
Code: 204 NO CONTENT
Content: Empty string
Code: 200 OK
Content: { "status": "Posted x of y Packet(s)" }
Code: 204 NO CONTENT
Content: Empty String
####Error Response
GET
Code: 400 BAD REQUEST
Content: { "error": "<Python exception string>" }
POST
Code: 400 BAD REQUEST
Content: { "error": "<Python exception string>" }