icwmp: remove unused file and option config && update README.md

This commit is contained in:
Amin Ben Ramdhane 2021-03-14 00:18:06 +01:00
parent f934307c24
commit 50c44750dd
3 changed files with 61 additions and 346 deletions

View file

@ -26,7 +26,7 @@ The package is composed of the following components:
The icwmp client is : The icwmp client is :
* tested with several ACS such as **Axiros**, **AVSytem**, **GenieACS**, **OpenACS**, etc... * tested with several ACS such as **Axiros**, **AVSytem**, **GenieACS**, **OpenACS**, etc...
* supports all required **TR069 RPCs**. * supports all required **TR069 RPCs**.
* supports all DataModel of TR family such as **TR-181**, **TR-104**, **TR-143**, **TR-157**, **TR-098**, etc... * supports all DataModel of TR family such as **TR-181**, **TR-104**, **TR-143**, **TR-157**, etc...
* supports all types of connection requests such as **HTTP**, **XMPP**, **STUN**. * supports all types of connection requests such as **HTTP**, **XMPP**, **STUN**.
* supports integrated file transfer such as **HTTP**, **HTTPS**, **FTP**. * supports integrated file transfer such as **HTTP**, **HTTPS**, **FTP**.
@ -46,7 +46,6 @@ config cpe 'cpe'
option interface 'eth0.1' option interface 'eth0.1'
option default_wan_interface 'wan' option default_wan_interface 'wan'
option userid 'iopsys' option userid 'iopsys'
option datamodel 'tr181'
option exec_download '0' option exec_download '0'
config lwn 'lwn' config lwn 'lwn'
@ -102,7 +101,6 @@ It defines **device configuration** (such as interface, manufacturer, etc...). T
| `instance_mode` | string | Specifies the instance mode to use, by default **'InstanceNumber'**. Two instance modes are supported: **'InstanceNumber' and 'InstanceNumber'**. | | `instance_mode` | string | Specifies the instance mode to use, by default **'InstanceNumber'**. Two instance modes are supported: **'InstanceNumber' and 'InstanceNumber'**. |
| `session_timeout` | integer | Represents the number of seconds that should be used by the ACS as the amount of time to wait before timing out a CWMP session due to the CPE not responding, by default **60**.| | `session_timeout` | integer | Represents the number of seconds that should be used by the ACS as the amount of time to wait before timing out a CWMP session due to the CPE not responding, by default **60**.|
| `notification` | boolean | If set to **1**, it enables the notification feature. | | `notification` | boolean | If set to **1**, it enables the notification feature. |
| `datamodel` | string | Specifies the data model to use, by default **'tr181'**. Two data models are supported: **'tr181' and 'tr098'**. |
| `exec_download` | boolean | If set to **1**, Specifies if Download method is executed. | | `exec_download` | boolean | If set to **1**, Specifies if Download method is executed. |
| `manufacturer` | string | Specifies the manafacturer of the device, by default **iopsys**. If set, its value will be the value of **Device.DeviceInfo.Manufacturer** parameter. | | `manufacturer` | string | Specifies the manafacturer of the device, by default **iopsys**. If set, its value will be the value of **Device.DeviceInfo.Manufacturer** parameter. |
| `manufacturer_oui` | string | Specifies the manafacturer oui of the device, by default empty. If set, its value will be the value of **Device.DeviceInfo.ManufacturerOUI** parameter. | | `manufacturer_oui` | string | Specifies the manafacturer oui of the device, by default empty. If set, its value will be the value of **Device.DeviceInfo.ManufacturerOUI** parameter. |
@ -307,17 +305,65 @@ There's an icwmp cli that can be called via the script `'icwmp'` as follow:
``` ```
root@iopsys:~# icwmp get Device.Time. root@iopsys:~# icwmp get Device.Time.
{ "parameter": "Device.Time.CurrentLocalTime", "value": "2019-12-19T16:52:05+01:00", "type": "xsd:dateTime" } {
{ "parameter": "Device.Time.Enable", "value": "1", "type": "xsd:boolean" } "parameters": [
{ "parameter": "Device.Time.LocalTimeZone", "value": "CET-1CEST,M3.5.0,M10.5.0/3", "type": "xsd:string" } {
{ "parameter": "Device.Time.NTPServer1", "value": "ntp1.sth.netnod.se", "type": "xsd:string" } "parameter": "Device.Time.CurrentLocalTime",
{ "parameter": "Device.Time.NTPServer2", "value": "ntp1.gbg.netnod.se", "type": "xsd:string" } "value": "2021-03-14T00:19:45Z",
{ "parameter": "Device.Time.NTPServer3", "value": "", "type": "xsd:string" } "type": "xsd:dateTime"
{ "parameter": "Device.Time.NTPServer4", "value": "", "type": "xsd:string" } },
{ "parameter": "Device.Time.NTPServer5", "value": "", "type": "xsd:string" } {
{ "parameter": "Device.Time.Status", "value": "Synchronized", "type": "xsd:string" } "parameter": "Device.Time.Enable",
{ "parameter": "Device.Time.X_IOPSYS_EU_LocalTimeZoneOlson", "value": "Europe/Stockholm", "type": "xsd:string" } "value": "1",
{ "parameter": "Device.Time.X_IOPSYS_EU_SourceInterface", "value": "", "type": "xsd:string" } "type": "xsd:boolean"
},
{
"parameter": "Device.Time.LocalTimeZone",
"value": "CET-1CEST,M3.5.0,M10.5.0/3",
"type": "xsd:string"
},
{
"parameter": "Device.Time.NTPServer1",
"value": "ntp1.sth.netnod.se",
"type": "xsd:string"
},
{
"parameter": "Device.Time.NTPServer2",
"value": "ntp1.gbg.netnod.se",
"type": "xsd:string"
},
{
"parameter": "Device.Time.NTPServer3",
"value": "",
"type": "xsd:string"
},
{
"parameter": "Device.Time.NTPServer4",
"value": "",
"type": "xsd:string"
},
{
"parameter": "Device.Time.NTPServer5",
"value": "",
"type": "xsd:string"
},
{
"parameter": "Device.Time.Status",
"value": "Synchronized",
"type": "xsd:string"
},
{
"parameter": "Device.Time.X_IOPSYS_EU_LocalTimeZoneName",
"value": "Europe/Stockholm",
"type": "xsd:string"
},
{
"parameter": "Device.Time.X_IOPSYS_EU_SourceInterface",
"value": "",
"type": "xsd:string"
}
]
}
root@iopsys:~# root@iopsys:~#
``` ```
@ -334,5 +380,3 @@ To successfully build icwmp, the following libraries are needed:
| libopenssl | http://ftp.fi.muni.cz/pub/openssl/source/ | OpenSSL | | libopenssl | http://ftp.fi.muni.cz/pub/openssl/source/ | OpenSSL |
| libcurl | https://dl.uxnr.de/mirror/curl | MIT | | libcurl | https://dl.uxnr.de/mirror/curl | MIT |
| libmicroxml | https://dev.freecwmp.org/microxml | LGPL 2.0 | | libmicroxml | https://dev.freecwmp.org/microxml | LGPL 2.0 |
| libpthread | | |

View file

@ -20,9 +20,6 @@ AC_ARG_ENABLE(debug, [AS_HELP_STRING([--enable-debug], [enable debugging message
AC_ARG_ENABLE(devel, [AS_HELP_STRING([--enable-devel], [enable development messages])], AC_DEFINE(WITH_DEV_DEBUG),) AC_ARG_ENABLE(devel, [AS_HELP_STRING([--enable-devel], [enable development messages])], AC_DEFINE(WITH_DEV_DEBUG),)
AC_ARG_ENABLE(dummy_mode, [AS_HELP_STRING([--enable-dummy-mode], [enable dummy mode])], AC_DEFINE(DUMMY_MODE),) AC_ARG_ENABLE(dummy_mode, [AS_HELP_STRING([--enable-dummy-mode], [enable dummy mode])], AC_DEFINE(DUMMY_MODE),)
AC_ARG_ENABLE(icwmp_tr098, [AS_HELP_STRING([--enable-icwmp_tr098], [enable icwmp tr098])], AC_DEFINE(ICWMP_TR098),)
AM_CONDITIONAL([ICWMP_TR098],[test "x$enable_icwmp_tr098" = "xyes"])
# checks for programs # checks for programs
AC_PROG_CC AC_PROG_CC
AM_PROG_CC_C_O AM_PROG_CC_C_O

View file

@ -1,326 +0,0 @@
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Copyright (C) 2013-2020 iopsys Software Solutions AB
* Author Omar Kallel <omar.kallel@pivasoftware.com>
*
*/
#include <unistd.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <netdb.h>
#include <libubox/list.h>
#include "notifications.h"
LIST_HEAD(list_value_change);
LIST_HEAD(list_lw_value_change);
pthread_mutex_t mutex_value_change = PTHREAD_MUTEX_INITIALIZER;
int cwmp_update_enabled_notify_file()
{
struct cwmp *cwmp = &cwmp_main;
FILE *fp;
json_object *param_obj = NULL, *param_name_obj = NULL, *value_obj = NULL, *type_obj = NULL, *notification_obj = NULL;
int e = cwmp_update_enabled_list_notify(cwmp->conf.instance_mode, OLD_LIST_NOTIFY);
if (e)
return 0;
remove(DM_ENABLED_NOTIFY);
fp = fopen(DM_ENABLED_NOTIFY, "a");
if (fp == NULL) {
return 0;
}
foreach_jsonobj_in_array(param_obj, old_list_notify)
{
json_object_object_get_ex(param_obj, "parameter", &param_name_obj);
if (!param_name_obj || strlen((char *)json_object_get_string(param_name_obj)) <= 0)
continue;
json_object_object_get_ex(param_obj, "value", &value_obj);
json_object_object_get_ex(param_obj, "type", &type_obj);
json_object_object_get_ex(param_obj, "notification", &notification_obj);
cwmp_json_fprintf(fp, 4, CWMP_JSON_ARGS{ { "parameter", (char *)json_object_get_string(param_name_obj) },
{ "notification", notification_obj ? (char *)json_object_get_string(notification_obj) : "" },
{ "value", value_obj ? (char *)json_object_get_string(value_obj) : "" },
{ "type", type_obj ? (char *)json_object_get_string(type_obj) : "" } });
}
fclose(fp);
return 1;
}
void get_parameter_value_from_parameters_list(json_object *list_params_obj, char *parameter_name, struct cwmp_dm_parameter **ret_dm_param)
{
json_object *param_obj = NULL, *param_name_obj = NULL, *value_obj = NULL, *type_obj = NULL;
foreach_jsonobj_in_array(param_obj, list_params_obj)
{
json_object_object_get_ex(param_obj, "parameter", &param_name_obj);
if (!param_name_obj || strlen((char *)json_object_get_string(param_name_obj)) <= 0)
continue;
if (strcmp((char *)json_object_get_string(param_name_obj), parameter_name) != 0)
continue;
*ret_dm_param = (struct cwmp_dm_parameter *)calloc(1, sizeof(struct cwmp_dm_parameter));
json_object_object_get_ex(param_obj, "value", &value_obj);
(*ret_dm_param)->name = strdup(parameter_name);
(*ret_dm_param)->data = strdup(value_obj ? (char *)json_object_get_string(value_obj) : "");
json_object_object_get_ex(param_obj, "type", &type_obj);
(*ret_dm_param)->type = strdup(type_obj ? (char *)json_object_get_string(type_obj) : "");
break;
}
}
int check_value_change(void)
{
FILE *fp;
char buf[512];
char *parameter, *notification = NULL, *value = NULL;
struct cwmp *cwmp = &cwmp_main;
struct cwmp_dm_parameter *dm_parameter = NULL;
json_object *buf_json_obj = NULL, *param_name_obj = NULL, *value_obj = NULL, *notification_obj = NULL;
int is_notify = 0;
fp = fopen(DM_ENABLED_NOTIFY, "r");
if (fp == NULL)
return false;
cwmp_update_enabled_list_notify(cwmp->conf.instance_mode, ACTUAL_LIST_NOTIFY);
while (fgets(buf, 512, fp) != NULL) {
int len = strlen(buf);
if (len)
buf[len - 1] = '\0';
cwmp_json_obj_init(buf, &buf_json_obj);
json_object_object_get_ex(buf_json_obj, "parameter", &param_name_obj);
if (param_name_obj == NULL || strlen((char *)json_object_get_string(param_name_obj)) <= 0)
continue;
parameter = strdup((char *)json_object_get_string(param_name_obj));
json_object_object_get_ex(buf_json_obj, "value", &value_obj);
json_object_object_get_ex(buf_json_obj, "notification", &notification_obj);
value = strdup(value_obj ? (char *)json_object_get_string(value_obj) : "");
notification = strdup(notification_obj ? (char *)json_object_get_string(notification_obj) : "");
cwmp_json_obj_clean(&buf_json_obj);
if (param_name_obj) {
json_object_put(param_name_obj);
param_name_obj = NULL;
}
if (value_obj) {
json_object_put(value_obj);
value_obj = NULL;
}
if (notification_obj) {
json_object_put(notification_obj);
notification_obj = NULL;
}
get_parameter_value_from_parameters_list(actual_list_notify, parameter, &dm_parameter);
if (dm_parameter == NULL)
continue;
if (notification && (strlen(notification) > 0) && (notification[0] >= '1') && (dm_parameter->data != NULL) && (value != NULL) && (strcmp(dm_parameter->data, value) != 0)) {
if (notification[0] == '1' || notification[0] == '2')
add_list_value_change(parameter, dm_parameter->data, dm_parameter->type);
if (notification[0] >= '3')
add_lw_list_value_change(parameter, dm_parameter->data, dm_parameter->type);
if (notification[0] == '1')
is_notify |= NOTIF_PASSIVE;
if (notification[0] == '2')
is_notify |= NOTIF_ACTIVE;
if (notification[0] == '5' || notification[0] == '6')
is_notify |= NOTIF_LW_ACTIVE;
}
FREE(value);
FREE(notification);
FREE(parameter);
FREE(dm_parameter->name);
FREE(dm_parameter->data);
FREE(dm_parameter->type);
FREE(dm_parameter);
}
fclose(fp);
return is_notify;
}
void sotfware_version_value_change(struct cwmp *cwmp, struct transfer_complete *p)
{
char *current_software_version = NULL;
if (!p->old_software_version || p->old_software_version[0] == 0)
return;
current_software_version = cwmp->deviceid.softwareversion;
if (p->old_software_version && current_software_version && strcmp(p->old_software_version, current_software_version) != 0) {
pthread_mutex_lock(&(cwmp->mutex_session_queue));
cwmp_add_event_container(cwmp, EVENT_IDX_4VALUE_CHANGE, "");
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
}
}
void *thread_periodic_check_notify(void *v)
{
struct cwmp *cwmp = (struct cwmp *)v;
static int periodic_interval;
static bool periodic_enable;
static struct timespec periodic_timeout = { 0, 0 };
time_t current_time;
int is_notify;
periodic_interval = cwmp->conf.periodic_notify_interval;
periodic_enable = cwmp->conf.periodic_notify_enable;
for (;;) {
if (periodic_enable) {
pthread_mutex_lock(&(cwmp->mutex_notify_periodic));
current_time = time(NULL);
periodic_timeout.tv_sec = current_time + periodic_interval;
pthread_cond_timedwait(&(cwmp->threshold_notify_periodic), &(cwmp->mutex_notify_periodic), &periodic_timeout);
pthread_mutex_lock(&(cwmp->mutex_session_send));
is_notify = check_value_change();
if (is_notify > 0)
cwmp_update_enabled_notify_file();
pthread_mutex_unlock(&(cwmp->mutex_session_send));
if (is_notify & NOTIF_ACTIVE)
send_active_value_change();
if (is_notify & NOTIF_LW_ACTIVE)
cwmp_lwnotification();
pthread_mutex_unlock(&(cwmp->mutex_notify_periodic));
} else
break;
}
return CWMP_OK;
}
void add_list_value_change(char *param_name, char *param_data, char *param_type)
{
pthread_mutex_lock(&(mutex_value_change));
add_dm_parameter_tolist(&list_value_change, param_name, param_data, param_type);
pthread_mutex_unlock(&(mutex_value_change));
}
void send_active_value_change(void)
{
struct cwmp *cwmp = &cwmp_main;
struct event_container *event_container;
pthread_mutex_lock(&(cwmp->mutex_session_queue));
event_container = cwmp_add_event_container(cwmp, EVENT_IDX_4VALUE_CHANGE, "");
if (event_container == NULL) {
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
return;
}
cwmp_save_event_container(event_container);
pthread_mutex_unlock(&(cwmp->mutex_session_queue));
pthread_cond_signal(&(cwmp->threshold_session_send));
return;
}
/*
* Light Weight Notifications
*/
void add_lw_list_value_change(char *param_name, char *param_data, char *param_type) { add_dm_parameter_tolist(&list_lw_value_change, param_name, param_data, param_type); }
static void udplw_server_param(struct addrinfo **res)
{
struct addrinfo hints = { 0 };
struct cwmp *cwmp = &cwmp_main;
struct config *conf;
char *port;
conf = &(cwmp->conf);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
asprintf(&port, "%d", conf->lw_notification_port);
getaddrinfo(conf->lw_notification_hostname, port, &hints, res);
//FREE(port);
}
static void message_compute_signature(char *msg_out, char *signature)
{
int i;
int result_len = 20;
unsigned char *result;
struct cwmp *cwmp = &cwmp_main;
struct config *conf;
conf = &(cwmp->conf);
/* unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
const unsigned char *d, size_t n, unsigned char *md,
unsigned int *md_len);*/
result = HMAC(EVP_sha1(), conf->acs_passwd, strlen(conf->acs_passwd), (unsigned char *)msg_out, strlen(msg_out), NULL, NULL);
for (i = 0; i < result_len; i++) {
sprintf(&(signature[i * 2]), "%02X", result[i]);
}
signature[i * 2] = '\0';
FREE(result);
}
char *calculate_lwnotification_cnonce()
{
int i;
char *cnonce = malloc(33 * sizeof(char));
srand((unsigned int)time(NULL));
for (i = 0; i < 4; i++) {
sprintf(&(cnonce[i * 8]), "%08x", rand());
}
cnonce[i * 8] = '\0';
return cnonce;
}
static void send_udp_message(struct addrinfo *servaddr, char *msg)
{
int fd;
fd = socket(servaddr->ai_family, SOCK_DGRAM, 0);
if (fd >= 0) {
sendto(fd, msg, strlen(msg), 0, servaddr->ai_addr, servaddr->ai_addrlen);
close(fd);
}
}
void del_list_lw_notify(struct cwmp_dm_parameter *dm_parameter)
{
list_del(&dm_parameter->list);
free(dm_parameter->name);
free(dm_parameter);
}
static void free_all_list_lw_notify()
{
struct cwmp_dm_parameter *dm_parameter;
while (list_lw_value_change.next != &list_lw_value_change) {
dm_parameter = list_entry(list_lw_value_change.next, struct cwmp_dm_parameter, list);
del_list_lw_notify(dm_parameter);
}
}
void cwmp_lwnotification()
{
char *msg, *msg_out;
char signature[41];
struct addrinfo *servaddr;
struct cwmp *cwmp = &cwmp_main;
struct config *conf;
conf = &(cwmp->conf);
udplw_server_param(&servaddr);
xml_prepare_lwnotification_message(&msg_out);
message_compute_signature(msg_out, signature);
<<<<<<< HEAD
asprintf(&msg, "%s \n %s: %s \n %s: %s \n %s: %d\n %s: %s\n\n%s", "POST /HTTPS/1.1", "HOST", conf->lw_notification_hostname, "Content-Type", "test/xml; charset=utf-8", "Content-Lenght", strlen(msg_out), "Signature", signature, msg_out);
=======
asprintf(&msg, "%s \n %s: %s \n %s: %s \n %s: %zd\n %s: %s\n\n%s",
"POST /HTTPS/1.1",
"HOST", conf->lw_notification_hostname,
"Content-Type", "test/xml; charset=utf-8",
"Content-Lenght", strlen(msg_out),
"Signature",signature,
msg_out);
>>>>>>> 3db1606... Fix compilation of x86 image
send_udp_message(servaddr, msg);
free_all_list_lw_notify();
//freeaddrinfo(servaddr); //To check
FREE(msg);
FREE(msg_out);
}