kopia lustrzana https://github.com/PiInTheSky/lora-gateway
Merge branch 'master' of https://github.com/PiInTheSky/lora-gateway
commit
3c8a3a7f39
|
@ -0,0 +1,30 @@
|
|||
tracker=LCARS
|
||||
EnableHabitat=N
|
||||
EnableSSDV=N
|
||||
LogTelemetry=Y
|
||||
LogPackets=Y
|
||||
CallingTimeout=60
|
||||
ServerPort=6004
|
||||
Latitude=51.950230
|
||||
Longitude=-2.544500
|
||||
Antenna=MagMount
|
||||
JPGFolder=SSDV
|
||||
EnableDev=N
|
||||
|
||||
#NetworkLED=21
|
||||
#InternetLED=22
|
||||
#ActivityLED_0=23
|
||||
#ActivityLED_1=24
|
||||
|
||||
frequency_0=434.450000
|
||||
mode_0=1
|
||||
#mode_0=1
|
||||
DIO0_0=6
|
||||
DIO5_0=5
|
||||
AFC_0=N
|
||||
|
||||
frequency_1=869.850000
|
||||
mode_1=3
|
||||
DIO0_1=27
|
||||
DIO5_1=26
|
||||
AFC_1=N
|
21
README.md
21
README.md
|
@ -226,6 +226,27 @@ Many thanks to David Brooke for coding this feature and the AFC.
|
|||
Change History
|
||||
==============
|
||||
|
||||
14/09/2016 - V1.8.3
|
||||
-------------------
|
||||
|
||||
Save boolean settings sent by client
|
||||
Use of atexit() so ncurses is always closed properly on exit
|
||||
Added an exit-with-message function
|
||||
Fixed errors where threads were closed on exit even if they hadn't been created (i.e. their functions disabled in the config)
|
||||
Consistent RSSI calculations that take HF/LF port into account
|
||||
|
||||
|
||||
14/09/2016 - V1.8.2
|
||||
-------------------
|
||||
|
||||
Configuration all in a generic array
|
||||
Generic code to read/write config array/file
|
||||
Send configuration values to JSON client
|
||||
Accept commands and new config settings from client
|
||||
Fixed SMS folder error
|
||||
Fixed LDRO setting
|
||||
|
||||
|
||||
03/09/2016 - V1.8
|
||||
-----------------
|
||||
|
||||
|
|
|
@ -0,0 +1,394 @@
|
|||
//// Generalised configuration manager
|
||||
// Generalised configuration manager
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "config.h"
|
||||
|
||||
#define MAX_SECTIONS 16
|
||||
#define SECTION_LENGTH 21
|
||||
#define MAX_SETTINGS 256
|
||||
|
||||
char *ConfigFilename;
|
||||
|
||||
int SectionCount=0;
|
||||
char Sections[MAX_SECTIONS][32];
|
||||
|
||||
int SettingsCount=0;
|
||||
struct TSetting Settings[MAX_SETTINGS];
|
||||
|
||||
void RegisterConfigFile(char *Filename)
|
||||
{
|
||||
ConfigFilename = Filename;
|
||||
}
|
||||
|
||||
int RegisterConfigSection(char *Section)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<SectionCount; i++)
|
||||
{
|
||||
if (strcmp(Section, Sections[i]) == 0)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (SectionCount < MAX_SECTIONS)
|
||||
{
|
||||
strcpy(Sections[SectionCount], Section);
|
||||
return SectionCount++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int FindSettingIndex(int SectionIndex, int Index, char *Name)
|
||||
{
|
||||
// Return existing position for this setting, if it's there, or allocate a new one
|
||||
int i;
|
||||
|
||||
for (i=0; i<SettingsCount; i++)
|
||||
{
|
||||
if ((Settings[i].SectionIndex == SectionIndex) &&
|
||||
(Settings[i].Index == Index) &&
|
||||
(strcmp(Settings[i].ValueName, Name) == 0))
|
||||
{
|
||||
// Found
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
// Room for one more on top ?
|
||||
if (SettingsCount < MAX_SETTINGS)
|
||||
{
|
||||
Settings[SettingsCount].SectionIndex = SectionIndex;
|
||||
Settings[SettingsCount].Index = Index;
|
||||
strcpy(Settings[SettingsCount].ValueName, Name);
|
||||
|
||||
return SettingsCount++;
|
||||
}
|
||||
|
||||
// Full or can't add, and not found, so return "fail"
|
||||
return -1;
|
||||
}
|
||||
|
||||
int RegisterConfigDouble(int SectionIndex, int Index, char *Name, double *DoubleValuePtr, void (Callback)(int))
|
||||
{
|
||||
if ((SectionIndex >= 0) && (SectionIndex < SectionCount))
|
||||
{
|
||||
int SettingIndex;
|
||||
|
||||
if ((SettingIndex = FindSettingIndex(SectionIndex, Index, Name)) >= 0)
|
||||
{
|
||||
Settings[SettingIndex].SectionIndex = SectionIndex;
|
||||
Settings[SettingIndex].Index = Index;
|
||||
strcpy(Settings[SettingIndex].ValueName, Name);
|
||||
Settings[SettingIndex].SettingType = stDouble;
|
||||
Settings[SettingIndex].DoubleValuePtr = DoubleValuePtr;
|
||||
// Settings[SettingIndex].Callback = Callback;
|
||||
|
||||
ReadConfigValue(SettingIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RegisterConfigInteger(int SectionIndex, int Index, char *Name, int *IntValuePtr, void (Callback)(int))
|
||||
{
|
||||
if ((SectionIndex >= 0) && (SectionIndex < SectionCount))
|
||||
{
|
||||
int SettingIndex;
|
||||
|
||||
if ((SettingIndex = FindSettingIndex(SectionIndex, Index, Name)) >= 0)
|
||||
{
|
||||
Settings[SettingIndex].SectionIndex = SectionIndex;
|
||||
Settings[SettingIndex].Index = Index;
|
||||
strcpy(Settings[SettingIndex].ValueName, Name);
|
||||
Settings[SettingIndex].SettingType = stInteger;
|
||||
Settings[SettingIndex].IntValuePtr = IntValuePtr;
|
||||
// Settings[SettingIndex].Callback = Callback;
|
||||
|
||||
return ReadConfigValue(SettingIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RegisterConfigBoolean(int SectionIndex, int Index, char *Name, int *BoolValuePtr, void (Callback)(int))
|
||||
{
|
||||
if ((SectionIndex >= 0) && (SectionIndex < SectionCount))
|
||||
{
|
||||
int SettingIndex;
|
||||
|
||||
if ((SettingIndex = FindSettingIndex(SectionIndex, Index, Name)) >= 0)
|
||||
{
|
||||
Settings[SettingIndex].SectionIndex = SectionIndex;
|
||||
Settings[SettingIndex].Index = Index;
|
||||
strcpy(Settings[SettingIndex].ValueName, Name);
|
||||
Settings[SettingIndex].SettingType = stBoolean;
|
||||
Settings[SettingIndex].IntValuePtr = BoolValuePtr;
|
||||
// Settings[SettingIndex].Callback = Callback;
|
||||
|
||||
return ReadConfigValue(SettingIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RegisterConfigString(int SectionIndex, int Index, char *Name, char *StringValuePtr, int MaxValueLength, void (Callback)(int))
|
||||
{
|
||||
if ((SectionIndex >= 0) && (SectionIndex < SectionCount))
|
||||
{
|
||||
int SettingIndex;
|
||||
|
||||
if ((SettingIndex = FindSettingIndex(SectionIndex, Index, Name)) >= 0)
|
||||
{
|
||||
Settings[SettingIndex].SectionIndex = SectionIndex;
|
||||
Settings[SettingIndex].Index = Index;
|
||||
strcpy(Settings[SettingIndex].ValueName, Name);
|
||||
Settings[SettingIndex].SettingType = stString;
|
||||
Settings[SettingIndex].StringValuePtr = StringValuePtr;
|
||||
Settings[SettingIndex].MaxValueLength = MaxValueLength;
|
||||
// Settings[SettingIndex].Callback = Callback;
|
||||
|
||||
return ReadConfigValue(SettingIndex);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GetLongName(int SettingIndex, char *ValueName, int Length)
|
||||
{
|
||||
struct TSetting *Setting;
|
||||
|
||||
Setting = &(Settings[SettingIndex]);
|
||||
|
||||
// Build string to look for in file
|
||||
if (Setting->Index >= 0)
|
||||
{
|
||||
sprintf(ValueName, "%s%s_%d", Sections[Setting->SectionIndex], Setting->ValueName, Setting->Index);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf(ValueName, "%s%s", Sections[Setting->SectionIndex], Setting->ValueName);
|
||||
}
|
||||
}
|
||||
|
||||
int ReadConfigValue(int SettingIndex)
|
||||
{
|
||||
char line[100], ValueName[64], *token, *temp;
|
||||
struct TSetting *Setting;
|
||||
FILE *fp;
|
||||
|
||||
GetLongName(SettingIndex, ValueName, sizeof(ValueName));
|
||||
|
||||
Setting = &(Settings[SettingIndex]);
|
||||
|
||||
if ((fp = fopen(ConfigFilename, "r" ) ) != NULL)
|
||||
{
|
||||
while (fgets(line, sizeof(line), fp) != NULL)
|
||||
{
|
||||
line[strcspn(line, "\r")] = '\0'; // Get rid of CR if there is one
|
||||
|
||||
token = strtok(line, "=" );
|
||||
if (strcasecmp(ValueName, token ) == 0)
|
||||
{
|
||||
temp = strtok( NULL, "\n");
|
||||
|
||||
switch (Setting->SettingType)
|
||||
{
|
||||
case stString:
|
||||
strncpy(Setting->StringValuePtr, temp, Setting->MaxValueLength-1);
|
||||
break;
|
||||
|
||||
case stInteger:
|
||||
*(Setting->IntValuePtr) = atoi(temp);
|
||||
break;
|
||||
|
||||
case stDouble:
|
||||
// So we can handle bandwidths such as "20K8", convert "K" to decimal point
|
||||
if (strchr(temp, 'K') != NULL)
|
||||
{
|
||||
*strchr(temp, 'K') = '.';
|
||||
}
|
||||
*(Setting->DoubleValuePtr) = atof(temp);
|
||||
break;
|
||||
|
||||
case stBoolean:
|
||||
*(Setting->IntValuePtr) = (*temp == '1') || (*temp == 'Y') || (*temp == 'y') || (*temp == 't') || (*temp == 'T');
|
||||
break;
|
||||
|
||||
case stNone:
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FindSettingByName(char *ValueNameToFind)
|
||||
{
|
||||
char ValueName[64];
|
||||
int SettingIndex;
|
||||
|
||||
for (SettingIndex=0; SettingIndex<SettingsCount; SettingIndex++)
|
||||
{
|
||||
GetLongName(SettingIndex, ValueName, sizeof(ValueName));
|
||||
|
||||
if (strcasecmp(ValueNameToFind, ValueName) == 0)
|
||||
{
|
||||
// Found
|
||||
return SettingIndex;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void SaveConfigFile(void)
|
||||
{
|
||||
char line[100], original[100], *token;
|
||||
FILE *src, *dest;
|
||||
struct TSetting *Setting;
|
||||
char *TempFileName="gateway.txt.tmp";
|
||||
char *SavedFileName="gateway.txt.old";
|
||||
int SettingIndex;
|
||||
|
||||
if ((src = fopen(ConfigFilename, "r" ) ) != NULL)
|
||||
{
|
||||
if ((dest = fopen(TempFileName, "w" ) ) != NULL)
|
||||
{
|
||||
while (fgets(line, sizeof(line), src) != NULL)
|
||||
{
|
||||
line[strcspn(line, "\r")] = '\0'; // Get rid of CR if there is one
|
||||
strcpy(original, line);
|
||||
|
||||
token = strtok(line, "=" ); // Name of setting
|
||||
|
||||
if (token == NULL)
|
||||
{
|
||||
// Write old line
|
||||
fputs(original, dest);
|
||||
}
|
||||
else if ((SettingIndex = FindSettingByName(token)) >= 0)
|
||||
{
|
||||
// Found, so write new value instead of old one
|
||||
// tracker=M0RPI/5
|
||||
Setting = &(Settings[SettingIndex]);
|
||||
switch (Setting->SettingType)
|
||||
{
|
||||
case stString:
|
||||
fprintf(dest, "%s=%s\n", token, Setting->StringValuePtr);
|
||||
break;
|
||||
|
||||
case stInteger:
|
||||
fprintf(dest, "%s=%d\n", token, *(Setting->IntValuePtr));
|
||||
break;
|
||||
|
||||
case stDouble:
|
||||
fprintf(dest, "%s=%lf\n", token, *(Setting->DoubleValuePtr));
|
||||
break;
|
||||
|
||||
case stBoolean:
|
||||
fprintf(dest, "%s=%c\n", token, *(Setting->IntValuePtr) ? 'Y' : 'N');
|
||||
break;
|
||||
|
||||
case stNone:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Just write old line
|
||||
fputs(original, dest);
|
||||
}
|
||||
}
|
||||
fclose(dest);
|
||||
|
||||
// Now save original file and replace with new one
|
||||
remove(SavedFileName);
|
||||
rename(ConfigFilename, SavedFileName);
|
||||
rename(TempFileName, ConfigFilename);
|
||||
}
|
||||
fclose(src);
|
||||
}
|
||||
}
|
||||
|
||||
void SetConfigValue(char *Setting, char *Value)
|
||||
{
|
||||
int SettingIndex;
|
||||
|
||||
if ((SettingIndex = FindSettingByName(Setting)) >= 0)
|
||||
{
|
||||
switch (Settings[SettingIndex].SettingType)
|
||||
{
|
||||
case stString:
|
||||
strncpy(Settings[SettingIndex].StringValuePtr, Value, Settings[SettingIndex].MaxValueLength-1);
|
||||
break;
|
||||
|
||||
case stInteger:
|
||||
*Settings[SettingIndex].IntValuePtr = atoi(Value);
|
||||
break;
|
||||
|
||||
case stDouble:
|
||||
*Settings[SettingIndex].DoubleValuePtr = atof(Value);
|
||||
break;
|
||||
|
||||
case stBoolean:
|
||||
*Settings[SettingIndex].IntValuePtr = Value[strcspn(Value, "1YyTt")];
|
||||
break;
|
||||
|
||||
case stNone:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int SettingAsString(int SettingIndex, char *SettingName, int SettingNameSize, char *SettingValue, int SettingValueSize)
|
||||
{
|
||||
if ((SettingIndex >= 0) && (SettingIndex < SettingsCount))
|
||||
{
|
||||
// strncpy(SettingName, Settings[Index].ValueName, SettingNameSize);
|
||||
|
||||
GetLongName(SettingIndex, SettingName, sizeof(SettingNameSize));
|
||||
|
||||
switch (Settings[SettingIndex].SettingType)
|
||||
{
|
||||
case stString:
|
||||
snprintf(SettingValue, SettingValueSize-1, "\"%s\"", Settings[SettingIndex].StringValuePtr);
|
||||
break;
|
||||
|
||||
case stInteger:
|
||||
snprintf(SettingValue, SettingValueSize-1, "%d", *Settings[SettingIndex].IntValuePtr);
|
||||
break;
|
||||
|
||||
case stDouble:
|
||||
snprintf(SettingValue, SettingValueSize-1, "%lf", *Settings[SettingIndex].DoubleValuePtr);
|
||||
break;
|
||||
|
||||
case stBoolean:
|
||||
snprintf(SettingValue, SettingValueSize-1, "%d", *Settings[SettingIndex].IntValuePtr ? 1 : 0);
|
||||
break;
|
||||
|
||||
case stNone:
|
||||
strncpy(SettingValue, "\"?\"", SettingValueSize);
|
||||
break;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
typedef enum {stNone, stString, stInteger, stDouble, stBoolean} TSettingType;
|
||||
|
||||
struct TSetting
|
||||
{
|
||||
int SectionIndex;
|
||||
int Index;
|
||||
char ValueName[32];
|
||||
TSettingType SettingType;
|
||||
char *StringValuePtr;
|
||||
int *IntValuePtr;
|
||||
double *DoubleValuePtr;
|
||||
int MaxValueLength;
|
||||
// void (Callback)(int);
|
||||
};
|
||||
|
||||
void RegisterConfigFile(char *Filename);
|
||||
int RegisterConfigSection(char *Section);
|
||||
int RegisterConfigString(int SectionIndex, int Index, char *Name, char *StringValuePtr, int MaxValueLength, void (Callback)(int));
|
||||
int RegisterConfigInteger(int SectionIndex, int Index, char *Name, int *IntValuePtr, void (Callback)(int));
|
||||
int RegisterConfigDouble(int SectionIndex, int Index, char *Name, double *DoubleValuePtr, void (Callback)(int));
|
||||
int RegisterConfigBoolean(int SectionIndex, int Index, char *Name, int *BoolValuePtr, void (Callback)(int));
|
||||
int ReadConfigValue(int SettingIndex);
|
||||
void SetConfigValue(char *Setting, char *Value);
|
||||
int SettingAsString(int SettingIndex, char *SettingName, int SettingNameSize, char *SettingValue, int SettingValueSize);
|
||||
void SaveConfigFile(void);
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
tracker=LCARS
|
||||
EnableHabitat=N
|
||||
EnableSSDV=N
|
||||
LogTelemetry=Y
|
||||
LogPackets=Y
|
||||
CallingTimeout=60
|
||||
ServerPort=6004
|
||||
Latitude=51.950230
|
||||
Longitude=-2.544500
|
||||
Antenna=MagMount
|
||||
JPGFolder=SSDV
|
||||
EnableDev=N
|
||||
|
||||
#NetworkLED=21
|
||||
#InternetLED=22
|
||||
#ActivityLED_0=23
|
||||
#ActivityLED_1=24
|
||||
|
||||
frequency_0=434.450000
|
||||
mode_0=0
|
||||
#frequency_0=434.447
|
||||
#mode_0=1
|
||||
DIO0_0=6
|
||||
DIO5_0=5
|
||||
AFC_0=N
|
||||
|
||||
frequency_1=869.850000
|
||||
mode_1=3
|
||||
#bandwidth_1=125K
|
||||
#implicit_1=n
|
||||
#coding_1=5
|
||||
DIO0_1=27
|
||||
DIO5_1=26
|
||||
AFC_1=N
|
21
global.h
21
global.h
|
@ -11,23 +11,23 @@
|
|||
int HighestPacket;
|
||||
bool Packets[1024];
|
||||
};
|
||||
struct TLoRaDevice
{
|
||||
int InUse;
|
||||
struct TLoRaDevice
{
|
||||
double Frequency;
|
||||
double Bandwidth;
|
||||
double CurrentBandwidth;
|
||||
int InUse;
|
||||
int DIO0;
|
||||
int DIO5;
|
||||
char Frequency[16];
|
||||
double activeFreq;
|
||||
bool AFC;
|
||||
int AFC;
|
||||
int SpeedMode;
|
||||
int Power;
|
||||
int PayloadLength;
|
||||
int ImplicitOrExplicit;
|
||||
int ErrorCoding;
|
||||
int Bandwidth;
|
||||
int SpreadingFactor;
|
||||
int LowDataRateOptimize;
|
||||
int CurrentBandwidth;
|
||||
WINDOW * Window;
|
||||
WINDOW * Window;
|
||||
unsigned int TelemetryCount, SSDVCount, BadCRCCount, UnknownCount;
|
||||
int Sending;
|
||||
char Telemetry[256];
|
||||
|
@ -59,8 +59,8 @@ int UplinkMode;
|
|||
// SSDV Packet Log
|
||||
struct TSSDVPackets SSDVPackets[3];
|
||||
};
|
||||
struct TConfig
{
|
||||
char Tracker[16];
|
||||
struct TConfig
{
char Tracker[16]; // Callsign or name of receiver
|
||||
double latitude, longitude; // Receiver's location
|
||||
int EnableHabitat;
|
||||
int EnableSSDV;
|
||||
int EnableTelemetryLogging;
|
||||
|
@ -75,8 +75,7 @@ int UplinkMode;
|
|||
int NetworkLED;
|
||||
int InternetLED;
|
||||
int ServerPort;
|
||||
float latitude, longitude;
|
||||
char SMSFolder[64];
|
||||
char SMSFolder[64];
|
||||
char antenna[64];
|
||||
int EnableDev;
|
||||
};
|
||||
|
|
|
@ -232,6 +232,7 @@ HabitatLoop( void *vars )
|
|||
total_packets++;
|
||||
|
||||
}
|
||||
delay(100); // Don't eat too much CPU
|
||||
}
|
||||
}
|
||||
|
||||
|
|
112
server.c
112
server.c
|
@ -4,8 +4,8 @@
|
|||
#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 <unistd.h> // UNIX standard function definitions
|
||||
#include <errno.h> // Error number definitions
|
||||
#include <termios.h> // POSIX terminal control definitions
|
||||
#include <stdint.h>
|
||||
|
@ -13,24 +13,80 @@
|
|||
#include <dirent.h>
|
||||
#include <math.h>
|
||||
#include <pthread.h>
|
||||
#include <wiringPi.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "server.h"
|
||||
#include "config.h"
|
||||
#include "global.h"
|
||||
|
||||
extern bool run;
|
||||
extern bool server_closed;
|
||||
|
||||
void ProcessClientLine(int connfd, char *line)
|
||||
{
|
||||
line[strcspn(line, "\r\n")] = '\0'; // Get rid of CR LF
|
||||
|
||||
LogMessage("Received %s from client\n", line);
|
||||
|
||||
if (strchr(line, '=') == NULL)
|
||||
{
|
||||
// Request or command
|
||||
|
||||
if (strcasecmp(line, "settings") == 0)
|
||||
{
|
||||
int Index;
|
||||
char SettingName[64], SettingValue[256], packet[4096];
|
||||
|
||||
LogMessage("Responding to settings request\n");
|
||||
|
||||
Index = 0;
|
||||
packet[0] = '\0';
|
||||
|
||||
while (SettingAsString(Index, SettingName, sizeof(SettingName), SettingValue, sizeof(SettingValue)))
|
||||
{
|
||||
char temp[300];
|
||||
|
||||
sprintf(temp, "{\"class\":\"SET\",\"set\":\"%s\",\"val\":%s}\r\n", SettingName, SettingValue);
|
||||
|
||||
if ((strlen(temp) + strlen(packet)) < sizeof(packet))
|
||||
{
|
||||
strcat(packet, temp);
|
||||
}
|
||||
|
||||
Index++;
|
||||
}
|
||||
|
||||
send(connfd, packet, strlen(packet), MSG_NOSIGNAL);
|
||||
}
|
||||
else if (strcasecmp(line, "save") == 0)
|
||||
{
|
||||
LogMessage("Saving Settings\n");
|
||||
SaveConfigFile();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Setting
|
||||
char *setting, *value, *saveptr;
|
||||
|
||||
setting = strtok_r(line, "=", &saveptr);
|
||||
value = strtok_r( NULL, "\n", &saveptr);
|
||||
|
||||
SetConfigValue(setting, value);
|
||||
}
|
||||
}
|
||||
|
||||
void *ServerLoop( void *some_void_ptr )
|
||||
{
|
||||
int listenfd = 0, connfd = 0;
|
||||
int sockfd = 0;
|
||||
struct sockaddr_in serv_addr;
|
||||
|
||||
char sendBuff[1025];
|
||||
|
||||
listenfd = socket( AF_INET, SOCK_STREAM, 0 );
|
||||
sockfd = socket( AF_INET, SOCK_STREAM, 0 );
|
||||
memset( &serv_addr, '0', sizeof( serv_addr ) );
|
||||
memset( sendBuff, '0', sizeof( sendBuff ) );
|
||||
|
||||
|
@ -40,7 +96,7 @@ void *ServerLoop( void *some_void_ptr )
|
|||
|
||||
LogMessage( "Listening on port %d\n", Config.ServerPort );
|
||||
|
||||
if ( setsockopt( listenfd, SOL_SOCKET, SO_REUSEADDR, &( int )
|
||||
if ( setsockopt( sockfd, SOL_SOCKET, SO_REUSEADDR, &( int )
|
||||
{
|
||||
1}, sizeof( int ) ) < 0 )
|
||||
{
|
||||
|
@ -48,28 +104,58 @@ void *ServerLoop( void *some_void_ptr )
|
|||
}
|
||||
|
||||
if ( bind
|
||||
( listenfd, ( struct sockaddr * ) &serv_addr,
|
||||
( sockfd, ( struct sockaddr * ) &serv_addr,
|
||||
sizeof( serv_addr ) ) < 0 )
|
||||
{
|
||||
LogMessage( "Server failed errno %d\n", errno );
|
||||
exit( -1 );
|
||||
}
|
||||
|
||||
listen( listenfd, 10 );
|
||||
|
||||
listen( sockfd, 10 );
|
||||
|
||||
while ( run )
|
||||
{
|
||||
int port_closed;
|
||||
int SendEveryMS = 1000;
|
||||
int MSPerLoop=100;
|
||||
int ms, port_closed, connfd;
|
||||
|
||||
connfd = accept( listenfd, ( struct sockaddr * ) NULL, NULL );
|
||||
fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) & ~O_NONBLOCK); // Blocking mode so we wait for a connection
|
||||
|
||||
connfd = accept( sockfd, ( struct sockaddr * ) NULL, NULL ); // Wait for connection
|
||||
|
||||
LogMessage( "Connected to client\n" );
|
||||
|
||||
fcntl(connfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK); // Non-blocking, so we don't block on receiving any commands from client
|
||||
|
||||
for ( port_closed = 0; !port_closed; )
|
||||
{
|
||||
int Channel;
|
||||
// Build json
|
||||
// sprintf(sendBuff, "{\"class\":\"POSN\",\"time\":\"12:34:56\",\"lat\":54.12345,\"lon\":-2.12345,\"alt\":169}\r\n");
|
||||
char packet[4096];
|
||||
|
||||
// Listen loop
|
||||
for (ms=0; ms<SendEveryMS; ms+=MSPerLoop)
|
||||
{
|
||||
int bytecount;
|
||||
|
||||
while ((bytecount = recv(connfd, packet, sizeof(packet), 0)) > 0)
|
||||
{
|
||||
char *line, *saveptr;
|
||||
|
||||
packet[bytecount] = 0;
|
||||
|
||||
line = strtok_r(packet, "\n", &saveptr);
|
||||
while (line)
|
||||
{
|
||||
ProcessClientLine(connfd, line);
|
||||
line = strtok_r( NULL, "\n", &saveptr);
|
||||
}
|
||||
}
|
||||
|
||||
delay(MSPerLoop);
|
||||
}
|
||||
|
||||
// Send part
|
||||
// Build json
|
||||
|
||||
for (Channel=0; Channel<=1; Channel++)
|
||||
{
|
||||
|
@ -123,10 +209,6 @@ void *ServerLoop( void *some_void_ptr )
|
|||
LogMessage( "Disconnected from client\n" );
|
||||
port_closed = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
ssdv.c
2
ssdv.c
|
@ -195,7 +195,7 @@ SSDVLoop( void *vars )
|
|||
|
||||
packets = 0;
|
||||
}
|
||||
|
||||
delay(100); // Don't eat too much CPU
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue