<!--
     Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)

     SPDX-License-Identifier: CC-BY-SA-4.0
-->

# 1. MISSION STATEMENT AND CURRENT STATUS.

The Serial Server thread is able to connect to a character device and act as a
multiplexer for writes to that device.

Generally the server's error messages are very descriptive, and you should be
able to tell what went wrong if you triggered an error.

## 1.1. CURRENT SUPPORTED FEATURES:
* Binding to a platform serial device.
* Writing to the platform serial device.
* Serializing access to the serial device from multiple clients.

## 1.2. CURRENTLY UNSUPPORTED FEATURES:
* Reading from the platform serial device.
* Multiple server instances.
* Write-back buffering or any kind of cache-type buffering really.

# 2. TOP LEVEL DESIGN

> **Caution**:
>
> All `vka_t`, `vspace_t` and `simple_t` instances provided to this library
> must remain functional for the duration of the Server thread's lifetime.

## 2.1. ROLES.

The library works on the basis of 3 roles being played by 3 parties:

* The "Parent", which spawns the server thread by calling
`serial_server_parent_spawn_thread()`. It is also generally, though not necessarily,
going to be the job of the Parent, to provide CSpace slots for the
Server to mint badged caps to its Endpoint into, but this may be done by any other
thread that exists in the same VSpace as the Server (because the Server's
badge-value allocation metadata exists in the Server's VSpace).
* The "Server", which is spawned by the Parent, and multiplexes accesses to the
underlying serial device. The Server also provides a badge value allocator that
the Parent *must* use when it is minting the Endpoint capabilities to the Clients.
* The "Clients", which connect to the Server and print through it. The Clients
need to have an endpoint minted to them by the Parent, or else they need to
somehow acquire a badged capability to the Server's Endpoint, the badge of which
was generated by the library.

Finally, some party must spawn the client threads themselves; this party is,
while a recognized actor, not a necessary part of the library specification.

## 2.2. ROLE QUICK REFERENCE (TL;DR):

Basic quick walkthrough of what you need to do, in order to get each role
working. Written role-specific so you only need to read the section you care
about.

### 2.2.1. SERVER QUICK REFERENCE:

You don't need to do anything with the server. If you want to know how to
_spawn_ the server, that's the role of the Parent.

### 2.2.2. PARENT QUICK REFERENCE:

Header: `#include <sel4utils/serial_server/parent.h>`.

Of the three roles, the Parent does the most work, and is responsible for:

* Spawning the Server.
* Generally, but not necessarily: allocating CSpace slots in the clients' CSpaces
  into which the Server library will mint badged Endpoint capabilities.

To spawn the Server, you'll need:

* A `simple_t` instance that has information about the Parent.
* A `vka_t` instance that manages the Parent's CSpace.
* A `vspace_t` instance that manages the Parent's VSpace.

When you have all of those, go ahead and spawn the Server thread like this:
    int error;

    error = serial_server_parent_spawn_thread(...);
    if (error != 0) {
        ZF_LOGF("Failed to spawn the server with error %d.", error);
    }
    ZF_LOGF("Serial server spawned.");

> #### Behaviour / Side effects
>
> * The server works with the assumption that it will be spawned in the Parent's
>   VSpace and CSpace, and it expects to be given the Parent's vspace_t, vka_t
>   and simple_t.
> * When the Server thread is spawned, the library automatically creates an
>   Endpoint object that it will listen on, and stores it a capability to this
>   Endpoint internally.
> * Keep all vka_t, vspace_t and simple_t instances that are passed to this
>   library alive for the duration of the lifetime of the Server thread.

Next you'll want to mint badged capabilities to the Server's Endpoint object,
to all the Clients you intend to spawn. The library takes care of this in a
two-fold manner:

* It provides convenience functions for minting new, badged copies of the Server
thread's Endpoint cap.
* It keeps an internal badge value allocator, which the aforementioned
convenience functions use to generate unique badge values for clients.

The library provides several convenience functions that will help you mint these easily:

* `serial_server_parent_vka_mint_endpoint(vka_t client_vka, cspacepath_t *result)`:
This function will ALLOCATE and mint a new, badged copy of the Server's Endpoint and return
the path into for it in `result`. Make sure you pass the **CLIENT**'s vka, and
not the Server's vka, since you're trying to mint the new cap to the client.
* `serial_server_allocate_client_badged_ep(cspacepath_t dest_path)`:
This function will mint a new, badged copy of the Server's Endpoint into the
designated slot -- this is meant to be used when the caller has already pre-allocated
a slot that s/he would like the server to use.
* `serial_server_parent_mint_endpoint_to_process(sel4utils_process_t *p)`:
This function relies on `sel4utils_mint_cap_to_process()`, but basically fills out
the arguments for you. By implication, it also takes up a slot in the destination
process's CSpace, so **if you had some policy for your client threads' slots,
you need to factor this function call into that policy**.

In this quick-reference, we'll use `serial_server_parent_vka_mint_endpoint()`
since it's super-convenient. We will be using 3 Client threads in our example:

    #define SERSERV_README_N_CLIENTS (3)

    vka_t client_vkas[SERSERV_README_N_CLIENTS];
    cspacepath_t client_server_ep_cspaths[SERSERV_README_N_CLIENTS];

    for (int i = 0; i < SERSERV_README_N_CLIENTS; i++) {
        /* I'm not going to cover how to initialize vkas here. */
        SETUP_YOUR_CLIENT'S_VKA(&client_vkas[i]);

        /* Ask the Server to Mint badged endpoints to the clients: the library
         * automatically both allocates a unique badge value and mints the
         * capability for us.
         *
         * We chose here to use `serial_server_parent_vka_mint_endpoint()`, but
         * the other functions provided by the library would have worked fine.
         */
        error = serial_server_parent_vka_mint_endpoint(&client_vkas[i],
                                                       &client_server_ep_cspaths[i]);
    }

    /* At the end of this loop, each Client has a badged capability to the
     * Endpoint that the server is listening on. (The client processes/threads
     * have not been spawned yet.)
     *
     * You want to keep the CPtrs to the badged endpoints somewhere safe,
     * because you'll need them later.
     */

Make sure that you save the CPtrs to the badged Endpoints that the library
returned to you: you'll need them later on. If your new Client will live in
a new VSpace or CSpace, **make sure you plan for how to make the these caps
visible to them**.

Finally, either the Parent or some other actor will have to actually spawn the
clients. I won't be covering how to spawn TCBs/CSpaces/VSpaces, etc here, but
it'll look something like:

    for (int i = 0; i < SERSERV_README_N_CLIENTS; i++) {
        MAKE_SERVER's_BADGED_ENDPOINT_CAPABILITY_VISIBLE_TO_CLIENT(i);

        SPAWN_CLIENT_THREAD_OR_PROCESS(i);
    }

### 2.2.3. CLIENT QUICK REFERENCE:

Header: `#include <sel4utils/serial_server/client.h>`.

The Client role is extremely simple: you retrieve the badged Endpoint capability
that was minted for you by the Parent, and then you call
`serial_server_client_connect()` to connect to the server. From then on, you can
call `serial_server_printf()` to ask the server to print.

A call to `serial_server_client_connect()` requires:

* The client's badged Server endpoint capability.
* An initialized vka_t instance which is able to allocate resources on behalf
  of the client. If the client lives in the same CSpace as the Parent, this will
  be the Parent's VKA.
* An initialize vspace_t instance which is able to allocate memory on behalf of
  the client. If the client lives in the same VSpace as the Parent, this will
  be the Parent's VSpace.
* An uninitialized `serial_client_context_t`, which is your context-cookie
  to the server.

You can use the library from a client like this:

    void client_main(void)
    {
        seL4_CPtr my_server_ep_cap;
        vka_t *my_vka;
        vspace_t *my_vspace;
        serial_client_context_t my_conn;
        int error;

        RETRIEVE_MY_BADGED_EP_CAP(&my_server_ep_cap);

        my_vka = OBTAIN_A_VKA_THAT_WORKS_FOR_MY_CSPACE();
        my_vspace = OBTAIN_A_VSPACE_THAT_WORKS_FOR_MY_VSPACE();

        error = serial_server_client_connect(my_server_ep_cap,
                                             my_vka, my_vspace,
                                             &my_conn);
        if (error != 0) {
            ZF_LOGF("Failed to connect to the server.");
        }

        /* From here on, you're free to print. */
        serial_server_printf(&my_conn, "Hello world from %s.\n", "John Doe");
    }

> #### Behaviour / Side effects
>
> * `serial_server_client_connect()` establishes a shared-memory window
> between the client and server. Make sure that you have enough virtual
> memory in both VSpaces, and make sure you have enough physical memory.
> At present, the shared mem window is 1 page in size.
> * `serial_server_client_connect()` also sends capabilities to the server via
> IPC. Be sure that the badged Endpoint capabilities generated for each
> client have the **GRANT** right on them.

# 3. HIGH LEVEL SERIAL SERVER MECHANICS:

## 3.1 DISCONNECTING:

Disconnecting causes the Server to tear down its connection to a specific
Client. That client will thenceforth be ignored by the Server, just as if it had
never connected in the first place. The client may subsequently reconnect if it
so desires.

> #### Behaviour / Side effects:
>
> After being disconnected, the only operation that a former Client can invoke
> on the Server is the `serial_server_client_connect()` function.

### 3.1.1: DISCONNECTING, SERVER ROLE AND PARENT ROLE:

You don't need to do anything with the Server or Parent when you wish to
disconnect a Client from the Server.

### 3.1.2: DISCONNECTING, CLIENT ROLE:

To disconnect a client from the Server, simply retrieve a pointer to your
connection token, and then call `serial_server_disconnect()`. (Your connection
token was filled out and returned to you when you called
`serial_server_client_connect()`).

    void client_main(void)
    {
        serial_client_context_t conn;

        serial_server_client_connect(&conn, ...);

        /* ... */

        serial_server_disconnect(&conn);
    }

That's it.

## 3.2 KILLING THE SERVER:

Killing the server causes the Server thread to first stop listening for
requests (it exits its message loop), and then unilaterally tear down all
connections to its current clients, before Suspending itself.

This operation may only be performed by a current Client of the Server. If your
Parent wishes to kill the Server, it itself will have to also connect to the
Server.

### 3.2.1 KILLING, SERVER ROLE AND PARENT ROLE:

You don't need to do anything with the Server or Parent when you wish to kill the
Server. If you wish to kill the Server from the Parent, then the Parent will
also itself need to connect to the Server.

### 3.2.2 KILLING, CLIENT ROLE:

To kill the Server, simply obtain a handle to your connection token, and then
call `serial_server_kill()`:

    void client_main(void)
    {
        serial_client_context_t conn;

        serial_server_client_connect(&conn);

        /* ... */

        serial_server_kill(&conn);
    }
