Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decouple RF Packet Functions - Avoid Imports #74

Open
kb1lqd opened this issue May 7, 2017 · 1 comment
Open

Decouple RF Packet Functions - Avoid Imports #74

kb1lqd opened this issue May 7, 2017 · 1 comment

Comments

@kb1lqd
Copy link
Contributor

kb1lqd commented May 7, 2017

Decouple the layer stacks by using function pointers that allow interactions between the stacks by pointing to a function rather than full import of the header. This will follow the higher levels of RF and UART stack interactions with applications themselves while allowing easier debugging.

This is a push to both clean, optimize, and potentially fix bugs such as corrupted telemetry data possibly getting sent to proxy.

Correct Method Example - Command Application

The command application "opens" a port from the RF receive stack which just places a function pointer to the command application PUT() function using a standardized FIFO interface. The pointer is stored in an array where the index is the "port".

To assign the command application through a function pointer the initialization in main{} is performed:

//Open RX RF service ports (Transport Layer)
rf_rx_service_open(2, app_command_rf_rx_put, 0); // RF Command Link, not safe for broadcast reception

When a data packet at the transport layer level is received the RF network stack uses the assigned port to call the correct standardized PUT() function in the Command application:

void rf_rx_stack_rx(unsigned char service_number, unsigned char *data, unsigned char payload_len){
	//Recieved a new uart packet from external device
	//ALL APPLICATIONS MUST BUFFER AS FULL UART HIGH LEVEL FRAME
	if((service_number <RF_SERVICE_ELEMENT_COUNT) && (srvc_open_func_ptrs[service_number] != 0)){
			(*srvc_open_func_ptrs[service_number]) (data, service_number);
		}
	else{
		__no_operation(); //Bad service port or registration, not a valid pointer in array.
	}
}

Command Application interacts with RF receive through this PUT() function the is used through a function pointer.

void app_command_rf_rx_put(unsigned char *packet){
//Put into the same local command queue
put_fifo_sram(&app_command_rx_fifo_state_machine, packet);
}

It is important to realize that:

  • Command application never imported the RF Network Stack header
  • RF Network Stack never imported Command application

Incorrect Implementation

Note below that the includes for "rf_transport.h" (layer 4) directly imported "rf.h" (layer 2) and this is unwanted and causing both headers to be coupled. This breaks the modular desirement and creates blurred interfaces between layers.

/* -- Includes -- */

/* standard includes */
#include "cc430f6137.h"
#include "rf_transport.h"

/* faraday rf layer 2 include */
#include "rf.h"

/* faraday rf layer 4 service include */
#include "rf_service.h"

/* faraday fifo include */
#include "../Ring_Buffers/FIFO.h"

/* faraday hardware allocation include */
#include "../REVA_Faraday.h"

/* faraday gpio hardware abstraction functions */
#include "../HAL/GPIO.h"

RF Layer 2 (rf.c)

Calls To Layer 4 (rf_transport.h)

Lines

  • 337 - rf_transport_parse()
  • 343 - rf_transport_parse()

These references are in rf_housekeeping() and simply checking the transport FIFO for new data from Layer 4 to Layer 2.

void rf_housekeeping(void){
	__no_operation();
	unsigned char status;
	if(rf_check_tx_fifo() && !transmitting_flag){
		ReceiveOff();
		rf_get_next_tx_fifo();
		}
	else if(rf_datalink_rx_fifo_state_machine.inwaiting>0){
		//Get packet from queue
		status = get_fifo(&rf_datalink_rx_fifo_state_machine, &rf_datalink_rx_fifo_buffer, rf_rx_datalink_buffer);

		//Parse received packet
		rf_datalink_parse(&rf_rx_datalink_buffer);

		//Determine destination of RX'd packet
		if(strstr((char *)rf_datalink_packet_rx_struct.destination_callsign, (char *)local_callsign) != NULL){
			if(rf_datalink_packet_rx_struct.destination_identifier == local_device_id){
				//__no_operation(); //This device!
				rf_transport_parse((unsigned char *)rf_datalink_packet_rx_struct.payload, 0);
			}
		}

		else if(*strstr((char *)rf_datalink_packet_rx_struct.destination_callsign, (char *)"CQCQCQ")){
			//__no_operation(); //Broadcast
				rf_transport_parse((unsigned char *)rf_datalink_packet_rx_struct.payload, 1);
		}

		else{
			//__no_operation(); //All others
		}
	}
	else{
	}
}

Layer 4 (rf_transport.c)

rf_transport.c includes both layer 2 and rf service headers:

/* faraday rf layer 2 include */
#include "rf.h"

/* faraday rf layer 4 service include */
#include "rf_service.h"

rf.h

Line

  • 48 - rf_tx_datalink_packet()

rf_service.h

Line

  • 91 - rf_rx_service_broadcast_rule_get()
  • 93 - rf_rx_stack_rx()
  • 98 - rf_rx_stack_rx()

Layer 4 Services (rf_services.h)

This layer doesn't seem to have any of its own import issues but it is also a weird header to have.

@kb1lqd
Copy link
Contributor Author

kb1lqd commented May 7, 2017

I'm going to start with Layer 4 <-> Layer 4 service first.

Line

  • 91 - rf_rx_service_broadcast_rule_get()
  • 93 - rf_rx_stack_rx()
  • 98 - rf_rx_stack_rx()

rf_rx_service_broadcast_rule_get()

Broadcast rule is a method for Faraday to determine if the packet should be accepted if it is not addressed to the specific Faraday (i.e. broadcasted). Unit specific data is determined at layer 2 (datalink) and therefore needs to be filtered to avoid commands from affecting ALL units in an area but allow all units to receive broadcasted telemetry.

Broadcast function argument is determined if the destination callsign is CQCQCQ.

For some reason I keep rf_rx_service_broadcast_rule_get() in services and this is an array where the indexes are the "ports" and if the value is 1 then that port is allowed to accept "broadcasted" data.

This really should be done completely in layer 2.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant