@ -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 . TO DO
* 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 * ax25 frame)
uint16_t KissClass : : DecodeFrame ( uint8_t string [ ] , struct kiss_tx_frame * kisstx frame)
{
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 ;
position + + ;
}
ssid = ssid < < 1 ;
ssid | = 0b01100000 ;
ssid = ( ssid < < 1 ) | 0b01100000 ;
if ( repeat_flag = = 1 )
ssid | = 0b10000000 ;
// add encoded ssid to encoded call array
call [ 6 ] = ssid ;