aboutsummaryrefslogtreecommitdiffstats
path: root/binding/wrap-unicens/wrap-unicens.c
diff options
context:
space:
mode:
Diffstat (limited to 'binding/wrap-unicens/wrap-unicens.c')
-rw-r--r--binding/wrap-unicens/wrap-unicens.c228
1 files changed, 228 insertions, 0 deletions
diff --git a/binding/wrap-unicens/wrap-unicens.c b/binding/wrap-unicens/wrap-unicens.c
new file mode 100644
index 0000000..e5d4570
--- /dev/null
+++ b/binding/wrap-unicens/wrap-unicens.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2019 Microchip Technology Inc. and its subsidiaries
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <wrap-json.h>
+#include "wrap-unicens.h"
+
+typedef struct async_job_ {
+ wrap_ucs_result_cb_t result_fptr;
+ void *result_user_ptr;
+} async_job_t;
+
+typedef struct parse_result_ {
+ int done;
+ char *str_result;
+} parse_result_t;
+
+static afb_api_t api_handle_ = NULL;
+
+/* Initializes UNICENS API wrapper */
+extern int wrap_ucs_init(afb_api_t api_handle) {
+ api_handle_ = api_handle;
+ return afb_api_require_api(api_handle_, "UNICENS", 1);
+}
+
+/*
+ * Subscribes to unicens2-binding events.
+ * \return Returns 0 if successful, otherwise != 0".
+ */
+extern int wrap_ucs_subscribe_sync(void) {
+ int err;
+
+ json_object *j_response, *j_query = NULL;
+ char *error, *info;
+
+ /* Build an empty JSON object */
+ if((err = wrap_json_pack(&j_query, "{}"))) {
+ AFB_API_ERROR(api_handle_, "Failed to create subscribe json object");
+ return err;
+ }
+
+ if((err = afb_api_call_sync(api_handle_, "UNICENS", "subscribe", j_query, &j_response, &error, &info))) {
+ AFB_API_ERROR(api_handle_, "Fail subscribing to UNICENS events");
+ return err;
+ }
+ else {
+ AFB_API_NOTICE(api_handle_, "Subscribed to UNICENS events, res=%s", json_object_to_json_string(j_response));
+ json_object_put(j_response);
+ }
+
+ return 0;
+}
+
+extern int wrap_ucs_interpret_event(const char *event, struct json_object *object, wrap_ucs_availability_cb_t callback) {
+ int node_id = 0;
+ int available = false;
+
+ if (strcmp(event, "UNICENS/node-availibility") != 0) {
+ return -1; // unhandled event
+ }
+
+ if (wrap_json_unpack(object, "{s:i,s:b}", "node", &node_id, "available", &available) != 0) {
+ AFB_API_NOTICE(api_handle_, "Parsing node-availibility failed.");
+ return -2;
+ }
+
+ if (callback != NULL) {
+ callback((uint16_t)node_id, (bool)available);
+ }
+
+ return 0;
+}
+
+/*
+ * Write I2C command to a network node.
+ * \param node Node address
+ * \param ata_ptr Reference to command data
+ * \param data_sz Size of the command data. Valid values: 1..32.
+ * \return Returns 0 if successful, otherwise != 0".
+ */
+extern int wrap_ucs_i2cwrite_sync(uint16_t node, uint8_t *data_ptr, uint8_t data_sz) {
+ int err;
+ uint8_t cnt;
+
+ json_object *j_response, *j_query, *j_array = NULL;
+ char *error, *info;
+
+ j_query = json_object_new_object();
+ j_array = json_object_new_array();
+
+ if(! j_query || ! j_array) {
+ AFB_API_ERROR(api_handle_, "Failed to create writei2c json objects");
+ return -1;
+ }
+
+ for(cnt = 0U; cnt < data_sz; cnt++)
+ json_object_array_add(j_array, json_object_new_int(data_ptr[cnt]));
+
+ json_object_object_add(j_query, "node", json_object_new_int(node));
+ json_object_object_add(j_query, "data", j_array);
+
+ if((err = afb_api_call_sync(api_handle_, "UNICENS", "writei2c", j_query, &j_response, &error, &info))) {
+ AFB_API_ERROR(api_handle_, "Failed to call writei2c_sync");
+ return err;
+ }
+ else {
+ AFB_API_INFO(api_handle_, "Called writei2c_sync, res=%s", json_object_to_json_string(j_response));
+ json_object_put(j_response);
+ }
+
+ return 0;
+}
+
+extern int wrap_ucs_sendmessage_sync(uint16_t src_addr, uint16_t msg_id, uint8_t *data_ptr, uint8_t data_sz) {
+
+ json_object *j_query, *j_response = NULL;
+ char *error, *info;
+ int err = 1;
+ int node = (int)src_addr;
+ int msgid = (int)msg_id;
+ size_t data_size = (size_t)data_sz;
+
+ AFB_API_NOTICE(api_handle_, "--- HAL triggering send message ---");
+
+ /* skip data attribute if possible, wrap_json_unpack may fail to deal with
+ * an empty Base64 string */
+ if (data_size > 0)
+ wrap_json_pack(&j_query, "{s:i, s:i, s:Y}", "node", node, "msgid", msgid, "data", data_ptr, data_size);
+ else
+ wrap_json_pack(&j_query, "{s:i, s:i}", "node", node, "msgid", msgid);
+
+ AFB_API_NOTICE(api_handle_, "wrap_ucs_sendmessage: jquery=%s", json_object_to_json_string(j_query));
+
+ err = afb_api_call_sync(api_handle_, "UNICENS", "sendmessage", j_query, &j_response, &error, &info);
+
+ if (err != 0) {
+ AFB_API_ERROR(api_handle_, "Failed to call wrap_ucs_sendmessage ret=%d", err);
+ }
+ else {
+ AFB_API_NOTICE(api_handle_, "Called wrap_ucs_sendmessage, successful");
+ }
+
+ if (j_response != NULL) {
+ AFB_API_NOTICE(api_handle_, "wrap_ucs_sendmessage, response=%s", json_object_to_json_string(j_response));
+ json_object_put(j_response);
+ }
+
+ return err;
+}
+
+/* ---------------------------- ASYNCHRONOUS API ---------------------------- */
+static void wrap_ucs_i2cwrite_cb(void *closure, /*int status, */struct json_object *j_result,
+ const char *error, const char * info, afb_api_t api) {
+ async_job_t *job_ptr;
+
+ AFB_API_INFO(api_handle_, "%s: closure=%p status=?, res=%s", __func__, closure, /*status,*/ json_object_to_json_string(j_result));
+
+ if(closure) {
+ job_ptr = (async_job_t *) closure;
+
+ if(job_ptr->result_fptr)
+ job_ptr->result_fptr(0/*(uint8_t) abs(status)*/, job_ptr->result_user_ptr);
+
+ free(closure);
+ }
+}
+
+/*
+ * Write I2C command to a network node.
+ * \param node Node address
+ * \param data_ptr Reference to command data
+ * \param data_sz Size of the command data. Valid values: 1..32.
+ * \return Returns 0 if successful, otherwise != 0".
+ */
+extern int wrap_ucs_i2cwrite(uint16_t node,
+ uint8_t *data_ptr,
+ uint8_t data_sz,
+ wrap_ucs_result_cb_t result_fptr,
+ void *result_user_ptr)
+{
+ uint8_t cnt;
+
+ json_object *j_query, *j_array = NULL;
+ async_job_t *job_ptr = NULL;
+
+ j_query = json_object_new_object();
+ j_array = json_object_new_array();
+
+ if(! j_query || ! j_array) {
+ AFB_API_ERROR(api_handle_, "Failed to create writei2c json objects");
+ return -1;
+ }
+
+ for(cnt = 0U; cnt < data_sz; cnt++)
+ json_object_array_add(j_array, json_object_new_int(data_ptr[cnt]));
+
+ json_object_object_add(j_query, "node", json_object_new_int(node));
+ json_object_object_add(j_query, "data", j_array);
+
+ job_ptr = malloc(sizeof(async_job_t));
+
+ if(! job_ptr) {
+ AFB_API_ERROR(api_handle_, "Failed to create async job object");
+ json_object_put(j_query);
+ return -2;
+ }
+
+ job_ptr->result_fptr = result_fptr;
+ job_ptr->result_user_ptr = result_user_ptr;
+
+ afb_api_call(api_handle_, "UNICENS", "writei2c", j_query, wrap_ucs_i2cwrite_cb, job_ptr);
+ return 0;
+}