Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 54 additions & 9 deletions libgstd/gstd_action.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,9 @@ gstd_action_create_default (GstdObject * object, const gchar * name,
GstdAction *action = NULL;
GSignalQuery query;
guint action_id;
gint ret_sig = 0;
GValue ret_sig = G_VALUE_INIT;
GValue *args = NULL;
gchar **arg_list = NULL;

GST_INFO_OBJECT (action, "Action create");

Expand All @@ -222,19 +224,62 @@ gstd_action_create_default (GstdObject * object, const gchar * name,
G_OBJECT_TYPE (action->target));
g_signal_query (action_id, &query);

if (query.n_params > 0) {
GST_ERROR_OBJECT (action, "Only actions with no parameters are supported");
ret = GSTD_BAD_VALUE;
goto out;
if (query.n_params > 0 && (!description || g_strcmp0(description, "(null)") == 0 || g_strcmp0(description, "") == 0)) {
return GSTD_NULL_ARGUMENT;
} else if (description) {
arg_list = g_strsplit (description, " ", query.n_params);
}

GST_INFO_OBJECT (action, "Emit to %s", GST_OBJECT_NAME (action->target));
g_signal_emit_by_name (action->target, name, &ret_sig);
if (g_strv_length (arg_list) != query.n_params) {
return GSTD_NULL_ARGUMENT;
}

/* One additional value to store the instance as first value */
args = g_new0 (GValue, query.n_params + 1);

g_value_init (&args[0], G_TYPE_OBJECT);
g_value_set_object (&args[0], action->target);

for (guint i = 0; i < query.n_params; i++) {
g_value_init (&args[i + 1], query.param_types[i]);

if (query.param_types[i] == G_TYPE_STRING) {
g_value_set_string (&args[i + 1], arg_list[i]);
} else if (query.param_types[i] == G_TYPE_INT) {
g_value_set_int (&args[i + 1], g_ascii_strtoll (arg_list[i], NULL, 10));
} else if (query.param_types[i] == G_TYPE_UINT) {
g_value_set_uint (&args[i + 1], (guint) g_ascii_strtoull (arg_list[i], NULL, 10));
} else if (query.param_types[i] == G_TYPE_UINT64) {
g_value_set_uint64 (&args[i + 1], (guint64) g_ascii_strtoull (arg_list[i],
NULL, 10));
} else if (query.param_types[i] == G_TYPE_BOOLEAN) {
g_value_set_boolean (&args[i + 1], g_ascii_strcasecmp (arg_list[i], "true") == 0);
} else if (query.param_types[i] == G_TYPE_FLOAT) {
g_value_set_float (&args[i + 1], g_ascii_strtod (arg_list[i], NULL));
} else if (query.param_types[i] == G_TYPE_DOUBLE) {
g_value_set_double (&args[i + 1], g_ascii_strtod (arg_list[i], NULL));
} else {
ret = GSTD_BAD_COMMAND;
goto out;
}
}

if (ret_sig != 0) {
ret = GSTD_BAD_VALUE;
if (query.return_type != G_TYPE_NONE) {
g_value_init(&ret_sig, query.return_type);
g_signal_emitv (args, action_id, 0, &ret_sig);

/* The return value is not required */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should document this. That the actions ignore the return values


g_value_unset(&ret_sig);
} else {
g_signal_emitv (args, action_id, 0, NULL);
}

out:
for (guint i = 0; i <= query.n_params; i++)
g_value_unset (&args[i]);
Comment on lines +279 to +280
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Braces

g_free (args);
g_strfreev (arg_list);

return ret;
}
66 changes: 63 additions & 3 deletions libgstd/gstd_http.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <string.h>
#include <gst/gst.h>
#include <libsoup/soup.h>
#include <json-glib/json-glib.h>

#include "gstd_http.h"
#include "gstd_parser.h"
Expand Down Expand Up @@ -83,6 +84,7 @@ static GstdReturnCode do_put (SoupServer * server, SoupMessage * msg,
static GstdReturnCode do_delete (SoupServer * server, SoupMessage * msg,
char *name, char **output, const char *path, GstdSession * session);
static void do_request (gpointer data_request, gpointer eval);
static void parse_json_body (SoupMessage *msg, gchar **out_name, gchar **out_desc);
static void server_callback (SoupServer * server, SoupMessage * msg,
const char *path, GHashTable * query, SoupClientContext * context,
gpointer data);
Expand Down Expand Up @@ -311,9 +313,13 @@ do_request (gpointer data_request, gpointer eval)
path = data_request_local->path;
query = data_request_local->query;

if (query != NULL) {
name = g_hash_table_lookup (query, "name");
description_pipe = g_hash_table_lookup (query, "description");
Comment on lines -314 to -316
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have you evaluated if this breaks something? It seems that everything is now encapsulated into a JSON. I wonder if this is going to break something on the HTTP side. Have you checked the examples?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I evaluated the examples using Postman and curl, with the current HTTP structure and using a JSON. For example:

curl --location 'http://127.0.0.1:3000/pipelines' --header 'Content-Type: application/json' --data '{"name": "p1", "description": "videotestsrc name=vts ! identity name=id ! autovideosink"}'

curl --location --request POST 'http://127.0.0.1:3000/pipelines?name=p0&description=videotestsrc%20name%3Dvts%20!%20identity%20name%3Did%20!%20autovideosink'

parse_json_body (msg, &name, &description_pipe);

if (!name && query) {
name = g_strdup (g_hash_table_lookup (query, "name"));
}
if (!description_pipe && query) {
description_pipe = g_strdup (g_hash_table_lookup (query, "description"));
}

if (msg->method == SOUP_METHOD_GET) {
Expand All @@ -327,6 +333,10 @@ do_request (gpointer data_request, gpointer eval)
} else if (msg->method == SOUP_METHOD_OPTIONS) {
ret = GSTD_EOK;
}
g_free (name);
g_free (description_pipe);
name = NULL;
description_pipe = NULL;

description = gstd_return_code_to_string (ret);
response =
Expand Down Expand Up @@ -356,6 +366,56 @@ do_request (gpointer data_request, gpointer eval)
return;
}

static void
parse_json_body (SoupMessage *msg, gchar **out_name, gchar **out_desc)
{
const char *content_type = NULL;
JsonParser *parser = NULL;
JsonNode *root = NULL;
GError *err = NULL;

g_return_if_fail (msg);
g_return_if_fail (out_name);
g_return_if_fail (out_desc);

*out_name = NULL;
*out_desc = NULL;

soup_message_body_flatten (msg->request_body);
if (!msg->request_body || msg->request_body->length == 0) {
return;
}

content_type = soup_message_headers_get_content_type (msg->request_headers, NULL);
if (!content_type || !g_str_has_prefix (content_type, "application/json")) {
return;
}

parser = json_parser_new ();
if (!json_parser_load_from_data (parser,
msg->request_body->data,
msg->request_body->length,
&err)) {
Comment on lines +395 to +398
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indentation is incorrect. You should use gst-indent

g_clear_error (&err);
g_object_unref (parser);
return;
}

root = json_parser_get_root (parser);
if (JSON_NODE_HOLDS_OBJECT (root)) {
JsonObject *obj = json_node_get_object (root);
if (json_object_has_member (obj, "name")) {
const char *value = json_object_get_string_member (obj, "name");
if (value) *out_name = g_strdup (value);
}
if (json_object_has_member (obj, "description")) {
const char *value = json_object_get_string_member (obj, "description");
if (value) *out_desc = g_strdup (value);
}
}
g_object_unref (parser);
}

static void
server_callback (SoupServer * server, SoupMessage * msg,
const char *path, GHashTable * query,
Expand Down
6 changes: 3 additions & 3 deletions libgstd/gstd_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -939,13 +939,13 @@ gstd_parser_action_emit (GstdSession * session, gchar * action,
g_return_val_if_fail (args, GSTD_NULL_ARGUMENT);
g_return_val_if_fail (response, GSTD_NULL_ARGUMENT);

tokens = g_strsplit (args, " ", 3);
tokens = g_strsplit (args, " ", 4);
check_argument (tokens[0], GSTD_BAD_COMMAND);
check_argument (tokens[1], GSTD_BAD_COMMAND);
check_argument (tokens[2], GSTD_BAD_COMMAND);

uri = g_strdup_printf ("/pipelines/%s/elements/%s/actions/%s %s",
tokens[0], tokens[1], tokens[2], tokens[2]);
uri = g_strdup_printf ("/pipelines/%s/elements/%s/actions/%s %s %s",
tokens[0], tokens[1], tokens[2], tokens[2], tokens[3]);
ret = gstd_parser_parse_raw_cmd (session, (gchar *) "create", uri, response);

g_free (uri);
Expand Down
Loading