kopia lustrzana https://github.com/PiInTheSky/lora-gateway
V1.10.0 - Removed all Habitat/HABHUB support
rodzic
2afab21f05
commit
76638b8c2b
|
@ -1,7 +1,9 @@
|
||||||
Habitat LoRa Gateway
|
Habitat LoRa Gateway
|
||||||
====================
|
====================
|
||||||
|
|
||||||
Part of the LoRa Balloon Tracking System
|
Part of the LoRa Balloon Tracking System. Receives balloon telemetry and uploads to Sondehub and/or MQTT.
|
||||||
|
|
||||||
|
** ALL HABHUB SUPPORT HAS BEEN REMOVED since the server has been decommissioned **
|
||||||
|
|
||||||
Runs on a Raspberry Pi with 1 or 2 RFM98HW modules attached to the SPI port.
|
Runs on a Raspberry Pi with 1 or 2 RFM98HW modules attached to the SPI port.
|
||||||
Also works with other compatible HopeRF and Semtec LoRa devices.
|
Also works with other compatible HopeRF and Semtec LoRa devices.
|
||||||
|
@ -92,8 +94,7 @@ Configuration
|
||||||
The configuration is in the file gateway.txt. Example:
|
The configuration is in the file gateway.txt. Example:
|
||||||
|
|
||||||
tracker=M0RPI
|
tracker=M0RPI
|
||||||
EnableHabitat=N
|
EnableSondehub=Y
|
||||||
EnableSondehub=N
|
|
||||||
EnableSSDV=Y
|
EnableSSDV=Y
|
||||||
LogTelemetry=Y
|
LogTelemetry=Y
|
||||||
LogPackets=Y
|
LogPackets=Y
|
||||||
|
|
|
@ -10,15 +10,13 @@ Antenna=Your antenna
|
||||||
|
|
||||||
##### Config Options #####
|
##### Config Options #####
|
||||||
|
|
||||||
EnableHabitat=Y
|
EnableSondehub=Y
|
||||||
EnableSSDV=Y
|
EnableSSDV=Y
|
||||||
JPGFolder=ssdv
|
JPGFolder=ssdv
|
||||||
LogTelemetry=Y
|
LogTelemetry=Y
|
||||||
LogPackets=Y
|
LogPackets=Y
|
||||||
CallingTimeout=60
|
CallingTimeout=60
|
||||||
ServerPort=6004
|
ServerPort=6004
|
||||||
#SMSFolder=./
|
|
||||||
EnableDev=N
|
|
||||||
|
|
||||||
NetworkLED=22
|
NetworkLED=22
|
||||||
InternetLED=23
|
InternetLED=23
|
||||||
|
|
58
gateway.c
58
gateway.c
|
@ -32,7 +32,6 @@
|
||||||
#include "base64.h"
|
#include "base64.h"
|
||||||
#include "ssdv.h"
|
#include "ssdv.h"
|
||||||
#include "ftp.h"
|
#include "ftp.h"
|
||||||
#include "habitat.h"
|
|
||||||
#include "sondehub.h"
|
#include "sondehub.h"
|
||||||
#include "mqtt.h"
|
#include "mqtt.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
@ -42,12 +41,11 @@
|
||||||
#include "gateway.h"
|
#include "gateway.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "listener.h"
|
|
||||||
#include "habpack.h"
|
#include "habpack.h"
|
||||||
#include "udpclient.h"
|
#include "udpclient.h"
|
||||||
#include "lifo_buffer.h"
|
#include "lifo_buffer.h"
|
||||||
|
|
||||||
#define VERSION "V1.9.6"
|
#define VERSION "V1.10.0"
|
||||||
bool run = TRUE;
|
bool run = TRUE;
|
||||||
|
|
||||||
// RFM98
|
// RFM98
|
||||||
|
@ -196,7 +194,6 @@ struct TBinaryPacket {
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
lifo_buffer_t Habitat_Upload_Buffer;
|
|
||||||
lifo_buffer_t MQTT_Upload_Buffer;
|
lifo_buffer_t MQTT_Upload_Buffer;
|
||||||
|
|
||||||
// Create pipes for inter proces communication
|
// Create pipes for inter proces communication
|
||||||
|
@ -1143,22 +1140,6 @@ int ProcessTelemetryMessage(int Channel, received_t *Received)
|
||||||
strcpy(Config.LoRaDevices[Channel].Telemetry, startmessage);
|
strcpy(Config.LoRaDevices[Channel].Telemetry, startmessage);
|
||||||
Config.LoRaDevices[Channel].TelemetryCount++;
|
Config.LoRaDevices[Channel].TelemetryCount++;
|
||||||
|
|
||||||
if (Config.EnableHabitat)
|
|
||||||
{
|
|
||||||
// Add to Habitat upload queue
|
|
||||||
received_t *queueReceived = malloc(sizeof(received_t));
|
|
||||||
if(queueReceived != NULL)
|
|
||||||
{
|
|
||||||
strcpy(Received->HabitatString, startmessage);
|
|
||||||
memcpy(queueReceived, Received, sizeof(received_t));
|
|
||||||
/* We haven't copied the linked list, this'll be free()ed later, so remove pointer */
|
|
||||||
queueReceived->Telemetry.habpack_extra = NULL;
|
|
||||||
|
|
||||||
/* Push pointer onto upload queue */
|
|
||||||
lifo_buffer_push(&Habitat_Upload_Buffer, (void *)queueReceived);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Config.EnableMQTT)
|
if (Config.EnableMQTT)
|
||||||
{
|
{
|
||||||
// Add to MQTT upload queue
|
// Add to MQTT upload queue
|
||||||
|
@ -2059,7 +2040,6 @@ void LoadConfigFile(void)
|
||||||
LogMessage( "Tracker = '%s'\n", Config.Tracker );
|
LogMessage( "Tracker = '%s'\n", Config.Tracker );
|
||||||
|
|
||||||
// Enable uploads
|
// Enable uploads
|
||||||
RegisterConfigBoolean(MainSection, -1, "EnableHabitat", &Config.EnableHabitat, NULL);
|
|
||||||
RegisterConfigBoolean(MainSection, -1, "EnableSSDV", &Config.EnableSSDV, NULL);
|
RegisterConfigBoolean(MainSection, -1, "EnableSSDV", &Config.EnableSSDV, NULL);
|
||||||
RegisterConfigBoolean(MainSection, -1, "EnableSondehub", &Config.EnableSondehub, NULL);
|
RegisterConfigBoolean(MainSection, -1, "EnableSondehub", &Config.EnableSondehub, NULL);
|
||||||
|
|
||||||
|
@ -2316,7 +2296,7 @@ WINDOW *InitDisplay(void)
|
||||||
|
|
||||||
char buffer[80];
|
char buffer[80];
|
||||||
|
|
||||||
sprintf( buffer, "LoRa Habitat and SSDV Gateway by M0RPI, M0DNY, M0RJX - " VERSION);
|
sprintf( buffer, "LoRa HAB Sondehub, SSDV and MQTT Gateway by M0RPI, M0DNY, M0RJX - " VERSION);
|
||||||
|
|
||||||
// Title bar
|
// Title bar
|
||||||
mvaddstr(0, ( 80 - strlen( buffer ) ) / 2, buffer );
|
mvaddstr(0, ( 80 - strlen( buffer ) ) / 2, buffer );
|
||||||
|
@ -2656,7 +2636,7 @@ int main( int argc, char **argv )
|
||||||
int ch;
|
int ch;
|
||||||
int LoopPeriod, MSPerLoop;
|
int LoopPeriod, MSPerLoop;
|
||||||
int Channel;
|
int Channel;
|
||||||
pthread_t SSDVThread, FTPThread, NetworkThread, HabitatThread, SondehubThread, ServerThread, TelnetThread, ListenerThread, DataportThread, ChatportThread, MQTTThread;
|
pthread_t SSDVThread, FTPThread, NetworkThread, SondehubThread, ServerThread, TelnetThread, DataportThread, ChatportThread, MQTTThread;
|
||||||
struct TServerInfo JSONInfo, TelnetInfo, DataportInfo, ChatportInfo;
|
struct TServerInfo JSONInfo, TelnetInfo, DataportInfo, ChatportInfo;
|
||||||
|
|
||||||
atexit(bye);
|
atexit(bye);
|
||||||
|
@ -2742,17 +2722,6 @@ int main( int argc, char **argv )
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.EnableHabitat)
|
|
||||||
{
|
|
||||||
lifo_buffer_init(&Habitat_Upload_Buffer, 1024);
|
|
||||||
|
|
||||||
if ( pthread_create (&HabitatThread, NULL, HabitatLoop, NULL))
|
|
||||||
{
|
|
||||||
fprintf( stderr, "Error creating Habitat thread\n" );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Config.EnableMQTT)
|
if (Config.EnableMQTT)
|
||||||
{
|
{
|
||||||
lifo_buffer_init(&MQTT_Upload_Buffer, 1024);
|
lifo_buffer_init(&MQTT_Upload_Buffer, 1024);
|
||||||
|
@ -2843,15 +2812,6 @@ int main( int argc, char **argv )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (( Config.latitude >= -90) && (Config.latitude <= 90) && (Config.longitude >= -180) && (Config.longitude <= 180))
|
|
||||||
{
|
|
||||||
if ( pthread_create( &ListenerThread, NULL, ListenerLoop, NULL ) )
|
|
||||||
{
|
|
||||||
fprintf( stderr, "Error creating Listener thread\n" );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initializes the structure used for storing calling mode settings
|
// Initializes the structure used for storing calling mode settings
|
||||||
callingModeSettings[0].Channel = -1;
|
callingModeSettings[0].Channel = -1;
|
||||||
callingModeSettings[1].Channel = -1;
|
callingModeSettings[1].Channel = -1;
|
||||||
|
@ -3004,9 +2964,6 @@ int main( int argc, char **argv )
|
||||||
LogMessage( "Stopping SSDV thread\n" );
|
LogMessage( "Stopping SSDV thread\n" );
|
||||||
stsv.parent_status = STOPPED;
|
stsv.parent_status = STOPPED;
|
||||||
|
|
||||||
LogMessage( "Stopping Habitat thread\n" );
|
|
||||||
lifo_buffer_quitwait(&Habitat_Upload_Buffer);
|
|
||||||
|
|
||||||
if (Config.EnableSSDV)
|
if (Config.EnableSSDV)
|
||||||
{
|
{
|
||||||
LogMessage( "Waiting for SSDV thread to close ...\n" );
|
LogMessage( "Waiting for SSDV thread to close ...\n" );
|
||||||
|
@ -3014,15 +2971,6 @@ int main( int argc, char **argv )
|
||||||
LogMessage( "SSDV thread closed\n" );
|
LogMessage( "SSDV thread closed\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Config.EnableHabitat)
|
|
||||||
{
|
|
||||||
LogMessage( "Waiting for Habitat thread to close ...\n" );
|
|
||||||
pthread_join( HabitatThread, NULL );
|
|
||||||
LogMessage( "Habitat thread closed\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
// CloseDisplay( mainwin );
|
|
||||||
|
|
||||||
pthread_mutex_destroy( &var );
|
pthread_mutex_destroy( &var );
|
||||||
|
|
||||||
curl_global_cleanup( ); // RJH thread safe
|
curl_global_cleanup( ); // RJH thread safe
|
||||||
|
|
1
global.h
1
global.h
|
@ -115,7 +115,6 @@ struct TConfig
|
||||||
char Tracker[16]; // Callsign or name of receiver
|
char Tracker[16]; // Callsign or name of receiver
|
||||||
double latitude, longitude, altitude; // Receiver's location
|
double latitude, longitude, altitude; // Receiver's location
|
||||||
|
|
||||||
int EnableHabitat;
|
|
||||||
int EnableSSDV;
|
int EnableSSDV;
|
||||||
int EnableHablink;
|
int EnableHablink;
|
||||||
int EnableSondehub;
|
int EnableSondehub;
|
||||||
|
|
228
habitat.c
228
habitat.c
|
@ -1,228 +0,0 @@
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdio.h> // Standard input/output definitions
|
|
||||||
#include <string.h> // String function definitions
|
|
||||||
#include <unistd.h> // UNIX standard function definitions
|
|
||||||
#include <fcntl.h> // File control definitions
|
|
||||||
#include <errno.h> // Error number definitions
|
|
||||||
#include <termios.h> // POSIX terminal control definitions
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#include <wiringPi.h>
|
|
||||||
|
|
||||||
#include "base64.h"
|
|
||||||
#include "habitat.h"
|
|
||||||
#include "global.h"
|
|
||||||
#include "sha256.h"
|
|
||||||
#include "wiringPi.h"
|
|
||||||
#include "gateway.h"
|
|
||||||
#include "lifo_buffer.h"
|
|
||||||
|
|
||||||
extern lifo_buffer_t Habitat_Upload_Buffer;
|
|
||||||
|
|
||||||
extern int telem_pipe_fd[2];
|
|
||||||
extern pthread_mutex_t var;
|
|
||||||
extern void ChannelPrintf( int Channel, int row, int column,
|
|
||||||
const char *format, ... );
|
|
||||||
|
|
||||||
size_t habitat_write_data( void *buffer, size_t size, size_t nmemb, void *userp )
|
|
||||||
{
|
|
||||||
// LogMessage("%s\n", (char *)buffer);
|
|
||||||
return size * nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hash_to_hex( unsigned char *hash, char *line )
|
|
||||||
{
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
for ( idx = 0; idx < 32; idx++ )
|
|
||||||
{
|
|
||||||
sprintf( &( line[idx * 2] ), "%02x", hash[idx] );
|
|
||||||
}
|
|
||||||
line[64] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
bool UploadTelemetryPacket( received_t * t )
|
|
||||||
{
|
|
||||||
CURL *curl;
|
|
||||||
CURLcode res;
|
|
||||||
char curl_error[CURL_ERROR_SIZE];
|
|
||||||
|
|
||||||
/* get a curl handle */
|
|
||||||
curl = curl_easy_init( );
|
|
||||||
if ( curl )
|
|
||||||
{
|
|
||||||
bool result;
|
|
||||||
char url[200];
|
|
||||||
char base64_data[1000];
|
|
||||||
size_t base64_length;
|
|
||||||
SHA256_CTX ctx;
|
|
||||||
unsigned char hash[32];
|
|
||||||
char doc_id[100];
|
|
||||||
char json[1000], now[32], doc_time[32];
|
|
||||||
char Sentence[512];
|
|
||||||
struct curl_slist *headers = NULL;
|
|
||||||
time_t rawtime;
|
|
||||||
struct tm *tm, *doc_tm;
|
|
||||||
int retries;
|
|
||||||
long int http_resp;
|
|
||||||
|
|
||||||
// Get formatted timestamp for now
|
|
||||||
time( &rawtime );
|
|
||||||
tm = gmtime( &rawtime );
|
|
||||||
strftime( now, sizeof( now ), "%Y-%0m-%0dT%H:%M:%SZ", tm );
|
|
||||||
|
|
||||||
// Get formatted timestamp for doc timestamp
|
|
||||||
doc_tm = gmtime( &t->Metadata.Timestamp );
|
|
||||||
strftime( doc_time, sizeof( doc_time ), "%Y-%0m-%0dT%H:%M:%SZ", doc_tm );
|
|
||||||
|
|
||||||
// Grab current telemetry string and append a linefeed
|
|
||||||
sprintf(Sentence, "%s\n", t->HabitatString);
|
|
||||||
|
|
||||||
// Convert sentence to base64
|
|
||||||
base64_encode( Sentence, strlen( Sentence ), &base64_length,
|
|
||||||
base64_data );
|
|
||||||
base64_data[base64_length] = '\0';
|
|
||||||
|
|
||||||
// Take SHA256 hash of the base64 version and express as hex. This will be the document ID
|
|
||||||
sha256_init( &ctx );
|
|
||||||
sha256_update( &ctx, base64_data, base64_length );
|
|
||||||
sha256_final( &ctx, hash );
|
|
||||||
hash_to_hex( hash, doc_id );
|
|
||||||
|
|
||||||
// Create json with the base64 data in hex, the tracker callsign and the current timestamp
|
|
||||||
sprintf( json,
|
|
||||||
"{\"data\": {\"_raw\": \"%s\"},\"receivers\": {\"%s\": {\"time_created\": \"%s\",\"time_uploaded\": \"%s\",\"rig_info\": {\"frequency\":%.0f}}}}",
|
|
||||||
base64_data, Config.Tracker, doc_time, now, (t->Metadata.Frequency + t->Metadata.FrequencyError) * 1000000 );
|
|
||||||
|
|
||||||
// Set the URL that is about to receive our PUT
|
|
||||||
sprintf( url, "http://habitat.habhub.org/habitat/_design/payload_telemetry/_update/add_listener/%s", doc_id);
|
|
||||||
|
|
||||||
// So that the response to the curl PUT doesn't mess up my finely crafted display!
|
|
||||||
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, habitat_write_data );
|
|
||||||
|
|
||||||
// Set the timeout
|
|
||||||
curl_easy_setopt( curl, CURLOPT_TIMEOUT, 15 );
|
|
||||||
|
|
||||||
// RJH capture http errors and report
|
|
||||||
// curl_easy_setopt( curl, CURLOPT_FAILONERROR, 1 );
|
|
||||||
curl_easy_setopt( curl, CURLOPT_ERRORBUFFER, curl_error );
|
|
||||||
|
|
||||||
// Avoid curl library bug that happens if above timeout occurs (sigh)
|
|
||||||
curl_easy_setopt( curl, CURLOPT_NOSIGNAL, 1 );
|
|
||||||
|
|
||||||
// Set the headers
|
|
||||||
headers = NULL;
|
|
||||||
headers = curl_slist_append(headers, "Accept: application/json");
|
|
||||||
headers = curl_slist_append(headers, "Content-Type: application/json");
|
|
||||||
headers = curl_slist_append(headers, "charsets: utf-8" );
|
|
||||||
|
|
||||||
// PUT to http://habitat.habhub.org/habitat/_design/payload_telemetry/_update/add_listener/<doc_id> with content-type application/json
|
|
||||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "PUT");
|
|
||||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json);
|
|
||||||
|
|
||||||
retries = 0;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// Perform the request, res will get the return code
|
|
||||||
res = curl_easy_perform( curl );
|
|
||||||
|
|
||||||
// Check for errors
|
|
||||||
if ( res == CURLE_OK )
|
|
||||||
{
|
|
||||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_resp);
|
|
||||||
if (http_resp != 201 && http_resp != 403 && http_resp != 409)
|
|
||||||
{
|
|
||||||
LogMessage("Unexpected HTTP response %ld for URL '%s'\n", http_resp, url);
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Everything performing nominally (even if we didn't successfully insert this time) */
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
http_resp = 0;
|
|
||||||
LogMessage("Failed for URL '%s'\n", url);
|
|
||||||
LogMessage("curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
|
|
||||||
LogMessage("error: %s\n", curl_error);
|
|
||||||
/* Likely a network error, so return false to requeue */
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (http_resp == 409)
|
|
||||||
{
|
|
||||||
// conflict between us and another uploader at the same time
|
|
||||||
// wait for a random period before trying again
|
|
||||||
delay(random() & 255); // 0-255 ms
|
|
||||||
}
|
|
||||||
} while ((http_resp == 409) && (++retries < 5));
|
|
||||||
|
|
||||||
// always cleanup
|
|
||||||
curl_slist_free_all( headers );
|
|
||||||
curl_easy_cleanup( curl );
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* CURL error, return false so we requeue */
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void *HabitatLoop( void *vars )
|
|
||||||
{
|
|
||||||
if ( Config.EnableHabitat )
|
|
||||||
{
|
|
||||||
received_t *dequeued_telemetry_ptr;
|
|
||||||
|
|
||||||
// Keep looping until the parent quits
|
|
||||||
while ( true )
|
|
||||||
{
|
|
||||||
dequeued_telemetry_ptr = lifo_buffer_waitpop(&Habitat_Upload_Buffer);
|
|
||||||
|
|
||||||
if(dequeued_telemetry_ptr != NULL)
|
|
||||||
{
|
|
||||||
ChannelPrintf( dequeued_telemetry_ptr->Metadata.Channel, 6, 1, "Habitat (%d queued)", lifo_buffer_queued(&Habitat_Upload_Buffer) );
|
|
||||||
|
|
||||||
if(UploadTelemetryPacket( dequeued_telemetry_ptr ))
|
|
||||||
{
|
|
||||||
ChannelPrintf( dequeued_telemetry_ptr->Metadata.Channel, 6, 1, " " );
|
|
||||||
free(dequeued_telemetry_ptr);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Network / CURL Error, requeue packet */
|
|
||||||
ChannelPrintf( dequeued_telemetry_ptr->Metadata.Channel, 6, 1, "Habitat Net Error! " );
|
|
||||||
|
|
||||||
if(!lifo_buffer_requeue(&Habitat_Upload_Buffer, dequeued_telemetry_ptr))
|
|
||||||
{
|
|
||||||
/* Requeue failed, drop packet */
|
|
||||||
free(dequeued_telemetry_ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* NULL returned: We've been asked to quit */
|
|
||||||
/* Don't bother free()ing stuff, as application is quitting */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
void *HabitatLoop( void *some_void_ptr );
|
|
122
listener.c
122
listener.c
|
@ -1,122 +0,0 @@
|
||||||
#include <stdio.h>
|
|
||||||
#include <wiringPi.h>
|
|
||||||
#include <curl/curl.h>
|
|
||||||
|
|
||||||
#include "global.h"
|
|
||||||
#include "gateway.h"
|
|
||||||
|
|
||||||
#define LISTENER_UPDATE_INTERVAL 30 // Minutes
|
|
||||||
#define LISTENER_LOOP_SLEEP 1000 // Milliseconds
|
|
||||||
|
|
||||||
size_t write_data( void *buffer, size_t size, size_t nmemb, void *userp )
|
|
||||||
{
|
|
||||||
return size * nmemb;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UploadListenerTelemetry( char *callsign, time_t gps_time, float gps_lat, float gps_lon, char *radio, char *antenna )
|
|
||||||
{
|
|
||||||
char time_string[20];
|
|
||||||
struct tm * time_info;
|
|
||||||
|
|
||||||
time_info = localtime (&gps_time);
|
|
||||||
strftime(time_string, sizeof(time_string), "%H:%M:%S", time_info);
|
|
||||||
|
|
||||||
if ( Config.EnableHabitat )
|
|
||||||
{
|
|
||||||
CURL *curl;
|
|
||||||
CURLcode res;
|
|
||||||
char PostFields[300];
|
|
||||||
char JsonData[200];
|
|
||||||
|
|
||||||
/* In windows, this will init the winsock stuff */
|
|
||||||
|
|
||||||
/* get a curl handle */
|
|
||||||
curl = curl_easy_init( );
|
|
||||||
if ( curl )
|
|
||||||
{
|
|
||||||
// So that the response to the curl POST doesn;'t mess up my finely crafted display!
|
|
||||||
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, write_data );
|
|
||||||
|
|
||||||
// Set the URL that is about to receive our POST
|
|
||||||
curl_easy_setopt( curl, CURLOPT_URL,
|
|
||||||
"http://habitat.habhub.org/transition/listener_telemetry" );
|
|
||||||
|
|
||||||
// Now specify the POST data
|
|
||||||
sprintf( JsonData, "{\"latitude\": %f, \"longitude\": %f}",
|
|
||||||
gps_lat, gps_lon );
|
|
||||||
sprintf( PostFields, "callsign=%s&time=%d&data=%s", callsign,
|
|
||||||
(int)gps_time, JsonData );
|
|
||||||
curl_easy_setopt( curl, CURLOPT_POSTFIELDS, PostFields );
|
|
||||||
|
|
||||||
// Perform the request, res will get the return code
|
|
||||||
res = curl_easy_perform( curl );
|
|
||||||
|
|
||||||
// Check for errors
|
|
||||||
if ( res == CURLE_OK )
|
|
||||||
{
|
|
||||||
LogMessage( "Uploaded listener %s %s,%f,%f\n",
|
|
||||||
callsign, time_string, gps_lat, gps_lon );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogMessage( "curl_easy_perform() failed: %s\n",
|
|
||||||
curl_easy_strerror( res ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// always cleanup
|
|
||||||
curl_easy_cleanup( curl );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In windows, this will init the winsock stuff */
|
|
||||||
|
|
||||||
/* get a curl handle */
|
|
||||||
curl = curl_easy_init( );
|
|
||||||
if ( curl )
|
|
||||||
{
|
|
||||||
// So that the response to the curl POST doesn;'t mess up my finely crafted display!
|
|
||||||
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, write_data );
|
|
||||||
|
|
||||||
// Set the URL that is about to receive our POST
|
|
||||||
curl_easy_setopt( curl, CURLOPT_URL,
|
|
||||||
"http://habitat.habhub.org/transition/listener_information" );
|
|
||||||
|
|
||||||
// Now specify the POST data
|
|
||||||
sprintf( JsonData, "{\"radio\": \"%s\", \"antenna\": \"%s\"}",
|
|
||||||
radio, antenna );
|
|
||||||
sprintf( PostFields, "callsign=%s&time=%d&data=%s", callsign, (int)gps_time, JsonData );
|
|
||||||
curl_easy_setopt( curl, CURLOPT_POSTFIELDS, PostFields );
|
|
||||||
|
|
||||||
// Perform the request, res will get the return code
|
|
||||||
res = curl_easy_perform( curl );
|
|
||||||
|
|
||||||
// Check for errors
|
|
||||||
if ( res != CURLE_OK )
|
|
||||||
{
|
|
||||||
LogMessage( "curl_easy_perform() failed: %s\n",
|
|
||||||
curl_easy_strerror( res ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
// always cleanup
|
|
||||||
curl_easy_cleanup( curl );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void *ListenerLoop(void *ptr)
|
|
||||||
{
|
|
||||||
(void) ptr;
|
|
||||||
|
|
||||||
uint32_t LoopPeriod = LISTENER_UPDATE_INTERVAL*60*1000; // So we upload listener at start, as well as every LISTENER_UPDATE_INTERVAL minutes thereafter
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
if (LoopPeriod > LISTENER_UPDATE_INTERVAL*60*1000)
|
|
||||||
{
|
|
||||||
UploadListenerTelemetry( Config.Tracker, time(NULL), Config.latitude, Config.longitude, Config.radio, Config.antenna );
|
|
||||||
LoopPeriod = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
delay(LISTENER_LOOP_SLEEP);
|
|
||||||
LoopPeriod += LISTENER_LOOP_SLEEP;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
void *ListenerLoop(void *ptr);
|
|
Ładowanie…
Reference in New Issue