summaryrefslogtreecommitdiff
path: root/c
diff options
context:
space:
mode:
authorMagnus Feuer <mfeuer@jaguarlandrover.com>2015-03-20 13:01:37 -0700
committerMagnus Feuer <mfeuer@jaguarlandrover.com>2015-03-20 13:01:37 -0700
commitb4e2f85659932201119ec8a1b2d9bcf062e09e67 (patch)
treea42acb95d02d640a64cbd2935f6f842759162680 /c
parent8f63d68945359f9fab1eca5907faee698743c481 (diff)
downloadrvi_core-b4e2f85659932201119ec8a1b2d9bcf062e09e67.tar.gz
Added skeleton native C API from sota_demo.
Diffstat (limited to 'c')
-rw-r--r--c/rvi.c133
-rw-r--r--c/rvi.h499
2 files changed, 632 insertions, 0 deletions
diff --git a/c/rvi.c b/c/rvi.c
new file mode 100644
index 0000000..749ed9e
--- /dev/null
+++ b/c/rvi.c
@@ -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;
+}
+
+
+
diff --git a/c/rvi.h b/c/rvi.h
new file mode 100644
index 0000000..73ba09e
--- /dev/null
+++ b/c/rvi.h
@@ -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);
+