diff options
Diffstat (limited to 'src/vpp-api/vapi')
-rw-r--r-- | src/vpp-api/vapi/vapi_doc.md | 155 | ||||
-rw-r--r-- | src/vpp-api/vapi/vapi_doc.rst | 191 |
2 files changed, 191 insertions, 155 deletions
diff --git a/src/vpp-api/vapi/vapi_doc.md b/src/vpp-api/vapi/vapi_doc.md deleted file mode 100644 index 0e7e29dde01..00000000000 --- a/src/vpp-api/vapi/vapi_doc.md +++ /dev/null @@ -1,155 +0,0 @@ -# VPP API module {#vapi_doc} - -## Overview - -VPP API module allows communicating with VPP over shared memory interface. -The API consists of 3 parts: - -* common code - low-level API -* generated code - high-level API -* code generator - to generate your own high-level API e.g. for custom plugins - -### Common code - -#### C common code - -C common code represents the basic, low-level API, providing functions to -connect/disconnect, perform message discovery and send/receive messages. -The C variant is in vapi.h. - -#### C++ common code - -C++ is provided by vapi.hpp and contains high-level API templates, -which are specialized by generated code. - -### Generated code - -Each API file present in the source tree is automatically translated to JSON -file, which the code generator parses and generates either C (`vapi_c_gen.py`) -or C++ (`vapi_cpp_gen.py`) code. - -This can then be included in the client application and provides convenient way -to interact with VPP. This includes: - -* automatic byte-swapping -* automatic request-response matching based on context -* automatic casts to appropriate types (type-safety) when calling callbacks -* automatic sending of control-pings for dump messages - -The API supports two modes of operation: - -* blocking -* non-blocking - -In blocking mode, whenever an operation is initiated, the code waits until it -can finish. This means that when sending a message, the call blocks until -the message can be written to shared memory. Similarly, receiving a message -blocks until a message becomes available. On higher level, this also means that -when doing a request (e.g. `show_version`), the call blocks until a response -comes back (e.g. `show_version_reply`). - -In non-blocking mode, these are decoupled, the API returns VAPI_EAGAIN whenever -an operation cannot be performed and after sending a request, it's up to -the client to wait for and process a response. - -### Code generator - -Python code generator comes in two flavors - C and C++ and generates high-level -API headers. All the code is stored in the headers. - -## Usage - -### Low-level API - -Refer to inline API documentation in doxygen format in `vapi.h` header -for description of functions. It's recommened to use the safer, high-level -API provided by specialized headers (e.g. `vpe.api.vapi.h` -or `vpe.api.vapi.hpp`). - -#### C high-level API - -##### Callbacks - -The C high-level API is strictly callback-based for maximum efficiency. -Whenever an operation is initiated a callback with a callback context is part -of that operation. The callback is then invoked when the response (or multiple -responses) arrive which are tied to the request. Also, callbacks are invoked -whenever an event arrives, if such callback is registered. All the pointers -to responses/events point to shared memory and are immediately freed after -callback finishes so the client needs to extract/copy any data in which it -is interested in. - -#### Blocking mode - -In simple blocking mode, the whole operation (being a simple request or a dump) -is finished and it's callback is called (potentially multiple times for dumps) -during function call. - -Example pseudo-code for a simple request in this mode: - -` -vapi_show_version(message, callback, callback_context) - -1. generate unique internal context and assign it to message.header.context -2. byteswap the message to network byte order -3. send message to vpp (message is now consumed and vpp will free it) -4. create internal "outstanding request context" which stores the callback, - callback context and the internal context value -5. call dispatch, which in this mode receives and processes responses until - the internal "outstanding requests" queue is empty. In blocking mode, this - queue always contains at most one item. -` - -**Note**: it's possible for different - unrelated callbacks to be called before -the response callbacks is called in cases where e.g. events are stored -in shared memory queue. - -#### Non-blocking mode - -In non-blocking mode, all the requests are only byte-swapped and the context -information along with callbacks is stored locally (so in the above example, -only steps 1-4 are executed and step 5 is skipped). Calling dispatch is up to -the client application. This allows to alternate between sending/receiving -messages or have a dedicated thread which calls dispatch. - -### C++ high level API - -#### Callbacks - -In C++ API, the response is automatically tied to the corresponding `Request`, -`Dump` or `Event_registration` object. Optionally a callback might be specified, -which then gets called when the response is received. - -**Note**: responses take up shared memory space and should be freed either -manually (in case of result sets) or automatically (by destroying the object -owning them) when no longer needed. Once a Request or Dump object was executed, -it cannot be re-sent, since the request itself (stores in shared memory) -is consumed by vpp and inaccessible (set to nullptr) anymore. - -#### Usage - -#### Requests & dumps - -0. Create on object of `Connection` type and call `connect()` to connect to vpp. -1. Create an object of `Request` or `Dump` type using it's typedef (e.g. - `Show_version`) -2. Use `get_request()` to obtain and manipulate the underlying request if - required. -3. Issue `execute()` to send the request. -4. Use either `wait_for_response()` or `dispatch()` to wait for the response. -5. Use `get_response_state()` to get the state and `get_response()` to read - the response. - -#### Events - -0. Create a `Connection` and execute the appropriate `Request` to subscribe to - events (e.g. `Want_stats`) -1. Create an `Event_registration` with a template argument being the type of - event you are insterested in. -2. Call `dispatch()` or `wait_for_response()` to wait for the event. A callback - will be called when an event occurs (if passed to `Event_registration()` - constructor). Alternatively, read the result set. - -**Note**: events stored in the result set take up space in shared memory -and should be freed regularly (e.g. in the callback, once the event is -processed). diff --git a/src/vpp-api/vapi/vapi_doc.rst b/src/vpp-api/vapi/vapi_doc.rst new file mode 100644 index 00000000000..4efbf2d9988 --- /dev/null +++ b/src/vpp-api/vapi/vapi_doc.rst @@ -0,0 +1,191 @@ +.. _vapi_doc: + +VPP API module +============== + +Overview +-------- + +VPP API module allows communicating with VPP over shared memory +interface. The API consists of 3 parts: + +- common code - low-level API +- generated code - high-level API +- code generator - to generate your own high-level API e.g. for custom + plugins + +Common code +~~~~~~~~~~~ + +C common code +^^^^^^^^^^^^^ + +C common code represents the basic, low-level API, providing functions +to connect/disconnect, perform message discovery and send/receive +messages. The C variant is in vapi.h. + +.. _c-common-code-1: + +C++ common code +^^^^^^^^^^^^^^^ + +C++ is provided by vapi.hpp and contains high-level API templates, which +are specialized by generated code. + +Generated code +~~~~~~~~~~~~~~ + +Each API file present in the source tree is automatically translated to +JSON file, which the code generator parses and generates either C +(``vapi_c_gen.py``) or C++ (``vapi_cpp_gen.py``) code. + +This can then be included in the client application and provides +convenient way to interact with VPP. This includes: + +- automatic byte-swapping +- automatic request-response matching based on context +- automatic casts to appropriate types (type-safety) when calling + callbacks +- automatic sending of control-pings for dump messages + +The API supports two modes of operation: + +- blocking +- non-blocking + +In blocking mode, whenever an operation is initiated, the code waits +until it can finish. This means that when sending a message, the call +blocks until the message can be written to shared memory. Similarly, +receiving a message blocks until a message becomes available. On higher +level, this also means that when doing a request +(e.g. ``show_version``), the call blocks until a response comes back +(e.g. ``show_version_reply``). + +In non-blocking mode, these are decoupled, the API returns VAPI_EAGAIN +whenever an operation cannot be performed and after sending a request, +it’s up to the client to wait for and process a response. + +Code generator +~~~~~~~~~~~~~~ + +Python code generator comes in two flavors - C and C++ and generates +high-level API headers. All the code is stored in the headers. + +Usage +----- + +Low-level API +~~~~~~~~~~~~~ + +Refer to inline API documentation in doxygen format in ``vapi.h`` header +for description of functions. It’s recommended to use the safer, +high-level API provided by specialized headers (e.g. ``vpe.api.vapi.h`` +or ``vpe.api.vapi.hpp``). + +C high-level API +^^^^^^^^^^^^^^^^ + +Callbacks +''''''''' + +The C high-level API is strictly callback-based for maximum efficiency. +Whenever an operation is initiated a callback with a callback context is +part of that operation. The callback is then invoked when the response +(or multiple responses) arrive which are tied to the request. Also, +callbacks are invoked whenever an event arrives, if such callback is +registered. All the pointers to responses/events point to shared memory +and are immediately freed after callback finishes so the client needs to +extract/copy any data in which it is interested in. + +Blocking mode +^^^^^^^^^^^^^ + +In simple blocking mode, the whole operation (being a simple request or +a dump) is finished and it’s callback is called (potentially multiple +times for dumps) during function call. + +Example pseudo-code for a simple request in this mode: + +\` vapi_show_version(message, callback, callback_context) + +1. generate unique internal context and assign it to + message.header.context +2. byteswap the message to network byte order +3. send message to vpp (message is now consumed and vpp will free it) +4. create internal “outstanding request context” which stores the + callback, callback context and the internal context value +5. call dispatch, which in this mode receives and processes responses + until the internal “outstanding requests” queue is empty. In blocking + mode, this queue always contains at most one item. \` + +**Note**: it’s possible for different - unrelated callbacks to be called +before the response callbacks is called in cases where e.g. events are +stored in shared memory queue. + +Non-blocking mode +^^^^^^^^^^^^^^^^^ + +In non-blocking mode, all the requests are only byte-swapped and the +context information along with callbacks is stored locally (so in the +above example, only steps 1-4 are executed and step 5 is skipped). +Calling dispatch is up to the client application. This allows to +alternate between sending/receiving messages or have a dedicated thread +which calls dispatch. + +.. _c-high-level-api-1: + +C++ high level API +~~~~~~~~~~~~~~~~~~ + +.. _callbacks-1: + +Callbacks +^^^^^^^^^ + +In C++ API, the response is automatically tied to the corresponding +``Request``, ``Dump`` or ``Event_registration`` object. Optionally a +callback might be specified, which then gets called when the response is +received. + +**Note**: responses take up shared memory space and should be freed +either manually (in case of result sets) or automatically (by destroying +the object owning them) when no longer needed. Once a Request or Dump +object was executed, it cannot be re-sent, since the request itself +(stores in shared memory) is consumed by vpp and inaccessible (set to +nullptr) anymore. + +.. _usage-1: + +Usage +^^^^^ + +Requests & dumps +^^^^^^^^^^^^^^^^ + +0. Create on object of ``Connection`` type and call ``connect()`` to + connect to vpp. +1. Create an object of ``Request`` or ``Dump`` type using it’s typedef + (e.g. ``Show_version``) +2. Use ``get_request()`` to obtain and manipulate the underlying request + if required. +3. Issue ``execute()`` to send the request. +4. Use either ``wait_for_response()`` or ``dispatch()`` to wait for the + response. +5. Use ``get_response_state()`` to get the state and ``get_response()`` + to read the response. + +Events +^^^^^^ + +0. Create a ``Connection`` and execute the appropriate ``Request`` to + subscribe to events (e.g. ``Want_stats``) +1. Create an ``Event_registration`` with a template argument being the + type of event you are interested in. +2. Call ``dispatch()`` or ``wait_for_response()`` to wait for the event. + A callback will be called when an event occurs (if passed to + ``Event_registration()`` constructor). Alternatively, read the result + set. + +**Note**: events stored in the result set take up space in shared memory +and should be freed regularly (e.g. in the callback, once the event is +processed). |