diff options
author | Magnus Feuer <mfeuer@jaguarlandrover.com> | 2015-03-20 13:01:37 -0700 |
---|---|---|
committer | Magnus Feuer <mfeuer@jaguarlandrover.com> | 2015-03-20 13:01:37 -0700 |
commit | b4e2f85659932201119ec8a1b2d9bcf062e09e67 (patch) | |
tree | a42acb95d02d640a64cbd2935f6f842759162680 /c | |
parent | 8f63d68945359f9fab1eca5907faee698743c481 (diff) | |
download | rvi_core-b4e2f85659932201119ec8a1b2d9bcf062e09e67.tar.gz |
Added skeleton native C API from sota_demo.
Diffstat (limited to 'c')
-rw-r--r-- | c/rvi.c | 133 | ||||
-rw-r--r-- | c/rvi.h | 499 |
2 files changed, 632 insertions, 0 deletions
@@ -0,0 +1,133 @@ +/* + Copyright (C) 2014, Jaguar Land Rover + + This program is licensed under the terms and conditions of the + Mozilla Public License, version 2.0. The full text of the + Mozilla Public License is at https://www.mozilla.org/MPL/2.0/ +*/ +#include "rvi.h" + +struct rvi_t { + uint32_t placeholder; /* Not yet implemented */ +}; + +int32_t rvi_init(void) +{ + return RVI_OK; +} + +int32_t rvi_cleanup(void) +{ + return RVI_OK; +} + + + +struct rvi_t* rvi_new(char* service_prefix, + void (*service_available_cb)(struct rvi_t* rvi, char* service_name), + void (*service_unavailable_cb)(struct rvi_t* rvi, char* service_name)) +{ + return RVI_OK; +} + + + +int32_t rvi_delete(struct rvi_t* rvi) +{ + return RVI_OK; +} + + + +int32_t rvi_set_user_data(struct rvi_t* rvi, void* user_data) +{ + return RVI_OK; +} + + +void* rvi_get_user_data(struct rvi_t* rvi) +{ + return RVI_OK; +} + + + +int32_t rvi_add_configuration(struct rvi_t* rvi, char* key, char* value) +{ + return RVI_OK; +} + + +int32_t rvi_add_public_key(struct rvi_t* rvi, char* id, char* public_key) +{ + return RVI_OK; +} + + +int32_t rvi_add_certificates(struct rvi_t* rvi, + char* certificate, + char* signature, + char *public_key_id) +{ + return RVI_OK; +} + + + +int32_t rvi_register_service(struct rvi_t* rvi, char* local_name, + char* full_service_name, uint32_t full_service_name_sz, + int32_t (*process_message_cb)(struct rvi_t*, char* service_name, + uint32_t trans_id, + uint8_t* data, uint32_t data_sz)) +{ + return RVI_OK; +} + + + +int32_t rvi_activate(struct rvi_t* rvi) +{ + return RVI_OK; +} + +int32_t rvi_deactivate(struct rvi_t* rvi) +{ + return RVI_OK; +} + + +int32_t rvi_get_descriptor(struct rvi_t* rvi, int32_t *descriptor) +{ + return RVI_OK; +} + + +int32_t rvi_process(struct rvi_t* rvi) +{ + return RVI_OK; +} + + +int32_t rvi_send_message(struct rvi_t*rvi, + char* service, + time_t timeout, + uint32_t trans_id, + uint8_t* data, uint32_t data_sz, + void (*reply_cb)(struct rvi_t*rvi, + uint32_t trans_id, + int32_t result, + uint8_t* data, + uint32_t data_sz)) +{ + return RVI_OK; +} + + +int32_t rvi_reply(struct rvi_t*rvi, uint32_t trans_id, + uint8_t* data, uint32_t data_sz) +{ + return RVI_OK; +} + + + @@ -0,0 +1,499 @@ +/* + Copyright (C) 2014, Jaguar Land Rover + + This program is licensed under the terms and conditions of the + Mozilla Public License, version 2.0. The full text of the + Mozilla Public License is at https://www.mozilla.org/MPL/2.0/ +*/ + +/* + Header file for native C RVI node. + + -------------- + We will start off this C code as a wrapper around JSON-RPC so that + we can talk to a full-fledged erlang RVI node. + + Once we mature, we will upgrade this code to become a complete, + stripped-down RVI node in its own right. The documentation below + describes the complete, end goal C implementation. + -------------- + + This header file describes the C API for an RVI node (C-RVI) with + reduced functionality. The following functionality are stripped out + of (C-RVI) in order to reduce its foot print. + + 1) Scheduling + No store and forward is available. If a message is sent to a service + that is currently not available, an error message is returned to the caller. + + 2) Single protocol + Only one protocol at the time is supported at data link level. + A protocol is loaded from an shared object (or is linked in to the library). + This protocol is the only one supported for as long as the library is in use. + +*/ +#include <stdint.h> +#include <time.h> + +/* Return codes */ +#define RVI_OK 0 +#define RVI_ARRAY_OVERFLOW 1 +#define RVI_PARAMETER 2 + +struct rvi_t; + + +/* Init the rvi library + + PARAMETERS: + N/A + + RETURNS: + RVI_OK Call successful + +*/ + // IMPLEMENT +int32_t rvi_init(void); + +/* Cleanup the rvi library after the last rvi_t* struct has been deleted + + PARAMETERS: + N/A + + RETURNS: + RVI_OK Call successful + +*/ + // IMPLEMENT +int32_t rvi_cleanup(void); + + +/* Initialize a new rvi_t struct and return it. + + 'service_prefix' is a string that will be used + to prefix all services registered with rvi_register_service(). + + If the service_prefix string is set to "jlr.com/vin/1234/", + and a service named "sota/install_package" is registered, the full + service name will be "jlr.com/vin/1234/sota/install_package" + + Call rvi_delete() to delete the struct that is created and returned + by rvi_new(). + + PARAMETERS: + service_prefix The string to prefix all registered services with. + + service_available_cb Callback to invoke when a new service + becomes available for invocation through + rvi_send_message(). + + service_unavailable_cb Callback to invoke when a previously available service + becomes unavailable for invocation through + rvi_send_message(). + + RETURNS: + Pointer to new rvi_t struct. +*/ + // IMPLEMENT - But ignore callbacks for now. +struct rvi_t* rvi_new(char* service_prefix, + void (*service_available_cb)(struct rvi_t* rvi, char* service_name), + void (*service_unavailable_cb)(struct rvi_t* rvi, char* service_name)); + + +/* Delete a previously created rvi_t struct + + Frees all resources occupied by 'rvi', including keys, configs, and + certificates. + + 'rvi' cannot be referenced after this function returns. + + PARAMETERS: + rvi The RVI struct, returned by rvi_new(), that is to be deleted. + + RETURNS: + RVI_OK Call successful + +*/ + // IMPLEMENT +int32_t rvi_delete(struct rvi_t* rvi); + + +/* Set user data for an rvi_t struct. + + Associate the pointer in 'user_data' with 'rvi'. The provided pointer + can be retrieved with get_user_data(). + + PARAMETERS: + rvi The RVI struct, returned by rvi_new(), that is to have user + data associated with it. + + user_data The data to associate with 'rvi' + + RETURNS: + RVI_OK Call successful + +*/ + // IMPLEMENT +int32_t rvi_set_user_data(struct rvi_t* rvi, void* user_data); + +/* Get user data for an rvi_t struct. + + + Return the pointer, previously registered with rvi_set_user_data(), associated + with 'rvi'. If rvi_set_user_data() has not been called for 'rvi', NULL will + be returned. + + PARAMETERS: + rvi The RVI struct, returned by rvi_new(), that is to have user + data associated with it. + + + RETURNS: + User data, or NULL if rvi_set_user_data() has not been called for 'rvi' + + +*/ + // IMPLEMENT +void* rvi_get_user_data(struct rvi_t* rvi); + + +/* Add configuration data to the rvi_t struct + + The given key/value pair is processed and integrated into + the configuration data of 'rvi'. + + Ownership of 'key' and 'value' arguments are *not* transfered to + the 'rvi'. These two arguments must be freed by the caller. + + PARAMETERS: + rvi The RVI struct returned by rvi_new(). + + key The name of the configuration entry to add. + + value The value of the configuration entry to add. + + RETURNS: + RVI_OK Call successful. + RVI_PARAMETER One or more config entries could not be processed. + +*/ + // IMPLEMENT + // Things that we need to configure for JSON-RPC wrapper: + // The URL that we listen to incoming JSON-RPC calls on (maybe just a port) + // The URL of the RVI node that we are talking to +int32_t rvi_add_configuration(struct rvi_t* rvi, char* key, char* value); + + +/* Add a public key to the rvi_t struct + + The provided public key is processed and integrated into 'rvi'. The + key will be used to validate the certificates attached to incoming + transactions. + + Ownership of 'public_key' argument is *not* transfered to the + 'rvi'. This argument must be freed by the caller. + + PARAMETERS: + rvi The RVI struct returned by rvi_new(). + + id A system-wide unique ID for the public key. + + public_key Public key string. + + + RETURNS: + RVI_OK Call successful. + RVI_PARAMETER One or more public keys could not be processed. +*/ + // DO NOT IMPLEMENT +int32_t rvi_add_public_key(struct rvi_t* rvi, char* id, char* public_key); + +/* Add a certificate to the rvi_t structnn + + The certificate is added as a clear text JSON string, signed by the + appropriate private key. See RVI HLD, rev A, chapter 7.2 for details + on the certificate format. + + The signature for the certificate is created using a private key where + the corresponsing public key has been added to the system + using the rvi_add_public_key() function. + + None of the provided arguments to rvi_add_certificates() will have + their ownership transfered to 'rvi'. All arguments must be freed by + the caller. + + PARAMETERS: + rvi The RVI struct returned by rvi_new(). + + certificate The JSON-RPC string containing the certificate. + + signature The signature, created by the private + + public_key_id The ID of the public key, registered with + rvi_add_public_key(), whose private counterpart + created the signature. + + RETURNS: + RVI_OK Call successful. + RVI_PARAMETER One or more certificates could not be processed. +*/ + // DO NOT IMPLEMENT +int32_t rvi_add_certificates(struct rvi_t* rvi, + char* certificate, + char* signature, + char *public_key_id); + + +/* Register a service available for callback + + + The 'service_name' will be appended to the service prefix specified + for 'rvi' and then announced to the rest of the RVI network + as being available to handle transactions. + + The full service name (prefix + name) is returned in 'full_service_name'. + + When a message is received for the given service, + 'process_message_cb' will be invoked with the following paramters: + + rvi Same rvi struct as that provided to rvi_register_service() + + service_name Full service name that triggered the callback. + + trans_id If 0, no reply expected. If != 0, a reply is + expected, with the given trans_id provided, + in rvi_send_reply(). + + data The data to provide as parameter to the service. + + data_sz Number of bytes in data. + + 'process_message_cb' is expected to return something from the + RVI_XXX result suite. + + + PARAMETERS: + rvi Te RVI struct returned by rvi_new(). + + local_service_name Local service name to append to the service name + prefix for 'rvi'. + + full_service_name Will be filled out with the full service name + of the registered service. + + full_service_name_sz Maximum number of bytes to write to + full_service_name. + + trans_id If 0, no reply expected. If != 0, a reply is expected, + with the given trans_id provided, in rvi_send_reply(). + + data The data to provide as parameter to the service. + + data_sz Number of bytes in data. + + + + + RETURNS: + RVI_OK Call succesful. + + RVI_ARRAY_OVERFLOW The full serivce name is longer than the number of bytes + specified by 'full_service_name_sz'. + +*/ + // IMPLEMENT - But ignore trans_id +int32_t rvi_register_service(struct rvi_t* rvi, char* local_name, + char* full_service_name, uint32_t full_service_name_sz, + int32_t (*process_message_cb)(struct rvi_t*, char* service_name, + uint32_t trans_id, + uint8_t* data, uint32_t data_sz)); + + + +/* Activate an rvi_t struct + + This function is called to activate 'rvi' once it has been configured with + rvi_register_service(), rvi_add_certificates(), rvi_add_public_keys(), + and rvi_add_configuration(). + + When this call is returns, the callbacks provided during the setup + of 'rvi' may be invoked at any time. + + PARAMETERS: + rvi The RVI struct returned by rvi_new(). + + RETURNS: + RVI_OK Call successful. + + RVI_NETOWRK A network error ocurred during activation. Check + errno. +*/ + // IMPLEMENT - Fire up listening socket and accept incoming + // JSON-RPC traffic from RVI node +int32_t rvi_activate(struct rvi_t* rvi); + + + + +/* Dectivate an rvi_t struct + + This function is called to deactivate 'rvi', previously activated through + rvi_activate(). + + When this call is returns, no more callbacks will be invoked + by the 'rvi', and any active network ports will be closed. + + PARAMETERS: + rvi The RVI struct returned by rvi_new(). + + RETURNS: + RVI_OK Call successful. + +*/ + // IMPLEMENT +int32_t rvi_deactivate(struct rvi_t* rvi); + + + +/* Return the file descriptor associated with an rvi_t struct. + + This function will set the provided 'descriptor' parameter + that was created by rvi_activate(). + + The returned descriptor should be rolled into a + poll()/epoll()/select() loop for read ready. (We will do non + blocking write ready later on.) + + When given descriptor is marked as read ready, rvi_process() + should be invoked as soon as possible to read and process + incoming data from other RVI nodes. + + Please note that this rvi_get_descriptor() must be called after + every rvi_activate() invocation for the given 'rvi' struct to get + the fresh descriptor created by the activation. + + PARAMETERS: + rvi The RVI struct returned by rvi_new(). + + descriptor Pointer to the integer to set to the descriptor. + + RETURNS: + RVI_OK Call successful. + + RVI_INACTIVE The 'rvi' struct has not been activated with + rvi_activate(). + +*/ + // IMPLEMENT +int32_t rvi_get_descriptor(struct rvi_t* rvi, int32_t *descriptor); + + + +/* Process any pending network traffic for the RVI node + + This call should only be invokd after the descriptor returned + by an rvi_get_descriptor() invocation is marked as ready to be read. + If that is not done, rvi_process() will wait until data is received. + + Any incoming data processed by rvi_process() may trigger callbacks + to the function pointers provided to rvi_new() and rvi_register_service(). + Once these functions returns, rvi_process() will return to its caller as well. + + The callbacks are, in other words, synchronous and processed byu the + rvi_process()-calling thread. + + +*/ + // IMPLEMENT +int32_t rvi_process(struct rvi_t* rvi); + + + +/* Send a message to a service + + This call will invoke the given service executing on the local or a + remote RVI node. If 'reply_cb' is set, a reply is expected by the + invoked (remote) service. The reply will be delivered by invoking the + 'reply_cb' with the following arguments: + + rvi Same rvi struct as that provided to rvi_send_message() + + result RVI_OK - Reply was delivered. Check data/data_sz. + RVI_TIMEOUT - Transaction timed out. + RVI_UNKNOWN - Unknown error + + trans_id Same value as the argument provided to + rvi_send_message(). + + data The data sent back by the invoked service with the reply + + data_sz Number of bytes in data. + + + + PARAMETERS: + rvi The RVI struct returned by rvi_new(). + + service Full name of the service to invoke. + + timeout UTC for when this message must be delivered by. If that does not + happen, the message is dropped. In that case, if reply_cb is set, + it will be invoked with the given 'rvi' and 'trans_id' with + 'result' set to 'timeout'. + + trans_id Id to send back with 'reply_cb' when it is invoked. + + data Data to provide to the invoked service. + + data_sz Number of bytes in 'data'. + + reply_cb Callback to invoke on error or reply. Set to 0 if no + reply is wanted. + + RETURNS: + RVI_OK Call successful. + + RVI_PARAMETER One or more config entries could not be processed. + +*/ + // IMPLEMENT - But ignore trans_id and reply_cb. +int32_t rvi_send_message(struct rvi_t*rvi, + char* service, + time_t timeout, + uint32_t trans_id, + uint8_t* data, uint32_t data_sz, + void (*reply_cb)(struct rvi_t*rvi, + uint32_t trans_id, + int32_t result, + uint8_t* data, + uint32_t data_sz)); + + +/* Send a reply back to an originating service + + This function, which should only be invoked by the function + pointed to by the 'process_message_cb' argument provided to + rvi_register_service(), will send back a reply to the service + originating a message. + + + PARAMETERS: + + rvi The same rvi_t struct as provided to the 'process_message_cb' + function. + + trans_id The same transaction id as provided to the + 'process_message_cb' function. + + data Data to send back with the reply + + data_sz Number of bytes in 'data'. + + RETURNS: + RVI_OK Call successful. + +*/ + // DO NOT IMPLEMENT +int32_t rvi_reply(struct rvi_t*rvi, uint32_t trans_id, + uint8_t* data, uint32_t data_sz); + |