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; }
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++; }