/**
@mainpage
@anchor platform
@brief The platform layer provides portability across different operating systems. <br><br>

All system calls (including networking) used in this SDK's libraries go through a lightweight platform layer. The functions of the platform layer are intended to be easily implementable on a wide variety of operating systems. The current platform layer has the following components:
- @ref platform_clock <br>
  @copybrief platform_clock
- @ref platform_threads <br>
  @copybrief platform_threads
- @ref platform_network <br>
  @copybrief platform_network
- @ref platform_metrics <br>
  <i>Only used by [Device Defender](@ref defender); does not need to be ported if not using Defender.</i> <br>
  @copybrief platform_metrics <br>
- @ref platform_atomic <br>
  <i>Porting is optional, as a generic implementation is provided.</i> <br>
  @copybrief platform_atomic

The following implementations are provided with this SDK as porting samples:
Component                   | Supported platforms
---------                   | -------------------
@ref platform_clock         | [POSIX](https://en.wikipedia.org/wiki/POSIX)
@ref platform_threads       | [POSIX](https://en.wikipedia.org/wiki/POSIX)
@ref platform_network       | [mbed TLS](https://tls.mbed.org/) <br>[Berkeley sockets](https://en.wikipedia.org/wiki/Berkeley_sockets) + [OpenSSL](https://en.wikipedia.org/wiki/OpenSSL) + [POSIX](https://en.wikipedia.org/wiki/POSIX)
@ref platform_metrics       | Sample implementation using the @ref platform_network abstraction. <br> This implementation is not intended for production use.
@ref platform_atomic        | GNU compilers (gcc/clang) <br> Generic implementation using a @ref platform_threads mutex.
*/

/**
@configpage{platform,platform layer}

@section IOT_ATOMIC_USE_PORT
@brief Use a custom atomics port, provided in the header `iot_atomic_port.h`.

Set this to `1` to use a custom atomics port in place of any atomics port provided with the SDK. The custom atomics port should be implemented in `platform/include/atomic/iot_atomic_port.h`.

See @ref platform_atomic and [atomics functions](@ref platform_atomic_functions) for details on writing an atomics port.

@configpossible `0` (no atomic port) or `1` (use atomic port) <br>
@configdefault `0`

@section IOT_LOG_LEVEL_PLATFORM
@brief Set the log level of all platform components except the [networking component](@ref platform_network).

This setting overrides @ref IOT_LOG_LEVEL_GLOBAL for the platform layer components that it affects. All log messages with a level at or below this setting will be printed. The [platform networking component](@ref platform_network) is generally more verbose than others, so its logging is controlled separately by @ref IOT_LOG_LEVEL_NETWORK.

@configpossible One of the @ref logging_constants_levels.<br>
@configdefault @ref IOT_LOG_LEVEL_GLOBAL; if that is undefined, then #IOT_LOG_NONE.

@section IOT_LOG_LEVEL_NETWORK
@brief Set the log level of the [platform networking component](@ref platform_network).

This setting overrides @ref IOT_LOG_LEVEL_GLOBAL for the [platform networking component](@ref platform_network). All log messages with a level at or below this setting will be printed. See @ref IOT_LOG_LEVEL_PLATFORM to set the log level of other platform components.

@configpossible One of the @ref logging_constants_levels.<br>
@configdefault @ref IOT_LOG_LEVEL_GLOBAL; if that is undefined, then #IOT_LOG_NONE.

@section platform_config_memory Memory allocation
@brief Memory allocation function overrides for the platform layer.

Some platform layers are not affected by @ref IOT_STATIC_MEMORY_ONLY. Currently, the following platform implementations require memory allocation:
- POSIX <br>
  This implementation is not affected by @ref IOT_STATIC_MEMORY_ONLY. However, its memory allocation functions may be overridden by setting the following constants. All memory allocation functions must have the same signatures as [malloc](http://pubs.opengroup.org/onlinepubs/9699919799/functions/malloc.html) and [free](http://pubs.opengroup.org/onlinepubs/9699919799/functions/free.html).
  - `IotThreads_Malloc` and `IotThreads_Free`.
  - `IotNetwork_Malloc` and `IotNetwork_Free`.

@section platform_config_posixheaders POSIX headers
@brief The POSIX platform layer allows the standard POSIX header includes to be overridden. Overrides only affect the POSIX platform layer.

Any substitute headers are expected to provide the same functionality as the standard POSIX headers. The POSIX header overrides should only be used if the system's headers do not follow the standard names for POSIX headers. The POSIX headers may be overridden by defining the following settings:
Standard name | Setting
------------- | -------
[errno.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html) | `POSIX_ERRNO_HEADER`
[limits.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/limits.h.html) | `POSIX_LIMITS_HEADER`
[pthread.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/pthread.h.html) | `POSIX_PTHREAD_HEADER`
[signal.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html) | `POSIX_SIGNAL_HEADER`
[semaphore.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/semaphore.h.html) | `POSIX_SEMAPHORE_HEADER`
[time.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/time.h.html) | `POSIX_TIME_HEADER`
[sys/types.h](http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_types.h.html) | `POSIX_TYPES_HEADER`

<b>Example:</b><br>
To use a header named `custom_errno.h` instead of `errno.h`, the `POSIX_ERRNO_HEADER` setting should be defined.
@code{c}
#define POSIX_ERRNO_HEADER    "custom_errno.h"
@endcode

@configpossible Strings representing file names. These files must be in the compiler's include path. <br>
@configdefault Standard POSIX header names.
*/

/**
@page platform_clock Clock
@brief @copybrief iot_clock.h

The platform clock component provides other libraries with functions relating to timers and clocks. It interfaces directly with the operation system to provide:
- Clocks for reading the current time.
- Timers that create a notification thread when they expire.

@dependencies{platform_clock,platform clock component}
@dot "Clock direct dependencies"
digraph clock_dependencies
{
    node[shape=box, fontname=Helvetica, fontsize=10, style=filled];
    edge[fontname=Helvetica, fontsize=10];
    subgraph { rank=min; logging[label="Logging", fillcolor="#aed8a9ff" URL="@ref logging"]; }
    subgraph
    {
        platform_clock[label="Clock", fillcolor="#e89025ff"];
    }
    subgraph
    {
        rank = same;
        rankdir = LR;
        operating_system[label="Operating system", fillcolor="#999999ff"]
        standard_library[label="Standard library\nstdbool, stddef, stdint", fillcolor="#d15555ff"];
    }
    platform_clock -> operating_system;
    platform_clock -> standard_library;
    platform_clock -> logging [label=" if logging enabled", style="dashed"];
}
@enddot

Currently, the platform clock component has the following dependencies:
- The operating system must provide the necessary APIs to implement the clock component's functions.
- The logging library may be used if @ref IOT_LOG_LEVEL_PLATFORM is not #IOT_LOG_NONE.
*/

/**
@page platform_threads Thread Management
@brief @copybrief iot_threads.h

The platform thread management component provides other libraries with functions relating to threading and synchronization. It interfaces directly with the operating system to provide:
- A function to create new threads.
- Synchronization mechanisms such as [mutexes](@ref IotMutex_t) and [counting semaphores](@ref IotSemaphore_t).

@dependencies{platform_threads,platform thread management component}
@dot "Thread management direct dependencies"
digraph threads_dependencies
{
    node[shape=box, fontname=Helvetica, fontsize=10, style=filled];
    edge[fontname=Helvetica, fontsize=10];
    subgraph { rank=min; logging[label="Logging", fillcolor="#aed8a9ff" URL="@ref logging"]; }
    subgraph
    {
        platform_threads[label="Thread management", fillcolor="#e89025ff"];
    }
    subgraph
    {
        rank = same;
        operating_system[label="Operating system", fillcolor="#999999ff"]
        standard_library[label="Standard library\nstdbool, stddef, stdint", fillcolor="#d15555ff"];
    }
    platform_threads -> operating_system;
    platform_threads -> standard_library;
    platform_threads -> logging [label=" if logging enabled", style="dashed"];
}
@enddot

Currently, the platform thread management component has the following dependencies:
- The operating system must provide the necessary APIs to implement the [thread management functions](@ref platform_threads_functions).
- The logging library may be used if @ref IOT_LOG_LEVEL_PLATFORM is not #IOT_LOG_NONE.
*/

/**
@page platform_network Networking
@brief @copybrief iot_network.h

The platform networking component provides other libraries with an abstraction for interacting with the network through an #IotNetworkInterface_t. Libraries that require the network will request an #IotNetworkInterface_t as a parameter and use those function pointers to access the network. This allows libraries to use different network stacks simultaneously.

@dependencies{platform_network,platform networking component}
@dot "Networking direct dependencies"
digraph network_dependencies
{
    node[shape=box, fontname=Helvetica, fontsize=10, style=filled];
    edge[fontname=Helvetica, fontsize=10];
    subgraph { rank=min; logging[label="Logging", fillcolor="#aed8a9ff", URL="@ref logging"]; }
    subgraph
    {
        rank = same;
        platform_network[label="Networking", fillcolor="#e89025ff"];
    }
    subgraph
    {
        rank = same;
        rankdir = LR;
        operating_system[label="Operating system", fillcolor="#999999ff"];
        security_library[label="Security library", fillcolor="#999999ff"];
        standard_library[label="Standard library", fillcolor="#d15555ff"];
    }
    platform_network -> operating_system;
    platform_network -> security_library [label=" secured connection", style="dashed"];
    platform_network -> standard_library;
    platform_network -> logging [label=" if logging enabled", style="dashed"];
    security_library -> operating_system;
}
@enddot

Functions should be implemented against the system's network stack to match the signatures given in an #IotNetworkInterface_t.
- The operating system must provide the necessary networking APIs, such as a sockets API.
- A third-party security library is needed to encrypt secured connections.
- The logging library may be used if @ref IOT_LOG_LEVEL_PLATFORM is not @ref IOT_LOG_NONE.
*/

/**
@page platform_metrics Metrics
@brief @copybrief iot_metrics.h

Device Defender reports metrics to monitor devices. This component of the platform layer is only required by Device Defender. It does not need to be implemented if Device Defender is not used.

@dependencies{platform_metrics,platform metrics component}
@dot "Metrics direct dependencies"
digraph metrics_dependencies
{
    node[shape=box, fontname=Helvetica, fontsize=10, style=filled];
    edge[fontname=Helvetica, fontsize=10];
    subgraph
    {
        platform_metrics[label="Metrics", fillcolor="#e89025ff"];
    }
    subgraph
    {
        rank = same;
        rankdir = LR;
        operating_system[label="Operating system", fillcolor="#999999ff"]
        standard_library[label="Standard library\nstdbool, stddef, stdint", fillcolor="#d15555ff"];
    }
    platform_metrics -> operating_system;
    platform_metrics -> standard_library;
}
@enddot

The platform metrics component is meant to query its data directory from the operating system.

@note Platform metrics implementations are generally not portable, since they depend on non-portable operating system APIs. Because maintaining OS-specific implementations is beyond the scope of this SDK, the provided metrics implementation is a sample that calls in to other platform components, instead of the operating system.
*/

/**
@page platform_atomic Atomics
@brief Atomic operations: small inlined functions used for atomically manipulating memory.

Unlike the other components of the platform layer, which rely on APIs provided by the host operating system, the atomics component relies on facilities provided by compilers. Many compilers, particularly recent versions that support C11 atomic features, provide compiler intrinsics for atomic operations. The header `platform/include/iot_atomic.h` will select an atomic port to use based on the detected compiler. If no suitable atomic port is available, then a <i>generic</i> atomic port will be used. The generic atomic port is slower than native compiler ports, but will work on all systems.

To provide a new compiler port, the preprocessor constant @ref IOT_ATOMIC_USE_PORT should be defined to `1` in the [config file](@ref global_config). When @ref IOT_ATOMIC_USE_PORT is `1`, a new compiler port should be implemented in a file named `iot_atomic_port.h`. This file should be created in `platform/include/atomic/`, as it will be included with the directive @c #`include "atomic/iot_atomic_port.h"`.

@dependencies{platform_atomic,platform atomics component}
@dot "Atomics direct dependencies"
digraph atomic_dependencies
{
    node[shape=box, fontname=Helvetica, fontsize=10, style=filled];
    edge[fontname=Helvetica, fontsize=10];
    subgraph
    {
        platform_atomic[label="Atomics", fillcolor="#e89025ff"];
    }
    subgraph
    {
        rank = same;
        rankdir = LR;
        compiler[label="Compiler", fillcolor="#999999ff"]
    }
    platform_atomic -> compiler;
}
@enddot
*/

/**
@handles{platform,platform layer}
@enums{platform,platform layer}
@paramstructs{platform, platform layer}
*/

/**
@functionspage{platform,platform layer}

- @subpage platform_clock_functions <br>
  @copybrief platform_clock_functions
- @subpage platform_network_functions <br>
  @copybrief platform_network_functions
- @subpage platform_threads_functions <br>
  @copybrief platform_threads_functions
- @subpage platform_metrics_functions <br>
  @copybrief platform_metrics_functions
- @subpage platform_atomic_functions <br>
  @copybrief platform_atomic_functions
*/
