| 17 | The User Command flow provides a simple way to send custom commands and data from your Python script to the WARP v3 nodes in your experimental network. This flow presents a simple pipe for exchanging arbitrary commands and responses between a Python script and the upper-level MAC in a WARP node running the 802.11 Reference Design. |
| 18 | |
| 19 | === Python === |
| 20 | In Python user commands are constructed as: |
| 21 | * Command ID: an arbitrary 24-bit integer |
| 22 | * Command arguments: an optional list of {{{u32}}} arguments supplied by the Python code that is passed to the C code handler |
| 23 | |
| 24 | The command ID is used by the C code to select which code block should process the command payload. The Python and C code must use matching lists of command IDs. All user command IDs must be 24-bit integers (i.e. in ~[0, 2^24-1]). The framework does not reserve any command ID values. |
| 25 | |
| 26 | The command arguments are an optional payload supplied by the Python script. The wlan_exp framework sends this payload to the node with no modifications. The arguments must be constructed as a list of unsigned 32-bit integers ({{{u32}}} values). The Python and C code must implement complementary argument construction/parsing functions. The argument list may be omitted if a command requires no payload. |
| 27 | |
| 28 | The WARP node must respond to every user command. The reference C code implements this response by default. Each command response may contain a payload supplied by the user C code. If the command handler supplies a response payload, this payload is conveyed back from the node to the Python code automatically. When present the response payload is always a list of {{{u32}}} values. Your Python and C code must implement complementary response payload generation/processing functions. |
| 29 | |
| 30 | User commands are passed to the wlan_exp framework using the {{{send_user_command(cmd_id, args)}}} method. For example: |
| 31 | |
| 32 | {{{#!python |
| 33 | #No command arguments, no response payload |
| 34 | my_node.send_user_command(CMDID_USR_MYCMD, args=None) |
| 35 | |
| 36 | #3 arguments, no response payload |
| 37 | my_node.send_user_command(CMDID_USR_MYCMD, args=[ARG0 ARG1 ARG2]) |
| 38 | |
| 39 | #2 arguments, with response payload |
| 40 | cmd_resp = my_node.send_user_command(CMDID_USR_MYCMD, args=[ARG0 ARG1]) |
| 41 | }}} |
| 42 | |
| 43 | For simple commands your Python script can call {{{send_user_command}}} directly. For more complicated commands it is suggested you implement your custom command functionality in a separate method. This will simplify debugging your code and reusing your custom commands across multiple experiments. The sample code below adopts the approach of a custom method for sending a user command. |
| 44 | |
| 45 | === MAC C Code === |
| 46 | |