#include #include #include #include #include //#include #include #include void main() { FILE *finputfile, *foutputfile; //both in /home/pi char inputbuffer[1925]; int linefillcounter; // Counter for characters of one line read in from input file int outcounter; // Counter for characters written out to the output file char *FCEMpointer; // pointer to the start of fcempointer char *UncompressedFileSize; // pointer to the start of the uncompressed file size in ASCII int finishedfirstinput; // track whether we have fouund the FC EM long UCFS, tempUCFS; // long version of uncompressed file size char LittleEndianString[20]; // string to get the 8 starting characters size_t asciisize; // characters in the ascii representation of the uncompressed file size char FCbuffer[35]; // buffer for the FC EM line char FCEMinbinary[10]="FC EM"; // beginning of FC EM proposal char *Datapointer; // pointer to pound-sign 02 char buf2[10] ; // buffer to grab things like "84" from comma-delimited ascii hex int bytesread; // counter to track how many characters we have read from this packet int PacketChar; // #of characters in this packet, found right after the 0x02 int endofline; // set to 1 when we reach end of line from a packet int DataElement; // an 8-bit data element to send to lzhuf int Left,Right; // individual portions of the Data Element char *PAYLOAD2; // pointer to the beginning of a PAYLOAD2 string char payload2array[10000]; // array to store the ASCII CHARS ("02,FA,BG....") of all payload 2's int LogicalPacketNr; // counter to know which logical packet we are working on int logicalpacketend; // 1 = we reached the end of this logical packet int RadioPacketNr; // counter to know which radio packet we are working on int radiopacketend; // 1 = we reached the end of this radio packet int radiofileend; // 1 = we reached the end of the radio file int totalbytes; // number of bytes packed into payload2array int begofmsg; // 1 = we have found the 00 30 00 and are past that // the importance being that in the first half of the program, from // that point on, we are just going to shove all of the payload2 // message payloads onto the payload2array[] -- and let the second // half figure it out how to strip out the 02's etc. int payload2index; int totalbytesread; // total bytes out of array that have been read (where we are in the array) int nextonepayload2; // way to keep track of the next one actually being the payload for 2 // We will be reading in PMON output lines. // The maximum size of those lines occurs in Payload 2 // The longest DATA field of a PACTOR III is 1276 characters in long-path mode. // One character = 1 byte transferred. // PMON adds a line start # // and presents data as 2-character hexadecimals with a comma. // I think one hexadecimal is 2 bytes, but to be VERY safe, I'll assume using one hex characters // (stored as ASCII viewable hex characters) // for each of up to 1276 character, (638 2-character hex) plus a comma // for each of those 638. // Making 1276 + 638 + add in 10 more = approx 1925 finishedfirstinput = 0 ; // set the task marker for finding FC EM finputfile = fopen("/home/pi/capturefile", "r"); if(finputfile==NULL) printf("Unable to open /home/pi/capturefile \n"); while (finishedfirstinput!= 1) // Loop to handle lines until we find FC EM { // BRACES A // Read in a line linefillcounter = 0 ; do { inputbuffer[linefillcounter] = getc(finputfile); //GET ONE CHAR if(inputbuffer[linefillcounter]==EOF) // this is not seeming to pick up the end of a file..... { printf("Error or reached end of file \n"); linefillcounter=1923; // set to let us OUT finishedfirstinput= 1; // set to get us OUT } linefillcounter++; } while ( (inputbuffer[linefillcounter -1] != 10 ) && (linefillcounter<1923) ); // SCS terminates line with 0d 0a I search for the 0d. // AT THIS POINT: we have one line into inputbuffer[] inputbuffer[linefillcounter]=0 ; // be CERTAIN it got terminated.... // print out the line printf("Line: %s \n",inputbuffer); // Check to make sure we haven't reached #EOF if( strstr(inputbuffer,"#EOF") != NULL) { // Braces X -- reached the end of the file before we ever found FCEM printf("Reached #EOF before finding FC transfer proposal "); fclose(finputfile); exit(0); } // Braces X // Now look for FC EM // Use this line if using PMON HEX 1 (ASCII readable output) // I think it will actually also work for PMON HEX 2 // Because the FC proposal is sent in readable ASCII and thus even in // binary mode it will be readable by human eyes. FCEMpointer = strstr(inputbuffer,"FC EM"); // Use this line if using PMON HEX 2 (Binary output) // FCEMpointer = strstr(inputbuffer, FCEMinbinary); if(FCEMpointer!=NULL) { // BRACES H strncpy(FCbuffer,FCEMpointer,27); FCbuffer[27]=0; // strncpy does not apparenlty 0 terminate... printf("\n\n\nFOUND FC EM: %s \n",FCbuffer); finishedfirstinput=1; // mark that we are done with the first chore // Because we FOUND the FC EM // Example: FC EM WTLHRAMSQAFB 1826 983 0 // Now find the start of the uncompressed file size. // 0903: We have to do a CHECK (not yet implemented) for the case that the // line was SPLIT and the file size is NOT ON THIS LINE!!! UncompressedFileSize =( strchr(FCEMpointer+8, 0x20)) +1; // start somewhere inside the message ID // step 1 character past the space after the message ID // now we are pointing to the start of the ascii formated uncompressed file size asciisize = strspn(UncompressedFileSize, "0123456789"); *(UncompressedFileSize + asciisize) = 0; // null terminate it printf("Uncompressed File Size (ASCII) = %s \n", UncompressedFileSize); UCFS = atol(UncompressedFileSize); printf("Int version of uncompressed file size = %ld \n",UCFS); } // BRACES H -- end of if statement on FCEMpointer } // BRACES A End of while loop to read all lines until we find the FC EM // Keep these open for now because we're advancing forward //fclose(finputfile); //printf("Capture File closed \n"); // First four bytes of the file are little endian (small side first) 4-byte // unencoded file size in binary [0-255] // see: https://ecfsapi.fcc.gov/file/108140794324824/KX4O_Demonstration_OTA_Decoding_Addendum.pdf // UCFS is already a long int. tempUCFS = UCFS ; // local long int version to be destroyed // open a file to begin to write to, and make the // REMEMBER: file is actually made of 0-255 base 256 binary numbers /// BYTES // REMEMBER: PMON Hex 1ngives us comma delimited, *hexadecimal representations* // of binary numbers in the received binary. // each individiual 0-255 binary character gets represented as TWO HEX // ASCII-printable characters. When Huggins was looking at the files // he was looking with a viewer that converts to 2-char-hex printable // representations also. // What I have to put into the file for lzhuf is REAL BINARY. // So the first four bytes are little-endian base 256 file size // first byte = 0-255 // second byte = gets us up by 256's to 64 kb -- enuf for my purposes // then six binary values of ZERO befoe the file begins. // Here is how Jean-Paul's encoder wrote it out: // textsize = ftell(infile); // ptr = (char *)&textsize; // for (i = 0 ; i < sizeof(textsize) ; i++) // crc_fputc(ptr[i], infile); // if (fwrite(&textsize, sizeof textsize, 1, outfile) < 1) // Error(wterr); /* output size of text */ // LittleEndianString[0]= (tempUCFS & 0x0ff); LittleEndianString[1]= (tempUCFS & 0x00ff00) >>8; LittleEndianString[2]= (tempUCFS & 0xff0000) >>16; // three characters is enough to contain 64kb!!! foutputfile = fopen("/home/pi/outputfile", "a"); if(finputfile==NULL) printf("Unable to open /home/pi/outputfile \n"); // C strings are initialized to 0 in all places for(outcounter=0; outcounter<8; outcounter++) { if( fputc( (int)LittleEndianString[outcounter], foutputfile) ==EOF ) printf("Unable to write size to /home/pi/outputfile \n"); } // end of the outcounter loop /*---------------NOW START READING LINES, HUNTING FOR THE START OF DATA SEGMENT (begoffile-->1) and packing the payload2 array of data elements ---------------*/ // Now go back to the input file and hunt for that start of file indicator // There should be a PAYLOAD 2 packet that starts either with 0x02 or has a // line #02, in hexidecimal (PMON Hex 1) or binary (PMONHex 2) finishedfirstinput = 0; // re-use this job tracker begofmsg=0; // haven't found the start of the message yet radiofileend = 0; // haven't reached the end of the radio captured file yet totalbytes = 0; // number of bytes stored in payload2 array radiopacketend= 0; // end of a PAYLOAD2 packet line // At this point we have found the FC EM... and now we need to pack the 1-dim // array from the remaining PAYLOAD 2 lines in the input file until we reach the // end of the message. while (radiofileend!= 1) // G Loop to handle lines from radio capture file forward of FC EM { // G while loop hunting for 00 30 00 02 (PMON HEX 1) or (PMON HEX 2) nextonepayload2 = 0; // set it to NOT at PAYLOAD2 at the moment // Read in a line linefillcounter = 0 ; //Note that the line are filled with ASCII CAPITALS BF,AC,etc // I'll code for hexadecimal, 2-character comma delimited input, // which should have a /n end [0] // READ IN ONE LINE do { // H do loop inputbuffer[linefillcounter] = getc(finputfile); // get 1 char if(inputbuffer[linefillcounter]==EOF) { printf("Error or reached end of file without finding #02 \n"); linefillcounter=1923; // set to let us OUT radiofileend= 1; // set to get us OUT } if(feof(finputfile)!=0) { printf("feof returned end of file \n"); linefillcounter=1923; // set to let us OUT radiofileend= 1; // set to get us OUT } linefillcounter++; } // H do-loop while ( (inputbuffer[linefillcounter -1] != 10 ) && (linefillcounter<1923) ); // END OF READING IN ONE C - LINE -- scs terminates lines with 0d 0a search for the 0d // TERMINATE STRING AND PRINT FOR DEBUG inputbuffer[linefillcounter]=0 ; // be CERTAIN it got terminated.... // print out the line if (radiofileend != 1) printf("=====Line: %s \n",inputbuffer); if( strstr(inputbuffer,"#EOF") != NULL) { radiofileend=1; // we reached the end of the file!! printf(" ************WE FOUND FILE END*************** "); } //DONT GO ANY FARTHER IF WE ARE AT RADIO FILE END if(radiofileend==0) { // GG loop to only evaluate while not at the end of the file // -----------TEST FOR PAYLOAD 2 LINE //See if we have found a PAYLOAD2 line: // need char *PAYLOAD2 printf("Test for PAYLOAD2. totalbytes = %d \n",totalbytes); PAYLOAD2 = strstr(inputbuffer,"###PAYLOAD2:"); // This is terminated with 0a 0d in the SCS printout....so now read in // AGAIN in order to get the actual line.... if(PAYLOAD2!=NULL) // we FOUND a payload 2 line so read in again... { // ZA brace to read in and deal with payload 2 if nonempty linefillcounter = 0 ; do { inputbuffer[linefillcounter] = getc(finputfile); //GET ONE CHAR if(inputbuffer[linefillcounter]==EOF) // this is not seeming to pick up the end of a file..... { printf("Error or reached end of file \n"); linefillcounter=1923; // set to let us OUT finishedfirstinput= 1; // set to get us OUT } linefillcounter++; } while ( (inputbuffer[linefillcounter -1] != 10 ) && (linefillcounter<1923) ); // SCS terminates line with 0d 0a I search for the 0d. // AT THIS POINT: we have a possibly non-empty PAYLOAD2 line into inputbuffer[] inputbuffer[linefillcounter]=0 ; // be CERTAIN it got terminated.... // print out the line printf("PAYLOAD2 Line: %s \n",inputbuffer); // IF we found it, then we can look for the 00,30,00,02 the next time we come here.... // if it isn't there, then we gingerly move one line forward and check until we find it printf("\n\n---------ZA Loop, nextonepayload2==1 %s \n\n",inputbuffer); // now search for the 00,30,00, if we haven't yet found the begofmsg=1 // Iinitialize Datapointer so this will work on the times through // after the first one (the one where we found the message start Datapointer = inputbuffer; // start it off at the beginning payload2index = 0; // index of characters taken out inputbuffer and shoved if(begofmsg==0) { // braces AA hunting for the start of the message Datapointer = strstr(inputbuffer, "00,30,00,"); if(Datapointer!= NULL) { // P loop because we FOUND start of file, first packet printf("We found the start of a Datafile \n"); Datapointer=Datapointer + 9; // point to where the FIRST 02 should be begofmsg=1; // mark that we found the beginning of the message // thus now we start squirreling away the bytes printf("string starting at begin of message: %s \n",Datapointer); } // end of P loop having found the unique start of file } // end of braces AA hunting for the start ofthe message if(begofmsg==1) // we have already previously found the beginning of message // so now we are just sending everything over except the 0d's if we find one { // braces AB packing away bytes from a logical packet // pack all bytes to the end of the radio packet line (character 13) into payload2 array printf("Loop for unpacking PAYLOAD2 bytes: totalbytes: %d \n",totalbytes); while( *(Datapointer+payload2index) !=13 ) { printf("Char: %c from PAYLOAD2 index: %d into arrray at %d \n",*(Datapointer+payload2index), payload2index, totalbytes ); payload2array[totalbytes]= *(Datapointer+payload2index); payload2index++; totalbytes++; } // now we are at the end of a RADIO PACKET -- and typically they do not have a comma!! // so we need to add one!!! payload2array[totalbytes] = 0x2c; // put in a comma totalbytes++; radiopacketend=1; // so now return to reading in lines and hunting for PAYLOAD2 } // end of braces AB packing away bytes from a logical packet // now reset the payload2 flag } // end of ZA loop dealing with a PAYLOAD2 line } // end of GG loop handling packing away a line } // end of G loop reading in lines until we hit radiofile end fclose(finputfile); printf("Closed the input file \n"); /* --------------WE HAVE THE 1-dim Array Filled ------------------------------------*/ printf("payload2array: %s \n\n", payload2array); // print out the array printf("\n\n--------------\n1-Dim Array is filled with totalbytes = %d \n\n\n",totalbytes); totalbytesread=0; // The array should now have 02, SIZE, ......[size# of comma delimieted]...02...repeat // we SHOULD be positioned right before a 02 in ASCII while(totalbytesread < (totalbytes-3)) { // BA loop to go through the entire array //first move to the start of a 02 logical packet Datapointer=strstr(& (payload2array[totalbytesread]),"02"); // Now we sit at the start of a logical packet // assume for the moment that bytesread=0; Datapointer=Datapointer+3; // now advanced to the size character totalbytesread = totalbytesread +3; buf2[0] = *Datapointer; // get the left character buf2[1] = 0; // null terminate it printf("Read the first size char: %s \n",buf2); buf2[0]=tolower(buf2[0]); // atoi doesn't handle CAPITALS sscanf(buf2, "%x", &Left); // get left as an int printf(" Left = %d \n",Left); printf(" Left Buffer: %s, Value %d \n", buf2, Left); Datapointer++; // increment to 2nd of size character buf2[0]= *Datapointer; // get the right character buf2[1]= 0; // null terminate it Datapointer=Datapointer + 2; //move so it points to the start of the next character buf2[0]=tolower(buf2[0]); sscanf(buf2, "%x", &Right); // get the right character of bytes in this packet printf(" Right Buffer: %s, Value %d \n", buf2, Right); PacketChar = (Left * 16) + Right; printf("Number of bytes in this logical packet = %d \n",PacketChar ); totalbytesread=totalbytesread+3; //Because we now have the entire message in memory, we will //definitely be able to find the entire packet endofline=0; for(bytesread= 0; (bytesread5) // to keep us from writing out the first 6 doubles [3 characters -- ??CRC??] { if( fputc((int)DataElement, foutputfile) ==EOF ) printf("Unable to write DataElement to /home/pi/outputfile \n"); else printf("wrote %d to output file \n",DataElement); } } // End of Q loop to deal with ONE LOGICAL PACKET. // Now we have to move to the next 02 and throw it out.... } // end of BA loop to write out the entire array printf("We printed out the entire file \n\n"); fclose(foutputfile); printf("output file closed \n"); } /* end of main */