Fully functioning KISS TNC
This commit is contained in:
		@@ -28,8 +28,12 @@ First (more or less) working version.
 | 
			
		||||
### Added
 | 
			
		||||
- All settings (LoRa and APRS) can now be saved to FLASH.
 | 
			
		||||
- Command added for restarting LoRa radio when settings are alterred: "restart lora"
 | 
			
		||||
- Received LoRa frames can now be converted to propper AX25 frames (needed for KISS TNC functionality)
 | 
			
		||||
- Received LoRa frames can now be converted to proper AX25 frames (needed for KISS TNC functionality)
 | 
			
		||||
- KISS mode works for receiving (LoRa -> USB port)
 | 
			
		||||
- KISS mode for transmitting in early phase of development
 | 
			
		||||
- Can enter KISS mode with command "kiss 1" and exit KISS mode with command "sudo kissparms -p ax0 -x"
 | 
			
		||||
 | 
			
		||||
## [1.0.4] - 2022-05-13
 | 
			
		||||
 | 
			
		||||
### Added
 | 
			
		||||
- Fully functioning KISS TNC, but repeater flag could not be tested because LoRa APRS software in general is a mess. It appears that nobody reads the AX.25 standard anymore. This software probably is also not up to spec. But at least I tried! You should too: [http://www.ax25.net/AX25.2.2-Jul%2098-2.pdf](http://www.ax25.net/AX25.2.2-Jul%2098-2.pdf)
 | 
			
		||||
 
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										52465
									
								
								build/src/main.dis
									
									
									
									
									
								
							
							
						
						
									
										52465
									
								
								build/src/main.dis
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										8548
									
								
								build/src/main.hex
									
									
									
									
									
								
							
							
						
						
									
										8548
									
								
								build/src/main.hex
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										232
									
								
								src/kiss.cpp
									
									
									
									
									
								
							
							
						
						
									
										232
									
								
								src/kiss.cpp
									
									
									
									
									
								
							@@ -4,7 +4,7 @@
 | 
			
		||||
 * KISS encoder uses two steps:
 | 
			
		||||
 * 
 | 
			
		||||
 * Step 1: encodes the LoRa APRS frame into an AX.25 frame. DONE
 | 
			
		||||
 * Step 2: encapsulates the AX.25 frame into a KISS frame. TODO
 | 
			
		||||
 * Step 2: encapsulates the AX.25 frame into a KISS frame. DONE
 | 
			
		||||
 * 
 | 
			
		||||
 *  struct aprs_frame {
 | 
			
		||||
 *      uint8_t source_address[10];
 | 
			
		||||
@@ -27,6 +27,9 @@ uint16_t KissClass::EncodeFrame(struct aprs_frame *aprsframe, struct ax25_frame
 | 
			
		||||
    uint16_t cnt=0;
 | 
			
		||||
    uint16_t position = 0;
 | 
			
		||||
    uint8_t digi_cnt = 0;
 | 
			
		||||
    uint8_t escaped_string_cnt=0;
 | 
			
		||||
    
 | 
			
		||||
    //printf("Encode KISS");
 | 
			
		||||
    
 | 
			
		||||
    // Destination call
 | 
			
		||||
    //printf("Destination: ");
 | 
			
		||||
@@ -35,7 +38,7 @@ uint16_t KissClass::EncodeFrame(struct aprs_frame *aprsframe, struct ax25_frame
 | 
			
		||||
    while (cnt < 7)
 | 
			
		||||
    {
 | 
			
		||||
        ax25frame->complete[position] = *(encoded_call+cnt);
 | 
			
		||||
        ////printf("0x%X ", *(encoded_call+cnt));
 | 
			
		||||
        //printf("0x%X ", *(encoded_call+cnt));
 | 
			
		||||
        //printf("0x%X ", ax25frame->complete[position]);
 | 
			
		||||
        cnt++;
 | 
			
		||||
        position++;
 | 
			
		||||
@@ -49,7 +52,7 @@ uint16_t KissClass::EncodeFrame(struct aprs_frame *aprsframe, struct ax25_frame
 | 
			
		||||
    while (cnt < 7)
 | 
			
		||||
    {
 | 
			
		||||
        ax25frame->complete[position] = *(encoded_call+cnt);
 | 
			
		||||
        ////printf("0x%X ", *(encoded_call+cnt));
 | 
			
		||||
        //printf("0x%X ", *(encoded_call+cnt));
 | 
			
		||||
        //printf("0x%X ", ax25frame->complete[position]);
 | 
			
		||||
        cnt++;
 | 
			
		||||
        position++;
 | 
			
		||||
@@ -73,7 +76,7 @@ uint16_t KissClass::EncodeFrame(struct aprs_frame *aprsframe, struct ax25_frame
 | 
			
		||||
            encoded_call = EncodeCall(aprsframe->digis[digi_cnt]);            
 | 
			
		||||
            while (cnt < 7) {
 | 
			
		||||
                ax25frame->complete[position] = *(encoded_call+cnt);
 | 
			
		||||
                ////printf("0x%X ", *(encoded_call+cnt));
 | 
			
		||||
                //printf("0x%X ", *(encoded_call+cnt));
 | 
			
		||||
                //printf("0x%X ", ax25frame->complete[position]);
 | 
			
		||||
                cnt++;
 | 
			
		||||
                position++;
 | 
			
		||||
@@ -109,6 +112,9 @@ uint16_t KissClass::EncodeFrame(struct aprs_frame *aprsframe, struct ax25_frame
 | 
			
		||||
    // Encapsulate AX.25 frame in KISS frame (including escaping FEND codes)    
 | 
			
		||||
    putchar(FEND);
 | 
			
		||||
    putchar(CMD_DATA);
 | 
			
		||||
    escaped_string_cnt=0;
 | 
			
		||||
    ax25frame->encoded_kiss_frame[escaped_string_cnt++] = FEND;
 | 
			
		||||
    ax25frame->encoded_kiss_frame[escaped_string_cnt++] = CMD_DATA;
 | 
			
		||||
    cnt=0;
 | 
			
		||||
    position=ax25frame->lenght;
 | 
			
		||||
    while (position-- != 0)
 | 
			
		||||
@@ -117,15 +123,21 @@ uint16_t KissClass::EncodeFrame(struct aprs_frame *aprsframe, struct ax25_frame
 | 
			
		||||
        if (ax25frame->complete[cnt] == FEND) {
 | 
			
		||||
            putchar(FESC);
 | 
			
		||||
            putchar(TFEND);
 | 
			
		||||
            ax25frame->encoded_kiss_frame[escaped_string_cnt++] = FESC;
 | 
			
		||||
            ax25frame->encoded_kiss_frame[escaped_string_cnt++] = TFEND;
 | 
			
		||||
        } else if (ax25frame->complete[cnt] == FESC) {
 | 
			
		||||
            putchar(FESC);
 | 
			
		||||
            putchar(TFESC);
 | 
			
		||||
            ax25frame->encoded_kiss_frame[escaped_string_cnt++] = FESC;
 | 
			
		||||
            ax25frame->encoded_kiss_frame[escaped_string_cnt++] = TFESC;
 | 
			
		||||
        } else {
 | 
			
		||||
            putchar(ax25frame->complete[cnt]);
 | 
			
		||||
            ax25frame->encoded_kiss_frame[escaped_string_cnt++] = ax25frame->complete[cnt];
 | 
			
		||||
        }
 | 
			
		||||
        cnt++;
 | 
			
		||||
    }
 | 
			
		||||
    putchar(FEND);
 | 
			
		||||
    ax25frame->encoded_kiss_frame[escaped_string_cnt++] = FEND;
 | 
			
		||||
    //printf("\n");
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
@@ -136,13 +148,21 @@ uint16_t KissClass::EncodeFrame(struct aprs_frame *aprsframe, struct ax25_frame
 | 
			
		||||
 * Decodes a KISS frame from the usb serial port
 | 
			
		||||
 * 
 | 
			
		||||
 * Input : string starting with FEND and ending with FEND
 | 
			
		||||
 * Output: ax25frame->decoded_kiss_frame terminated with NULL
 | 
			
		||||
 * Output: filled struct AprsFrame
 | 
			
		||||
 * Return: 0 = OK, 1 = ERROR, 2 = EXIT KISS MODE
 | 
			
		||||
 */
 | 
			
		||||
uint16_t KissClass::DecodeFrame(uint8_t string[], struct ax25_frame *ax25frame)
 | 
			
		||||
uint16_t KissClass::DecodeFrame(uint8_t string[], struct kiss_tx_frame *kisstxframe)
 | 
			
		||||
{
 | 
			
		||||
    uint16_t position  =0 ;
 | 
			
		||||
    uint16_t loop_counter = 0;
 | 
			
		||||
    uint16_t cnt  =0 ;
 | 
			
		||||
    uint16_t ssid = 0;
 | 
			
		||||
    uint16_t last_digi = 0;
 | 
			
		||||
    uint16_t digi_cnt = 0;
 | 
			
		||||
    
 | 
			
		||||
    //printf("Decode KISS");
 | 
			
		||||
    
 | 
			
		||||
    kisstxframe->valid_data = false;
 | 
			
		||||
    
 | 
			
		||||
    // Not a valid frame
 | 
			
		||||
    if (string[position] != FEND)
 | 
			
		||||
@@ -182,6 +202,176 @@ uint16_t KissClass::DecodeFrame(uint8_t string[], struct ax25_frame *ax25frame)
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // If we are here we have a valid AX.25 frame in 'string' which is decapsulated from its KISS frame
 | 
			
		||||
    /*
 | 
			
		||||
    0-5 destination
 | 
			
		||||
    6 destination ssid
 | 
			
		||||
    7-12 source
 | 
			
		||||
    13 desitination sidd
 | 
			
		||||
    
 | 
			
		||||
    vanaf byte 13 LAST FLAG zoeken
 | 
			
		||||
    
 | 
			
		||||
    03
 | 
			
		||||
    f0
 | 
			
		||||
    payload tot aan NULL
 | 
			
		||||
    */
 | 
			
		||||
    
 | 
			
		||||
    // Decode destination call
 | 
			
		||||
    position = 0;
 | 
			
		||||
    cnt = 0;
 | 
			
		||||
    loop_counter = 0;
 | 
			
		||||
    while (loop_counter < 6)
 | 
			
		||||
    {
 | 
			
		||||
        kisstxframe->digis[0][cnt] = string[position] >> 1;
 | 
			
		||||
        // Remove space
 | 
			
		||||
        if (kisstxframe->digis[0][cnt] == ' ')
 | 
			
		||||
            cnt--;
 | 
			
		||||
        position++;
 | 
			
		||||
        loop_counter++;
 | 
			
		||||
        cnt++;
 | 
			
		||||
        //printf("%u ", position);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Extract SSID
 | 
			
		||||
    //printf("position: %u\n", position);
 | 
			
		||||
    ssid = (string[position] & 0b00011110) >> 1;
 | 
			
		||||
    //printf("DIGI SSID: %u (%u)\n", ssid, position);
 | 
			
		||||
    
 | 
			
		||||
    // Place SSID behind call or not if it is zero
 | 
			
		||||
    if (ssid != 0) {
 | 
			
		||||
        kisstxframe->digis[0][cnt++] = '-';
 | 
			
		||||
        if (ssid < 10)
 | 
			
		||||
        {
 | 
			
		||||
            kisstxframe->digis[0][cnt++] = ssid + 48;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            kisstxframe->digis[0][cnt++] = '1';
 | 
			
		||||
            kisstxframe->digis[0][cnt++] = (ssid%10)+48;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // Is has-been-repeated flag set?
 | 
			
		||||
    if(string[position] & 0b10000000) {
 | 
			
		||||
        kisstxframe->digis[0][cnt] = '*';
 | 
			
		||||
        cnt++;
 | 
			
		||||
    }
 | 
			
		||||
    kisstxframe->digis[0][cnt] = 0;   //terminate string
 | 
			
		||||
    position++;
 | 
			
		||||
    
 | 
			
		||||
    // Decode source call
 | 
			
		||||
    cnt = 0;
 | 
			
		||||
    loop_counter=0;
 | 
			
		||||
    while (loop_counter < 6)
 | 
			
		||||
    {
 | 
			
		||||
        kisstxframe->source_address[cnt] = string[position] >> 1;
 | 
			
		||||
        // Remove space
 | 
			
		||||
        if (kisstxframe->source_address[cnt] == ' ')
 | 
			
		||||
            cnt--;
 | 
			
		||||
        position++;
 | 
			
		||||
        loop_counter++;
 | 
			
		||||
        cnt++;
 | 
			
		||||
        //printf("%u ", position);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Extract SSID
 | 
			
		||||
    ssid = (string[position] & 0b00011110) >> 1;
 | 
			
		||||
    //printf("sources SSID: %u (%u)\n", ssid, position);
 | 
			
		||||
    
 | 
			
		||||
   // Place SSID behind call or not if it is zero
 | 
			
		||||
    if (ssid != 0) {
 | 
			
		||||
        kisstxframe->source_address[cnt++] = '-';
 | 
			
		||||
        if (ssid < 10)
 | 
			
		||||
        {
 | 
			
		||||
            kisstxframe->source_address[cnt++] = ssid + 48;
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            kisstxframe->source_address[cnt++] = '1';
 | 
			
		||||
            kisstxframe->source_address[cnt++] = (ssid%10)+48;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    // Is has-been-repeated flag set?
 | 
			
		||||
    if(string[position] & 0b10000000) {
 | 
			
		||||
        kisstxframe->source_address[cnt] = '*';
 | 
			
		||||
        cnt++;
 | 
			
		||||
    }
 | 
			
		||||
    kisstxframe->source_address[cnt] = 0;   //terminate string
 | 
			
		||||
    
 | 
			
		||||
    // Check LAST flag
 | 
			
		||||
    if ( (string[position] & 0b00000001))
 | 
			
		||||
        last_digi = 1;
 | 
			
		||||
    
 | 
			
		||||
    position++;
 | 
			
		||||
     
 | 
			
		||||
    // Decode digi path
 | 
			
		||||
    digi_cnt=1;
 | 
			
		||||
    while (last_digi == 0) {
 | 
			
		||||
        
 | 
			
		||||
        cnt = 0;
 | 
			
		||||
        loop_counter=0;
 | 
			
		||||
        while (loop_counter < 6)
 | 
			
		||||
        {
 | 
			
		||||
            kisstxframe->digis[digi_cnt][cnt] = string[position] >> 1;
 | 
			
		||||
            // Remove space
 | 
			
		||||
            if (kisstxframe->digis[digi_cnt][cnt] == ' ')
 | 
			
		||||
                cnt--;
 | 
			
		||||
            position++;
 | 
			
		||||
            loop_counter++;
 | 
			
		||||
            cnt++;
 | 
			
		||||
            //printf("%u ", position);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        // Extract SSID
 | 
			
		||||
        ssid = (string[position] & 0b00011110) >> 1;
 | 
			
		||||
        //printf("DIGI  SSID: %u (%u)\n", ssid, position);
 | 
			
		||||
        
 | 
			
		||||
        // Place SSID behind call or not if it is zero
 | 
			
		||||
        if (ssid != 0) {
 | 
			
		||||
            kisstxframe->digis[digi_cnt][cnt++] = '-';
 | 
			
		||||
            if (ssid < 10)
 | 
			
		||||
            {
 | 
			
		||||
                kisstxframe->digis[digi_cnt][cnt++] = ssid + 48;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                kisstxframe->digis[digi_cnt][cnt++] = '1';
 | 
			
		||||
                kisstxframe->digis[digi_cnt][cnt++] = (ssid%10) + 48;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
     
 | 
			
		||||
        // Is has-been-repeated flag set?
 | 
			
		||||
        if(string[position] & 0b10000000) {
 | 
			
		||||
            kisstxframe->digis[digi_cnt][cnt] = '*';
 | 
			
		||||
            cnt++;
 | 
			
		||||
        }
 | 
			
		||||
        kisstxframe->digis[digi_cnt][cnt] = 0;   //terminate string
 | 
			
		||||
        
 | 
			
		||||
        // Check LAST flag (also ends when more than 10 digis)
 | 
			
		||||
        if ( (string[position] & 0b00000001) || digi_cnt > 8)
 | 
			
		||||
            last_digi = 1;
 | 
			
		||||
    
 | 
			
		||||
        digi_cnt++;
 | 
			
		||||
        position++;
 | 
			
		||||
    }
 | 
			
		||||
    kisstxframe->number_of_digipeaters = digi_cnt-1;
 | 
			
		||||
    //printf("Digipeaters: %u \n",kisstxframe->number_of_digipeaters );
 | 
			
		||||
    
 | 
			
		||||
    //Skip the two control fields
 | 
			
		||||
    position++;
 | 
			
		||||
    position++;
 | 
			
		||||
   
 | 
			
		||||
    //Rest of string up to NULL is payload
 | 
			
		||||
    cnt = 0;
 | 
			
		||||
    kisstxframe->data_field[cnt++] = ':';
 | 
			
		||||
    while (string[position] != 0 && position < 512)
 | 
			
		||||
    {
 | 
			
		||||
        kisstxframe->data_field[cnt] = string[position];
 | 
			
		||||
        position++;
 | 
			
		||||
        cnt++;
 | 
			
		||||
    }
 | 
			
		||||
    kisstxframe->data_field[cnt] = 0;     //terminate string
 | 
			
		||||
    
 | 
			
		||||
    kisstxframe->valid_data = true;
 | 
			
		||||
    
 | 
			
		||||
    
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
@@ -197,10 +387,26 @@ uint8_t * KissClass::EncodeCall(uint8_t string[])
 | 
			
		||||
{
 | 
			
		||||
    uint8_t position = 0;
 | 
			
		||||
    uint8_t cnt = 0;
 | 
			
		||||
    uint8_t repeat_flag = 0;
 | 
			
		||||
    
 | 
			
		||||
    static uint8_t call[7] = { 0,0,0,0,0,0,0} ;
 | 
			
		||||
    uint8_t ssid = 0;
 | 
			
		||||
    
 | 
			
		||||
    // if asterix is pressent in string, than the message has been repeated, so set the 'has been repeated' flag in the ssid register
 | 
			
		||||
    // At the same time delete the asterix and place a NULL (string terminator) at its place. As the asterix should be the last character in the string, this should work.
 | 
			
		||||
    position = 0;
 | 
			
		||||
    while( string[position] != 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (string[position] == '*') {
 | 
			
		||||
            repeat_flag = 1;
 | 
			
		||||
            string[position] == 0;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        position++;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    position = 0;
 | 
			
		||||
    // extract call
 | 
			
		||||
    while( string[position] != 0 || cnt < 6)
 | 
			
		||||
    {
 | 
			
		||||
@@ -229,17 +435,11 @@ uint8_t * KissClass::EncodeCall(uint8_t string[])
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // if asterix is pressent in string, than the message has been repeated, so set the 'has been repeated' flag in the ssid register
 | 
			
		||||
    position = 0;
 | 
			
		||||
    while( string[position] != 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (string[position] == '*')
 | 
			
		||||
            ssid = 0b10000000;
 | 
			
		||||
    ssid = ssid << 1;
 | 
			
		||||
    ssid |= 0b01100000;
 | 
			
		||||
    
 | 
			
		||||
        position++;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    ssid = (ssid << 1) | 0b01100000;
 | 
			
		||||
    if (repeat_flag == 1)            
 | 
			
		||||
        ssid |= 0b10000000;
 | 
			
		||||
    
 | 
			
		||||
    // add encoded ssid to encoded call array
 | 
			
		||||
    call[6] = ssid;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								src/kiss.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/kiss.h
									
									
									
									
									
								
							@@ -39,15 +39,27 @@
 | 
			
		||||
    struct ax25_frame {
 | 
			
		||||
        uint8_t complete[512];
 | 
			
		||||
        uint16_t lenght = 0;
 | 
			
		||||
        uint8_t encoded_kiss_frame[512];
 | 
			
		||||
        uint8_t decoded_kiss_frame[512];
 | 
			
		||||
        uint16_t kiss_length = 0;
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    struct kiss_tx_frame {
 | 
			
		||||
        uint8_t source_address[10];
 | 
			
		||||
        uint8_t data_field[512];
 | 
			
		||||
        uint8_t digis[10][10];
 | 
			
		||||
        uint16_t number_of_digipeaters = 0;
 | 
			
		||||
        
 | 
			
		||||
        uint8_t lora_string[512];
 | 
			
		||||
        
 | 
			
		||||
        uint8_t valid_data = false;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  class KissClass
 | 
			
		||||
  {
 | 
			
		||||
  public:
 | 
			
		||||
      uint16_t EncodeFrame(struct aprs_frame *frame, struct ax25_frame *ax25frame);
 | 
			
		||||
      uint16_t DecodeFrame(uint8_t string[], struct ax25_frame *ax25frame);
 | 
			
		||||
      uint16_t DecodeFrame(uint8_t string[], struct kiss_tx_frame *kisstxframe);
 | 
			
		||||
  private:
 | 
			
		||||
      uint8_t * EncodeCall(uint8_t string[]);
 | 
			
		||||
  };
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										78
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										78
									
								
								src/main.cpp
									
									
									
									
									
								
							@@ -11,7 +11,9 @@
 | 
			
		||||
#include "hardware/claim.h"
 | 
			
		||||
 | 
			
		||||
KissClass Kiss;
 | 
			
		||||
struct ax25_frame AX25Frame;  //defined in kiss.h
 | 
			
		||||
struct ax25_frame AX25Frame;        //defined in kiss.h
 | 
			
		||||
struct aprs_frame AprsFrame;        //defined in kiss.h
 | 
			
		||||
struct kiss_tx_frame KissTxFrame;   //defined in kiss.h
 | 
			
		||||
 | 
			
		||||
bool startRadio();
 | 
			
		||||
void getPacketData(int packetLength);
 | 
			
		||||
@@ -23,6 +25,7 @@ uint16_t decode_packet ();
 | 
			
		||||
 | 
			
		||||
/* declaration for transmit functions */
 | 
			
		||||
void ComposeAprsFrame(uint8_t payload[]);
 | 
			
		||||
void ComposeAprsFrameFromKiss();
 | 
			
		||||
bool TransmitRequest = false;
 | 
			
		||||
void transmit();
 | 
			
		||||
 | 
			
		||||
@@ -433,6 +436,7 @@ void ReadUSBSerial(void)
 | 
			
		||||
    static char strg[512];
 | 
			
		||||
    int chr;
 | 
			
		||||
    static int lp = 0;
 | 
			
		||||
    uint16_t tmp;
 | 
			
		||||
    
 | 
			
		||||
    if (Status.KissMode == OFF) {
 | 
			
		||||
        // Read serial port (USB) - non-blocking!
 | 
			
		||||
@@ -472,15 +476,21 @@ void ReadUSBSerial(void)
 | 
			
		||||
            // Received FEND (=begin or end frame)
 | 
			
		||||
            if(chr == FEND)
 | 
			
		||||
            {
 | 
			
		||||
                // Valid FISS frame received
 | 
			
		||||
                // Valid KISS frame received
 | 
			
		||||
                if (strg[0] == FEND && lp > 1)
 | 
			
		||||
                {
 | 
			
		||||
                    if (Kiss.DecodeFrame((uint8_t *) strg, &AX25Frame) == 2)
 | 
			
		||||
                    tmp = Kiss.DecodeFrame((uint8_t *) strg, &KissTxFrame);
 | 
			
		||||
                    if ( tmp == 2)
 | 
			
		||||
                    {
 | 
			
		||||
                        //exit KISS MODE
 | 
			
		||||
                        stdio_set_translate_crlf(&stdio_usb, true);
 | 
			
		||||
                        Status.KissMode = OFF; 
 | 
			
		||||
                    }
 | 
			
		||||
                    // Valid KISS data frame, so lets send it
 | 
			
		||||
                    else if (tmp == 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        ComposeAprsFrameFromKiss();
 | 
			
		||||
                    }
 | 
			
		||||
                    lp = 0;		//reset string buffer pointer
 | 
			
		||||
                }
 | 
			
		||||
                // We received a FEND byte,so we are probably between two KISS frames. Let's assume the latest FEND is the beginning of a new frame
 | 
			
		||||
@@ -682,8 +692,6 @@ uint16_t decode_packet ()
 | 
			
		||||
    int position = 0;
 | 
			
		||||
    int cnt = 0;
 | 
			
		||||
    
 | 
			
		||||
    struct aprs_frame AprsFrame;  //defined in kiss.h
 | 
			
		||||
 | 
			
		||||
    memset(AprsFrame.source_address, 0, sizeof(AprsFrame.source_address));
 | 
			
		||||
    memset(AprsFrame.digi_path, 0, sizeof(AprsFrame.digi_path));
 | 
			
		||||
    memset(AprsFrame.data_field, 0, sizeof(AprsFrame.data_field));
 | 
			
		||||
@@ -809,8 +817,11 @@ uint16_t decode_packet ()
 | 
			
		||||
        log_out("Source address: %s\nDigipeaters (%u): %s %s %s %s\nData: %s\n", AprsFrame.source_address, AprsFrame.number_of_digipeaters+1, AprsFrame.digis[0], AprsFrame.digis[1], AprsFrame.digis[2], AprsFrame.digis[3], AprsFrame.data_field);
 | 
			
		||||
        
 | 
			
		||||
        // If in KISS mode the struct AprsFrame is handed over to the KISS encoder
 | 
			
		||||
        if (Status.KissMode == ON)
 | 
			
		||||
        if (Status.KissMode == ON) {
 | 
			
		||||
            Kiss.EncodeFrame(&AprsFrame, &AX25Frame);
 | 
			
		||||
            //if (Kiss.DecodeFrame(AX25Frame.encoded_kiss_frame, &KissTxFrame) == 0)
 | 
			
		||||
                //ComposeAprsFrameFromKiss();
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        if (AprsFrame.message[0])
 | 
			
		||||
        {
 | 
			
		||||
@@ -960,6 +971,61 @@ void ComposeAprsFrame(uint8_t payload[])
 | 
			
		||||
    log_out("%s\n", txBuffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ComposeAprsFrameFromKiss()
 | 
			
		||||
{
 | 
			
		||||
    uint16_t BufferPosition = 0;
 | 
			
		||||
    uint16_t cnt = 0;
 | 
			
		||||
    uint8_t digi_cnt=0;
 | 
			
		||||
    
 | 
			
		||||
    log_out( "Compose APRS from KISS frame");
 | 
			
		||||
    
 | 
			
		||||
    memset(txBuffer, 0, sizeof(txBuffer));
 | 
			
		||||
    
 | 
			
		||||
    // APRS header
 | 
			
		||||
    txBuffer[BufferPosition++] = '<';
 | 
			
		||||
    txBuffer[BufferPosition++] = 0xff;
 | 
			
		||||
    txBuffer[BufferPosition++] = 0x01;
 | 
			
		||||
    
 | 
			
		||||
    while ( KissTxFrame.source_address[cnt] != 0 && BufferPosition<MTU )
 | 
			
		||||
    {
 | 
			
		||||
        txBuffer[BufferPosition] = KissTxFrame.source_address[cnt];
 | 
			
		||||
        BufferPosition++;
 | 
			
		||||
        cnt++;
 | 
			
		||||
    }
 | 
			
		||||
    txBuffer[BufferPosition++] = '>';
 | 
			
		||||
    
 | 
			
		||||
    digi_cnt=0;
 | 
			
		||||
    while(digi_cnt <= KissTxFrame.number_of_digipeaters) {
 | 
			
		||||
        cnt=0;
 | 
			
		||||
        
 | 
			
		||||
        while ( KissTxFrame.digis[digi_cnt][cnt] != 0 && BufferPosition<MTU )
 | 
			
		||||
        {
 | 
			
		||||
            txBuffer[BufferPosition++] = KissTxFrame.digis[digi_cnt][cnt];
 | 
			
		||||
            cnt++;
 | 
			
		||||
        }
 | 
			
		||||
        txBuffer[BufferPosition++] = ',';
 | 
			
		||||
        digi_cnt++;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Overwrite last command with colon
 | 
			
		||||
    txBuffer[--BufferPosition] = ':';
 | 
			
		||||
    
 | 
			
		||||
    cnt=0;
 | 
			
		||||
    while ( KissTxFrame.data_field[cnt] != 0 && BufferPosition<MTU )
 | 
			
		||||
    {
 | 
			
		||||
        txBuffer[BufferPosition++] = KissTxFrame.data_field[cnt];
 | 
			
		||||
        cnt++;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Set variable to indicate a send request
 | 
			
		||||
    TransmitRequest = true; 
 | 
			
		||||
    
 | 
			
		||||
    // Ready for next input KISS frame.
 | 
			
		||||
    KissTxFrame.valid_data = false;
 | 
			
		||||
    
 | 
			
		||||
    log_out("%s\n", txBuffer);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void transmit() {
 | 
			
		||||
  uint16_t position = 0;
 | 
			
		||||
  
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user