Staging:CC31xx & CC32xx Advanced Networking

Introduction
This page describes in detail, the different features/options that could be built around raw-sockets - These options can be used to develop advanced networking applications using CC3x00. Using raw sockets, the application can be designed to bypass few/certain networking layers and implement their proprietary protocols.

Raw sockets provide the following three options to be operated in:
 * Raw Socket Mode: It’s a regular L4 socket above the “Network” layer that allow applications to directly read/write the IP datagrams
 * Stack Bypass Mode: It’s similar to the regular ‘raw-socket’ but by defining some socket options, the applications can bypass the “Network” layer as well
 * Transceiver Mode: These are L2 sockets and allow applications to read/write datagrams directly over WLAN PHY. It’s a Texas Instruments proprietary mode

The page also discusses about the various filters that can be applied to the incoming packets.

Raw socket mode
This mode enables applications to directly read/write IPv4 datagrams bypassing the ‘Transport’ layer. It as well lets applications read and process ICMPv4/6 and IGMP packets separately.

CC3x00 only processes a subset of all the “Protocol” types that are defined in IANA’s ‘Protocol Numbers’ registry. All the other packet types can be read directly by the application (if it intends to) over raw-sockets and processed.

The device should be connected to an access-point for working in this mode.

Socket creation
This section explains how a raw-socket is created by the application using the host-driver APIs.
 * A raw socket is created using ‘sl_Socket’ API and by defining the socket ‘type’ as ‘SL_SOCK_RAW’
 * Domain as SL_AF_INET: It defines the address/protocol-family of the to-be created socket.
 * Type as SL_SOCK_RAW: This is to indicate that the socket is of raw data-type.
 * : It specifies the protocol’s type that shall be associated w/ the socket. Different combinations (like SL_IPPROTO_TCP, SL_IPPROTO_UDP, SL_IPPROTO_RAW etc.) are possible here and w/ each combination, CC3x00 interacts differently w/ the application that has created the raw-socket. This value is what the ‘Network’ layer will write to the ‘PROTOCOL’ field in its header (IP Frame) to define the upper level protocol. This is one of the most critical fields when creating a raw-socket – The ‘Network’ layer of the receiver will use it to deliver the packet to appropriate upper level layers.




 * A value 0 can be used as well for  to select a default protocol from the selected domain and type.


 * On success, a 4Byte socket handle is returned that shall be used for subsequent socket operations.


 * ‘sl_Bind’ can be called on a raw-socket but this is rare. There is no concept of a port-number in a raw-socket, and hence this function sets only the local address. With regard to the raw-socket output, calling ‘sl_Bind’ sets the ‘Source IP Address’ that will be used for datagrams sent on the raw-socket.
 * ‘sl_Connect’ can be called on a raw-socket, but again, this is rare. With regard to the output, calling ‘sl_Connect’ sets the ‘Destination IP Address’ that shall be used by the datagrams sent on the raw-socket – This lets the applications use ‘sl_Send’ instead of ‘sl_SendTo’.

Socket output>>

 * The encapsulated raw-data packet (w/o IP headers) can now be sent over raw-socket using ‘sl_Send’ – It shall be called w/ below parameters
 * : A 4Byte handler returned when creating the socket
 * : It’s the encapsulated raw-data that’s to be transmitted over ‘Network’ layer
 * : It’s the size of the packet in bytes


 * The opened socket can then be closed using ‘sl_Close’ API

Socket input<<

 * Once the raw-socket is created, the raw-data packets can be received using ‘sl_Recv’ – This API shall be called w/ below parameters. It’s the application’s responsibility to process these IP datagrams.
 * : A 4Byte handler returned when creating the socket
 *  : It’s the buffer into which the raw-data shall be received
 * : It’s the size of the packet in bytes
 *  : It shall be set to ‘0’ 


 * The opened socket can then be closed using ‘sl_Close’ API


 * CC3x00 passes the received datagrams to application’s raw-socket w/ below rules:
 * Received UDP and TCP packets are never passed to the raw-sockets – If the application wants to read these IP datagrams, it has to read the packets from L2 layer itself.
 * All ICMP packets other than echo-requests, timestamp requests and address-mask-requests are passed to the raw-sockets.
 * All IGMP messages are passed to the raw sockets after some basic processing in NWP.
 * All IP datagrams that the device doesn’t understand are passed to raw-sockets to be processed by application.


 * CC3x00 performs the following tests on a raw-socket and delivers the datagram on this socket only if below tests are true:
 * If the application has created the raw-socket w/ a nonzero value for , then the received datagram's ‘PROTOCOL’ field must match this value for the datagram to be delivered to this socket.
 * If the application has created a raw-socket and bound a local IP address to it using ‘sl_Bind’, then the ‘Destination IP Address’ of the received datagram must match this address for the datagram to be delivered to this socket.
 * If the application has created a raw-socket and assigned a ‘Destination IP Address’ to it using ‘sl_Connect’, then the ‘Source IP Address’ of the received datagram must match this address for the datagram to be delivered to this socket.

Stack bypass mode
By settings few additional socket properties, applications can use raw sockets to directly write/read 802.11 MAC datagrams, bypassing the IP stack completely.

The device should be connected to an access-point for working in this mode.

Socket creation
A raw-socket for bypassing the IP stack can be created in the same way as that of a normal raw-socket. Application only need to set ‘SL_IP_HDRINCL’ property of the raw-socket to indicate CC3x00 that the IP headers are already added to the data-packet and that it can directly pass the packets to the lower layer (w/o adding IP headers again)

Socket output>>
The L2/MAC datagrams can be written in the same way as that of a L3/IP datagrams. Please refer to the Socket output>> section above for more details.

Socket input<<
The L2/MAC datagrams can be read in the same way as that of a L3/IP datagrams. Please refer to the Socket input<< section above for more details.

Transceiver mode
It’s the Texas Instruments proprietary mode, using which applications can bypass the IP and MAC layers altogether, thereby allowing the application-developers define their proprietary protocols over WLAN PHY. ‘CC3x00_TransceiverMode_vXX.pdf has detailed information on this topic.

Socket creation

 * Firstly, the socket has to be created with a couple of unique parameters to start the ‘Transceiver Mode’ feature
 * Domain as SL_AF_RF: This is to indicate the device to override 802.11 headers for transmission and reception. For optimized power consumption, the socket will be started in TX-only mode until ‘sl_Recv’ is activated.
 * Type as SL_SOCK_RAW: This is to indicate that the socket is of raw data-type. And since ‘Domain’ is set to ‘SL_AF_RF’, this indicates the device that it’s a L1 socket
 * : This is to configure the operational channel to receive and transmit data on

On success, a 4Byte socket handle is returned that shall be used for subsequent socket operations.

Socket output>>

 * Once the raw-socket is created, the encapsulated raw-data packet can now be sent using ‘sl_Send’ – It shall be called w/ below parameters
 * : A 4Byte handler returned when creating the socket
 * RawPingPacket: It’s the encapsulated raw-data that’s to be transmitted over WLAN PHY
 * : It’s the size of the packet in bytes
 * : In ‘Transceiver Mode’, macro ‘SL_RAW_RF_TX_PARAMS’ shall be used for setting the transmission parameters.
 * a. : This is to configure the operational channel to receive and transmit data on.
 * b.  : This is to configure the rate-of-transmission
 * c. : This is to set the Tx power (1 being the highest) – Each level induces a 3dB loss on signal strength.
 * d.  : This is to set the preamble value – A ‘0’ is to indicate a short-nibble and a ‘1’ is to indicate a long-nibble.


 * The opened socket can then be closed using ‘sl_Close’ API.

Socket input<<

 * Once the raw-socket is created, the raw-data packet can be received using ‘sl_Recv’ – It shall be called w/ below parameters. It’s the application’s responsibility to process these MAC datagrams.
 * : A 2Byte handler returned when creating the socket
 *  : It’s the buffer into which the raw-data shall be received
 * <packet_size>: It’s the size of the packet in bytes
 *  : It shall be set to ‘0’


 * CC3x00 device will add 8Bytes of proprietary radio header to the received packet. The header will have important information about the packet. The actual data will follow this 8Byte header and the application developers shall have to parse it as per their protocol
 * The opened socket can then be closed using ‘sl_Close’ API

Use-cases
Using the modes described above, many use-cases can be defined by the application. Below are few applications that could be built using raw-sockets:

Sniffer
In ‘Transceiver Mode’, the device can receive every packet that’s on the air and hence can be used to implement ‘Sniffer’ like applications. Document: CC3x00_TransceiverMode_v01.pdf has detailed description on how raw-packets can be received in ‘Transceiver Mode’.

The application developers can as well define filters and apply them to the received frames.

Tagging
In ‘Transceiver Mode’, the device can transmit raw-packets continuously over WLAN PHY and hence can be used to implement ‘Tagging’ applications. Document: CC3x00_TransceiverMode_v01.pdf has detailed description on how raw-packets can be transmitted in ‘Transceiver Mode’.

Receiver-Statistics
In ‘Transceiver Mode’, the device can transmit raw-packets continuously over WLAN PHY and hence can be used to implement applications that could measure the packet loss at the receiver.

CC3x00’s host-driver has functions defined to measure the Rx-statistics on the receiver side.

Radio Tool for RF evaluation
Using the Tx and Rx functionalities defined above for/in ‘Transceiver Mode’, application developers can design radio-tools for evaluating their device’s RF performance.

In addition to the legacy transmission and reception discussed above, application developers can as well:
 * Set the raw socket properties, instructing WLAN PHY to continuously transmit a given packet ‘n’ number of times
 * Instruct the device to transmit a ‘Continuous Wave’ at a given power-level

Proprietary Protocol Definition
Raw-sockets, in various modes defined above, can be used by applications for transmitting proprietary information – It as well enables application-developers to define their own protocols at/over various layers of the networking model.

Rx-Filters
CC3x00’s ‘Rx-Filter’ feature enables the application-developers to define and manage the filtering process for every packet that’s received. The primary motivation of having this feature in the device is to reduce the traffic that gets transferred to the host and in-turn achieves an efficient power-management scheme.

Every frame received by the device traverses through a series of ‘Decision Trees’ that determine how the frame should be handled. The ‘Decision Trees’ are composed of one-or-more ‘Filter Nodes’ and each node has its ‘filter-rule’, ‘trigger’ and ‘action’. The frame’s filtering process will start at the decision-tree’s root node, and if the received frame’s characters match the node’s ‘filter-rule’ and ‘trigger’, the ‘action’ will be performed. The received frame will then traverse to the child-node, if any.

Let’s suppose, a user wants to create filers w/ below rules:


 * Receive ‘Data’ broadcast frames from MAC address ‘A1:A2:A3:A4:A5:A6’ and ‘B1:B2:B3:B4:B5:B6’ only, the “Decision-Tree” that shall be created would look like:




 * Receive all unicast frames w/ below rules:
 * Drop the frames from IP ‘192.168.1.100’
 * If the frame is received from MAC address ‘A1:A2:A3:A4:A5:A6’, perform ‘Action-1’
 * If the frame is received from MAC address ‘B1:B2:B3:B4:B5:B6’, perform ‘Action-2’
 * If the frame received on MAC address ‘A1:A2:A3:A4:A5:A6’ or ‘B1:B2:B3:B4:B5:B6’ is a ‘UDP’ packet, drop all frames that are not from port-5001

The ‘Decision-Tree’ for the above rule shall be as below:



Sample Application
CC3x00’s host-driver provides extensive set of APIs for the application-developers to create and manage the ‘Rx-Filters’. The use-case implemented below provides more and detailed insight on how these features could/should be used in end-applications.

Sniffer
Let’s define a ‘Sniffer-like’ application using CC3x00’s ‘Raw sockets’ and ‘Rx-Filters’ feature. For ease of discussion, let’s design the application to sniff all the incoming packets over WLAN PHY (.i.e. in Transceiver Mode) and drop the ones that are not from MAC address ‘A1:A2:A3:A4:A5:A6’. The application developers, can as well, develop applications to receive data in other ‘raw-socket’ modes and apply other filters to the incoming packets.


 * A ‘Rx-Filter’ can be created using host-driver API ‘sl_WlanRxFilterAdd’ – It shall be called w/ below parameters:
 * <rule_type>: This 1Byte parameter defines the type of the rule. Since we intend to apply the rule to the incoming packet’s header, this shall be set to HEADER (Its value is defined as 0 in host-driver). The only other value supported for <rule_type> now is ‘COMBINATION’.
 * <filter_flag>: This 1Byte parameter defines the behavior of the Rx-Filter and shall be set to ‘RX_FILTER_BINARY’ since we are not defining ASCII values here.
 *  : This variable defines the filter-rule’s logic and since ours is a ‘HEADER’ type rule, ‘SlrxFilterHeaderType_t’ shall be filled by the application:
 * a. RuleHeaderfield: Since the filter is for the source’s MAC-Address, this field has to be set as ‘MAC_SRC_ADDRESS_FIELD’
 * b. RuleHeaderArgs.RxFilterDB6BytesRuleArgs: This field has to be filled w/ the source’s MAC-Address with which the incoming packet shall be compared. ‘RuleHeaderArgs’ has large and small size buffers as well for holding the header arguments – Use appropriate fields as per the HEADER rules.
 * c. RuleHeaderArgs.RuleHeaderArgsMask: It’s a mask value used for partial comparison – We set it to 0xFFFFFFFF since we don’t intend to use this mask.
 * d. RuleCompareFunc: Since we intend to drop all packets that don’t match our rule, this shall be set as ‘COMPARE_FUNC_NOT_EQUAL_TO’
 *  : This parameter ‘triggers’ the rule
 * a. ParentFilterID: It shall be set to 0 since it’s a parent-node
 * b. Trigger: There is no trigger to activate this rule and hence it’s set to ‘NO_TRIGGER’. The rule will be active on below connection-state and role
 * c. TriggerArgConnectionState.IntRepresentation: Shall be set to 0 <TBD – Why?? And will it still be used when trigger is set to NO_TRIGGER>
 * d. TriggerArgRoleStatus.IntRepresentation: Shall be set to RX_FILTER_ROLE_PROMISCUOUS <TBD – Why?? And will it still be used when trigger is set to NO_TRIGGER >
 *  : It defines the action to be taken when there is a match in rule and since we intend to drop the packet, it shall be set to ‘RX_FILTER_ACTION_DROP’
 * <filter-id>: Shall be set to 0 since it’s a parent node


 * The functionalities in the above code snippet can be called before receiving raw-datagrams in ‘Transceiver Mode’ to apply the Rx-filters