API for linking to the Huxley National Rail REST proxy for the retrieval of live National Rail data. Still needs work (sadly), but works well for the time being!

Dependencies:   EthernetInterface

National Rail Huxley Integration Interface

This API provides a clear link between the National Rail Huxley Integration JSON interface (available at https://huxley.unop.uk/), and mbed devices, over an Ethernet connection. This project is still very much a work-in-progress, but hopefully I will be able to provide a comprehensive method of retrieving live National Rail departures data in a simple and effective way.

/media/uploads/Leigh_LbR/nre_powered_logo.jpg

Committer:
Leigh_LbR
Date:
Tue May 24 15:17:38 2016 +0000
Revision:
11:4532ff549fcf
Parent:
8:6e063a3827c0
Fixed a small glitch with NR_Network.cpp

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Leigh_LbR 0:bf04f62339a4 1 #include "departure_board.h"
Leigh_LbR 0:bf04f62339a4 2 #include "arrival_board.h"
Leigh_LbR 1:1de042ff6324 3 #include "nr_network.h"
Leigh_LbR 11:4532ff549fcf 4 #include "mbed.h"
Leigh_LbR 0:bf04f62339a4 5 #include <string>
Leigh_LbR 1:1de042ff6324 6 #include <vector>
Leigh_LbR 0:bf04f62339a4 7
Leigh_LbR 0:bf04f62339a4 8 #ifndef nullptr
Leigh_LbR 0:bf04f62339a4 9 #define nullptr 0 // nullptr is undefined by default...
Leigh_LbR 0:bf04f62339a4 10 #endif
Leigh_LbR 0:bf04f62339a4 11
Leigh_LbR 0:bf04f62339a4 12 using std::string;
Leigh_LbR 1:1de042ff6324 13 using std::vector;
Leigh_LbR 0:bf04f62339a4 14
Leigh_LbR 0:bf04f62339a4 15 /*
Leigh_LbR 0:bf04f62339a4 16 * Initialise the network connection with the required attributes.
Leigh_LbR 0:bf04f62339a4 17 */
Leigh_LbR 0:bf04f62339a4 18 void NR_Network_Conn::init(const char* address, const char* mask, const char* gateway)
Leigh_LbR 0:bf04f62339a4 19 {
Leigh_LbR 0:bf04f62339a4 20 conn = EthernetInterface();
Leigh_LbR 0:bf04f62339a4 21
Leigh_LbR 0:bf04f62339a4 22 if(address == nullptr) _address[0] = '\0'; else strcpy(_address, address);
Leigh_LbR 0:bf04f62339a4 23 if(mask == nullptr) _sub_mask[0] = '\0'; else strcpy(_sub_mask, mask);
Leigh_LbR 0:bf04f62339a4 24 if(gateway == nullptr) _gateway[0] = '\0'; else strcpy(_gateway, gateway);
Leigh_LbR 0:bf04f62339a4 25 }
Leigh_LbR 0:bf04f62339a4 26
Leigh_LbR 0:bf04f62339a4 27 NR_Network_Conn::NR_Network_Conn()
Leigh_LbR 0:bf04f62339a4 28 {
Leigh_LbR 0:bf04f62339a4 29 init(nullptr, nullptr, nullptr);
Leigh_LbR 0:bf04f62339a4 30 }
Leigh_LbR 0:bf04f62339a4 31
Leigh_LbR 0:bf04f62339a4 32 TCPSocketConnection NR_Network_Conn::GetSocket()
Leigh_LbR 0:bf04f62339a4 33 {
Leigh_LbR 0:bf04f62339a4 34 return socket;
Leigh_LbR 0:bf04f62339a4 35 }
Leigh_LbR 0:bf04f62339a4 36
Leigh_LbR 0:bf04f62339a4 37 Departure_Board NR_Network_Conn::GetDepartures(const string& code_stn, const string& number)
Leigh_LbR 0:bf04f62339a4 38 {
Leigh_LbR 0:bf04f62339a4 39 const string command = "GET /departures/" + code_stn + "/" + number + "/ HTTP/1.1";
Leigh_LbR 0:bf04f62339a4 40
Leigh_LbR 0:bf04f62339a4 41 vector<char> command_cstr (command.begin(), command.end());
Leigh_LbR 0:bf04f62339a4 42 command_cstr.push_back('\0');
Leigh_LbR 0:bf04f62339a4 43
Leigh_LbR 0:bf04f62339a4 44 socket.send_all(&command_cstr[0], sizeof(&command_cstr[0]) - 1); // Ignore the null-terminating character
Leigh_LbR 0:bf04f62339a4 45
Leigh_LbR 0:bf04f62339a4 46 char buf[1000];
Leigh_LbR 0:bf04f62339a4 47 string json;
Leigh_LbR 0:bf04f62339a4 48
Leigh_LbR 0:bf04f62339a4 49 int ret;
Leigh_LbR 0:bf04f62339a4 50
Leigh_LbR 0:bf04f62339a4 51 while(true) {
Leigh_LbR 1:1de042ff6324 52 ret = socket.receive(buf, sizeof(buf) - 1);
Leigh_LbR 0:bf04f62339a4 53 if(ret <= 0){
Leigh_LbR 0:bf04f62339a4 54 json.append(buf);
Leigh_LbR 0:bf04f62339a4 55 break;
Leigh_LbR 0:bf04f62339a4 56 }
Leigh_LbR 0:bf04f62339a4 57 buf[ret] = '\0';
Leigh_LbR 0:bf04f62339a4 58 json.append(buf);
Leigh_LbR 0:bf04f62339a4 59 memset(buf, '\0', 1000);
Leigh_LbR 0:bf04f62339a4 60 }
Leigh_LbR 0:bf04f62339a4 61
Leigh_LbR 1:1de042ff6324 62 Departure_Board dep = depBoardFromJson(json);
Leigh_LbR 0:bf04f62339a4 63
Leigh_LbR 0:bf04f62339a4 64 return dep;
Leigh_LbR 0:bf04f62339a4 65 }
Leigh_LbR 0:bf04f62339a4 66
Leigh_LbR 0:bf04f62339a4 67 Arrival_Board NR_Network_Conn::GetArrivals(const string& code_stn, const string& number)
Leigh_LbR 0:bf04f62339a4 68 {
Leigh_LbR 0:bf04f62339a4 69 const string command = "GET /arrivals/" + code_stn + "/" + number + "/ HTTP/1.1";
Leigh_LbR 0:bf04f62339a4 70
Leigh_LbR 0:bf04f62339a4 71 vector<char> command_cstr (command.begin(), command.end());
Leigh_LbR 0:bf04f62339a4 72 command_cstr.push_back('\0');
Leigh_LbR 0:bf04f62339a4 73
Leigh_LbR 0:bf04f62339a4 74 socket.send_all(&command_cstr[0], sizeof(&command_cstr[0]) - 1); // Ignore the null-terminating character
Leigh_LbR 0:bf04f62339a4 75
Leigh_LbR 0:bf04f62339a4 76 char buf[1000];
Leigh_LbR 0:bf04f62339a4 77 string json;
Leigh_LbR 0:bf04f62339a4 78
Leigh_LbR 0:bf04f62339a4 79 int ret;
Leigh_LbR 0:bf04f62339a4 80
Leigh_LbR 0:bf04f62339a4 81 while(true) {
Leigh_LbR 0:bf04f62339a4 82 ret = socket.receive(buf, sizeof(buf) - 1);
Leigh_LbR 0:bf04f62339a4 83 if(ret <= 0){
Leigh_LbR 0:bf04f62339a4 84 json.append(buf);
Leigh_LbR 0:bf04f62339a4 85 break;
Leigh_LbR 0:bf04f62339a4 86 }
Leigh_LbR 0:bf04f62339a4 87 buf[ret] = '\0';
Leigh_LbR 0:bf04f62339a4 88 json.append(buf);
Leigh_LbR 0:bf04f62339a4 89 memset(buf, '\0', 1000);
Leigh_LbR 0:bf04f62339a4 90 }
Leigh_LbR 0:bf04f62339a4 91
Leigh_LbR 0:bf04f62339a4 92 Arrival_Board arr = arrBoardFromJson(json);
Leigh_LbR 0:bf04f62339a4 93
Leigh_LbR 0:bf04f62339a4 94 return arr;
Leigh_LbR 0:bf04f62339a4 95 }
Leigh_LbR 0:bf04f62339a4 96
Leigh_LbR 0:bf04f62339a4 97 char* NR_Network_Conn::GetIP()
Leigh_LbR 0:bf04f62339a4 98 {
Leigh_LbR 0:bf04f62339a4 99 return conn.getIPAddress();
Leigh_LbR 0:bf04f62339a4 100 }
Leigh_LbR 0:bf04f62339a4 101
Leigh_LbR 0:bf04f62339a4 102 NR_Network_Conn::NR_Network_Conn(const char* address, const char* mask, const char* gateway)
Leigh_LbR 0:bf04f62339a4 103 {
Leigh_LbR 0:bf04f62339a4 104 init(address, mask, gateway);
Leigh_LbR 0:bf04f62339a4 105 }
Leigh_LbR 0:bf04f62339a4 106
Leigh_LbR 0:bf04f62339a4 107 /*
Leigh_LbR 8:6e063a3827c0 108 * Connect to the Huxley (NR) API.
Leigh_LbR 8:6e063a3827c0 109 * @param url URL of the Huxley implementation to be used
Leigh_LbR 0:bf04f62339a4 110 */
Leigh_LbR 8:6e063a3827c0 111 int NR_Network_Conn::Connect(const char* url)
Leigh_LbR 0:bf04f62339a4 112 {
Leigh_LbR 11:4532ff549fcf 113 Serial pc(USBTX, USBRX);
Leigh_LbR 11:4532ff549fcf 114 pc.baud(115200);
Leigh_LbR 11:4532ff549fcf 115 pc.printf("Initiating connection (2A)...\n");
Leigh_LbR 11:4532ff549fcf 116
Leigh_LbR 11:4532ff549fcf 117 if((_address[0] == '\0') || (_sub_mask[0] == '\0') || (_gateway == '\0')) {
Leigh_LbR 11:4532ff549fcf 118 pc.printf("IP Address is being set by DHCP.\n");
Leigh_LbR 0:bf04f62339a4 119 if(conn.init() < 0) return -1;
Leigh_LbR 0:bf04f62339a4 120 } else {
Leigh_LbR 11:4532ff549fcf 121 pc.printf("IP Address is being set manually.\n");
Leigh_LbR 0:bf04f62339a4 122 if(conn.init(_address, _sub_mask, _gateway) < 0) return -1;
Leigh_LbR 0:bf04f62339a4 123 }
Leigh_LbR 0:bf04f62339a4 124
Leigh_LbR 11:4532ff549fcf 125 pc.printf("Connecting (2B)...\n");
Leigh_LbR 11:4532ff549fcf 126
Leigh_LbR 11:4532ff549fcf 127 if(int err = conn.connect() < 0) return err;
Leigh_LbR 11:4532ff549fcf 128
Leigh_LbR 11:4532ff549fcf 129 pc.printf("Creating TCPSocketConnection (2C)...\n");
Leigh_LbR 0:bf04f62339a4 130
Leigh_LbR 0:bf04f62339a4 131 socket = TCPSocketConnection();
Leigh_LbR 0:bf04f62339a4 132
Leigh_LbR 8:6e063a3827c0 133 socket.connect(url, 80);
Leigh_LbR 0:bf04f62339a4 134
Leigh_LbR 0:bf04f62339a4 135 return 0;
Leigh_LbR 0:bf04f62339a4 136 }
Leigh_LbR 0:bf04f62339a4 137
Leigh_LbR 0:bf04f62339a4 138 void NR_Network_Conn::Disconnect()
Leigh_LbR 0:bf04f62339a4 139 {
Leigh_LbR 0:bf04f62339a4 140 socket.close();
Leigh_LbR 0:bf04f62339a4 141 conn.disconnect();
Leigh_LbR 0:bf04f62339a4 142 }