<!---
  Copyright 2017, Data61
  Commonwealth Scientific and Industrial Research Organisation (CSIRO)
  ABN 41 687 119 230.

  This software may be distributed and modified according to the terms of
  the BSD 2-Clause license. Note that NO WARRANTY is provided.
  See "LICENSE_BSD2.txt" for details.

    @TAG(DATA61_BSD)
-->
# 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 Serrver 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);
    }
