kopia lustrzana https://github.com/PiInTheSky/lora-gateway
204 wiersze
5.7 KiB
C
204 wiersze
5.7 KiB
C
#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 <dirent.h>
|
|
#include <math.h>
|
|
#include <pthread.h>
|
|
#include <curl/curl.h>
|
|
#include <wiringPi.h>
|
|
|
|
#include "urlencode.h"
|
|
#include "base64.h"
|
|
#include "ssdv.h"
|
|
#include "gateway.h"
|
|
#include "global.h"
|
|
|
|
extern int ssdv_pipe_fd[2];
|
|
extern pthread_mutex_t var;
|
|
|
|
size_t
|
|
write_ssdv_data( void *buffer, size_t size, size_t nmemb, void *userp )
|
|
{
|
|
return size * nmemb;
|
|
}
|
|
|
|
|
|
void
|
|
ConvertStringToHex( unsigned char *Target, unsigned char *Source, int Length )
|
|
{
|
|
const char Hex[16] = "0123456789ABCDEF";
|
|
int i;
|
|
|
|
for ( i = 0; i < Length; i++ )
|
|
{
|
|
*Target++ = Hex[Source[i] >> 4];
|
|
*Target++ = Hex[Source[i] & 0x0F];
|
|
}
|
|
|
|
*Target++ = '\0';
|
|
}
|
|
|
|
|
|
void
|
|
UploadImagePacket( ssdv_t * s, unsigned int packets )
|
|
{
|
|
CURL *curl;
|
|
CURLcode res;
|
|
char curl_error[CURL_ERROR_SIZE];
|
|
char base64_data[512], json[32768], packet_json[1000];
|
|
struct curl_slist *headers = NULL;
|
|
size_t base64_length;
|
|
char now[32];
|
|
time_t rawtime;
|
|
struct tm *tm;
|
|
char url[250];
|
|
|
|
/* 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_ssdv_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 );
|
|
|
|
// Get formatted timestamp
|
|
time( &rawtime );
|
|
tm = gmtime( &rawtime );
|
|
strftime( now, sizeof( now ), "%Y-%0m-%0dT%H:%M:%SZ", tm );
|
|
|
|
int PacketIndex;
|
|
|
|
// Create json with the base64 data in hex, the tracker callsign and the current timestamp
|
|
strcpy( json, "{\"type\": \"packets\",\"packets\":[" );
|
|
|
|
for (PacketIndex = 0; PacketIndex < packets; PacketIndex++)
|
|
{
|
|
base64_encode(s[PacketIndex].SSDV_Packet, 256, &base64_length, base64_data);
|
|
base64_data[base64_length] = '\0';
|
|
|
|
sprintf(packet_json,
|
|
"{\"type\": \"packet\", \"packet\": \"%s\", \"encoding\": \"base64\", \"received\": \"%s\", \"receiver\": \"%s\"}%s",
|
|
base64_data, now, Config.Tracker,
|
|
PacketIndex == ( packets - 1 ) ? "" : ",");
|
|
strcat(json, packet_json);
|
|
}
|
|
strcat(json, "]}");
|
|
|
|
// LogTelemetryPacket(json);
|
|
|
|
strcpy( url, "http://ssdv.habhub.org/api/v0/packets" );
|
|
|
|
// 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" );
|
|
|
|
curl_easy_setopt( curl, CURLOPT_HTTPHEADER, headers );
|
|
curl_easy_setopt( curl, CURLOPT_URL, url );
|
|
|
|
curl_easy_setopt( curl, CURLOPT_CUSTOMREQUEST, "POST" );
|
|
curl_easy_setopt( curl, CURLOPT_POSTFIELDS, json );
|
|
|
|
// Perform the request, res will get the return code
|
|
res = curl_easy_perform( curl );
|
|
|
|
/* Check for errors */
|
|
if ( res == CURLE_OK )
|
|
{
|
|
}
|
|
else
|
|
{
|
|
LogMessage( "Failed for URL '%s'\n", url );
|
|
LogMessage( "curl_easy_perform() failed: %s\n",
|
|
curl_easy_strerror( res ) );
|
|
LogMessage( "error: %s\n", curl_error );
|
|
}
|
|
|
|
/* always cleanup */
|
|
curl_slist_free_all( headers ); // RJH Added this from habitat.c as was missing
|
|
curl_easy_cleanup( curl );
|
|
}
|
|
}
|
|
|
|
void *SSDVLoop( void *vars )
|
|
{
|
|
if ( Config.EnableSSDV )
|
|
{
|
|
const int max_packets = 51;
|
|
thread_shared_vars_t *stsv;
|
|
stsv = vars;
|
|
ssdv_t s[max_packets];
|
|
unsigned int j = 0;
|
|
unsigned int packets = 0;
|
|
unsigned long total_packets = 0;
|
|
|
|
// Keep looping until the parent quits and there are no more packets to
|
|
// send to ssdv.
|
|
while ( ( stsv->parent_status == RUNNING ) || ( packets > 0 ) )
|
|
{
|
|
|
|
if ( stsv->packet_count > total_packets )
|
|
{
|
|
packets = read( ssdv_pipe_fd[0], &s[j], sizeof( ssdv_t ) );
|
|
}
|
|
else
|
|
{
|
|
packets = 0;
|
|
|
|
// If we have have a rollover after processing 4294967295 packets
|
|
if ( stsv->packet_count < total_packets )
|
|
total_packets = 0;
|
|
|
|
}
|
|
|
|
if ( packets )
|
|
{
|
|
j++;
|
|
total_packets++;
|
|
}
|
|
|
|
if ( j == 50 || ( ( packets == 0 ) && ( j > 0 ) ) )
|
|
{
|
|
ChannelPrintf(s[0].Channel, 6, 16, "SSDV");
|
|
|
|
UploadImagePacket( s, j );
|
|
|
|
ChannelPrintf(s[0].Channel, 6, 16, " ");
|
|
|
|
j = 0;
|
|
|
|
packets = 0;
|
|
}
|
|
delay(100); // Don't eat too much CPU
|
|
}
|
|
}
|
|
|
|
close( ssdv_pipe_fd[0] );
|
|
close( ssdv_pipe_fd[1] );
|
|
|
|
LogMessage( "SSDV thread closing\n" );
|
|
|
|
return NULL;
|
|
|
|
}
|