mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-07 22:02:12 +08:00
111 lines
4.0 KiB
ReStructuredText
111 lines
4.0 KiB
ReStructuredText
==============
|
|
Agent workflow
|
|
==============
|
|
|
|
Running the agent
|
|
=================
|
|
|
|
The agent is actually a wrapper around Guile's Scheme shell. By default, you
|
|
enter an interactive prompt that allows you to interact with Jami using the
|
|
primitive bindings or by using the agent helper. For help for running the
|
|
agent, run ``./agent --help``.
|
|
|
|
Guile bindings
|
|
==============
|
|
|
|
Guile needs primitive bindings to communicate with Jami. Usually, these
|
|
bindings can written in pure Scheme using the foreign function interface (FFI)
|
|
and some dlopen() magics. However, this method cannot applies here for two main
|
|
reasons:
|
|
|
|
1. Jami source code is in C++ not C.
|
|
2. Dynamic loading is not present on some platform supported by Jami.
|
|
|
|
The first reason makes it hard to interface C++ container types and other
|
|
standard types to bytevector used by Guile to interface with foreign functions.
|
|
In C, it's trivial to just types and pointers to bytevector.
|
|
|
|
The second reason is a constraint on the agent. Since the goal is to have a set
|
|
of bindings that can run on any platform where Jami is supported, bindings
|
|
should be registered in C++.
|
|
|
|
All bindings can be found under ``test/agent/src/bindings/*``. Bindings should
|
|
be decouple into module that reflect their common functionality. For example,
|
|
``test/agent/src/bindings/account.h`` has all the Jami's bindings for managing
|
|
accounts. When a set of bindings is to be added to a new module, the latter has
|
|
to be registered into Guile. In order accomplish this, one has to include the
|
|
bindings and define the module under ``test/agent/src/bindings/bindings.cpp``.
|
|
|
|
When a binding is called from Guile, the arguments passed are Scheme objects of
|
|
type ``SCM``. This is an opaque type that is generic. In order to be clear on
|
|
what the underlying type needed by the primitive procedure is, one should add
|
|
the suffix of the type at the end.
|
|
|
|
For example, ``my_primitive_procedure()`` expects that ``some_variable_str``
|
|
will be of type ``string``.
|
|
|
|
There's also a set of utilities that can be used to convert C++ object to Scheme
|
|
and vice versa. These utilities can be found under ``test/agent/src/utils.h``
|
|
and are all template based and can usually be used without specifying any type
|
|
thanks to type inference.
|
|
|
|
For example, to convert ``std::string bar`` to ``SCM baz``, one would do ``baz =
|
|
to_guile(bar)``. One can also do the opposite like so ``bar = from_guile(baz)``.
|
|
|
|
Examples
|
|
========
|
|
|
|
Examples on how to use the agent can be found under ``test/agent/examples``.
|
|
|
|
Compiling modules
|
|
=================
|
|
|
|
Modules such as ``(agent)`` and ``(jami logger)`` can be compiled using the
|
|
agent itself like so::
|
|
|
|
./agent.exe compile /path/to/module.scm /path/to/module.scm.go
|
|
|
|
You however do not need to do this manually. You should instead add your Scheme
|
|
(.scm) file to the list MODULES in ``tests/agent/Makefile.am`` and invoke
|
|
``make compile``.
|
|
|
|
Demuxing outputs
|
|
================
|
|
|
|
While developing scenarios, you don't want Jami's output to clobber Guile's
|
|
output. One easy way to do so is by using the ``JAMI_LOG_FILE`` environment
|
|
variable.
|
|
|
|
For example::
|
|
|
|
JAMI_LOG_FILE=jami.log ./agent.exe -s my-scenario.scm
|
|
|
|
But sometime you want Jami's output on the console. The agent disable the
|
|
console output for Jami, but you can do the following as a workaround::
|
|
|
|
JAMI_LOG_FILE=/dev/stdout ./agent.exe -s my-scenario.scm
|
|
|
|
|
|
Debugging the agent
|
|
===================
|
|
|
|
Since ``agent.exe`` is a regular ELF executable, you can attach a debugger to
|
|
it. If you're using GDB, you will need to handle some signals, otherwise your
|
|
program will keep getting interrupted. Here's a recommended GDB file to use::
|
|
|
|
handle SIGPWR noprint pass
|
|
handle SIGXCPU noprint pass
|
|
|
|
set environment XDG_CONFIG_HOME=/tmp/jami-agent
|
|
set environment XDG_CACHE_HOME=/tmp/jami-agent
|
|
set environment XDG_DATA_HOME=/tmp/jami-agent
|
|
|
|
set environment SIPLOGLEVEL 5
|
|
|
|
set environment UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1
|
|
set environment ASAN_OPTIONS=print_stacktrace=1:halt_on_error=1
|
|
|
|
set environment JAMI_LOG_FILE jami.log
|
|
|
|
run
|