Skip to content

Instantly share code, notes, and snippets.

@Cees-Meijer
Created November 2, 2019 15:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Cees-Meijer/24778495e45755958ebf3e9fd93df5f0 to your computer and use it in GitHub Desktop.
Save Cees-Meijer/24778495e45755958ebf3e9fd93df5f0 to your computer and use it in GitHub Desktop.
Gateway code. Corrected
/******************************************************************************
*
* Copyright (c) 2015 Thomas Telkamp
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
* 2019 - Cees Meijer. - Added a Carriage return to the JSON output so it can be read by the lorawan_gateway.py program.
* Set 'is_pizero' to true to enforce the Pi Zero. (line 103)
*******************************************************************************/
// Raspberry PI pin mapping
// Pin number in this global_conf.json are Wiring Pi number (wPi colunm)
// issue a `gpio readall` on PI command line to see mapping
#include "base64.h"
#include <rapidjson/document.h>
#include <rapidjson/filereadstream.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/writer.h>
#include <wiringPi.h>
#include <wiringPiSPI.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include <netdb.h>
#include <cstdlib>
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
using namespace rapidjson;
#define BASE64_MAX_LENGTH 341
static const int SPI_CHANNEL = 0;
bool sx1272 = true;
struct sockaddr_in si_other;
int s;
int slen = sizeof(si_other);
struct ifreq ifr;
uint32_t cp_nb_rx_rcv;
uint32_t cp_nb_rx_ok;
uint32_t cp_nb_rx_ok_tot;
uint32_t cp_nb_rx_bad;
uint32_t cp_nb_rx_nocrc;
uint32_t cp_up_pkt_fwd;
typedef enum SpreadingFactors
{
SF7 = 7,
SF8 = 8,
SF9 = 9,
SF10 = 10,
SF11 = 11,
SF12 = 12
} SpreadingFactor_t;
typedef struct Server
{
string address;
uint16_t port;
bool enabled;
} Server_t;
/*******************************************************************************
*
* Default values, configure them in global_conf.json
*
*******************************************************************************/
// SX1272 - Raspberry connections
// Put them in global_conf.json
int nssPin = 0xff;
int dio0 = 0xff;
int rstPin = 0xff;
// Set location in global_conf.json
float lat = 0.0;
float lon = 0.0;
int alt = 0;
/* Informal status fields */
char platform[24] ; /* platform definition */
char email[40] ; /* used for contact email */
char description[64] ; /* used for free form description */
bool is_pizero = true;
// Set spreading factor (SF7 - SF12), &nd center frequency
// Overwritten by the ones set in global_conf.json
SpreadingFactor_t sf = SF7;
uint16_t bw = 125;
uint32_t freq = 868100000; // in Mhz! (868.1)
// Servers
vector<Server_t> servers;
// #############################################
// #############################################
#define REG_FIFO 0x00
#define REG_FIFO_ADDR_PTR 0x0D
#define REG_FIFO_TX_BASE_AD 0x0E
#define REG_FIFO_RX_BASE_AD 0x0F
#define REG_RX_NB_BYTES 0x13
#define REG_OPMODE 0x01
#define REG_FIFO_RX_CURRENT_ADDR 0x10
#define REG_IRQ_FLAGS 0x12
#define REG_DIO_MAPPING_1 0x40
#define REG_DIO_MAPPING_2 0x41
#define REG_MODEM_CONFIG 0x1D
#define REG_MODEM_CONFIG2 0x1E
#define REG_MODEM_CONFIG3 0x26
#define REG_SYMB_TIMEOUT_LSB 0x1F
#define REG_PKT_SNR_VALUE 0x19
#define REG_PAYLOAD_LENGTH 0x22
#define REG_IRQ_FLAGS_MASK 0x11
#define REG_MAX_PAYLOAD_LENGTH 0x23
#define REG_HOP_PERIOD 0x24
#define REG_SYNC_WORD 0x39
#define REG_VERSION 0x42
#define SX72_MODE_RX_CONTINUOS 0x85
#define SX72_MODE_TX 0x83
#define SX72_MODE_SLEEP 0x80
#define SX72_MODE_STANDBY 0x81
#define PAYLOAD_LENGTH 0x40
// LOW NOISE AMPLIFIER
#define REG_LNA 0x0C
#define LNA_MAX_GAIN 0x23
#define LNA_OFF_GAIN 0x00
#define LNA_LOW_GAIN 0x20
// CONF REG
#define REG1 0x0A
#define REG2 0x84
#define SX72_MC2_FSK 0x00
#define SX72_MC2_SF7 0x70
#define SX72_MC2_SF8 0x80
#define SX72_MC2_SF9 0x90
#define SX72_MC2_SF10 0xA0
#define SX72_MC2_SF11 0xB0
#define SX72_MC2_SF12 0xC0
#define SX72_MC1_LOW_DATA_RATE_OPTIMIZE 0x01 // mandated for SF11 and SF12
// FRF
#define REG_FRF_MSB 0x06
#define REG_FRF_MID 0x07
#define REG_FRF_LSB 0x08
#define FRF_MSB 0xD9 // 868.1 Mhz
#define FRF_MID 0x06
#define FRF_LSB 0x66
#define BUFLEN 2048 //Max length of buffer
#define PROTOCOL_VERSION 1
#define PKT_PUSH_DATA 0
#define PKT_PUSH_ACK 1
#define PKT_PULL_DATA 2
#define PKT_PULL_RESP 3
#define PKT_PULL_ACK 4
#define TX_BUFF_SIZE 2048
#define STATUS_SIZE 1024
void LoadConfiguration(string filename);
void PrintConfiguration();
void Die(const char *s)
{
perror(s);
exit(1);
}
void SelectReceiver()
{
digitalWrite(nssPin, LOW);
}
void UnselectReceiver()
{
digitalWrite(nssPin, HIGH);
}
uint8_t ReadRegister(uint8_t addr)
{
uint8_t spibuf[2];
spibuf[0] = addr & 0x7F;
spibuf[1] = 0x00;
SelectReceiver();
wiringPiSPIDataRW(SPI_CHANNEL, spibuf, 2);
UnselectReceiver();
return spibuf[1];
}
void WriteRegister(uint8_t addr, uint8_t value)
{
uint8_t spibuf[2];
spibuf[0] = addr | 0x80;
spibuf[1] = value;
SelectReceiver();
wiringPiSPIDataRW(SPI_CHANNEL, spibuf, 2);
UnselectReceiver();
}
bool ReceivePkt(char* payload, uint8_t* p_length)
{
// clear rxDone
WriteRegister(REG_IRQ_FLAGS, 0x40);
int irqflags = ReadRegister(REG_IRQ_FLAGS);
cp_nb_rx_rcv++;
// payload crc: 0x20
if((irqflags & 0x20) == 0x20) {
printf("CRC error\n");
WriteRegister(REG_IRQ_FLAGS, 0x20);
return false;
} else {
cp_nb_rx_ok++;
cp_nb_rx_ok_tot++;
uint8_t currentAddr = ReadRegister(REG_FIFO_RX_CURRENT_ADDR);
uint8_t receivedCount = ReadRegister(REG_RX_NB_BYTES);
*p_length = receivedCount;
WriteRegister(REG_FIFO_ADDR_PTR, currentAddr);
for(int i = 0; i < receivedCount; i++) {
payload[i] = ReadRegister(REG_FIFO);
}
}
return true;
}
char * PinName(int pin, char * buff) {
strcpy(buff, "unused");
if (pin != 0xff) {
sprintf(buff, "%d", pin);
}
return buff;
}
void SetupLoRa()
{
char buff[16];
printf("Trying to detect module with ");
printf("NSS=%s " , PinName(nssPin, buff));
printf("DIO0=%s " , PinName(dio0 , buff));
printf("Reset=%s ", PinName(rstPin , buff));
// check basic
if (nssPin == 0xff || dio0 == 0xff) {
Die("Bad pin configuration nssPin and dio0 need at least to be defined");
}
digitalWrite(rstPin, HIGH);
delay(100);
digitalWrite(rstPin, LOW);
delay(100);
uint8_t version = ReadRegister(REG_VERSION);
if (version == 0x22) {
// sx1272
printf("SX1272 detected, starting.\n");
sx1272 = true;
} else {
// sx1276?
digitalWrite(rstPin, LOW);
delay(100);
digitalWrite(rstPin, HIGH);
delay(100);
version = ReadRegister(REG_VERSION);
if (version == 0x12) {
// sx1276
printf("SX1276 detected, starting.\n");
sx1272 = false;
} else {
printf("Transceiver version 0x%02X\n", version);
Die("Unrecognized transceiver");
}
}
WriteRegister(REG_OPMODE, SX72_MODE_SLEEP);
// set frequency
uint64_t frf = ((uint64_t)freq << 19) / 32000000;
WriteRegister(REG_FRF_MSB, (uint8_t)(frf >> 16) );
WriteRegister(REG_FRF_MID, (uint8_t)(frf >> 8) );
WriteRegister(REG_FRF_LSB, (uint8_t)(frf >> 0) );
WriteRegister(REG_SYNC_WORD, 0x34); // LoRaWAN public sync word
if (sx1272) {
if (sf == SF11 || sf == SF12) {
WriteRegister(REG_MODEM_CONFIG, 0x0B);
} else {
WriteRegister(REG_MODEM_CONFIG, 0x0A);
}
WriteRegister(REG_MODEM_CONFIG2, (sf << 4) | 0x04);
} else {
if (sf == SF11 || sf == SF12) {
WriteRegister(REG_MODEM_CONFIG3, 0x0C);
} else {
WriteRegister(REG_MODEM_CONFIG3, 0x04);
}
WriteRegister(REG_MODEM_CONFIG, 0x72);
WriteRegister(REG_MODEM_CONFIG2, (sf << 4) | 0x04);
}
if (sf == SF10 || sf == SF11 || sf == SF12) {
WriteRegister(REG_SYMB_TIMEOUT_LSB, 0x05);
} else {
WriteRegister(REG_SYMB_TIMEOUT_LSB, 0x08);
}
WriteRegister(REG_MAX_PAYLOAD_LENGTH, 0x80);
WriteRegister(REG_PAYLOAD_LENGTH, PAYLOAD_LENGTH);
WriteRegister(REG_HOP_PERIOD, 0xFF);
WriteRegister(REG_FIFO_ADDR_PTR, ReadRegister(REG_FIFO_RX_BASE_AD));
// Set Continous Receive Mode
WriteRegister(REG_LNA, LNA_MAX_GAIN); // max lna gain
WriteRegister(REG_OPMODE, SX72_MODE_RX_CONTINUOS);
}
void SolveHostname(const char* p_hostname, uint16_t port, struct sockaddr_in* p_sin)
{
struct addrinfo hints;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
char service[6] = { '\0' };
snprintf(service, 6, "%hu", port);
struct addrinfo* p_result = NULL;
// Resolve the domain name into a list of addresses
int error = getaddrinfo(p_hostname, service, &hints, &p_result);
if (error != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(error));
exit(EXIT_FAILURE);
}
// Loop over all returned results
for (struct addrinfo* p_rp = p_result; p_rp != NULL; p_rp = p_rp->ai_next) {
struct sockaddr_in* p_saddr = (struct sockaddr_in*)p_rp->ai_addr;
//printf("%s solved to %s\n", p_hostname, inet_ntoa(p_saddr->sin_addr));
p_sin->sin_addr = p_saddr->sin_addr;
}
freeaddrinfo(p_result);
}
void SendUdp(char *msg, int length)
{
for (vector<Server_t>::iterator it = servers.begin(); it != servers.end(); ++it) {
if (it->enabled) {
si_other.sin_port = htons(it->port);
SolveHostname(it->address.c_str(), it->port, &si_other);
if (sendto(s, (char *)msg, length, 0 , (struct sockaddr *) &si_other, slen)==-1) {
Die("sendto()");
}
}
}
}
void SendStat()
{
static char status_report[STATUS_SIZE]; /* status report as a JSON object */
char stat_timestamp[24];
int stat_index = 0;
/* pre-fill the data buffer with fixed fields */
status_report[0] = PROTOCOL_VERSION;
status_report[3] = PKT_PUSH_DATA;
status_report[4] = (unsigned char)ifr.ifr_hwaddr.sa_data[0];
status_report[5] = (unsigned char)ifr.ifr_hwaddr.sa_data[1];
status_report[6] = (unsigned char)ifr.ifr_hwaddr.sa_data[2];
status_report[7] = 0xFF;
status_report[8] = 0xFF;
status_report[9] = (unsigned char)ifr.ifr_hwaddr.sa_data[3];
status_report[10] = (unsigned char)ifr.ifr_hwaddr.sa_data[4];
status_report[11] = (unsigned char)ifr.ifr_hwaddr.sa_data[5];
/* start composing datagram with the header */
uint8_t token_h = (uint8_t)rand(); /* random token */
uint8_t token_l = (uint8_t)rand(); /* random token */
status_report[1] = token_h;
status_report[2] = token_l;
stat_index = 12; /* 12-byte header */
/* get timestamp for statistics */
time_t t = time(NULL);
strftime(stat_timestamp, sizeof stat_timestamp, "%F %T %Z", gmtime(&t));
// Build JSON object.
StringBuffer sb;
Writer<StringBuffer> writer(sb);
writer.StartObject();
writer.String("stat");
writer.StartObject();
writer.String("time");
writer.String(stat_timestamp);
writer.String("lati");
writer.Double(lat);
writer.String("long");
writer.Double(lon);
writer.String("alti");
writer.Int(alt);
writer.String("rxnb");
writer.Uint(cp_nb_rx_rcv);
writer.String("rxok");
writer.Uint(cp_nb_rx_ok);
writer.String("rxfw");
writer.Uint(cp_up_pkt_fwd);
writer.String("ackr");
writer.Double(0);
writer.String("dwnb");
writer.Uint(0);
writer.String("txnb");
writer.Uint(0);
writer.String("pfrm");
writer.String(platform);
writer.String("mail");
writer.String(email);
writer.String("desc");
writer.String(description);
writer.EndObject();
writer.EndObject();
string json = sb.GetString();
//printf("stat update: %s\n", json.c_str());
printf("gateway status update\n");
printf("%s\n", stat_timestamp);
fflush(stdout);
if (cp_nb_rx_ok_tot == 0) {
printf("status: no packet yet...\n0 packets received\n");
fflush(stdout);
}
else {
printf("status: new packet!\n");
printf(" %u packet%sreceived\n", cp_nb_rx_ok_tot, cp_nb_rx_ok_tot > 1 ? "s " : " ");
fflush(stdout);
}
// Build and send message.
memcpy(status_report + 12, json.c_str(), json.size());
SendUdp(status_report, stat_index + json.size());
}
bool Receivepacket()
{
long int SNR;
int rssicorr;
bool ret = false;
if (digitalRead(dio0) == 1) {
char message[256];
uint8_t length = 0;
if (ReceivePkt(message, &length)) {
// OK got one
ret = true;
uint8_t value = ReadRegister(REG_PKT_SNR_VALUE);
if (value & 0x80) { // The SNR sign bit is 1
// Invert and divide by 4
value = ((~value + 1) & 0xFF) >> 2;
SNR = -value;
} else {
// Divide by 4
SNR = ( value & 0xFF ) >> 2;
}
rssicorr = sx1272 ? 139 : 157;
printf("incoming packet...\n");
char buff_up[TX_BUFF_SIZE]; /* buffer to compose the upstream packet */
int buff_index = 0;
/* gateway <-> MAC protocol variables */
//static uint32_t net_mac_h; /* Most Significant Nibble, network order */
//static uint32_t net_mac_l; /* Least Significant Nibble, network order */
/* pre-fill the data buffer with fixed fields */
buff_up[0] = PROTOCOL_VERSION;
buff_up[3] = PKT_PUSH_DATA;
/* process some of the configuration variables */
//net_mac_h = htonl((uint32_t)(0xFFFFFFFF & (lgwm>>32)));
//net_mac_l = htonl((uint32_t)(0xFFFFFFFF & lgwm ));
//*(uint32_t *)(buff_up + 4) = net_mac_h;
//*(uint32_t *)(buff_up + 8) = net_mac_l;
buff_up[4] = (uint8_t)ifr.ifr_hwaddr.sa_data[0];
buff_up[5] = (uint8_t)ifr.ifr_hwaddr.sa_data[1];
buff_up[6] = (uint8_t)ifr.ifr_hwaddr.sa_data[2];
buff_up[7] = 0xFF;
buff_up[8] = 0xFF;
buff_up[9] = (uint8_t)ifr.ifr_hwaddr.sa_data[3];
buff_up[10] = (uint8_t)ifr.ifr_hwaddr.sa_data[4];
buff_up[11] = (uint8_t)ifr.ifr_hwaddr.sa_data[5];
/* start composing datagram with the header */
uint8_t token_h = (uint8_t)rand(); /* random token */
uint8_t token_l = (uint8_t)rand(); /* random token */
buff_up[1] = token_h;
buff_up[2] = token_l;
buff_index = 12; /* 12-byte header */
// TODO: tmst can jump is time is (re)set, not good.
struct timeval now;
gettimeofday(&now, NULL);
uint32_t tmst = (uint32_t)(now.tv_sec * 1000000 + now.tv_usec);
// Encode payload.
char b64[BASE64_MAX_LENGTH];
bin_to_b64((uint8_t*)message, length, b64, BASE64_MAX_LENGTH);
// Build JSON object.
StringBuffer sb;
Writer<StringBuffer> writer(sb);
writer.StartObject();
writer.String("rxpk");
writer.StartArray();
writer.StartObject();
writer.String("tmst");
writer.Uint(tmst);
writer.String("freq");
writer.Double((double)freq / 1000000);
writer.String("chan");
writer.Uint(0);
writer.String("rfch");
writer.Uint(0);
writer.String("stat");
writer.Uint(1);
writer.String("modu");
writer.String("LORA");
writer.String("datr");
char datr[] = "SFxxBWxxx";
snprintf(datr, strlen(datr) + 1, "SF%hhuBW%hu", sf, bw);
writer.String(datr);
writer.String("codr");
writer.String("4/5");
writer.String("rssi");
writer.Int(ReadRegister(0x1A) - rssicorr);
writer.String("lsnr");
writer.Double(SNR); // %li.
writer.String("size");
writer.Uint(length);
writer.String("data");
writer.String(b64);
writer.EndObject();
writer.EndArray();
writer.EndObject();
string json = sb.GetString();
printf(json.c_str());printf("\n");
fflush(stdout);
// Build and send message.
memcpy(buff_up + 12, json.c_str(), json.size());
SendUdp(buff_up, buff_index + json.size());
fflush(stdout);
}
}
return ret;
}
int main()
{
struct timeval nowtime;
uint32_t lasttime;
LoadConfiguration("global_conf.json");
PrintConfiguration();
// Init WiringPI
wiringPiSetup() ;
pinMode(nssPin, OUTPUT);
pinMode(dio0, INPUT);
pinMode(rstPin, OUTPUT);
// Init SPI
wiringPiSPISetup(SPI_CHANNEL, 500000);
// Setup LORA
SetupLoRa();
// Prepare Socket connection
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
Die("socket");
}
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
ifr.ifr_addr.sa_family = AF_INET;
if (is_pizero) { // pi zero
strncpy(ifr.ifr_name, "wlan0", IFNAMSIZ - 1);
}
else {
strncpy(ifr.ifr_name, "eth0", IFNAMSIZ - 1);
}
ioctl(s, SIOCGIFHWADDR, &ifr);
// ID based on MAC Adddress of eth0
printf( "Gateway ID: %.2x:%.2x:%.2x:ff:ff:%.2x:%.2x:%.2x\n",
(uint8_t)ifr.ifr_hwaddr.sa_data[0],
(uint8_t)ifr.ifr_hwaddr.sa_data[1],
(uint8_t)ifr.ifr_hwaddr.sa_data[2],
(uint8_t)ifr.ifr_hwaddr.sa_data[3],
(uint8_t)ifr.ifr_hwaddr.sa_data[4],
(uint8_t)ifr.ifr_hwaddr.sa_data[5]
);
printf("Listening at SF%i on %.6lf Mhz.\n", sf,(double)freq/1000000);
printf("-----------------------------------\n");
while(1) {
// rx packet
Receivepacket();
fflush(stdout);
// timestamp packet
gettimeofday(&nowtime, NULL);
fflush(stdout);
uint32_t nowseconds = (uint32_t)(nowtime.tv_sec);
if (nowseconds - lasttime >= 5) {
lasttime = nowseconds;
SendStat();
fflush(stdout);
cp_nb_rx_rcv = 0;
cp_nb_rx_ok = 0;
cp_up_pkt_fwd = 0;
}
// Let some time to the OS
delay(1);
}
return (0);
}
void LoadConfiguration(string configurationFile)
{
FILE* p_file = fopen(configurationFile.c_str(), "r");
char buffer[65536];
FileReadStream fs(p_file, buffer, sizeof(buffer));
Document document;
document.ParseStream(fs);
for (Value::ConstMemberIterator fileIt = document.MemberBegin(); fileIt != document.MemberEnd(); ++fileIt) {
string objectType(fileIt->name.GetString());
if (objectType.compare("SX127x_conf") == 0) {
const Value& sx127x_conf = fileIt->value;
if (sx127x_conf.IsObject()) {
for (Value::ConstMemberIterator confIt = sx127x_conf.MemberBegin(); confIt != sx127x_conf.MemberEnd(); ++confIt) {
string key(confIt->name.GetString());
if (key.compare("freq") == 0) {
freq = confIt->value.GetUint();
} else if (key.compare("spread_factor") == 0) {
sf = (SpreadingFactor_t)confIt->value.GetUint();
} else if (key.compare("pin_nss") == 0) {
nssPin = confIt->value.GetUint();
} else if (key.compare("pin_dio0") == 0) {
dio0 = confIt->value.GetUint();
} else if (key.compare("pin_rstPin") == 0) {
rstPin = confIt->value.GetUint();
}
}
}
} else if (objectType.compare("gateway_conf") == 0) {
const Value& gateway_conf = fileIt->value;
if (gateway_conf.IsObject()) {
for (Value::ConstMemberIterator confIt = gateway_conf.MemberBegin(); confIt != gateway_conf.MemberEnd(); ++confIt) {
string memberType(confIt->name.GetString());
if (memberType.compare("ref_latitude") == 0) {
lat = confIt->value.GetDouble();
} else if (memberType.compare("ref_longitude") == 0) {
lon = confIt->value.GetDouble();
} else if (memberType.compare("ref_altitude") == 0) {
alt = confIt->value.GetUint();
} else if (memberType.compare("name") == 0 && confIt->value.IsString()) {
string str = confIt->value.GetString();
strcpy(platform, str.length()<=24 ? str.c_str() : "name too long");
} else if (memberType.compare("email") == 0 && confIt->value.IsString()) {
string str = confIt->value.GetString();
strcpy(email, str.length()<=40 ? str.c_str() : "email too long");
} else if (memberType.compare("desc") == 0 && confIt->value.IsString()) {
string str = confIt->value.GetString();
strcpy(description, str.length()<=64 ? str.c_str() : "description is too long");
} else if (memberType.compare("is_pi_zero") >= 0 && confIt->value.IsBool()) {
is_pizero = confIt->value.GetBool();
} else if (memberType.compare("servers") == 0) {
const Value& serverConf = confIt->value;
if (serverConf.IsObject()) {
const Value& serverValue = serverConf;
Server_t server;
for (Value::ConstMemberIterator srvIt = serverValue.MemberBegin(); srvIt != serverValue.MemberEnd(); ++srvIt) {
string key(srvIt->name.GetString());
if (key.compare("address") == 0 && srvIt->value.IsString()) {
server.address = srvIt->value.GetString();
} else if (key.compare("port") == 0 && srvIt->value.IsUint()) {
server.port = srvIt->value.GetUint();
} else if (key.compare("enabled") == 0 && srvIt->value.IsBool()) {
server.enabled = srvIt->value.GetBool();
}
}
servers.push_back(server);
}
else if (serverConf.IsArray()) {
for (SizeType i = 0; i < serverConf.Size(); i++) {
const Value& serverValue = serverConf[i];
Server_t server;
for (Value::ConstMemberIterator srvIt = serverValue.MemberBegin(); srvIt != serverValue.MemberEnd(); ++srvIt) {
string key(srvIt->name.GetString());
if (key.compare("address") == 0 && srvIt->value.IsString()) {
server.address = srvIt->value.GetString();
} else if (key.compare("port") == 0 && srvIt->value.IsUint()) {
server.port = srvIt->value.GetUint();
} else if (key.compare("enabled") == 0 && srvIt->value.IsBool()) {
server.enabled = srvIt->value.GetBool();
}
}
servers.push_back(server);
}
}
}
}
}
}
}
}
void PrintConfiguration()
{
for (vector<Server_t>::iterator it = servers.begin(); it != servers.end(); ++it) {
printf("server: .address = %s; .port = %hu; .enable = %d\n", it->address.c_str(), it->port, it->enabled);
}
printf("Gateway Configuration\n");
printf(" %s (%s)\n %s\n", platform, email, description);
printf(" Latitude=%.8f\n Longitude=%.8f\n Altitude=%d\n", lat,lon,alt);
printf("Pi Zero? %d\n", is_pizero);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment