Signed-off-by: Ahmed ZRIBI <ahmed.zribi@pivasoftware.com>
Signed-off-by: Mohamed <mohamed.kallel@pivasoftware.com>
---
src/cwmp.c | 2 +-
src/external.c | 70 +++++++++++++-----------------------
src/external.h | 3 +-
src/ubus.c | 39 ++++++++++++++++++++
src/xml.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/xml.h | 4 ++
6 files changed, 181 insertions(+), 48 deletions(-)
diff --git a/src/cwmp.c b/src/cwmp.c
index b75c762..7de19e3 100644
--- a/src/cwmp.c
+++ b/src/cwmp.c
@@ -248,7 +248,7 @@ void cwmp_clear_events(void)
void cwmp_add_notification(char *parameter, char *value, char *type)
{
char *c = NULL;
- external_get_action("notification", parameter, &c);
+ external_get_action_data("notification", parameter, &c);
if (!c) return;
struct notification *n = NULL;
diff --git a/src/external.c b/src/external.c
index 94ae9b8..4973d1a 100644
--- a/src/external.c
+++ b/src/external.c
@@ -60,14 +60,32 @@ void external_free_list_parameter()
}
}
-int external_get_action(char *action, char *name, char **value)
+int external_get_action_data(char *action, char *name, char **value)
+{
+ struct external_parameter *external_parameter;
+ external_get_action(action, name, NULL);
+ if (external_list_parameter.next!=&external_list_parameter) {
+ external_parameter = list_entry(external_list_parameter.next,
struct external_parameter, list);
+ if (external_parameter->data)
+ *value = external_parameter->data;
+ list_del(&external_parameter->list);
+ free(external_parameter->name);
+ free(external_parameter->data);
+ free(external_parameter->type);
+ free(external_parameter->fault_code);
+ free(external_parameter);
+ }
+ external_free_list_parameter();
+ return 0;
+}
+
+int external_get_action(char *action, char *name, char *arg /* arg is added
for GetParameterNames NextLevel argument*/)
{
freecwmp_log_message(NAME, L_NOTICE,
"executing get %s '%s'\n", action, name);
- int pfds[2];
- if (pipe(pfds) < 0)
- return -1;
+
+ pthread_create(&ubus_thread, NULL, &thread_uloop_run, NULL);
if ((uproc.pid = fork()) == -1)
goto error;
@@ -79,66 +97,28 @@ int external_get_action(char *action, char *name, char
**value)
int i = 0;
argv[i++] = "/bin/sh";
argv[i++] = fc_script;
- argv[i++] = "--newline";
- argv[i++] = "--value";
argv[i++] = "get";
argv[i++] = action;
argv[i++] = name;
+ if(arg) argv[i++] = arg;
argv[i++] = NULL;
- close(pfds[0]);
- dup2(pfds[1], 1);
- close(pfds[1]);
-
execvp(argv[0], (char **) argv);
exit(ESRCH);
} else if (uproc.pid < 0)
goto error;
- /* parent */
- close(pfds[1]);
-
int status;
while (wait(&status) != uproc.pid) {
DD("waiting for child to exit");
}
+ pthread_cancel(ubus_thread);
+ pthread_join(ubus_thread,NULL);
- char buffer[64];
- ssize_t rxed;
- char *c;
- int t;
-
- *value = NULL;
- while ((rxed = read(pfds[0], buffer, sizeof(buffer))) > 0) {
- if (*value)
- t = asprintf(&c, "%s%.*s", *value, (int) rxed, buffer);
- else
- t = asprintf(&c, "%.*s", (int) rxed, buffer);
-
- if (t == -1) goto error;
-
- free(*value);
- *value = strdup(c);
- free(c);
- }
-
- if (!strlen(*value)) {
- FREE(*value);
- goto done;
- }
-
- if (rxed < 0)
- goto error;
-
-done:
- close(pfds[0]);
return 0;
error:
- FREE(*c);
- FREE(*value);
- close(pfds[0]);
return -1;
}
diff --git a/src/external.h b/src/external.h
index c6df2ea..8e82c39 100644
--- a/src/external.h
+++ b/src/external.h
@@ -27,7 +27,8 @@ struct external_parameter {
char *fault_code;
};
-int external_get_action(char *action, char *name, char **value);
+int external_get_action(char *action, char *name, char *arg);
+int external_get_action_data(char *action, char *name, char **value);
int external_get_action_write(char *action, char *name, char *arg);
int external_get_action_execute();
int external_set_action_write(char *action, char *name, char *value);
diff --git a/src/ubus.c b/src/ubus.c
index 0fd1def..cbf94b0 100644
--- a/src/ubus.c
+++ b/src/ubus.c
@@ -201,11 +201,50 @@ freecwmpd_handle_get_param_values(struct ubus_context
*ctx, struct ubus_object *
return 0;
}
+static enum get_param_names {
+ GET_PARAM_NAMES_PARAM,
+ GET_PARAM_NAMES_WRITABLE,
+ GET_PARAM_NAMES_FAULT,
+ __GET_PARAM_NAMES_MAX
+};
+
+static const struct blobmsg_policy get_param_names_policy[] = {
+ [GET_PARAM_NAMES_PARAM] = { .name = "parameter", .type =
BLOBMSG_TYPE_STRING },
+ [GET_PARAM_NAMES_WRITABLE] = { .name = "writable", .type =
BLOBMSG_TYPE_STRING },
+ [GET_PARAM_NAMES_FAULT] = { .name = "fault_code", .type =
BLOBMSG_TYPE_STRING },
+};
+
+static int
+freecwmpd_handle_get_param_names(struct ubus_context *ctx, struct ubus_object
*obj,
+ struct ubus_request_data *req, const char *method,
+ struct blob_attr *msg)
+{
+ struct blob_attr *tb[__GET_PARAM_NAMES_MAX];
+
+ blobmsg_parse(get_param_names_policy,
ARRAY_SIZE(get_param_names_policy), tb,
+ blob_data(msg), blob_len(msg));
+
+ if (!tb[GET_PARAM_NAMES_PARAM])
+ return UBUS_STATUS_INVALID_ARGUMENT;
+
+ freecwmp_log_message(NAME, L_NOTICE,
+ "triggered ubus get_parameter_names for the
parameter %s\n",
+ blobmsg_data(tb[GET_PARAM_NAMES_PARAM]));
+
+ external_add_list_paramameter(blobmsg_data(tb[GET_PARAM_NAMES_PARAM]),
+ tb[GET_PARAM_NAMES_WRITABLE]?
blobmsg_data(tb[GET_PARAM_NAMES_WRITABLE]) : NULL,
+ NULL,
+ tb[GET_PARAM_NAMES_FAULT]?
blobmsg_data(tb[GET_PARAM_NAMES_FAULT]) : NULL);
+
+ return 0;
+}
+
static const struct ubus_method freecwmp_methods[] = {
UBUS_METHOD("notify", freecwmpd_handle_notify, notify_policy),
UBUS_METHOD("inform", freecwmpd_handle_inform, inform_policy),
UBUS_METHOD("command", freecwmpd_handle_command, command_policy),
UBUS_METHOD("get_parameter_values", freecwmpd_handle_get_param_values,
get_param_values_policy),
+ UBUS_METHOD("get_parameter_names", freecwmpd_handle_get_param_names,
get_param_names_policy),
};
static struct ubus_object_type main_object_type =
diff --git a/src/xml.c b/src/xml.c
index 612c0bb..c735244 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -51,6 +51,7 @@ static struct cwmp_namespaces
const struct rpc_method rpc_methods[] = {
{ "SetParameterValues", xml_handle_set_parameter_values },
{ "GetParameterValues", xml_handle_get_parameter_values },
+ { "GetParameterNames", xml_handle_get_parameter_names },
{ "SetParameterAttributes", xml_handle_set_parameter_attributes },
{ "Download", xml_handle_download },
{ "FactoryReset", xml_handle_factory_reset },
@@ -716,7 +717,6 @@ int xml_handle_get_parameter_values(mxml_node_t *body_in,
free(external_parameter->fault_code);
free(external_parameter);
}
-
#ifdef ACS_MULTI
b = mxmlFindElement(tree_out, tree_out, "ParameterList",
NULL, NULL, MXML_DESCEND);
@@ -736,6 +736,115 @@ out:
return -1;
}
+int xml_handle_get_parameter_names(mxml_node_t *body_in,
+ mxml_node_t *tree_in,
+ mxml_node_t *tree_out)
+{
+ mxml_node_t *n, *parameter_list, *b = body_in;
+ struct external_parameter *external_parameter;
+ char *parameter_name = NULL;
+ char *NextLevel = NULL;
+ char *c;
+ int counter = 0;
+
+ n = mxmlFindElement(tree_out, tree_out, "soap_env:Body",
+ NULL, NULL, MXML_DESCEND);
+ if (!n) return -1;
+
+ n = mxmlNewElement(n, "cwmp:GetParameterNamesResponse");
+ if (!n) return -1;
+
+ n = mxmlNewElement(n, "ParameterList");
+ if (!n) return -1;
+
+#ifdef ACS_MULTI
+ mxmlElementSetAttr(n, "xsi:type", "soap_enc:Array");
+#endif
+
+ while (b) {
+ if (b && b->type == MXML_TEXT &&
+ b->value.text.string &&
+ b->parent->type == MXML_ELEMENT &&
+ !strcmp(b->parent->value.element.name,
"ParameterPath")) {
+ parameter_name = b->value.text.string;
+ }
+ if (b && b->type == MXML_ELEMENT && /* added in order to
support GetParameterNames with empty ParameterPath*/
+ !strcmp(b->value.element.name, "ParameterPath") &&
+ !b->child) {
+ parameter_name = "";
+ }
+ if (b && b->type == MXML_TEXT &&
+ b->value.text.string &&
+ b->parent->type == MXML_ELEMENT &&
+ !strcmp(b->parent->value.element.name, "NextLevel")) {
+ NextLevel = b->value.text.string;
+ }
+ b = mxmlWalkNext(b, body_in, MXML_DESCEND);
+ }
+ if (parameter_name && NextLevel) {
+ if (!external_get_action("name", parameter_name, NextLevel)) {
+ // got the parameter value via external script
+ } else {
+ // error occurred when getting parameter value
+ goto out;
+ }
+ }
+
+ parameter_list = mxmlFindElement(tree_out, tree_out, "ParameterList",
NULL, NULL, MXML_DESCEND);
+ if (!parameter_list) goto out;
+
+ while (external_list_parameter.next!=&external_list_parameter) {
+
+ external_parameter = list_entry(external_list_parameter.next,
struct external_parameter, list);
+
+ if (external_parameter->fault_code &&
external_parameter->fault_code[0]=='9')
+ goto out; // KMD TODO return FAULT message the fault
code is in ->fault_code
+
+ n = mxmlNewElement(parameter_list, "ParameterInfoStruct");
+ if (!n) goto out;
+
+ n = mxmlNewElement(n, "Name");
+ if (!n) goto out;
+
+ n = mxmlNewText(n, 0, external_parameter->name);
+ if (!n) goto out;
+
+ n = n->parent->parent;
+ n = mxmlNewElement(n, "Writable");
+ if (!n) goto out;
+
+ n = mxmlNewText(n, 0, external_parameter->data);
+ if (!n) goto out;
+
+ counter++;
+
+ list_del(&external_parameter->list);
+ free(external_parameter->name);
+ free(external_parameter->data);
+ free(external_parameter->type);
+ free(external_parameter->fault_code);
+ free(external_parameter);
+ }
+
+#ifdef ACS_MULTI
+ b = mxmlFindElement(tree_out, tree_out, "ParameterList",
+ NULL, NULL, MXML_DESCEND);
+ if (!b) goto out;
+
+ if (asprintf(&c, "cwmp:ParameterInfoStruct[%d]", counter) == -1)
+ goto out;
+
+ mxmlElementSetAttr(b, "soap_enc:arrayType", c);
+ FREE(c);
+#endif
+
+ return 0;
+
+out:
+ external_free_list_parameter();
+ return -1;
+}
+
static int xml_handle_set_parameter_attributes(mxml_node_t *body_in,
mxml_node_t *tree_in,
mxml_node_t *tree_out) {
diff --git a/src/xml.h b/src/xml.h
index 8f63192..a9191eb 100644
--- a/src/xml.h
+++ b/src/xml.h
@@ -26,6 +26,10 @@ static int xml_handle_get_parameter_values(mxml_node_t
*body_in,
mxml_node_t *tree_in,
mxml_node_t *tree_out);
+static int xml_handle_get_parameter_names(mxml_node_t *body_in,
+ mxml_node_t *tree_in,
+ mxml_node_t *tree_out);
+
static int xml_handle_set_parameter_attributes(mxml_node_t *body_in,
mxml_node_t *tree_in,
mxml_node_t *tree_out);
--
1.7.4.1
|