mirror of
https://git.jami.net/savoirfairelinux/jami-daemon.git
synced 2025-08-07 22:02:12 +08:00
doc/agent: Add agent documentation
Change-Id: I028985ac90d07199cfa30d33e21f55ebef228ff3
This commit is contained in:

committed by
Sébastien Blin

parent
8bab18aad4
commit
e14868e43b
41
doc/agent/build.rst
Normal file
41
doc/agent/build.rst
Normal file
@ -0,0 +1,41 @@
|
||||
==================================
|
||||
Agent build steps (GNU/Linux only)
|
||||
==================================
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
Guile library version 3.0.7 or higher is required. Guile lib may require other
|
||||
dependencies in particular libunistring-dev and libgc-deb packages.
|
||||
|
||||
Guile can be provided by the distro if available, or built locally. Note that
|
||||
Guile v3.0.7 is quite recent and most likely not yet provided by most linux
|
||||
distributions. If the required version is available on your distro, just
|
||||
install it using your distro's package manager. Development packages must be
|
||||
installed as well.
|
||||
|
||||
Build Guile library
|
||||
===================
|
||||
|
||||
To build Guile locally, you first need to enable it when building contrib, then
|
||||
recompile contrib::
|
||||
|
||||
cd daemon/contrib/native
|
||||
../bootstrap --enable-guile
|
||||
make list
|
||||
make fetch
|
||||
make -j
|
||||
|
||||
|
||||
Compile
|
||||
=======
|
||||
|
||||
To compile the agent, one has to enable it while configuring the daemon. At this
|
||||
stage, Guile must be already available::
|
||||
|
||||
cd daemon
|
||||
./configure --enable-agent # other options can be added if needed such as --enable-debug
|
||||
cd test/agent
|
||||
make check
|
||||
|
||||
|
110
doc/agent/workflow.rst
Normal file
110
doc/agent/workflow.rst
Normal file
@ -0,0 +1,110 @@
|
||||
==============
|
||||
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
|
@ -1,86 +1 @@
|
||||
# Agent build steps (GNU/Linux only)
|
||||
Last revision: 2021-08-31
|
||||
|
||||
# Requirements
|
||||
Guile library version 3.0.7 or higher is required. Guile lib may require other
|
||||
dependencies in particular libunistring-dev and libgc-deb packages.
|
||||
|
||||
Guile can be provided by the distro if available, or built locally. Note that
|
||||
Guile v3.0.7 is quite recent and most likely not yet provided by most linux
|
||||
distributions.
|
||||
If the required version is available on your distro, just install it using your
|
||||
distro's package manager. Development packages must be installed as well.
|
||||
|
||||
# Build Guile library
|
||||
To build Guile locally, you first need to enable it when building contrib, then
|
||||
recompile contrib:
|
||||
|
||||
```sh
|
||||
cd daemon/contrib/native
|
||||
../bootstrap --enable-guile
|
||||
make list
|
||||
make fetch
|
||||
make -j
|
||||
```
|
||||
|
||||
# Compile
|
||||
To compile the agent, one has to enable it while configuring the daemon. At this
|
||||
stage, Guile must be already available.
|
||||
|
||||
```sh
|
||||
cd daemon
|
||||
./configure --enable-agent # other options can be added if needed such as --enable-debug
|
||||
cd test/agent
|
||||
make check
|
||||
```
|
||||
|
||||
# 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 `src/bindings/*`. Bindings should be decouple
|
||||
into module that reflect their common functionnality. For example,
|
||||
`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 `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 `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`, onw would do
|
||||
`baz = to_guile(bar)`. One can also do the oposite like so
|
||||
`bar = from_guile(baz)`.
|
||||
|
||||
# Examples
|
||||
See `examples/`
|
||||
|
||||
See doc/agent/*.
|
||||
|
Reference in New Issue
Block a user