🌐 English

    UDP API#

    Oasis supports UDP (User Datagram Protocol) servers and clients.

    It supports DTLS version 1.2 as a secure connection.

    Header File#

    OasisNet.h

    UdpEventDelegate Interface#

    class UdpEventDelegate : public std::enable_shared_from_this<UdpEventDelegate>
    {
    public:
        UdpEventDelegate();
        virtual ~UdpEventDelegate();
    
    public: 
    };
    

    Currently, there are no defined event callback functions.

    Functions#

    UdpConnectionRef udpCreate ( int32_t s , bool is_secure , key_value_map_t & parameters )
    OasisNet.h
    Creates a UDP connection object from a socket handle.
    Parameters
    s  The socket handle number having the SOCK_DGRAM characteristic.
    is_secure  Applies the secure protocol (DTLS) if true.
    parameters  The key-value map required for object creation.
    Return Value
    Returns a UDP connection object on success. Returns nullptr on failure.

    Below is the key-value map required for creating a UDP connection object.

    Key
    Default
    M
    Description
    tls-enabled
    0
     
    Specifies whether to enable TLS. It is enabled if "1", and TLS is not used if "0". When using it, key values such as certificate paths must be valid. If "1", cert-file-path and pkey-file-path must be specified.
    tls-version
    1.2
     
    The TLS version. Enter "1.2".
    tls-client-verify
    0
     
    Specifies whether to validate the certificate of the connecting client. If "1", connections are allowed only for names registered in the tls-certificate-request-authority-names key.
    tls-certificate-request-authority-names
     
    The list of authority names (CN) separated by \0xa. For example, it is formatted like "MediaStek-Root-CA\x0aMediaStek Inc.".
    ca-certs-file-path
     
    The path to the ROOT CA certificate files in PEM format separated by \0xa. For example, it is formatted like "/data/certs/cacerts.pem\x0a/data/certs/RootCA.pem".
    cert-file-path
    The path to the public certificate file in PEM format such as RSA, ECDSA, DSS, etc.
    pkey-file-path
    The path to the private key file in PEM format.
    UdpConnectionRef udpCreate ( const char * local_ip_address , uint16_t local_port , bool is_secure , key_value_map_t & parameters )
    OasisNet.h
    Creates a UDP connection object using an address and a port number.
    Parameters
    local_ip_address  The local IPv4 address string.
    local_port  The local port number.
    is_secure  Applies the secure protocol (DTLS) if true.
    parameters  The key-value map required for object creation.
    Return Value
    Returns a UDP connection object on success. Returns nullptr on failure.
    int32_t udpSetAsyncEventDelegate ( const UdpConnectionRef & connection , const std::shared_ptr<UdpEventDelegate> & delegate , void * user_data )
    OasisNet.h
    Sets a user-defined object derived from UdpEventDelegate. Currently, no events occur.
    Parameters
    connection  The UDP connection object.
    delegate  The user-defined object derived from UdpEventDelegate.
    user_data  User-defined data to be passed to the event callback function of the user-defined object derived from UdpEventDelegate.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t udpAccept ( const UdpConnectionRef & connection , const char * remote_ip_address , uint16_t remote_port , int32_t timeout )
    OasisNet.h
    Parameters
    connection  The UDP connection object.
    remote_ip_address  The IPv4 address of the remote side, if accepting only a specific remote side.
    remote_port  The port number of the remote side, if accepting only a specific remote side.
    timeout  The time to wait until accepting a connection request. Measured in milliseconds. If the value is "0", it waits indefinitely.
    Return Value
    Returns the socket handle number on success. Returns -1 on failure.
    int32_t udpConnect ( const UdpConnectionRef & connection , const char * remote_ip_address , uint16_t remote_port , int32_t timeout )
    OasisNet.h
    Connects to a UDP server.
    Parameters
    connection  The UDP connection object.
    remote_ip_address  The IPv4 address of the remote server to connect to.
    remote_port  The port number of the remote server to connect to.
    timeout  The maximum time to wait until connected. Measured in milliseconds.
    Return Value
    Returns the connected socket handle number on success. Returns -1 on failure.
    ssize_t udpSend ( const UdpConnectionRef & connection , int32_t s , const void * data , size_t length )
    OasisNet.h
    Transmits data.
    Parameters
    connection  The UDP connection object.
    s  The connected socket handle number.
    data  The pointer to the data buffer to transmit.
    length  The length of the data to transmit. Measured in bytes.
    Return Value
    ssize_t udpReceive ( const UdpConnectionRef & connection , int32_t s , void * data , size_t size , int32_t timeout )
    OasisNet.h
    Receives data.
    Parameters
    connection  The UDP connection object.
    s  The connected socket handle number.
    data  OUT The pointer to the buffer that will store the received data.
    size  The maximum size of the buffer. Measured in bytes.
    timeout  The waiting time. Measured in milliseconds.
    Return Value
    Returns the received data length. Measured in bytes. Returns -1 on failure or if the connection is disconnected.
    int32_t udpClose ( const UdpConnectionRef & connection , int32_t s )
    OasisNet.h
    Closes the connection.
    Parameters
    connection  The UDP connection object.
    s  The connected socket handle number.
    Return Value
    • 0: Success
    • -1: Failure
    int32_t udpDestroy ( UdpConnectionRef & connection )
    OasisNet.h
    Releases the UDP connection object.
    Parameters
    connection  The UDP connection object.
    Return Value
    • 0: Success
    • -1: Failure

    Example#

    UDP Server#

    Below is an example of a server performing DTLS UDP communication.

    #include "OasisAPI.h"
    #include "OasisLog.h"
    #include "OasisNet.h"
    
    
    #include <thread>
    #include <mutex>
    #include <memory>
    #include <condition_variable>
    
    #define DLOG_THIS   0x00080000
    
    #undef DLOG_FLAGS
    #define  DLOG_FLAGS (DLOG_FLAGS_DEFAULT|DLOG_THIS/**/)
    
    #undef DLOG_TAG
    #define DLOG_TAG "DTLSS"
    
    #define USE_RSA 1
    #define USE_ECDSA 0
    #define USE_DSS 0
    
    #define DTLS_CLIENT_VERIFY 0
    
    using namespace oasis;
    
    static bool continuing = true;
    
    class MyUdpEventDelegate : public UdpEventDelegate
    {
    public:
      MyUdpEventDelegate() {}
      virtual ~MyUdpEventDelegate() {}
    
    
    };
    
    
    void cancel_handler(int signum)
    {
      continuing = false;
    }
    
    
    int main(int argc, char* argv[])
    {
      int32_t c, err;
      uint16_t port;
      std::thread t3;
      key_value_map_t parameters, fields;
    
    
      if(argc < 2) {
        printf("USAGE: %s <port number>\n", argv[0]);
        return 255;
      }
    
      port = (uint16_t)atoi(argv[1]);
      if(port == 0) {
        printf("USAGE: %s <port number>\n", argv[0]);
        return 255;
      }
    
      signal(SIGINT, cancel_handler);
    
      parameters["offs-disable"] = "1";
      if(oasis::initialize(parameters) < 0) {
        DLOG(DLOG_ERROR, "Oasis init failed\n");
        return -1;
      }
    
      parameters.clear();
    
    #if DTLS_CLIENT_VERIFY
      //when restrict the accessible clients, each of which root ca should be the same as the server's.
      parameters["tls-client-verify"] = "1"; 
      //\x0a-seperated strings (if needs. by default server's CN used)
      parameters["tls-certificate-request-authority-names"] = "MediaStek-Root-CA\x0aMediaStek Inc.";
    #endif
    
      parameters["ca-certs-file-path"] = "/data/certs/RootCA.pem";
    
    #if USE_RSA
        parameters["cert-file-path"] = "/data/certs/fullchain.pem";
        parameters["pkey-file-path"] = "/data/certs/privkey.pem";
    #elif USE_ECDSA
        //ECDSA
        parameters["cert-file-path"] = "/data/certs/ec_fullchain.pem";
        parameters["pkey-file-path"] = "/data/certs/ec_pkey.pem";
    #elif USE_DSS
        parameters["cert-file-path"] = "/data/certs/dsa_fullchain.pem";
        parameters["pkey-file-path"] = "/data/certs/dsa_pkey.pem";
    #else
        #error "No certficates!"
    #endif
    
      std::shared_ptr<MyUdpEventDelegate> delegate = std::make_shared<MyUdpEventDelegate>();
    
      UdpConnectionRef conn;
    
      conn = udpCreate(nullptr, port, true, parameters);
      ASSERT(conn != nullptr);
    
      t3 = std::thread([&]() {
    
        do {
    
          DLOG(DLOG_THIS, "accepting...\n");
          int32_t c = udpAccept(conn, nullptr, 0, 0);
    
          DLOG(DLOG_THIS, "accepted socket %d\n", c);
    
          if(c >= 0) {
    
            uint8_t buffer[65536];
            ssize_t length = udpReceive(conn, c, buffer, sizeof(buffer), 100000);
            if(length > 0) {
              DUMP("RX", buffer, length);
            }
    
            udpClose(conn, c);
          }
    
        } while(continuing && conn);
    
      });
    
      do {
        usleep(100000);
      } while (continuing);
    
      udpDestroy(conn);
    
      if (t3.joinable()) {
        t3.join();
      }
    
      oasis::finalize();
    
      return 0;
    }
    

    UDP Client#

    Below is an example of a client that transmits messages at intervals of 1 second after connecting to a DTLS UDP server.

    #include "OasisAPI.h"
    #include "OasisLog.h"
    #include "OasisNet.h"
    
    #include <thread>
    #include <mutex>
    #include <memory>
    #include <condition_variable>
    
    #define DLOG_THIS   0x00080000
    
    #undef DLOG_FLAGS
    #define  DLOG_FLAGS (DLOG_FLAGS_DEFAULT|DLOG_THIS/**/)
    
    #undef DLOG_TAG
    #define DLOG_TAG "DTLSC"
    
    using namespace oasis;
    
    static bool continuing = true;
    
    void cancel_handler(int signum)
    {
      continuing = false;
    }
    
    
    int main(int argc, char* argv[])
    {
      int32_t err;
    
      int32_t status_code;
      std::string reason_string;
      std::string content_type; 
      std::vector<char> res_content;
      size_t content_length;
    
      int32_t wait_count = 0;
    
      key_value_map_t parameters, fields;
    
    
      if(argc < 3) {
        printf("USAGE: %s <target address> <port>\n", argv[0]);
        return 255;
      }
    
      signal(SIGINT, cancel_handler);
    
      const char *remote_ip = argv[1];
      uint16_t remote_port = (uint16_t)atoi(argv[2]);
      if(remote_port == 0) {
        printf("USAGE: %s <target address> <port>\n", argv[0]);
        return 255;
      }
    
      parameters["offs-disable"] = "1";
      if(oasis::initialize(parameters) < 0) {
        DLOG(DLOG_ERROR, "Oasis init failed\n");
        return -1;
      }
    
      parameters.clear();
    
      parameters["ca-certs-file-path"] = "/data/certs/cacerts.pem\x0a/data/certs/RootCA.pem";
      parameters["cert-file-path"] = "/data/certs/client_fullchain.pem";
      parameters["pkey-file-path"] = "/data/certs/client_privkey.pem";
    
      UdpConnectionRef conn;
      char buffer[512];
      ssize_t len;
      int ch;
    
      conn = udpCreate(nullptr, 0, true, parameters);
      if(conn) {
    
        int32_t c = udpConnect(conn, remote_ip, remote_port, 10000);
    
        if(c >= 0) {
    
          DLOG(DLOG_THIS, "connected %d\n", c);
          DLOG(DLOG_THIS, "press Ctrl+C to disconnect and quit.\n");
    
          do {
    
            fprintf(stdout, "> ");
            fflush(stdout);
    
            len = 128;
            for(int32_t i=0; i<len; i++) {
              buffer[i] = '0' + (i%10);
            }
            buffer[len] = 0;
            udpSend(conn, c, buffer, len);
            usleep(1000000);
    
          } while (continuing);
    
          udpClose(conn, c);
        }
    
        udpDestroy(conn);
      }
    
      conn = nullptr;
    
    done:
    
      oasis::finalize();
    
      return 0;
    }