+// - Remote Capability Variables -
+#define Connect_receive_RemoteCapabilityMaxArgs 5 // XXX Calculate the max using kll
+RemoteCapabilityCommand Connect_receive_RemoteCapabilityBuffer;
+uint8_t Connect_receive_RemoteCapabilityArgs[Connect_receive_RemoteCapabilityMaxArgs];
+
+uint8_t Connect_receive_RemoteCapability( uint8_t byte, uint16_t *pending_bytes, uint8_t uart_num )
+{
+ // Check which byte in the packet we are at
+ switch ( (*pending_bytes)-- )
+ {
+ // Byte count always starts at 0xFFFF
+ case 0xFFFF: // Device Id
+ Connect_receive_RemoteCapabilityBuffer.id = byte;
+ break;
+
+ case 0xFFFE: // Capability Index
+ Connect_receive_RemoteCapabilityBuffer.capabilityIndex = byte;
+ break;
+
+ case 0xFFFD: // State
+ Connect_receive_RemoteCapabilityBuffer.state = byte;
+ break;
+
+ case 0xFFFC: // StateType
+ Connect_receive_RemoteCapabilityBuffer.stateType = byte;
+ break;
+
+ case 0xFFFB: // Number of args
+ Connect_receive_RemoteCapabilityBuffer.numArgs = byte;
+ *pending_bytes = byte;
+ break;
+
+ default: // Args (# defined by previous byte)
+ Connect_receive_RemoteCapabilityArgs[
+ Connect_receive_RemoteCapabilityBuffer.numArgs - *pending_bytes + 1
+ ] = byte;
+
+ // If entire packet has been fully received
+ if ( *pending_bytes == 0 )
+ {
+ // Determine if this is the node to run the capability on
+ // Conditions: Matches or broadcast (0xFF)
+ if ( Connect_receive_RemoteCapabilityBuffer.id == 0xFF
+ || Connect_receive_RemoteCapabilityBuffer.id == Connect_id )
+ {
+ extern const Capability CapabilitiesList[]; // See generatedKeymap.h
+ void (*capability)(uint8_t, uint8_t, uint8_t*) = (void(*)(uint8_t, uint8_t, uint8_t*))(
+ CapabilitiesList[ Connect_receive_RemoteCapabilityBuffer.capabilityIndex ].func
+ );
+ capability(
+ Connect_receive_RemoteCapabilityBuffer.state,
+ Connect_receive_RemoteCapabilityBuffer.stateType,
+ &Connect_receive_RemoteCapabilityArgs[2]
+ );
+ }
+
+ // If this is not the correct node, keep sending it in the same direction (doesn't matter if more nodes exist)
+ // or if this is a broadcast
+ if ( Connect_receive_RemoteCapabilityBuffer.id == 0xFF
+ || Connect_receive_RemoteCapabilityBuffer.id != Connect_id )
+ {
+ // Prepare outgoing packet
+ Connect_receive_RemoteCapabilityBuffer.command = RemoteCapability;
+
+ // Send to the other UART (not the one receiving the packet from
+ uint8_t uart_direction = uart_num == UART_Master ? UART_Slave : UART_Master;
+
+ // Lock Tx UART
+ switch ( uart_direction )
+ {
+ case UART_Master: uart_lockTx( UART_Master ); break;
+ case UART_Slave: uart_lockTx( UART_Slave ); break;
+ }
+
+ // Send header
+ uint8_t header[] = { 0x16, 0x01 };
+ Connect_addBytes( header, sizeof( header ), uart_direction );
+
+ // Send Remote Capability and arguments
+ Connect_addBytes( (uint8_t*)&Connect_receive_RemoteCapabilityBuffer, sizeof( RemoteCapabilityCommand ), uart_direction );
+ Connect_addBytes( Connect_receive_RemoteCapabilityArgs, Connect_receive_RemoteCapabilityBuffer.numArgs, uart_direction );
+
+ // Unlock Tx UART
+ switch ( uart_direction )
+ {
+ case UART_Master: uart_unlockTx( UART_Master ); break;
+ case UART_Slave: uart_unlockTx( UART_Slave ); break;
+ }
+ }
+ }
+ break;
+ }
+
+ // Check whether the scan codes have finished sending
+ return *pending_bytes == 0 ? 1 : 0;
+}
+