Framework#

In addition to Guidance API and Flight supervisor API, Air SDK provides access to generic libraries.

Supported languages are C/C++ and Python.

Parrot specific libraries:

  • Msghub exchanges messages between processes (Python binding available)

  • Pomp event loop management (Python binding available)

  • Shsettings allows to change settings from any process (Python binding available)

  • Telemetry gives access to data flight between processes via shared memory (Python binding available)

  • Ulog macros and functions to log text message in the logging system (Python binding available)

  • Video-acquisition give access to camera auto-exposure settings

  • Video-ipc gives access to video feeds

Open source libraries:

You can find these libraries on Github Parrot open source.

API Parrot#

Msghub#

Telemetry#

Video-acquisition#

Video-ipc#

Pomp#

Library for event loop management (based on poll/epoll mechanism). Also contains timer and socket utilities. For further information, you can find the source code here.

POMP_API struct pomp_loop *pomp_loop_new(void)#

Create a new loop structure.

Returns:

loop structure or NULL in case of error.

POMP_API int pomp_loop_destroy(struct pomp_loop *loop)#

Destroy a loop.

Parameters:

loop – : loop to destroy.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_loop_add(struct pomp_loop *loop, int fd, uint32_t events, pomp_fd_event_cb_t cb, void *userdata)#

Register a new fd in loop.

See also

pomp_fd_event.

Parameters:
  • loop – : loop.

  • fd – : fd to register.

  • events – : events to monitor.

  • cb – : callback for notifications.

  • userdata – user data for callback.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_loop_update(struct pomp_loop *loop, int fd, uint32_t events)#

Modify the set of events to monitor for a registered fd.

See also

pomp_fd_event.

Parameters:
  • loop – : loop.

  • fd – : fd to modify.

  • events – : new events to monitor.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_loop_update2(struct pomp_loop *loop, int fd, uint32_t events_to_add, uint32_t events_to_remove)#

Modify the set of events to monitor for a registered fd.

See also

pomp_fd_event.

See also

pomp_fd_event.

Parameters:
  • loop – : loop.

  • fd – : fd to modify.

  • events_to_add – : events to add.

  • events_to_remove – : events to remove.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_loop_remove(struct pomp_loop *loop, int fd)#

Unregister a fd from the loop

Parameters:
  • loop – : loop.

  • fd – : fd to unregister.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_loop_has_fd(struct pomp_loop *loop, int fd)#

Check if fd has been added in loop.

Parameters:
  • loop – : loop.

  • fd – : fd to check.

Returns:

1 if fd is in loop 0 otherwise.

POMP_API int pomp_loop_process_fd(struct pomp_loop *loop)#

Function to be called when the loop is signaled for readiness.

Remark

this is equivalent to calling pomp_loop_wait_and_process with a timeout of 0 (no wait).

Parameters:

loop – : loop.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_loop_wait_and_process(struct pomp_loop *loop, int timeout)#

Wait for events to occur in loop and process them.

Parameters:
  • loop – : loop.

  • timeout – : timeout of wait (in ms) or -1 for infinite wait.

Returns:

0 in case of success, -ETIMEDOUT if timeout occurred, negative errno value in case of error.

POMP_API int pomp_loop_wakeup(struct pomp_loop *loop)#

Wakeup a loop from a wait in pomp_loop_wait_and_process.

Remark

: this function is safe to call from another thread that the one associated normally with the loop. It is also safe to call it from a signal handler. However caller must ensure that the given context will be valid for the complete duration of the call.

Parameters:

loop – : loop.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_loop_idle_add(struct pomp_loop *loop, pomp_idle_cb_t cb, void *userdata)#

Register a function to be called when loop is idle, i.e. there is no event to be processed. The registered function will be called only once and in the order they are registered.

Remark

: this function is useful to register cleanup functions when called by an fd event callback for example.

Remark

: this function is safe to call from another thread that the one associated normally with the loop. However caller must ensure that the given loop will be valid for the complete duration of the call.

Parameters:
  • loop – : loop.

  • cb – : callback to call.

  • userdata – : user data for callback.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_loop_idle_remove(struct pomp_loop *loop, pomp_idle_cb_t cb, void *userdata)#

Unregister a function registered with pomp_loop_idle_add.

Remark

: if nothing match the given criteria, no error is returned.

Remark

: if several match the given criteria, all are removed.

Remark

: this function is safe to call from another thread that the one associated normally with the loop. However caller must ensure that the given loop will be valid for the complete duration of the call.

Parameters:
  • loop – : loop.

  • cb – : callback given in pomp_loop_idle_add.

  • userdata – : user data given in pomp_loop_idle_add.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API struct pomp_evt *pomp_evt_new(void)#

Create a new event.

Returns:

new event or NULL in case of error.

POMP_API int pomp_evt_destroy(struct pomp_evt *evt)#

Destroy an event.

Parameters:

evt – : event to destroy.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_evt_attach_to_loop(struct pomp_evt *evt, struct pomp_loop *loop, pomp_evt_cb_t cb, void *userdata)#

Attach a pomp_evt to a loop.

Parameters:
  • evt – : event to attach.

  • loop – : loop to attach to.

  • cb – : callback for notifications.

  • userdata – user data for callback.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_evt_detach_from_loop(struct pomp_evt *evt, struct pomp_loop *loop)#

Detach an event from a loop.

Parameters:
  • evt – : event to detach.

  • loop – : loop.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_evt_is_attached(struct pomp_evt *evt, struct pomp_loop *loop)#

Check if the event is attached to the given loop.

Parameters:
  • evt – : event to check.

  • loop – : loop to check. If NULL, check if the event is attached to any loop.

Returns:

1 if event is attached to the given loop, 0 otherwise.

POMP_API int pomp_evt_signal(struct pomp_evt *evt)#

Signal an event.

The fd associated with the pomp_evt will become readable.

Parameters:

evt – : event.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_evt_clear(struct pomp_evt *event)#

Clear an event.

The fd associated with the pomp_evt will no longer be readable.

Parameters:

evt – : event.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API struct pomp_timer *pomp_timer_new(struct pomp_loop *loop, pomp_timer_cb_t cb, void *userdata)#

Create a new timer.

Parameters:
  • loop – : fd loop to use for notifications.

  • cb – : callback to use for notifications.

  • userdata – : user data for callback.

Returns:

new timer or NULL in case of error.

POMP_API int pomp_timer_destroy(struct pomp_timer *timer)#

Destroy a timer.

Parameters:

timer – : timer to destroy.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_timer_set(struct pomp_timer *timer, uint32_t delay)#

Set a one shot timer.

Parameters:
  • timer – : timer to set.

  • delay – : expiration delay in milliseconds.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_timer_set_periodic(struct pomp_timer *timer, uint32_t delay, uint32_t period)#

Set a periodic timer.

Parameters:
  • timer – : timer to set.

  • delay – : initial expiration delay in milliseconds.

  • period – : period in milliseconds.

Returns:

0 in case of success, negative errno value in case of error.

POMP_API int pomp_timer_clear(struct pomp_timer *timer)#

Clear a timer.

Parameters:

timer – : timer to clear.

Returns:

0 in case of success, negative errno value in case of error.

Shsettings#

Library used to store reboot persistent-settings. You can subscribe to get notifications when a setting is updated.

SHS_API struct shs_ctx *shs_ctx_new_client(shs_change_cb_t cb, void *userdata)#

Create a context that will be used as client. It means it will be able to synchronize settings with other processes.

Parameters:
  • cb – : function to call when a subscribed setting is changed.

  • userdata – : user data to be given back in cb.

SHS_API int shs_ctx_destroy(struct shs_ctx *ctx)#

Destroy the context. It must be previously stopped.

Parameters:

ctx

SHS_API int shs_ctx_start(struct shs_ctx *ctx)#

Start the context. It will internally creates sockets based of server/client role and subscribed settings. For servers, it will load default settings from:

  • ’/etc/libshsettings/<rootname>.cfg’

  • ’/var/lib/libshsettings/<rootname>.cfg’ Sockets will be unix domain stored in tmpfs (for easy introspection):

  • ’/tmp/libshsettings/<rootname>.socket’

Parameters:

ctx

SHS_API int shs_ctx_stop(struct shs_ctx *ctx)#

Stop the context. It will internally destroy all sockets.

Parameters:

ctx

SHS_API int shs_ctx_subscribe(struct shs_ctx *ctx, const char *name, shs_change_cb_t cb, void *userdata)#

Subscribe to a setting to be able to get its value, be notified of changes and modify the value. This function can also be called by clients and servers contexts. Can only be called BEFORE the context is started.

Remark

: ‘<rootname>.*’ is recognized to subscribe to ALL settings of a given server.

Remark

: ‘*’ is recognized to subscribe to ALL settings of ALL running servers (periodically checked).

Parameters:
  • ctx

  • name – : full name of setting to subscribe to. The first component will be the root name and will identify the socket associated with the server.

SHS_API int shs_ctx_set(struct shs_ctx *ctx, const char *name, const struct shs_value *val)#

Modify the value of a setting. For servers, it will notify clients that have subscribed to the setting. For clients, it will send the value to a remote process that will ultimately notify the client back when change is done.

Parameters:

ctx

SHS_API int shs_ctx_pomp_loop_register(struct shs_ctx *ctx, struct pomp_loop *loop)#

Register a context to a pomp loop

SHS_API int shs_ctx_pomp_loop_unregister(struct shs_ctx *ctx, struct pomp_loop *loop)#

Unregister a context from a pomp loop

Ulog#

Library with macros and functions to log text messages in the logging system (printf-like but redirected to a kernel device to allow saving on storage and real-time display). For further information, you can find the source code here.


/*
 * HOW TO USE ULOG:
 * ----------------
 *
 * 1. Declare one or several ULOG tag names in a .c or .cpp source file, like
 * this:
 *
 *   #include "ulog.h"
 *   ULOG_DECLARE_TAG(toto);
 *   ULOG_DECLARE_TAG(Foo_Bar);
 *
 * Note that the argument of ULOG_DECLARE_TAG() is the tag name and should be a
 * valid C symbol string, such as 'my_module', 'MyTag', etc.
 *
 * 2. Then, set the default tag to use inside a given source file by defining
 * macro ULOG_TAG before including "ulog.h":
 *
 *   #define ULOG_TAG Foo_Bar
 *   #include "ulog.h"
 *
 * 3. You can now use short macros for logging:
 *
 *   ULOGW("This module will auto-destruct in %d seconds...\n", 3);
 *   ULOGE("Fatal error\n");
 *
 * If you forget to define macro ULOG_TAG, then a default empty tag is used.
 *
 * NOTE: If you need to log messages from a signal handler, make sure a first
 * message using the tag is logged at runtime before installing your handler.
 *
 * HOW TO CONTROL ULOG LOGGING LEVEL:
 * ----------------------------------
 * ULOG logging is globally controlled by environment variable ULOG_LEVEL.
 * This variable should contain a single letter ('C', 'E', 'W', 'N', 'I', or
 * 'D') or, alternatively, a single digit with an equivalent meaning:
 *
 * C = Critical = 2
 * E = Error    = 3
 * W = Warning  = 4
 * N = Notice   = 5
 * I = Info     = 6
 * D = Debug    = 7
 *
 * For instance, to enable all priorities up to and including the 'Warning'
 * level, you should set:
 * ULOG_LEVEL=W
 * or, equivalently,
 * ULOG_LEVEL=4
 *
 * The default logging level is 'I', i.e. all priorities logged except Debug.
 * ULOG_LEVEL controls logging levels globally for all tags.
 * Setting an empty ULOG_LEVEL string disables logging completely.
 * You can also control the logging level of a specific tag by defining
 * environment variable ULOG_LEVEL_<tagname>. For instance:
 *
 * ULOG_LEVEL_Foo_Bar=D   (set level Debug for tag 'Foo_Bar')