static int dslink_init_responder(Responder *responder) { responder->super_root = dslink_node_create(NULL, "/", "node"); if (!responder->super_root) { goto cleanup; } DSLINK_RESPONDER_MAP_INIT(open_streams, uint32) DSLINK_RESPONDER_MAP_INIT(list_subs, str) DSLINK_RESPONDER_MAP_INIT(value_path_subs, str) DSLINK_RESPONDER_MAP_INIT(value_sid_subs, uint32) return 0; cleanup: if (responder->open_streams) { DSLINK_MAP_FREE(responder->open_streams, {}); } if (responder->list_subs) { DSLINK_MAP_FREE(responder->list_subs, {}); } if (responder->value_path_subs) { DSLINK_MAP_FREE(responder->value_path_subs, {}); } if (responder->value_sid_subs) { DSLINK_MAP_FREE(responder->value_sid_subs, {}); } if (responder->super_root) { dslink_node_tree_free(NULL, responder->super_root); } return DSLINK_ALLOC_ERR; }
void responder_init_serialization(DSLink *link, DSNode *root) { DSNode *node = dslink_node_create(root, "saved", "node"); // data for serialization testing dslink_node_set_meta_new(link, node, "$$$password", json_string_nocheck("Test1234")); // load the data after set password to test if the deserialization is correct load_node(link, node); dslink_node_set_meta_new(link, node, "$writable", json_string_nocheck("write")); dslink_node_set_meta_new(link, node, "$type", json_string_nocheck("string")); if (dslink_node_add_child(link, node) != 0) { log_warn("Failed to add the serialization node to the root\n"); dslink_node_tree_free(link, node); } node->on_data_changed = on_node_changed; }
int dslink_init(int argc, char **argv, const char *name, uint8_t isRequester, uint8_t isResponder, DSLinkCallbacks *cbs) { mbedtls_ecdh_context ctx; DSLinkConfig config; Url *url = NULL; json_t *handshake = NULL; char *dsId = NULL; Socket *sock = NULL; DSLink link; memset(&link, 0, sizeof(DSLink)); int ret = 0; config.name = name; if ((ret = dslink_parse_opts(argc, argv, &config)) != 0) { if (ret == DSLINK_ALLOC_ERR) { log_fatal("Failed to allocate memory during argument parsing\n"); } return 1; } // TODO: move .key as a parameter if ((ret = dslink_handshake_key_pair_fs(&ctx, ".key")) != 0) { if (ret == DSLINK_CRYPT_KEY_DECODE_ERR) { log_fatal("Failed to decode existing key\n"); } else if (ret == DSLINK_OPEN_FILE_ERR) { log_fatal("Failed to write generated key to disk\n"); } else if (ret == DSLINK_CRYPT_KEY_PAIR_GEN_ERR) { log_fatal("Failed to generated key\n"); } else { log_fatal("Unknown error occurred during key handling: %d\n", ret); } ret = 1; goto exit; } url = dslink_url_parse(config.broker_url); if (!url) { log_fatal("Failed to parse url: %s\n", config.broker_url); ret = 1; goto exit; } if (isResponder) { link.responder = calloc(1, sizeof(Responder)); if (!link.responder) { log_fatal("Failed to create responder\n"); goto exit; } if (dslink_init_responder(link.responder) != 0) { log_fatal("Failed to initialize responder\n"); goto exit; } } if (cbs->init_cb) { cbs->init_cb(&link); } if ((ret = dslink_handshake_generate(url, &ctx, config.name, isRequester, isResponder, &handshake, &dsId)) != 0) { log_fatal("Handshake failed: %d\n", ret); ret = 1; goto exit; } const char *uri = json_string_value(json_object_get(handshake, "wsUri")); const char *tKey = json_string_value(json_object_get(handshake, "tempKey")); const char *salt = json_string_value(json_object_get(handshake, "salt")); if (!(uri && tKey && salt)) { log_fatal("Handshake didn't return the " "necessary parameters to complete\n"); ret = 1; goto exit; } if ((ret = dslink_handshake_connect_ws(url, &ctx, uri, tKey, salt, dsId, &sock)) != 0) { log_fatal("Failed to connect to the broker: %d\n", ret); ret = 1; goto exit; } else { log_info("Successfully connected to the broker\n"); } if (cbs->on_connected_cb) { cbs->on_connected_cb(&link); } link._socket = sock; dslink_handshake_handle_ws(&link); // TODO: automatic reconnecting log_warn("Disconnected from the broker\n") if (cbs->on_disconnected_cb) { cbs->on_disconnected_cb(&link); } exit: mbedtls_ecdh_free(&ctx); DSLINK_CHECKED_EXEC(dslink_socket_close, sock); if (link.responder) { if (link.responder->super_root) { dslink_node_tree_free(NULL, link.responder->super_root); } if (link.responder->open_streams) { DSLINK_MAP_FREE(link.responder->open_streams, { free(entry->key); free(entry->value); });