added clang format C and H files.
This commit is contained in:
+186
-232
@@ -1,47 +1,47 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
* @date 2012
|
||||
* @brief BACnet/IP to MS/TP Router example application.
|
||||
* The Router connects two or more BACnet/IP and BACnet MS/TP networks.
|
||||
* Number of netwoks is limited only by available hardware communication
|
||||
* devices (or ports for Ethernet).
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
* @file
|
||||
* @author Andriy Sukhynyuk, Vasyl Tkhir, Andriy Ivasiv
|
||||
* @date 2012
|
||||
* @brief BACnet/IP to MS/TP Router example application.
|
||||
* The Router connects two or more BACnet/IP and BACnet MS/TP networks.
|
||||
* Number of netwoks is limited only by available hardware communication
|
||||
* devices (or ports for Ethernet).
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h> /* for time */
|
||||
#include <time.h> /* for time */
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <libconfig.h> /* read config files */
|
||||
#include <unistd.h> /* for getopt */
|
||||
#include <termios.h> /* used in kbhit() */
|
||||
#include <libconfig.h> /* read config files */
|
||||
#include <unistd.h> /* for getopt */
|
||||
#include <termios.h> /* used in kbhit() */
|
||||
#include <getopt.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
@@ -55,49 +55,33 @@
|
||||
|
||||
#define KEY_ESC 27
|
||||
|
||||
ROUTER_PORT *head = NULL; /* pointer to list of router ports */
|
||||
ROUTER_PORT *head = NULL; /* pointer to list of router ports */
|
||||
|
||||
int port_count;
|
||||
|
||||
void print_help(
|
||||
);
|
||||
void print_help();
|
||||
|
||||
bool read_config(
|
||||
char *filepath);
|
||||
bool read_config(char *filepath);
|
||||
|
||||
bool parse_cmd(
|
||||
int argc,
|
||||
char *argv[]);
|
||||
bool parse_cmd(int argc, char *argv[]);
|
||||
|
||||
void init_port_threads(
|
||||
ROUTER_PORT * port_list);
|
||||
void init_port_threads(ROUTER_PORT *port_list);
|
||||
|
||||
bool init_router(
|
||||
);
|
||||
bool init_router();
|
||||
|
||||
void cleanup(
|
||||
);
|
||||
void cleanup();
|
||||
|
||||
void print_msg(
|
||||
BACMSG * msg);
|
||||
void print_msg(BACMSG *msg);
|
||||
|
||||
uint16_t process_msg(
|
||||
BACMSG * msg,
|
||||
MSG_DATA * data,
|
||||
uint8_t ** buff);
|
||||
uint16_t process_msg(BACMSG *msg, MSG_DATA *data, uint8_t **buff);
|
||||
|
||||
uint16_t get_next_free_dnet(
|
||||
);
|
||||
uint16_t get_next_free_dnet();
|
||||
|
||||
int kbhit(
|
||||
);
|
||||
int kbhit();
|
||||
|
||||
inline bool is_network_msg(
|
||||
BACMSG * msg);
|
||||
inline bool is_network_msg(BACMSG *msg);
|
||||
|
||||
int main(
|
||||
int argc,
|
||||
char *argv[])
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
printf("I am router\n");
|
||||
|
||||
@@ -119,9 +103,8 @@ int main(
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
send_network_message(NETWORK_MESSAGE_I_AM_ROUTER_TO_NETWORK, msg_data,
|
||||
&buff, NULL);
|
||||
&buff, NULL);
|
||||
|
||||
while (true) {
|
||||
if (kbhit()) {
|
||||
@@ -135,83 +118,78 @@ int main(
|
||||
bacmsg = recv_from_msgbox(head->main_id, &msg_storage);
|
||||
if (bacmsg) {
|
||||
switch (bacmsg->type) {
|
||||
case DATA:
|
||||
{
|
||||
MSGBOX_ID msg_src = bacmsg->origin;
|
||||
case DATA: {
|
||||
MSGBOX_ID msg_src = bacmsg->origin;
|
||||
|
||||
/* allocate message structure */
|
||||
msg_data = malloc(sizeof(MSG_DATA));
|
||||
if (!msg_data) {
|
||||
PRINT(ERROR, "Error: Could not allocate memory\n");
|
||||
/* allocate message structure */
|
||||
msg_data = malloc(sizeof(MSG_DATA));
|
||||
if (!msg_data) {
|
||||
PRINT(ERROR, "Error: Could not allocate memory\n");
|
||||
break;
|
||||
}
|
||||
|
||||
print_msg(bacmsg);
|
||||
|
||||
if (is_network_msg(bacmsg)) {
|
||||
buff_len =
|
||||
process_network_message(bacmsg, msg_data, &buff);
|
||||
if (buff_len == 0) {
|
||||
free_data(bacmsg->data);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
buff_len = process_msg(bacmsg, msg_data, &buff);
|
||||
}
|
||||
|
||||
/* if buff_len */
|
||||
/* >0 - form new message and send */
|
||||
/* =-1 - try to find next router */
|
||||
/* other value - discard message */
|
||||
|
||||
if (buff_len > 0) {
|
||||
/* form new message */
|
||||
msg_data->pdu = buff;
|
||||
msg_data->pdu_len = buff_len;
|
||||
msg_storage.origin = head->main_id;
|
||||
msg_storage.type = DATA;
|
||||
msg_storage.data = msg_data;
|
||||
|
||||
print_msg(bacmsg);
|
||||
|
||||
if (is_network_msg(bacmsg)) {
|
||||
buff_len =
|
||||
process_network_message(bacmsg, msg_data,
|
||||
&buff);
|
||||
if (buff_len == 0) {
|
||||
free_data(bacmsg->data);
|
||||
break;
|
||||
}
|
||||
msg_data->ref_count = 1;
|
||||
send_to_msgbox(msg_src, &msg_storage);
|
||||
} else if (msg_data->dest.net !=
|
||||
BACNET_BROADCAST_NETWORK) {
|
||||
msg_data->ref_count = 1;
|
||||
port =
|
||||
find_dnet(msg_data->dest.net, &msg_data->dest);
|
||||
send_to_msgbox(port->port_id, &msg_storage);
|
||||
} else {
|
||||
buff_len = process_msg(bacmsg, msg_data, &buff);
|
||||
}
|
||||
|
||||
/* if buff_len */
|
||||
/* >0 - form new message and send */
|
||||
/* =-1 - try to find next router */
|
||||
/* other value - discard message */
|
||||
|
||||
if (buff_len > 0) {
|
||||
/* form new message */
|
||||
msg_data->pdu = buff;
|
||||
msg_data->pdu_len = buff_len;
|
||||
msg_storage.origin = head->main_id;
|
||||
msg_storage.type = DATA;
|
||||
msg_storage.data = msg_data;
|
||||
|
||||
print_msg(bacmsg);
|
||||
|
||||
if (is_network_msg(bacmsg)) {
|
||||
msg_data->ref_count = 1;
|
||||
send_to_msgbox(msg_src, &msg_storage);
|
||||
} else if (msg_data->dest.net !=
|
||||
BACNET_BROADCAST_NETWORK) {
|
||||
msg_data->ref_count = 1;
|
||||
port =
|
||||
find_dnet(msg_data->dest.net,
|
||||
&msg_data->dest);
|
||||
send_to_msgbox(port->port_id, &msg_storage);
|
||||
} else {
|
||||
port = head;
|
||||
msg_data->ref_count = port_count - 1;
|
||||
while (port != NULL) {
|
||||
if (port->port_id == msg_src ||
|
||||
port->state == FINISHED) {
|
||||
port = port->next;
|
||||
continue;
|
||||
}
|
||||
send_to_msgbox(port->port_id,
|
||||
&msg_storage);
|
||||
port = head;
|
||||
msg_data->ref_count = port_count - 1;
|
||||
while (port != NULL) {
|
||||
if (port->port_id == msg_src ||
|
||||
port->state == FINISHED) {
|
||||
port = port->next;
|
||||
continue;
|
||||
}
|
||||
send_to_msgbox(port->port_id, &msg_storage);
|
||||
port = port->next;
|
||||
}
|
||||
} else if (buff_len == -1) {
|
||||
uint16_t net = msg_data->dest.net; /* NET to find */
|
||||
PRINT(INFO, "Searching NET...\n");
|
||||
send_network_message
|
||||
(NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK,
|
||||
msg_data, &buff, &net);
|
||||
} else {
|
||||
/* if invalid message send Reject-Message-To-Network */
|
||||
PRINT(ERROR, "Error: Invalid message\n");
|
||||
free_data(msg_data);
|
||||
}
|
||||
} else if (buff_len == -1) {
|
||||
uint16_t net = msg_data->dest.net; /* NET to find */
|
||||
PRINT(INFO, "Searching NET...\n");
|
||||
send_network_message(
|
||||
NETWORK_MESSAGE_WHO_IS_ROUTER_TO_NETWORK, msg_data,
|
||||
&buff, &net);
|
||||
} else {
|
||||
/* if invalid message send Reject-Message-To-Network */
|
||||
PRINT(ERROR, "Error: Invalid message\n");
|
||||
free_data(msg_data);
|
||||
}
|
||||
break;
|
||||
} break;
|
||||
case SERVICE:
|
||||
default:
|
||||
break;
|
||||
@@ -220,27 +198,29 @@ int main(
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void print_help(
|
||||
)
|
||||
void print_help()
|
||||
{
|
||||
printf("Usage: router <init_method> [init_parameters]\n" "\ninit_method:\n"
|
||||
"-c, --config <filepath>\n\tinitialize router with a configuration file (.cfg) located at <filepath>\n"
|
||||
"-D, --device <dev_type> <iface> [params]\n\tinitialize a <dev_type> device using an <iface> interface specified with\n\t[params]\n"
|
||||
printf(
|
||||
"Usage: router <init_method> [init_parameters]\n"
|
||||
"\ninit_method:\n"
|
||||
"-c, --config <filepath>\n\tinitialize router with a configuration "
|
||||
"file (.cfg) located at <filepath>\n"
|
||||
"-D, --device <dev_type> <iface> [params]\n\tinitialize a <dev_type> "
|
||||
"device using an <iface> interface specified with\n\t[params]\n"
|
||||
"\ninit_parameters:\n"
|
||||
"-n, --network <net>\n\tspecify device network number\n"
|
||||
"-P, --port <port>\n\tspecify udp port for BIP device\n"
|
||||
"-m, --mac <mac_address> [max_master] [max_frames]\n\tspecify MSTP port parameters\n"
|
||||
"-m, --mac <mac_address> [max_master] [max_frames]\n\tspecify MSTP "
|
||||
"port parameters\n"
|
||||
"-b, --baud <baud>\n\tspecify MSTP port baud rate\n"
|
||||
"-p, --parity <None|Even|Odd>\n\tspecify MSTP port parity\n"
|
||||
"-d, --databits <5|6|7|8>\n\tspecify MSTP port databits\n"
|
||||
"-s, --stopbits <1|2>\n\tspecify MSTP port stopbits\n");
|
||||
}
|
||||
|
||||
bool read_config(
|
||||
char *filepath)
|
||||
bool read_config(char *filepath)
|
||||
{
|
||||
config_t cfg;
|
||||
config_setting_t *setting;
|
||||
@@ -252,7 +232,7 @@ bool read_config(
|
||||
/* open configuration file */
|
||||
if (!config_read_file(&cfg, filepath)) {
|
||||
PRINT(ERROR, "Config file error: %d - %s\n", config_error_line(&cfg),
|
||||
config_error_text(&cfg));
|
||||
config_error_text(&cfg));
|
||||
config_destroy(&cfg);
|
||||
return false;
|
||||
}
|
||||
@@ -273,13 +253,13 @@ bool read_config(
|
||||
|
||||
/* create new list node to store port information */
|
||||
if (head == NULL) {
|
||||
head = (ROUTER_PORT *) malloc(sizeof(ROUTER_PORT));
|
||||
head = (ROUTER_PORT *)malloc(sizeof(ROUTER_PORT));
|
||||
head->next = NULL;
|
||||
current = head;
|
||||
} else {
|
||||
ROUTER_PORT *tmp = current;
|
||||
current = current->next;
|
||||
current = (ROUTER_PORT *) malloc(sizeof(ROUTER_PORT));
|
||||
current = (ROUTER_PORT *)malloc(sizeof(ROUTER_PORT));
|
||||
current->next = NULL;
|
||||
tmp->next = current;
|
||||
}
|
||||
@@ -293,7 +273,7 @@ bool read_config(
|
||||
result = config_setting_lookup_string(port, "device", &iface);
|
||||
if (result) {
|
||||
current->iface =
|
||||
(char *) malloc((strlen(iface) + 1) * sizeof(char));
|
||||
(char *)malloc((strlen(iface) + 1) * sizeof(char));
|
||||
strcpy(current->iface, iface);
|
||||
|
||||
/* check if interface is valid */
|
||||
@@ -301,13 +281,13 @@ bool read_config(
|
||||
if (fd) {
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, current->iface,
|
||||
sizeof(ifr.ifr_name) - 1);
|
||||
sizeof(ifr.ifr_name) - 1);
|
||||
result = ioctl(fd, SIOCGIFADDR, &ifr);
|
||||
if (result != -1) {
|
||||
close(fd);
|
||||
} else {
|
||||
PRINT(ERROR,
|
||||
"Error: Invalid interface for BIP device\n");
|
||||
"Error: Invalid interface for BIP device\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -315,15 +295,14 @@ bool read_config(
|
||||
current->iface = "eth0";
|
||||
}
|
||||
|
||||
result =
|
||||
config_setting_lookup_int(port, "port", (int *) ¶m);
|
||||
result = config_setting_lookup_int(port, "port", (int *)¶m);
|
||||
if (result) {
|
||||
current->params.bip_params.port = param;
|
||||
} else {
|
||||
current->params.bip_params.port = 0xBAC0;
|
||||
}
|
||||
result =
|
||||
config_setting_lookup_int(port, "network", (int *) ¶m);
|
||||
config_setting_lookup_int(port, "network", (int *)¶m);
|
||||
if (result) {
|
||||
current->route_info.net = param;
|
||||
} else {
|
||||
@@ -336,7 +315,7 @@ bool read_config(
|
||||
result = config_setting_lookup_string(port, "device", &iface);
|
||||
if (result) {
|
||||
current->iface =
|
||||
(char *) malloc((strlen(iface) + 1) * sizeof(char));
|
||||
(char *)malloc((strlen(iface) + 1) * sizeof(char));
|
||||
strcpy(current->iface, iface);
|
||||
|
||||
/* check if interface is valid */
|
||||
@@ -345,14 +324,13 @@ bool read_config(
|
||||
close(fd);
|
||||
} else {
|
||||
PRINT(ERROR,
|
||||
"Error: Invalid interface for MSTP device\n");
|
||||
"Error: Invalid interface for MSTP device\n");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
current->iface = "/dev/ttyS0";
|
||||
}
|
||||
result =
|
||||
config_setting_lookup_int(port, "mac", (int *) ¶m);
|
||||
result = config_setting_lookup_int(port, "mac", (int *)¶m);
|
||||
if (result) {
|
||||
current->route_info.mac[0] = param;
|
||||
current->route_info.mac_len = 1;
|
||||
@@ -360,24 +338,21 @@ bool read_config(
|
||||
current->route_info.mac[0] = 127;
|
||||
current->route_info.mac_len = 1;
|
||||
}
|
||||
result =
|
||||
config_setting_lookup_int(port, "max_master",
|
||||
(int *) ¶m);
|
||||
result = config_setting_lookup_int(port, "max_master",
|
||||
(int *)¶m);
|
||||
if (result) {
|
||||
current->params.mstp_params.max_master = param;
|
||||
} else {
|
||||
current->params.mstp_params.max_master = 127;
|
||||
}
|
||||
result =
|
||||
config_setting_lookup_int(port, "max_frames",
|
||||
(int *) ¶m);
|
||||
result = config_setting_lookup_int(port, "max_frames",
|
||||
(int *)¶m);
|
||||
if (result) {
|
||||
current->params.mstp_params.max_frames = param;
|
||||
} else {
|
||||
current->params.mstp_params.max_frames = 1;
|
||||
}
|
||||
result =
|
||||
config_setting_lookup_int(port, "baud", (int *) ¶m);
|
||||
result = config_setting_lookup_int(port, "baud", (int *)¶m);
|
||||
if (result) {
|
||||
current->params.mstp_params.baudrate = param;
|
||||
} else {
|
||||
@@ -401,23 +376,21 @@ bool read_config(
|
||||
current->params.mstp_params.parity = PARITY_NONE;
|
||||
}
|
||||
result =
|
||||
config_setting_lookup_int(port, "databits",
|
||||
(int *) ¶m);
|
||||
config_setting_lookup_int(port, "databits", (int *)¶m);
|
||||
if (result && param >= 5 && param <= 8) {
|
||||
current->params.mstp_params.databits = param;
|
||||
} else {
|
||||
current->params.mstp_params.databits = 8;
|
||||
}
|
||||
result =
|
||||
config_setting_lookup_int(port, "stopbits",
|
||||
(int *) ¶m);
|
||||
config_setting_lookup_int(port, "stopbits", (int *)¶m);
|
||||
if (result && param >= 1 && param <= 2) {
|
||||
current->params.mstp_params.stopbits = param;
|
||||
} else {
|
||||
current->params.mstp_params.stopbits = 1;
|
||||
}
|
||||
result =
|
||||
config_setting_lookup_int(port, "network", (int *) ¶m);
|
||||
config_setting_lookup_int(port, "network", (int *)¶m);
|
||||
if (result) {
|
||||
current->route_info.net = param;
|
||||
} else {
|
||||
@@ -439,9 +412,7 @@ bool read_config(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_cmd(
|
||||
int argc,
|
||||
char *argv[])
|
||||
bool parse_cmd(int argc, char *argv[])
|
||||
{
|
||||
const char *optString = "hc:D:";
|
||||
const char *bipString = "p:n:D:";
|
||||
@@ -463,11 +434,10 @@ bool parse_cmd(
|
||||
int opt, dev_opt, index, result, fd;
|
||||
ROUTER_PORT *current = head;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
if (argc < 2) {
|
||||
print_help();
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* begin checking cmd parameters */
|
||||
opt = getopt_long(argc, argv, optString, Options, &index);
|
||||
@@ -485,13 +455,13 @@ bool parse_cmd(
|
||||
|
||||
/* create new list node to store port information */
|
||||
if (head == NULL) {
|
||||
head = (ROUTER_PORT *) malloc(sizeof(ROUTER_PORT));
|
||||
head = (ROUTER_PORT *)malloc(sizeof(ROUTER_PORT));
|
||||
head->next = NULL;
|
||||
current = head;
|
||||
} else {
|
||||
ROUTER_PORT *tmp = current;
|
||||
current = current->next;
|
||||
current = (ROUTER_PORT *) malloc(sizeof(ROUTER_PORT));
|
||||
current = (ROUTER_PORT *)malloc(sizeof(ROUTER_PORT));
|
||||
current->next = NULL;
|
||||
tmp->next = current;
|
||||
}
|
||||
@@ -507,7 +477,7 @@ bool parse_cmd(
|
||||
}
|
||||
|
||||
/* setup default parameters */
|
||||
current->params.bip_params.port = 0xBAC0; /* 47808 */
|
||||
current->params.bip_params.port = 0xBAC0; /* 47808 */
|
||||
current->route_info.net = get_next_free_dnet();
|
||||
|
||||
/* check if interface is valid */
|
||||
@@ -515,13 +485,13 @@ bool parse_cmd(
|
||||
if (fd) {
|
||||
struct ifreq ifr;
|
||||
strncpy(ifr.ifr_name, current->iface,
|
||||
sizeof(ifr.ifr_name) - 1);
|
||||
sizeof(ifr.ifr_name) - 1);
|
||||
result = ioctl(fd, SIOCGIFADDR, &ifr);
|
||||
if (result != -1) {
|
||||
close(fd);
|
||||
} else {
|
||||
PRINT(ERROR,
|
||||
"Error: Invalid interface for BIP device \n");
|
||||
"Error: Invalid interface for BIP device \n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -534,24 +504,23 @@ bool parse_cmd(
|
||||
result = atoi(optarg);
|
||||
if (result) {
|
||||
current->params.bip_params.port =
|
||||
(uint16_t) result;
|
||||
(uint16_t)result;
|
||||
} else {
|
||||
current->params.bip_params.port = 0xBAC0; /* 47808 */
|
||||
current->params.bip_params.port =
|
||||
0xBAC0; /* 47808 */
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
result = atoi(optarg);
|
||||
if (result) {
|
||||
current->route_info.net =
|
||||
(uint16_t) result;
|
||||
current->route_info.net = (uint16_t)result;
|
||||
} else {
|
||||
current->route_info.net = port_count;
|
||||
}
|
||||
break;
|
||||
}
|
||||
dev_opt =
|
||||
getopt_long(argc, argv, bipString, Options,
|
||||
&index);
|
||||
getopt_long(argc, argv, bipString, Options, &index);
|
||||
}
|
||||
opt = dev_opt;
|
||||
} else if (strcmp(optarg, "mstp") == 0) {
|
||||
@@ -569,7 +538,7 @@ bool parse_cmd(
|
||||
close(fd);
|
||||
} else {
|
||||
PRINT(ERROR,
|
||||
"Error: Invalid interface for MSTP device\n");
|
||||
"Error: Invalid interface for MSTP device\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -592,22 +561,19 @@ bool parse_cmd(
|
||||
result = atoi(optarg);
|
||||
if (result) {
|
||||
current->route_info.mac[0] =
|
||||
(uint8_t) result;
|
||||
(uint8_t)result;
|
||||
}
|
||||
if (argv[optind][0] != '-') {
|
||||
current->params.mstp_params.max_master =
|
||||
(uint8_t) atoi(argv[optind]);
|
||||
if (current->params.mstp_params.
|
||||
max_master <
|
||||
(uint8_t)atoi(argv[optind]);
|
||||
if (current->params.mstp_params.max_master <
|
||||
current->route_info.mac[0])
|
||||
current->params.mstp_params.
|
||||
max_master =
|
||||
current->params.mstp_params.max_master =
|
||||
current->route_info.mac[0];
|
||||
|
||||
if (argv[optind + 1][0] != '-') {
|
||||
current->params.mstp_params.
|
||||
max_frames =
|
||||
(uint8_t) atoi(argv[optind + 1]);
|
||||
current->params.mstp_params.max_frames =
|
||||
(uint8_t)atoi(argv[optind + 1]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -615,7 +581,7 @@ bool parse_cmd(
|
||||
result = atoi(optarg);
|
||||
if (result) {
|
||||
current->params.mstp_params.baudrate =
|
||||
(uint32_t) result;
|
||||
(uint32_t)result;
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
@@ -638,27 +604,25 @@ bool parse_cmd(
|
||||
result = atoi(optarg);
|
||||
if (result >= 5 && result <= 8) {
|
||||
current->params.mstp_params.databits =
|
||||
(uint8_t) result;
|
||||
(uint8_t)result;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
result = atoi(optarg);
|
||||
if (result >= 1 && result <= 2) {
|
||||
current->params.mstp_params.stopbits =
|
||||
(uint8_t) result;
|
||||
(uint8_t)result;
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
result = atoi(optarg);
|
||||
if (result) {
|
||||
current->route_info.net =
|
||||
(uint16_t) result;
|
||||
current->route_info.net = (uint16_t)result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
dev_opt =
|
||||
getopt_long(argc, argv, mstpString, Options,
|
||||
&index);
|
||||
dev_opt = getopt_long(argc, argv, mstpString, Options,
|
||||
&index);
|
||||
}
|
||||
opt = dev_opt;
|
||||
} else {
|
||||
@@ -671,8 +635,7 @@ bool parse_cmd(
|
||||
return true;
|
||||
}
|
||||
|
||||
void init_port_threads(
|
||||
ROUTER_PORT * port_list)
|
||||
void init_port_threads(ROUTER_PORT *port_list)
|
||||
{
|
||||
ROUTER_PORT *port = port_list;
|
||||
pthread_t *thread;
|
||||
@@ -688,17 +651,16 @@ void init_port_threads(
|
||||
}
|
||||
|
||||
port->state = INIT;
|
||||
thread = (pthread_t *) malloc(sizeof(pthread_t));
|
||||
thread = (pthread_t *)malloc(sizeof(pthread_t));
|
||||
pthread_create(thread, NULL, port->func, port);
|
||||
|
||||
pthread_detach(*thread); /* for proper thread termination */
|
||||
pthread_detach(*thread); /* for proper thread termination */
|
||||
|
||||
port = port->next;
|
||||
}
|
||||
}
|
||||
|
||||
bool init_router(
|
||||
)
|
||||
bool init_router()
|
||||
{
|
||||
MSGBOX_ID msgboxid;
|
||||
ROUTER_PORT *port;
|
||||
@@ -735,8 +697,7 @@ bool init_router(
|
||||
return true;
|
||||
}
|
||||
|
||||
void cleanup(
|
||||
)
|
||||
void cleanup()
|
||||
{
|
||||
ROUTER_PORT *port;
|
||||
BACMSG msg;
|
||||
@@ -748,7 +709,7 @@ void cleanup(
|
||||
msg.type = SERVICE;
|
||||
msg.subtype = SHUTDOWN;
|
||||
|
||||
del_msgbox(head->main_id); /* close routers message box */
|
||||
del_msgbox(head->main_id); /* close routers message box */
|
||||
|
||||
/* send shutdown message to all router ports */
|
||||
port = head;
|
||||
@@ -772,12 +733,11 @@ void cleanup(
|
||||
pthread_mutex_destroy(&msg_lock);
|
||||
}
|
||||
|
||||
void print_msg(
|
||||
BACMSG * msg)
|
||||
void print_msg(BACMSG *msg)
|
||||
{
|
||||
if (msg->type == DATA) {
|
||||
int i;
|
||||
MSG_DATA *data = (MSG_DATA *) msg->data;
|
||||
MSG_DATA *data = (MSG_DATA *)msg->data;
|
||||
|
||||
if (data->pdu_len) {
|
||||
PRINT(DEBUG, "Message PDU: ");
|
||||
@@ -788,12 +748,8 @@ void print_msg(
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t process_msg(
|
||||
BACMSG * msg,
|
||||
MSG_DATA * data,
|
||||
uint8_t ** buff)
|
||||
uint16_t process_msg(BACMSG *msg, MSG_DATA *data, uint8_t **buff)
|
||||
{
|
||||
|
||||
BACNET_ADDRESS addr;
|
||||
BACNET_NPDU_DATA npdu_data;
|
||||
ROUTER_PORT *srcport;
|
||||
@@ -816,12 +772,14 @@ uint16_t process_msg(
|
||||
if (srcport && destport) {
|
||||
data->src.net = srcport->route_info.net;
|
||||
|
||||
/* if received from another router save real source address (not other router source address) */
|
||||
/* if received from another router save real source address (not other
|
||||
* router source address) */
|
||||
if (addr.net > 0 && addr.net < BACNET_BROADCAST_NETWORK &&
|
||||
data->src.net != addr.net)
|
||||
memmove(&data->src, &addr, sizeof(BACNET_ADDRESS));
|
||||
|
||||
/* encode both source and destination for broadcast and router-to-router communication */
|
||||
/* encode both source and destination for broadcast and router-to-router
|
||||
* communication */
|
||||
if (data->dest.net == BACNET_BROADCAST_NETWORK ||
|
||||
destport->route_info.net != data->dest.net) {
|
||||
npdu_len =
|
||||
@@ -832,9 +790,10 @@ uint16_t process_msg(
|
||||
|
||||
buff_len = npdu_len + data->pdu_len - apdu_offset;
|
||||
|
||||
*buff = (uint8_t *) malloc(buff_len);
|
||||
*buff = (uint8_t *)malloc(buff_len);
|
||||
memmove(*buff, npdu, npdu_len); /* copy newly formed NPDU */
|
||||
memmove(*buff + npdu_len, &data->pdu[apdu_offset], apdu_len); /* copy APDU */
|
||||
memmove(*buff + npdu_len, &data->pdu[apdu_offset],
|
||||
apdu_len); /* copy APDU */
|
||||
|
||||
} else {
|
||||
/* request net search */
|
||||
@@ -842,13 +801,12 @@ uint16_t process_msg(
|
||||
}
|
||||
|
||||
/* delete received message */
|
||||
free_data((MSG_DATA *) msg->data);
|
||||
free_data((MSG_DATA *)msg->data);
|
||||
|
||||
return buff_len;
|
||||
}
|
||||
|
||||
int kbhit(
|
||||
)
|
||||
int kbhit()
|
||||
{
|
||||
static const int STDIN = 0;
|
||||
static bool initialized = false;
|
||||
@@ -868,22 +826,18 @@ int kbhit(
|
||||
return bytesWaiting;
|
||||
}
|
||||
|
||||
bool is_network_msg(
|
||||
BACMSG * msg)
|
||||
bool is_network_msg(BACMSG *msg)
|
||||
{
|
||||
|
||||
uint8_t control_byte; /* NPDU control byte */
|
||||
MSG_DATA *data = (MSG_DATA *) msg->data;
|
||||
uint8_t control_byte; /* NPDU control byte */
|
||||
MSG_DATA *data = (MSG_DATA *)msg->data;
|
||||
|
||||
control_byte = data->pdu[1];
|
||||
|
||||
return control_byte & 0x80; /* check 7th bit */
|
||||
}
|
||||
|
||||
uint16_t get_next_free_dnet(
|
||||
)
|
||||
uint16_t get_next_free_dnet()
|
||||
{
|
||||
|
||||
ROUTER_PORT *port = head;
|
||||
uint16_t i = 1;
|
||||
while (port) {
|
||||
|
||||
Reference in New Issue
Block a user