Newer
Older
/*
* event.c: event handler
*
* Copyright (C) 2023 IOPSYS Software Solutions AB. All rights reserved.
*
* Author: Iryna Antsyferova <iryna.antsyferova@iopsys.eu>
*
* See LICENSE file for license related information.
*/
#include "libdmtree/dmcommon.h"
#include "event.h"
#include <unistd.h>
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#define FIREWALL_RULE_DATA_SIP "Device.Services.VoiceService.1.SIP.Network.1.X_RDK_Firewall_Rule_Data"
#define FIREWALL_RULE_DATA_SIP_PATTERN "Device\\.Services\\.VoiceService\\.[0-9]+\\.SIP\\.Network\\.[0-9]+\\.X_RDK_Firewall_Rule_Data"
#define FIREWALL_RULE_DATA_RTP "Device.Services.VoiceService.1.VoIPProfile.1.RTP.X_RDK_Firewall_Rule_Data"
#define FIREWALL_RULE_DATA_RTP_PATTERN "Device\\.Services\\.VoiceService\\.[0-9]+\\.VoIPProfile\\.[0-9]+\\.RTP\\.X_RDK_Firewall_Rule_Data"
// 4 IPv6 rules max
#define FIREWALL_RULE_STR_LEN_MAX 218
struct rule_node {
struct list_head list;
char ip[INET6_ADDRSTRLEN];
uint16_t port;
};
static struct list_head sip_list, rtp_list;
int subs_event_init()
{
INIT_LIST_HEAD(&sip_list);
INIT_LIST_HEAD(&rtp_list);
return 0;
}
void subs_event_uninit()
{
struct rule_node *iter = NULL, *node = NULL;
list_for_each_entry_safe(iter, node, &sip_list, list) {
list_del(&iter->list);
free(iter);
}
list_for_each_entry_safe(iter, node, &rtp_list, list) {
list_del(&iter->list);
free(iter);
}
}
int subs_event_handler(const json_object *jmsg, int param_count, json_object *jreply)
{
int ret = RETURN_OK;
int param_index = 0;
hal_subscribe_event_request_t param_request;
if (jmsg == NULL || jreply == NULL) {
ERR("event handler: Invalid memory");
return RETURN_ERR;
}
memset(¶m_request, 0, sizeof(param_request));
for (param_index = 0; param_index < param_count; param_index++) {
/* Unpack the request parameter */
if (json_hal_get_subscribe_event_request((json_object *)jmsg,
param_index, ¶m_request) != RETURN_OK) {
INFO("Failed to get subscription data from the server");
return RETURN_ERR;
}
if (!match(param_request.name, FIREWALL_RULE_DATA_SIP_PATTERN, 0, NULL) &&
!match(param_request.name, FIREWALL_RULE_DATA_RTP_PATTERN, 0, NULL)) {
ret = RETURN_ERR;
WARNING("Unexpected event [%s][%d]", param_request.name, (int)param_request.type);
}
else
INFO("Subscribed [%s][%d]", param_request.name, (int)param_request.type);
}
ret = json_hal_add_result_status(jreply, ret == RETURN_OK ? RESULT_SUCCESS :
RESULT_FAILURE);
INFO("[%s] Replly msg = %s", __FUNCTION__,
json_object_to_json_string_ext(jreply, JSON_C_TO_STRING_PRETTY));
return ret;
}
static int update_fw_rule_list(bool enable, char *ip, int port,
struct list_head *rule_list, bool *changed)
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
struct rule_node *node = NULL;
bool found = false;
*changed = false;
list_for_each_entry(node, rule_list, list) {
if (DM_STRNCMP(node->ip, ip, sizeof(node->ip)) == 0 &&
node->port == port) {
found = true;
break;
}
}
if (enable == found) {
return 0;
}
if (!enable && found) {
list_del(&node->list);
free(node);
}
if (enable && !found) {
node = malloc(sizeof(struct rule_node));
if (!node) {
ERR("failed to allocate memory");
return -1;
}
DM_STRNCPY(node->ip, ip, sizeof(node->ip));
node->port = port;
INIT_LIST_HEAD(&node->list);
list_add_tail(&node->list, rule_list);
}
*changed = true;
return 0;
/* Expected format of rule : ip,port;
Example: 192.168.0.11,5060;192.168.0.12,5060;
*/
static int create_fw_rule_payload(struct list_head *rule_list, char *buf, int buf_size)
struct rule_node *node = NULL;
char *pos = buf, *end = buf + buf_size;
list_for_each_entry(node, rule_list, list) {
if (pos < end) {
pos += snprintf(pos, end - pos, "%s,%d;", node->ip, node->port);
}
}
if (pos == end) {
ERR("fw rule string overflow");
return -1;
}
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
return 0;
}
static int pub_fw_rule_event(bool enable, char *ip, int port,
struct list_head *rule_list, const char *param_name)
{
int ret;
bool changed = false;
char buf[FIREWALL_RULE_STR_LEN_MAX] = {0};
ret = update_fw_rule_list(enable, ip, port, rule_list, &changed);
if (ret) {
ERR("failed to create fw rule list");
return -1;
}
if (!changed) {
return 0;
}
ret = create_fw_rule_payload(rule_list, buf, sizeof(buf));
if (ret) {
ERR("failed to create fw rule");
return -1;
}
ret = json_hal_server_publish_event(param_name, buf);
if (ret != RETURN_OK) {
ERR("failed to send fw event");
return -1;
}
return 0;
int send_fw_rule_event(bool enable, char *protocol, char *ip, int port)
{
if (DM_STRCMP(protocol, "sip") == 0) {
return pub_fw_rule_event(enable, ip, port, &sip_list, FIREWALL_RULE_DATA_SIP);
}
if (DM_STRCMP(protocol, "rtp") == 0) {
return pub_fw_rule_event(enable, ip, port, &rtp_list, FIREWALL_RULE_DATA_RTP);
}
DEBUG("wrong protocol: %s", protocol);
return -1;
}
int send_fw_rules_clear_event()
{
int ret = 0;
char fw_rule[] = {0};
ret = json_hal_server_publish_event(FIREWALL_RULE_DATA_SIP, fw_rule);
if (ret != RETURN_OK) {
ERR("failed to send fw sip event");
return -1;
}
ret = json_hal_server_publish_event(FIREWALL_RULE_DATA_RTP, fw_rule);
if (ret != RETURN_OK) {
ERR("failed to send fw rtp event");
return -1;
}
list_for_each_entry_safe(iter, node, &sip_list, list) {
list_del(&iter->list);
free(iter);
}
list_for_each_entry_safe(iter, node, &rtp_list, list) {
list_del(&iter->list);
free(iter);
}
return 0;