static void ui_connection_handle_message(UiConnection *self, const gchar *protocol, const gchar *command, JsonObject *payload, SoupWebsocketConnection *ws) { if (g_strcmp0(protocol, "graph") == 0) { handle_graph_message(self, command, payload, ws); } else if (g_strcmp0(protocol, "network") == 0) { handle_network_message(self, command, payload, ws); } else if (g_strcmp0(protocol, "component") == 0 && g_strcmp0(command, "list") == 0) { gint no_components = 0; gchar **operation_names = library_list_components(self->component_lib, &no_components); for (int i=0; i<no_components; i++) { const gchar *op = operation_names[i]; if (op) { JsonObject *component = library_get_component(self->component_lib, op); send_response(ws, "component", "component", component); } } g_strfreev(operation_names); } else if (g_strcmp0(protocol, "component") == 0 && g_strcmp0(command, "source") == 0) { const gchar *name = json_object_get_string_member(payload, "name"); gchar *actual_name = library_set_source(self->component_lib, name, json_object_get_string_member(payload, "code") ); if (actual_name) { JsonObject *component = library_get_component(self->component_lib, name); send_response(ws, "component", "component", component); } else { // TODO: error response } g_free(actual_name); } else if (g_strcmp0(protocol, "component") == 0 && g_strcmp0(command, "getsource") == 0) { const gchar *name = json_object_get_string_member(payload, "name"); JsonObject *source_info = json_object_new(); // TODO: generalize for subgraphs-as-components if (g_strcmp0(name, self->main_network) == 0) { json_object_set_string_member(source_info, "name", "main"); // FIXME: dont hardcode json_object_set_string_member(source_info, "library", "default"); // FIXME: dont hardcode Network *n = g_hash_table_lookup(self->network_map, self->main_network); g_assert(n); JsonObject *g = graph_save_json(n->graph); gsize len = 0; gchar *code = json_stringify(g, &len); g_assert(len); json_object_set_string_member(source_info, "language", "json"); json_object_set_string_member(source_info, "code", code); } else { json_object_set_string_member(source_info, "name", name); gchar *code = library_get_source(self->component_lib, name); json_object_set_string_member(source_info, "library", "imgflo"); json_object_set_string_member(source_info, "language", "c"); json_object_set_string_member(source_info, "code", code); } send_response(ws, "component", "source", source_info); } else if (g_strcmp0(protocol, "runtime") == 0 && g_strcmp0(command, "getruntime") == 0) { JsonObject *runtime = json_object_new(); json_object_set_string_member(runtime, "version", "0.4"); // protocol version json_object_set_string_member(runtime, "type", "imgflo"); json_object_set_string_member(runtime, "graph", self->main_network); JsonArray *capabilities = json_array_new(); json_array_add_string_element(capabilities, "protocol:component"); json_array_add_string_element(capabilities, "protocol:graph"); json_array_add_string_element(capabilities, "protocol:runtime"); json_array_add_string_element(capabilities, "protocol:network"); json_array_add_string_element(capabilities, "component:getsource"); json_array_add_string_element(capabilities, "component:setsource"); json_object_set_array_member(runtime, "capabilities", capabilities); send_response(ws, "runtime", "runtime", runtime); if (self->main_network) { send_ports(g_hash_table_lookup(self->network_map, self->main_network), ws); } } else if (g_strcmp0(protocol, "runtime") == 0 && g_strcmp0(command, "packet") == 0) { gchar *graph_id = g_strdup(json_object_get_string_member(payload, "graph")); const gchar *port = json_object_get_string_member(payload, "port"); const gchar *event = json_object_get_string_member(payload, "event"); if (!graph_id) { // NoFlo RemoteSubGraph currently does not send graph info graph_id = g_strdup(self->main_network); } Network *network = (graph_id) ? g_hash_table_lookup(self->network_map, graph_id) : NULL; g_free(graph_id); g_return_if_fail(network); if (g_strcmp0(event, "data") == 0) { GValue data = G_VALUE_INIT; json_node_get_value(json_object_get_member(payload, "payload"), &data); network_send_packet(network, port, &data); } else { // TODO: support connect/disconnect? imgflo_warning("Unknown runtime:packet event: %s", event); } } else { imgflo_warning("Unhandled message: protocol='%s', command='%s'", protocol, command); } }
void ControlPack::parse() { uint8_t src = _buffer[0]; uint8_t dst = _buffer[1]; uint8_t cmd = _buffer[2]; if (dst == _me || dst == CP_EVERYONE) { switch (cmd) { case CPC_HEARTBEAT: if (_cb_heartbeat != 0) { _cb_heartbeat(src, dst); } break; case CPC_VERSION_QUERY: send_version(dst); break; case CPC_VERSION_INFO: if (_cb_version_info != 0) { uint16_t version = (_buffer[3] << 8) + _buffer[4]; _cb_version_info(src, dst, version); } break; case CPC_MODEL_QUERY: send_model(dst); break; case CPC_MODEL_INFO: if (_cb_model_info != 0) { _cb_model_info(src, dst, _buffer[3]); } break; case CPC_PORT_QUERY: send_ports(dst); break; case CPC_PORT_INFO: if (_cb_port_info != 0) { _cb_port_info(src, dst, _buffer[3]); } break; case CPC_ALL_OFF: if (_cb_all_off != 0) { _cb_all_off(src, dst); } break; case CPC_ALL_ON: if (_cb_all_on != 0) { _cb_all_on(src, dst); } break; case CPC_ALL_TIMED: if (_cb_all_timed != 0) { uint16_t millis = (_buffer[3] << 8) + _buffer[4]; _cb_all_timed(src, dst, millis); } break; case CPC_PORT_OFF: if (_cb_port_off != 0) { _cb_port_off(src, dst, _buffer[3]); } break; case CPC_PORT_ON: if (_cb_port_on != 0) { _cb_port_on(src, dst, _buffer[3]); } break; case CPC_PORT_TIMED: if (_cb_port_timed != 0) { uint16_t millis = (_buffer[4] << 8) + _buffer[5]; _cb_port_timed(src, dst, _buffer[3], millis); } break; case CPC_SEQUENCE_UP: if (_cb_sequence_up != 0) { uint16_t millis = (_buffer[3] << 8) + _buffer[4]; _cb_sequence_up(src, dst, millis); } break; case CPC_SEQUENCE_DOWN: if (_cb_sequence_down != 0) { uint16_t millis = (_buffer[3] << 8) + _buffer[4]; _cb_sequence_down(src, dst, millis); } break; default: break; } } }