diff --git a/README.md b/README.md index 5c37be8..f1f4d82 100644 --- a/README.md +++ b/README.md @@ -291,6 +291,40 @@ root@iopsys:~# /etc/init.d/icwmpd restart > - This JSON file shouldn't contain duplicate parameters or parameters of the standard inform parameters specified in the datamodel > - Forced inform parameters defined in JSON should be leaf elements +## icwmpd notifications +As per the cwmp notifications requirements, there is a list parameters specified in the standard that has forced notification type. Those parameters are defined internally in icwmp client. The list contains below parameters: + +| Parameter name | Notification | +| ------------------------------------- |---------------| +| Device.DeviceInfo.SoftwareVersion | 2 | +| Device.DeviceInfo.ProvisioningCode | 2 | + +According to the standard, if the ACS set new notification of one of those parameters so icwmp will return the CWMP fault 9009. + +In addition to thos parameters, icwmp gives the possibility to set default notifications of some parameters that the customer choose using a json file, in order to permit icwmp to start with those parameters with default notification type. +The json file must respect following form: + +```bash +{ + "custom_notification": [ + { + "parameter": "Device.Users.", + "notify_type": "2" + }, + { + "parameter": "Device.WiFi.SSID.1.SSID", + "notify_type": "1" + } + ] +} +``` +the location of this file should be specified in the uci config option: cwmp.cpe.json_custom_notify_file + +Contrary to forced parameters notifications, the ACS has privileges to set new notification type of those custom parameters. + +>- The actual update doesn't support wildcard parameters. So parameter like Device.WiFi.SSID.*. will be skipped +>- The actual update doesn't support multiple json notify files + ## Dependencies To successfully build icwmp, the following libraries are needed: diff --git a/config.c b/config.c index 0a82edc..cc9ea00 100755 --- a/config.c +++ b/config.c @@ -583,6 +583,17 @@ int get_global_config(struct config *conf) if (conf->forced_inform_json_file) CWMP_LOG(DEBUG, "CWMP CONFIG - cpe forced inform json file: %s", conf->forced_inform_json_file); } + if (uci_get_value(UCI_CPE_JSON_CUSTOM_NOTIFY_FILE, &value) == CWMP_OK) { + FREE(conf->json_custom_notify_file); + if (value != NULL) { + conf->json_custom_notify_file = strdup(value); + FREE(value); + } else { + conf->json_custom_notify_file = NULL; + } + if (conf->json_custom_notify_file) + CWMP_LOG(DEBUG, "CWMP CONFIG - cpe json custom notify file: %s", conf->json_custom_notify_file); + } return CWMP_OK; } diff --git a/cwmp.c b/cwmp.c index 479c1c0..8820695 100644 --- a/cwmp.c +++ b/cwmp.c @@ -486,6 +486,7 @@ static int cwmp_init(int argc, char **argv, struct cwmp *cwmp) cwmp_get_deviceid(cwmp); load_forced_inform_json_file(cwmp); + load_json_custom_notify_file(cwmp); return CWMP_OK; } diff --git a/inc/common.h b/inc/common.h index 0b426a7..bb23d2b 100644 --- a/inc/common.h +++ b/inc/common.h @@ -71,6 +71,7 @@ typedef struct config { char *cpe_userid; char *cpe_passwd; char *forced_inform_json_file; + char *json_custom_notify_file; char *ip; char *ipv6; char *interface; diff --git a/inc/cwmp_uci.h b/inc/cwmp_uci.h index 20e9059..b28c21b 100644 --- a/inc/cwmp_uci.h +++ b/inc/cwmp_uci.h @@ -56,6 +56,7 @@ #define UCI_CPE_SCHEDULE_REBOOT "cwmp.cpe.schedule_reboot" #define UCI_CPE_DELAY_REBOOT "cwmp.cpe.delay_reboot" #define UCI_CPE_FORCED_INFORM_JSON "cwmp.cpe.forced_inform_json" +#define UCI_CPE_JSON_CUSTOM_NOTIFY_FILE "cwmp.cpe.json_custom_notify_file" #define LW_NOTIFICATION_ENABLE "cwmp.lwn.enable" #define LW_NOTIFICATION_HOSTNAME "cwmp.lwn.hostname" #define LW_NOTIFICATION_PORT "cwmp.lwn.port" diff --git a/inc/notifications.h b/inc/notifications.h index c083c1f..16754cb 100644 --- a/inc/notifications.h +++ b/inc/notifications.h @@ -62,6 +62,7 @@ void add_list_value_change(char *param_name, char *param_data, char *param_type) void clean_list_value_change(); char *cwmp_set_parameter_attributes(char *parameter_name, int notification); char *cwmp_get_parameter_attributes(char *parameter_name, struct list_head *parameters_list); +void load_json_custom_notify_file(struct cwmp *cwmp); void add_lw_list_value_change(char *param_name, char *param_data, char *param_type); char *calculate_lwnotification_cnonce(); void cwmp_lwnotification(); diff --git a/notifications.c b/notifications.c index 27cdb13..4aa7bee 100644 --- a/notifications.c +++ b/notifications.c @@ -17,6 +17,7 @@ #include "notifications.h" #include "ubus.h" #include "cwmp_uci.h" +#include "log.h" LIST_HEAD(list_value_change); LIST_HEAD(list_lw_value_change); @@ -377,6 +378,72 @@ void cwmp_update_enabled_notify_file(void) fclose(fp); } +/* + * Load custom notify json file + */ +void load_json_custom_notify_file(struct cwmp *cwmp) +{ + struct blob_buf bbuf; + struct blob_attr *cur; + struct blob_attr *custom_notify_list = NULL; + int rem; + struct cwmp_dm_parameter cwmp_dm_param = { 0 }; + + if (!file_exists("/etc/icwmpd/.icwmpd_notify")) + return; + remove("/etc/icwmpd/.icwmpd_notify"); + + if (cwmp->conf.json_custom_notify_file == NULL || !file_exists(cwmp->conf.json_custom_notify_file)) + return; + + memset(&bbuf, 0, sizeof(struct blob_buf)); + blob_buf_init(&bbuf, 0); + + if (blobmsg_add_json_from_file(&bbuf, cwmp->conf.json_custom_notify_file) == false) { + CWMP_LOG(WARNING, "The file %s is not a valid JSON file", cwmp->conf.json_custom_notify_file); + blob_buf_free(&bbuf); + return; + } + blobmsg_for_each_attr(cur, bbuf.head, rem) + { + if (blobmsg_type(cur) == BLOBMSG_TYPE_ARRAY) { + custom_notify_list = cur; + break; + } + } + if (custom_notify_list == NULL) { + CWMP_LOG(WARNING, "The JSON file %s doesn't contain a notify parameters list", cwmp->conf.json_custom_notify_file); + blob_buf_free(&bbuf); + return; + } + const struct blobmsg_policy p[2] = { { "parameter", BLOBMSG_TYPE_STRING }, { "notify_type", BLOBMSG_TYPE_STRING } }; + blobmsg_for_each_attr(cur, custom_notify_list, rem) + { + printf("%s:%s line %d\n", __FILE__, __FUNCTION__, __LINE__); + struct blob_attr *tb[2] = { NULL, NULL }; + blobmsg_parse(p, 2, tb, blobmsg_data(cur), blobmsg_len(cur)); + if (!tb[0] || !tb[1]) + continue; + if (!icwmp_validate_int_in_range(blobmsg_get_string(tb[1]), 0, 6)) { + CWMP_LOG(WARNING, "Wrong notification value: %s", blobmsg_get_string(tb[1])); + continue; + } + char *fault = cwmp_set_parameter_attributes(blobmsg_get_string(tb[0]), atoi(blobmsg_get_string(tb[1]))); + if (fault == NULL) + continue; + if (strcmp(fault, "9005") == 0) { + CWMP_LOG(WARNING, "The parameter %s is wrong path", blobmsg_get_string(tb[0])); + continue; + } + if (strcmp(fault, "9009") == 0) { + CWMP_LOG(WARNING, "This parameter %s is force notification parameter, can't be changed", blobmsg_get_string(tb[0])); + continue; + } + } + blob_buf_free(&bbuf); + +} + /* * Check value change */ diff --git a/rpc_soap.c b/rpc_soap.c index f8fb471..1f873f1 100755 --- a/rpc_soap.c +++ b/rpc_soap.c @@ -1313,11 +1313,14 @@ int cwmp_handle_rpc_cpe_add_object(struct session *session, struct rpc *rpc) b = mxmlNewOpaque(b, "1"); if (!b) goto fault; - FREE(instance); if (!cwmp_transaction_commit()) goto fault; + char *object_path = NULL; + icwmp_asprintf(&object_path, "%s%s.", object_name, instance); + cwmp_set_parameter_attributes(object_path, 0); + FREE(instance); cwmp_set_end_session(END_SESSION_RESTART_SERVICES); return 0;