Exemplo n.º 1
0
void ProcessKeyPress(int ch)
{
	int Channel = 0;

	/* shifted keys act on channel 1 */
	if (ch >= 'A' && ch <= 'Z')
	{
		Channel = 1;
		/* change from upper to lower case */
		ch += ('a' - 'A');
	}

	if (ch == 'q')
	{
		run = FALSE;
		return;
	}

	/* ignore if channel is not in use */
	if (!Config.LoRaDevices[Channel].InUse)
	{
		return;
	}

	switch(ch)
	{
		case 'f':
			Config.LoRaDevices[Channel].AFC = !Config.LoRaDevices[Channel].AFC;
			ChannelPrintf(Channel, 11, 24, "%s", Config.LoRaDevices[Channel].AFC?"AFC":"   ");
			break;
		case 'a':
			ReTune(Channel, 0.1);
			break;
		case 'z':
			ReTune(Channel, -0.1);
			break;
		case 's':
			ReTune(Channel, 0.01);
			break;
		case 'x':
			ReTune(Channel, -0.01);
			break;
		case 'd':
			ReTune(Channel, 0.001);
			break;
		case 'c':
			ReTune(Channel, -0.001);
			break;
		default:
			//LogMessage("KeyPress %d\n", ch);
			return;
	}
}
Exemplo n.º 2
0
void setFrequency(int Channel, double Frequency)
{
	unsigned long FrequencyValue;

	FrequencyValue = (unsigned long)(Frequency * 7110656 / 434);

	writeRegister(Channel, 0x06, (FrequencyValue >> 16) & 0xFF);		// Set frequency
	writeRegister(Channel, 0x07, (FrequencyValue >> 8) & 0xFF);
	writeRegister(Channel, 0x08, FrequencyValue & 0xFF);

	Config.LoRaDevices[Channel].activeFreq = Frequency;

	// LogMessage("Set Frequency to %lf\n", Frequency);
	
	ChannelPrintf(Channel, 1, 1, "Channel %d %8.4lfMHz ", Channel, Frequency);
	// ChannelPrintf(Channel, 1, 1, "Channel %d %8.4lfMHz  %s mode", Channel, Frequency, Modes[Config.LoRaDevices[Channel].SpeedMode]);
	// ChannelPrintf(Channel, 1, 11, "%8.4fMHz", Frequency);
}
Exemplo n.º 3
0
void ProcessCallingMessage(int Channel, char *Message)
{
	char Payload[16];
	double Frequency;
	int ImplicitOrExplicit, ErrorCoding, Bandwidth, SpreadingFactor, LowDataRateOptimize;
	
	ChannelPrintf(Channel, 4, 1, "Calling message %d bytes ", strlen(Message));
													
	if (sscanf(Message+2, "%15[^,],%lf,%d,%d,%d,%d,%d,%*d",
						Payload,
						&Frequency,
						&ImplicitOrExplicit,
						&ErrorCoding,
						&Bandwidth,
						&SpreadingFactor,
						&LowDataRateOptimize) == 7)
	{
		if (Config.LoRaDevices[Channel].AFC)
		{
			double MasterFrequency;
			
			sscanf(Config.LoRaDevices[Channel].Frequency, "%lf", &MasterFrequency);
		
			Frequency += Config.LoRaDevices[Channel].activeFreq - MasterFrequency;
		}
		
		LogMessage("Ch %d: Calling message, new frequency %7.3lf\n", Channel, Frequency);
		
		// Decoded OK
		setMode(Channel, RF96_MODE_SLEEP);
		
		// setFrequency(Channel, Config.LoRaDevices[Channel].activeFreq + );
		setFrequency(Channel, Frequency);

		SetLoRaParameters(Channel, ImplicitOrExplicit, ErrorCoding, Bandwidth, SpreadingFactor, LowDataRateOptimize);
		
		setMode(Channel, RF96_MODE_RX_CONTINUOUS); 
		
		Config.LoRaDevices[Channel].InCallingMode = 1;
		
		// ChannelPrintf(Channel, 1, 1, "Channel %d %7.3lfMHz              ", Channel, Frequency);
	}
}
Exemplo n.º 4
0
void ProcessTelemetryMessage(int Channel, char *Message)
{
	if (strlen(Message+1) < 150)
	{
		char *startmessage, *endmessage;

		ChannelPrintf(Channel, 4, 1, "Telemetry %d bytes       ", strlen(Message+1));

		endmessage = Message;
								
		startmessage = endmessage;
		endmessage = strchr(startmessage, '\n');

		if (endmessage != NULL)
		{
			time_t now;
			struct tm *tm;
			
			*endmessage = '\0';

			LogTelemetryPacket(startmessage);
			
			UploadTelemetryPacket(startmessage);

			ProcessLine(Channel, startmessage);
		

			now = time(0);
			tm = localtime(&now);
		
			LogMessage("%02d:%02d:%02d Ch%d: %s\n", tm->tm_hour, tm->tm_min, tm->tm_sec, Channel, startmessage);
		}
		
		// DoPositionCalcs(Channel);
		
		Config.LoRaDevices[Channel].TelemetryCount++;								
	}
}
Exemplo n.º 5
0
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;

}
Exemplo n.º 6
0
void LoadConfigFile()
{
	FILE *fp;
	char *filename = "gateway.txt";
	char Keyword[32];
	int Channel, Temp;
	char TempString[16];

	Config.EnableHabitat = 1;
	Config.EnableSSDV = 1;
	Config.EnableTelemetryLogging = 0;
	Config.ftpServer[0] = '\0';
	Config.ftpUser[0] = '\0';
	Config.ftpPassword[0] = '\0';
	Config.ftpFolder[0] = '\0';
	
	if ((fp = fopen(filename, "r")) == NULL)
	{
		printf("\nFailed to open config file %s (error %d - %s).\nPlease check that it exists and has read permission.\n", filename, errno, strerror(errno));
		exit(1);
	}

	// Receiver config
	ReadString(fp, "tracker", Config.Tracker, sizeof(Config.Tracker), 1);
	LogMessage("Tracker = '%s'\n", Config.Tracker);
	
	// Enable uploads
	ReadBoolean(fp, "EnableHabitat", 0, &Config.EnableHabitat);
	ReadBoolean(fp, "EnableSSDV", 0, &Config.EnableSSDV);
	
	// Enable logging
	ReadBoolean(fp, "LogTelemetry", 0, &Config.EnableTelemetryLogging);

	// Calling mode
	Config.CallingTimeout = ReadInteger(fp, "CallingTimeout", 0, 300);
	
	// LED allocations
	Config.NetworkLED = ReadInteger(fp, "NetworkLED", 0, -1);
	Config.InternetLED = ReadInteger(fp, "InternetLED", 0, -1);
	Config.LoRaDevices[0].ActivityLED = ReadInteger(fp, "ActivityLED_0", 0, -1);
	Config.LoRaDevices[1].ActivityLED = ReadInteger(fp, "ActivityLED_1", 0, -1);
	
	// Server Port
	Config.ServerPort = ReadInteger(fp, "ServerPort", 0, -1);	
	
	ReadString(fp, "ftpserver", Config.ftpServer, sizeof(Config.ftpServer), 0);
	ReadString(fp, "ftpUser", Config.ftpUser, sizeof(Config.ftpUser), 0);
	ReadString(fp, "ftpPassword", Config.ftpPassword, sizeof(Config.ftpPassword), 0);
	ReadString(fp, "ftpFolder", Config.ftpFolder, sizeof(Config.ftpFolder), 0);	

	for (Channel=0; Channel<=1; Channel++)
	{
		// Defaults
		Config.LoRaDevices[Channel].Frequency[0] = '\0';
		
		sprintf(Keyword, "frequency_%d", Channel);
		ReadString(fp, Keyword, Config.LoRaDevices[Channel].Frequency, sizeof(Config.LoRaDevices[Channel].Frequency), 0);
		if (Config.LoRaDevices[Channel].Frequency[0])
		{
			Config.LoRaDevices[Channel].ImplicitOrExplicit = EXPLICIT_MODE;
			Config.LoRaDevices[Channel].ErrorCoding = ERROR_CODING_4_8;
			Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_20K8;
			Config.LoRaDevices[Channel].SpreadingFactor = SPREADING_11;
			Config.LoRaDevices[Channel].LowDataRateOptimize = 0x00;		
			Config.LoRaDevices[Channel].AFC = FALSE;
			
			LogMessage("Channel %d frequency set to %s\n", Channel, Config.LoRaDevices[Channel].Frequency);
			Config.LoRaDevices[Channel].InUse = 1;

			// DIO0 / DIO5 overrides
			sprintf(Keyword, "DIO0_%d", Channel);
			Config.LoRaDevices[Channel].DIO0 = ReadInteger(fp, Keyword, 0, Config.LoRaDevices[Channel].DIO0);

			sprintf(Keyword, "DIO5_%d", Channel);
			Config.LoRaDevices[Channel].DIO5 = ReadInteger(fp, Keyword, 0, Config.LoRaDevices[Channel].DIO5);

			LogMessage("LoRa Channel %d DIO0=%d DIO5=%d\n", Channel, Config.LoRaDevices[Channel].DIO0, Config.LoRaDevices[Channel].DIO5);
			
			Config.LoRaDevices[Channel].SpeedMode = 0;
			sprintf(Keyword, "mode_%d", Channel);
			Config.LoRaDevices[Channel].SpeedMode = ReadInteger(fp, Keyword, 0, 0);

			if (Config.LoRaDevices[Channel].SpeedMode == 5)
			{
				// Calling channel
				Config.LoRaDevices[Channel].ImplicitOrExplicit = EXPLICIT_MODE;
				Config.LoRaDevices[Channel].ErrorCoding = ERROR_CODING_4_8;
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_41K7;
				Config.LoRaDevices[Channel].SpreadingFactor = SPREADING_11;
				Config.LoRaDevices[Channel].LowDataRateOptimize = 0;
			}
			else if (Config.LoRaDevices[Channel].SpeedMode == 4)
			{
				// Testing
				Config.LoRaDevices[Channel].ImplicitOrExplicit = IMPLICIT_MODE;
				Config.LoRaDevices[Channel].ErrorCoding = ERROR_CODING_4_5;
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_250K;
				Config.LoRaDevices[Channel].SpreadingFactor = SPREADING_6;
				Config.LoRaDevices[Channel].LowDataRateOptimize = 0;		
			}
			else if (Config.LoRaDevices[Channel].SpeedMode == 3)
			{
				// Normal mode for high speed images in 868MHz band
				Config.LoRaDevices[Channel].ImplicitOrExplicit = EXPLICIT_MODE;
				Config.LoRaDevices[Channel].ErrorCoding = ERROR_CODING_4_6;
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_250K;
				Config.LoRaDevices[Channel].SpreadingFactor = SPREADING_7;
				Config.LoRaDevices[Channel].LowDataRateOptimize = 0;		
			}
			else if (Config.LoRaDevices[Channel].SpeedMode == 2)
			{
				// Normal mode for repeater network
				Config.LoRaDevices[Channel].ImplicitOrExplicit = EXPLICIT_MODE;
				Config.LoRaDevices[Channel].ErrorCoding = ERROR_CODING_4_8;
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_62K5;
				Config.LoRaDevices[Channel].SpreadingFactor = SPREADING_8;
				Config.LoRaDevices[Channel].LowDataRateOptimize = 0x00;		
			}
			else if (Config.LoRaDevices[Channel].SpeedMode == 1)
			{
				// Normal mode for SSDV
				Config.LoRaDevices[Channel].ImplicitOrExplicit = IMPLICIT_MODE;
				Config.LoRaDevices[Channel].ErrorCoding = ERROR_CODING_4_5;
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_20K8;
				Config.LoRaDevices[Channel].SpreadingFactor = SPREADING_6;
				Config.LoRaDevices[Channel].LowDataRateOptimize = 0;
			}
			else
			{
				Config.LoRaDevices[Channel].ImplicitOrExplicit = EXPLICIT_MODE;
				Config.LoRaDevices[Channel].ErrorCoding = ERROR_CODING_4_8;
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_20K8;
				Config.LoRaDevices[Channel].SpreadingFactor = SPREADING_11;
				Config.LoRaDevices[Channel].LowDataRateOptimize = 0x08;		
			}

			sprintf(Keyword, "sf_%d", Channel);
			Temp = ReadInteger(fp, Keyword, 0, 0);
			if ((Temp >= 6) && (Temp <= 12))
			{
				Config.LoRaDevices[Channel].SpreadingFactor = Temp << 4;
				LogMessage("Setting SF=%d\n", Temp);
			}

			sprintf(Keyword, "bandwidth_%d", Channel);
			ReadString(fp, Keyword, TempString, sizeof(TempString), 0);
			if (*TempString)
			{
				LogMessage("Setting BW=%s\n", TempString);
			}
			if (strcmp(TempString, "7K8") == 0)
			{
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_7K8;
			}
			else if (strcmp(TempString, "10K4") == 0)
			{
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_10K4;
			}
			else if (strcmp(TempString, "15K6") == 0)
			{
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_15K6;
			}
			else if (strcmp(TempString, "20K8") == 0)
			{
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_20K8;
			}
			else if (strcmp(TempString, "31K25") == 0)
			{
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_31K25;
			}
			else if (strcmp(TempString, "41K7") == 0)
			{
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_41K7;
			}
			else if (strcmp(TempString, "62K5") == 0)
			{
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_62K5;
			}
			else if (strcmp(TempString, "125K") == 0)
			{
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_125K;
			}
			else if (strcmp(TempString, "250K") == 0)
			{
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_250K;
			}
			else if (strcmp(TempString, "500K") == 0)
			{
				Config.LoRaDevices[Channel].Bandwidth = BANDWIDTH_500K;
			}
			
			sprintf(Keyword, "implicit_%d", Channel);
			if (ReadBoolean(fp, Keyword, 0, &Temp))
			{
				if (Temp)
				{
					Config.LoRaDevices[Channel].ImplicitOrExplicit = IMPLICIT_MODE;
				}
			}
			
			sprintf(Keyword, "coding_%d", Channel);
			Temp = ReadInteger(fp, Keyword, 0, 0);
			if ((Temp >= 5) && (Temp <= 8))
			{
				Config.LoRaDevices[Channel].ErrorCoding = (Temp-4) << 1;
				LogMessage("Setting Error Coding=%d\n", Temp);
			}

			sprintf(Keyword, "lowopt_%d", Channel);
			if (ReadBoolean(fp, Keyword, 0, &Temp))
			{
				if (Temp)
				{
					Config.LoRaDevices[Channel].LowDataRateOptimize = 0x08;
				}
			}
			
			sprintf(Keyword, "AFC_%d", Channel);
			if (ReadBoolean(fp, Keyword, 0, &Temp))
			{
				if (Temp)
				{
					Config.LoRaDevices[Channel].AFC = TRUE;
					ChannelPrintf(Channel, 11, 24, "AFC");
				}
			}			
		}
	}

	fclose(fp);
}
Exemplo n.º 7
0
int main(int argc, char **argv)
{
	unsigned char Message[257];
	int Bytes, ch;
	uint32_t LoopCount[2];
	pthread_t SSDVThread, FTPThread, NetworkThread, HabitatThread, ServerThread;
	WINDOW * mainwin;
	int LEDCounts[2];
	
	if (prog_count("gateway") > 1)
	{
		printf("\nThe gateway program is already running!\n\n");
		exit(1);
	}

	mainwin = InitDisplay();
	
	// Settings for character input
	noecho();
	cbreak();
	nodelay(stdscr, TRUE);
	keypad(stdscr, TRUE);
		
	Config.LoRaDevices[0].InUse = 0;
	Config.LoRaDevices[1].InUse = 0;
	
	LEDCounts[0] = 0;
	LEDCounts[1] = 0;	
	
	// Remove any old SSDV files
	// system("rm -f /tmp/*.bin");	
	
	// Default pin allocations

	Config.LoRaDevices[0].DIO0 = 6;
	Config.LoRaDevices[0].DIO5 = 5;
	
	Config.LoRaDevices[1].DIO0 = 27;
	Config.LoRaDevices[1].DIO5 = 26;
	
	LoadConfigFile();
	LoadPayloadFiles();
	
	if (wiringPiSetup() < 0)
	{
		fprintf(stderr, "Failed to open wiringPi\n");
		exit(1);
	}
	
	if (Config.LoRaDevices[0].ActivityLED >= 0) pinMode(Config.LoRaDevices[0].ActivityLED, OUTPUT);
	if (Config.LoRaDevices[1].ActivityLED >= 0) pinMode(Config.LoRaDevices[1].ActivityLED, OUTPUT);
	if (Config.InternetLED >= 0) pinMode(Config.InternetLED, OUTPUT);
	if (Config.NetworkLED >= 0) pinMode(Config.NetworkLED, OUTPUT);
	
	setupRFM98(0);
	setupRFM98(1);
	
	ShowPacketCounts(0);
	ShowPacketCounts(1);

	LoopCount[0] = 0;
	LoopCount[1] = 0;
	
	if (pthread_create(&SSDVThread, NULL, SSDVLoop, NULL))
	{
		fprintf(stderr, "Error creating SSDV thread\n");
		return 1;
	}

	if (pthread_create(&FTPThread, NULL, FTPLoop, NULL))
	{
		fprintf(stderr, "Error creating FTP thread\n");
		return 1;
	}

	if (pthread_create(&HabitatThread, NULL, HabitatLoop, NULL))
	{
		fprintf(stderr, "Error creating Habitat thread\n");
		return 1;
	}
	
	if (Config.ServerPort > 0)
	{
		if (pthread_create(&ServerThread, NULL, ServerLoop, NULL))
		{
			fprintf(stderr, "Error creating server thread\n");
			return 1;
		}
	}

	if ((Config.NetworkLED >= 0) && (Config.InternetLED >= 0))
	{
		if (pthread_create(&NetworkThread, NULL, NetworkLoop, NULL))
		{
			fprintf(stderr, "Error creating Network thread\n");
			return 1;
		}
	}

	while (run)
	{
		int Channel;
		
		for (Channel=0; Channel<=1; Channel++)
		{
			if (Config.LoRaDevices[Channel].InUse)
			{
				if (digitalRead(Config.LoRaDevices[Channel].DIO0))
				{
					Bytes = receiveMessage(Channel, Message+1);
					
					if (Bytes > 0)
					{
						if (Config.LoRaDevices[Channel].ActivityLED >= 0)
						{
							digitalWrite(Config.LoRaDevices[Channel].ActivityLED, 1);
							LEDCounts[Channel] = 5;
						}
						// LogMessage("Channel %d data available - %d bytes\n", Channel, Bytes);
						// LogMessage("Line = '%s'\n", Message);

						if (Message[1] == '!')
						{
							ProcessUploadMessage(Channel, (char *) Message+1);
						}
						else if (Message[1] == '^')
						{
							ProcessCallingMessage(Channel, (char *) Message+1);
						}
						else if (Message[1] == '$')
						{
							ProcessTelemetryMessage(Channel, (char *) Message+1);
						}
						else if (Message[1] == 0x66)
						{
							ProcessSSDVMessage(Channel, Message);
						}
						else
						{
							LogMessage("Unknown packet type is %02Xh, RSSI %d\n", Message[1], readRegister(Channel, REG_PACKET_RSSI) - 157);
							ChannelPrintf(Channel, 4, 1, "Unknown Packet %d, %d bytes", Message[0], Bytes);
							Config.LoRaDevices[Channel].UnknownCount++;
						}
						
						Config.LoRaDevices[Channel].LastPacketAt = time(NULL);
						
						if (Config.LoRaDevices[Channel].InCallingMode && (Config.CallingTimeout > 0))
						{
							Config.LoRaDevices[Channel].ReturnToCallingModeAt = time(NULL) + Config.CallingTimeout;
						}
						

						ShowPacketCounts(Channel);
					}
				}
				
				if (++LoopCount[Channel] > 1000000)
				{
					LoopCount[Channel] = 0;
					ShowPacketCounts(Channel);
					ChannelPrintf(Channel, 12, 1, "Current RSSI = %4d   ", readRegister(Channel, REG_CURRENT_RSSI) - 157);
					
					if (Config.LoRaDevices[Channel].LastPacketAt > 0)
					{
						ChannelPrintf(Channel, 6, 1, "%us since last packet   ", (unsigned int)(time(NULL) - Config.LoRaDevices[Channel].LastPacketAt));
					}
					
					if (Config.LoRaDevices[Channel].InCallingMode && (Config.CallingTimeout > 0) && (Config.LoRaDevices[Channel].ReturnToCallingModeAt > 0) && (time(NULL) > Config.LoRaDevices[Channel].ReturnToCallingModeAt))
					{
						Config.LoRaDevices[Channel].InCallingMode = 0;
						Config.LoRaDevices[Channel].ReturnToCallingModeAt = 0;
						
						LogMessage("Return to calling mode\n");
						// setMode(Channel, RF96_MODE_SLEEP);
						
						// setFrequency(Channel, Frequency);

						// SetLoRaParameters(Channel, ImplicitOrExplicit, ErrorCoding, Bandwidth, SpreadingFactor, LowDataRateOptimize);
						
						// setMode(Channel, RF96_MODE_RX_CONTINUOUS); 
					
						setLoRaMode(Channel);

						SetDefaultLoRaParameters(Channel);
		
						setMode(Channel, RF96_MODE_RX_CONTINUOUS); 
						
						ChannelPrintf(Channel, 1, 1, "Channel %d %sMHz  %s mode", Channel, Config.LoRaDevices[Channel].Frequency, Modes[Config.LoRaDevices[Channel].SpeedMode]);
					}
						 
					if ((ch = getch()) != ERR)
					{
						ProcessKeyPress(ch);
					}
					
					if (LEDCounts[Channel] && (Config.LoRaDevices[Channel].ActivityLED >= 0))
					{
						if (--LEDCounts[Channel] == 0)
						{
							digitalWrite(Config.LoRaDevices[Channel].ActivityLED, 0);
						}
					}
				}
			}
		}
		// delay(5);
 	}

	CloseDisplay(mainwin);
	
	if (Config.NetworkLED >= 0) digitalWrite(Config.NetworkLED, 0);
	if (Config.InternetLED >= 0) digitalWrite(Config.InternetLED, 0);
	if (Config.LoRaDevices[0].ActivityLED >= 0) digitalWrite(Config.LoRaDevices[0].ActivityLED, 0);
	if (Config.LoRaDevices[1].ActivityLED >= 0) digitalWrite(Config.LoRaDevices[1].ActivityLED, 0);	
	
	return 0;
}
Exemplo n.º 8
0
void ProcessSSDVMessage(int Channel, unsigned char *Message)
{
	// SSDV packet
	static uint32_t PreviousCallsignCode=0;
	static int PreviousImageNumber=-1, PreviousPacketNumber=0;
	uint32_t CallsignCode;
	char Callsign[7], *FileMode, *EncodedCallsign, *EncodedEncoding, *EncodedData, HexString[513];
	int ImageNumber, PacketNumber;
	char filename[100];
	FILE *fp;
	
	Message[0] = 0x55;
	
	CallsignCode = Message[2]; CallsignCode <<= 8;
	CallsignCode |= Message[3]; CallsignCode <<= 8;
	CallsignCode |= Message[4]; CallsignCode <<= 8;
	CallsignCode |= Message[5];
	
	decode_callsign(Callsign, CallsignCode);
								
	ImageNumber = Message[6];
	PacketNumber = Message[8];

	// Create new file ?
	if ((ImageNumber != PreviousImageNumber) || (PacketNumber <= PreviousPacketNumber) || (CallsignCode != PreviousCallsignCode))
	{
		// New image so new file
		// FileMode = "wb";
		FileMode = "ab";
		Config.LoRaDevices[Channel].SSDVMissing = PacketNumber;
	}
	else
	{
		FileMode = "ab";
		if (PacketNumber > (PreviousPacketNumber+1))
		{
			Config.LoRaDevices[Channel].SSDVMissing += PacketNumber - PreviousPacketNumber - 1;
		}
	}

	LogMessage("Ch%d: SSDV Packet, Callsign %s, Image %d, Packet %d, %d Missing\n", Channel, Callsign, Message[6], Message[7] * 256 + Message[8], Config.LoRaDevices[Channel].SSDVMissing);
	ChannelPrintf(Channel, 4, 1, "SSDV Packet            ");
	
	PreviousImageNumber = ImageNumber;
	PreviousPacketNumber = PacketNumber;
	PreviousCallsignCode = CallsignCode;

	// Save to file
	
	sprintf(filename, "/tmp/%s_%d.bin", Callsign, ImageNumber);

	if ((fp = fopen(filename, FileMode)))
	{
		fwrite(Message, 1, 256, fp); 
		fclose(fp);
	}

	// Upload to server
	if (Config.EnableSSDV)
	{
		EncodedCallsign = url_encode(Callsign); 
		EncodedEncoding = url_encode("hex"); 

		// Base64Data = base64_encode(Message, 256, &output_length);
		// printf("output_length=%d, byte=%02Xh\n", output_length, Base64Data[output_length]);
		// Base64Data[output_length] = '\0';
		// printf ("Base64Data '%s'\n", Base64Data);
		ConvertStringToHex(HexString, Message, 256);
		EncodedData = url_encode(HexString); 

		UploadImagePacket(EncodedCallsign, EncodedEncoding, EncodedData);
		
		free(EncodedCallsign);
		free(EncodedEncoding);
		// free(Base64Data);
		free(EncodedData);
	}

	Config.LoRaDevices[Channel].SSDVCount++;
}