Format ports/bsd for standard style.

This commit is contained in:
Steve Karg
2025-07-01 12:52:39 -05:00
parent def3cb14bb
commit 51b899fc36
16 changed files with 392 additions and 304 deletions
-7
View File
@@ -1,7 +0,0 @@
---
# Disable formatting for now as there is external code. We should move external
# code to a separate directory and enable formatting for our code.
DisableFormat: true
# DisableFormat will not disable include sorting with some versions.
SortIncludes: Never
+18 -18
View File
@@ -1,39 +1,39 @@
/************************************************************************** /**************************************************************************
* *
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net> * Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
* *
* SPDX-License-Identifier: MIT * SPDX-License-Identifier: MIT
* *
*********************************************************************/ *********************************************************************/
#ifndef BACPORT_H #ifndef BACPORT_H
#define BACPORT_H #define BACPORT_H
/* common unix sockets headers needed */ /* common unix sockets headers needed */
#include <sys/types.h> /* basic system data types */ #include <sys/types.h> /* basic system data types */
#include <sys/time.h> /* timeval{} for select() */ #include <sys/time.h> /* timeval{} for select() */
#include <time.h> /* timespec{} for pselect() */ #include <time.h> /* timespec{} for pselect() */
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */ #include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h> /* inet(3) functions */ #include <arpa/inet.h> /* inet(3) functions */
#include <fcntl.h> /* for nonblocking */ #include <fcntl.h> /* for nonblocking */
#include <netdb.h> #include <netdb.h>
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <sys/stat.h> /* for S_xxx file mode constants */ #include <sys/stat.h> /* for S_xxx file mode constants */
#include <sys/uio.h> /* for iovec{} and readv/writev */ #include <sys/uio.h> /* for iovec{} and readv/writev */
#include <unistd.h> #include <unistd.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/un.h> /* for Unix domain sockets */ #include <sys/un.h> /* for Unix domain sockets */
#ifdef HAVE_SYS_SELECT_H #ifdef HAVE_SYS_SELECT_H
#include <sys/select.h> /* for convenience */ #include <sys/select.h> /* for convenience */
#endif #endif
#ifdef HAVE_POLL_H #ifdef HAVE_POLL_H
#include <poll.h> /* for convenience */ #include <poll.h> /* for convenience */
#endif #endif
/* Three headers are normally needed for socket/file ioctl's: /* Three headers are normally needed for socket/file ioctl's:
@@ -60,7 +60,7 @@
#include <net/if_arp.h> #include <net/if_arp.h>
#include <net/if_dl.h> #include <net/if_dl.h>
#include <ifaddrs.h> #include <ifaddrs.h>
#include <net/ethernet.h> /* the L2 protocols */ #include <net/ethernet.h> /* the L2 protocols */
#include <netinet/in.h> #include <netinet/in.h>
#include <netinet/in_var.h> #include <netinet/in_var.h>
#include <arpa/inet.h> #include <arpa/inet.h>
+27 -19
View File
@@ -73,12 +73,10 @@ static void debug_print_ipv6(const char *str, const struct in6_addr *addr)
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:" "%02x%02x:%02x%02x:%02x%02x:%02x%02x:"
"%02x%02x:%02x%02x:%02x%02x:%02x%02x\n", "%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
str, (int)addr->s6_addr[0], (int)addr->s6_addr[1], str, (int)addr->s6_addr[0], (int)addr->s6_addr[1],
(int)addr->s6_addr[2], (int)addr->s6_addr[3], (int)addr->s6_addr[2], (int)addr->s6_addr[3], (int)addr->s6_addr[4],
(int)addr->s6_addr[4], (int)addr->s6_addr[5], (int)addr->s6_addr[5], (int)addr->s6_addr[6], (int)addr->s6_addr[7],
(int)addr->s6_addr[6], (int)addr->s6_addr[7], (int)addr->s6_addr[8], (int)addr->s6_addr[9], (int)addr->s6_addr[10],
(int)addr->s6_addr[8], (int)addr->s6_addr[9], (int)addr->s6_addr[11], (int)addr->s6_addr[12], (int)addr->s6_addr[13],
(int)addr->s6_addr[10], (int)addr->s6_addr[11],
(int)addr->s6_addr[12], (int)addr->s6_addr[13],
(int)addr->s6_addr[14], (int)addr->s6_addr[15]); (int)addr->s6_addr[14], (int)addr->s6_addr[15]);
} }
@@ -120,12 +118,14 @@ void bip6_set_interface(char *ifname)
} }
while (ifa_tmp) { while (ifa_tmp) {
if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6)) { if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6)) {
debug_fprintf_bip6(stdout, "BIP6: found interface: %s\n", ifa_tmp->ifa_name); debug_fprintf_bip6(
stdout, "BIP6: found interface: %s\n", ifa_tmp->ifa_name);
} }
if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6) && if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6) &&
(bacnet_stricmp(ifa_tmp->ifa_name, ifname) == 0)) { (bacnet_stricmp(ifa_tmp->ifa_name, ifname) == 0)) {
sin = (struct sockaddr_in6 *)ifa_tmp->ifa_addr; sin = (struct sockaddr_in6 *)ifa_tmp->ifa_addr;
bvlc6_address_set(&BIP6_Addr, ntohs(sin->sin6_addr.s6_addr16[0]), bvlc6_address_set(
&BIP6_Addr, ntohs(sin->sin6_addr.s6_addr16[0]),
ntohs(sin->sin6_addr.s6_addr16[1]), ntohs(sin->sin6_addr.s6_addr16[1]),
ntohs(sin->sin6_addr.s6_addr16[2]), ntohs(sin->sin6_addr.s6_addr16[2]),
ntohs(sin->sin6_addr.s6_addr16[3]), ntohs(sin->sin6_addr.s6_addr16[3]),
@@ -141,7 +141,8 @@ void bip6_set_interface(char *ifname)
ifa_tmp = ifa_tmp->ifa_next; ifa_tmp = ifa_tmp->ifa_next;
} }
if (!found) { if (!found) {
debug_fprintf_bip6(stdout, "BIP6: unable to set interface: %s\n", ifname); debug_fprintf_bip6(
stdout, "BIP6: unable to set interface: %s\n", ifname);
exit(1); exit(1);
} }
} }
@@ -260,8 +261,9 @@ int bip6_send_mpdu(
} }
/* load destination IP address */ /* load destination IP address */
bvlc_dest.sin6_family = AF_INET6; bvlc_dest.sin6_family = AF_INET6;
bvlc6_address_get(dest, &addr16[0], &addr16[1], &addr16[2], &addr16[3], bvlc6_address_get(
&addr16[4], &addr16[5], &addr16[6], &addr16[7]); dest, &addr16[0], &addr16[1], &addr16[2], &addr16[3], &addr16[4],
&addr16[5], &addr16[6], &addr16[7]);
bvlc_dest.sin6_addr.s6_addr16[0] = htons(addr16[0]); bvlc_dest.sin6_addr.s6_addr16[0] = htons(addr16[0]);
bvlc_dest.sin6_addr.s6_addr16[1] = htons(addr16[1]); bvlc_dest.sin6_addr.s6_addr16[1] = htons(addr16[1]);
bvlc_dest.sin6_addr.s6_addr16[2] = htons(addr16[2]); bvlc_dest.sin6_addr.s6_addr16[2] = htons(addr16[2]);
@@ -274,7 +276,8 @@ int bip6_send_mpdu(
bvlc_dest.sin6_scope_id = BIP6_Socket_Scope_Id; bvlc_dest.sin6_scope_id = BIP6_Socket_Scope_Id;
debug_print_ipv6("Sending MPDU->", &bvlc_dest.sin6_addr); debug_print_ipv6("Sending MPDU->", &bvlc_dest.sin6_addr);
/* Send the packet */ /* Send the packet */
return sendto(BIP6_Socket, (const char *)mtu, mtu_len, 0, return sendto(
BIP6_Socket, (const char *)mtu, mtu_len, 0,
(struct sockaddr *)&bvlc_dest, sizeof(bvlc_dest)); (struct sockaddr *)&bvlc_dest, sizeof(bvlc_dest));
} }
@@ -290,7 +293,8 @@ int bip6_send_mpdu(
* @return Upon successful completion, returns the number of bytes sent. * @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned to indicate the error. * Otherwise, -1 shall be returned to indicate the error.
*/ */
int bip6_send_pdu(BACNET_ADDRESS *dest, int bip6_send_pdu(
BACNET_ADDRESS *dest,
BACNET_NPDU_DATA *npdu_data, BACNET_NPDU_DATA *npdu_data,
uint8_t *pdu, uint8_t *pdu,
unsigned pdu_len) unsigned pdu_len)
@@ -342,8 +346,9 @@ uint16_t bip6_receive(
max = BIP6_Socket; max = BIP6_Socket;
/* see if there is a packet for us */ /* see if there is a packet for us */
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) { if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
received_bytes = recvfrom(BIP6_Socket, (char *)&npdu[0], max_npdu, 0, received_bytes = recvfrom(
(struct sockaddr *)&sin, &sin_len); BIP6_Socket, (char *)&npdu[0], max_npdu, 0, (struct sockaddr *)&sin,
&sin_len);
} else { } else {
return 0; return 0;
} }
@@ -361,7 +366,8 @@ uint16_t bip6_receive(
} }
/* pass the packet into the BBMD handler */ /* pass the packet into the BBMD handler */
debug_print_ipv6("Received MPDU->", &sin.sin6_addr); debug_print_ipv6("Received MPDU->", &sin.sin6_addr);
bvlc6_address_set(&addr, ntohs(sin.sin6_addr.s6_addr16[0]), bvlc6_address_set(
&addr, ntohs(sin.sin6_addr.s6_addr16[0]),
ntohs(sin.sin6_addr.s6_addr16[1]), ntohs(sin.sin6_addr.s6_addr16[2]), ntohs(sin.sin6_addr.s6_addr16[1]), ntohs(sin.sin6_addr.s6_addr16[2]),
ntohs(sin.sin6_addr.s6_addr16[3]), ntohs(sin.sin6_addr.s6_addr16[4]), ntohs(sin.sin6_addr.s6_addr16[3]), ntohs(sin.sin6_addr.s6_addr16[4]),
ntohs(sin.sin6_addr.s6_addr16[5]), ntohs(sin.sin6_addr.s6_addr16[6]), ntohs(sin.sin6_addr.s6_addr16[5]), ntohs(sin.sin6_addr.s6_addr16[6]),
@@ -486,13 +492,15 @@ bool bip6_init(char *ifname)
} }
debug_fprintf_bip6(stdout, "BIP6: IPv6 UDP port: 0x%04X\n", BIP6_Addr.port); debug_fprintf_bip6(stdout, "BIP6: IPv6 UDP port: 0x%04X\n", BIP6_Addr.port);
if (BIP6_Broadcast_Addr.address[0] == 0) { if (BIP6_Broadcast_Addr.address[0] == 0) {
bvlc6_address_set(&BIP6_Broadcast_Addr, BIP6_MULTICAST_SITE_LOCAL, 0, 0, bvlc6_address_set(
0, 0, 0, 0, BIP6_MULTICAST_GROUP_ID); &BIP6_Broadcast_Addr, BIP6_MULTICAST_SITE_LOCAL, 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_GROUP_ID);
} }
/* assumes that the driver has already been initialized */ /* assumes that the driver has already been initialized */
BIP6_Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); BIP6_Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (BIP6_Socket < 0) if (BIP6_Socket < 0) {
return false; return false;
}
/* Allow us to use the same socket for sending and receiving */ /* Allow us to use the same socket for sending and receiving */
/* This makes sure that the src port is correct when sending */ /* This makes sure that the src port is correct when sending */
sockopt = 1; sockopt = 1;
+12 -14
View File
@@ -95,10 +95,9 @@ void bsc_event_wait(BSC_EVENT *ev)
if (!ev->counter) { if (!ev->counter) {
ev->v = false; ev->v = false;
DEBUG_PRINTF("bsc_event_wait() reset ev\n"); DEBUG_PRINTF("bsc_event_wait() reset ev\n");
} } else {
else { DEBUG_PRINTF("bsc_event_wait() wake up other waiting threads\n");
DEBUG_PRINTF("bsc_event_wait() wake up other waiting threads\n"); pthread_cond_broadcast(&ev->cond);
pthread_cond_broadcast(&ev->cond);
} }
DEBUG_PRINTF("bsc_event_wait() <<< ev = %p\n", ev); DEBUG_PRINTF("bsc_event_wait() <<< ev = %p\n", ev);
pthread_mutex_unlock(&ev->mutex); pthread_mutex_unlock(&ev->mutex);
@@ -115,8 +114,9 @@ bool bsc_event_timedwait(BSC_EVENT *ev, unsigned int ms_timeout)
to.tv_sec += to.tv_nsec / 1000000000; to.tv_sec += to.tv_nsec / 1000000000;
to.tv_nsec %= 1000000000; to.tv_nsec %= 1000000000;
DEBUG_PRINTF("bsc_event_timedwait() >>> before lock ev = %p ev->v = %d\n", DEBUG_PRINTF(
ev, ev->v); "bsc_event_timedwait() >>> before lock ev = %p ev->v = %d\n", ev,
ev->v);
pthread_mutex_lock(&ev->mutex); pthread_mutex_lock(&ev->mutex);
@@ -133,8 +133,8 @@ bool bsc_event_timedwait(BSC_EVENT *ev, unsigned int ms_timeout)
} }
} }
if(ev->v) { if (ev->v) {
if(r!=0) { if (r != 0) {
DEBUG_PRINTF("Fired!!! r = %d\n", r); DEBUG_PRINTF("Fired!!! r = %d\n", r);
} }
r = 0; r = 0;
@@ -144,13 +144,11 @@ bool bsc_event_timedwait(BSC_EVENT *ev, unsigned int ms_timeout)
DEBUG_PRINTF("bsc_event_timedwait() counter %zu\n", ev->counter); DEBUG_PRINTF("bsc_event_timedwait() counter %zu\n", ev->counter);
if (!ev->counter) { if (!ev->counter) {
DEBUG_PRINTF( DEBUG_PRINTF("bsc_event_timedwait() event is reset, err = %d\n", r);
"bsc_event_timedwait() event is reset, err = %d\n", r);
ev->v = false; ev->v = false;
} } else {
else { DEBUG_PRINTF("bsc_event_timedwait() wake up other waiting threads\n");
DEBUG_PRINTF("bsc_event_timedwait() wake up other waiting threads\n"); pthread_cond_broadcast(&ev->cond);
pthread_cond_broadcast(&ev->cond);
} }
DEBUG_PRINTF( DEBUG_PRINTF(
+7 -6
View File
@@ -19,7 +19,6 @@
#include "bacport.h" #include "bacport.h"
#include "bacnet/datetime.h" #include "bacnet/datetime.h"
/** /**
* @brief Set offset from the system clock. * @brief Set offset from the system clock.
* @param bdate BACnet Date structure to hold local time * @param bdate BACnet Date structure to hold local time
@@ -44,7 +43,8 @@ void datetime_timesync(BACNET_DATE *bdate, BACNET_TIME *btime, bool utc)
* @param true if DST is enabled and active * @param true if DST is enabled and active
* @return true if local time was retrieved * @return true if local time was retrieved
*/ */
bool datetime_local(BACNET_DATE *bdate, bool datetime_local(
BACNET_DATE *bdate,
BACNET_TIME *btime, BACNET_TIME *btime,
int16_t *utc_offset_minutes, int16_t *utc_offset_minutes,
bool *dst_active) bool *dst_active)
@@ -70,11 +70,12 @@ bool datetime_local(BACNET_DATE *bdate,
* int tm_isdst Daylight Savings flag. * int tm_isdst Daylight Savings flag.
* long tm_gmtoff offset from UTC in seconds * long tm_gmtoff offset from UTC in seconds
*/ */
datetime_set_date(bdate, (uint16_t)tblock->tm_year + 1900, datetime_set_date(
bdate, (uint16_t)tblock->tm_year + 1900,
(uint8_t)tblock->tm_mon + 1, (uint8_t)tblock->tm_mday); (uint8_t)tblock->tm_mon + 1, (uint8_t)tblock->tm_mday);
datetime_set_time(btime, (uint8_t)tblock->tm_hour, datetime_set_time(
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, btime, (uint8_t)tblock->tm_hour, (uint8_t)tblock->tm_min,
(uint8_t)(tv.tv_usec / 10000)); (uint8_t)tblock->tm_sec, (uint8_t)(tv.tv_usec / 10000));
if (dst_active) { if (dst_active) {
/* The value of tm_isdst is: /* The value of tm_isdst is:
- positive if Daylight Saving Time is in effect, - positive if Daylight Saving Time is in effect,
+17 -25
View File
@@ -206,16 +206,14 @@ static bool dlmstp_compare_data_expecting_reply(
request_pdu, request_pdu_len, NULL, &request.address, request_pdu, request_pdu_len, NULL, &request.address,
&request.npdu_data); &request.npdu_data);
if (request.npdu_data.network_layer_message) { if (request.npdu_data.network_layer_message) {
debug_printf( debug_printf("DLMSTP: DER Compare failed: "
"DLMSTP: DER Compare failed: " "Request is Network message.\n");
"Request is Network message.\n");
return false; return false;
} }
request.pdu_type = request_pdu[offset] & 0xF0; request.pdu_type = request_pdu[offset] & 0xF0;
if (request.pdu_type != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) { if (request.pdu_type != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) {
debug_printf( debug_printf("DLMSTP: DER Compare failed: "
"DLMSTP: DER Compare failed: " "Not Confirmed Request.\n");
"Not Confirmed Request.\n");
return false; return false;
} }
request.invoke_id = request_pdu[offset + 2]; request.invoke_id = request_pdu[offset + 2];
@@ -231,9 +229,8 @@ static bool dlmstp_compare_data_expecting_reply(
offset = (uint16_t)bacnet_npdu_decode( offset = (uint16_t)bacnet_npdu_decode(
reply_pdu, reply_pdu_len, &reply.address, NULL, &reply.npdu_data); reply_pdu, reply_pdu_len, &reply.address, NULL, &reply.npdu_data);
if (reply.npdu_data.network_layer_message) { if (reply.npdu_data.network_layer_message) {
debug_printf( debug_printf("DLMSTP: DER Compare failed: "
"DLMSTP: DER Compare failed: " "Reply is Network message.\n");
"Reply is Network message.\n");
return false; return false;
} }
/* reply could be a lot of things: /* reply could be a lot of things:
@@ -270,30 +267,26 @@ static bool dlmstp_compare_data_expecting_reply(
(reply.pdu_type == PDU_TYPE_ABORT) || (reply.pdu_type == PDU_TYPE_ABORT) ||
(reply.pdu_type == PDU_TYPE_SEGMENT_ACK)) { (reply.pdu_type == PDU_TYPE_SEGMENT_ACK)) {
if (request.invoke_id != reply.invoke_id) { if (request.invoke_id != reply.invoke_id) {
debug_printf( debug_printf("DLMSTP: DER Compare failed: "
"DLMSTP: DER Compare failed: " "Invoke ID mismatch.\n");
"Invoke ID mismatch.\n");
return false; return false;
} }
} else { } else {
if (request.invoke_id != reply.invoke_id) { if (request.invoke_id != reply.invoke_id) {
debug_printf( debug_printf("DLMSTP: DER Compare failed: "
"DLMSTP: DER Compare failed: " "Invoke ID mismatch.\n");
"Invoke ID mismatch.\n");
return false; return false;
} }
if (request.service_choice != reply.service_choice) { if (request.service_choice != reply.service_choice) {
debug_printf( debug_printf("DLMSTP: DER Compare failed: "
"DLMSTP: DER Compare failed: " "Service choice mismatch.\n");
"Service choice mismatch.\n");
return false; return false;
} }
} }
if (request.npdu_data.protocol_version != if (request.npdu_data.protocol_version !=
reply.npdu_data.protocol_version) { reply.npdu_data.protocol_version) {
debug_printf( debug_printf("DLMSTP: DER Compare failed: "
"DLMSTP: DER Compare failed: " "NPDU Protocol Version mismatch.\n");
"NPDU Protocol Version mismatch.\n");
return false; return false;
} }
#if 0 #if 0
@@ -306,9 +299,8 @@ static bool dlmstp_compare_data_expecting_reply(
} }
#endif #endif
if (!bacnet_address_same(&request.address, &reply.address)) { if (!bacnet_address_same(&request.address, &reply.address)) {
debug_printf( debug_printf("DLMSTP: DER Compare failed: "
"DLMSTP: DER Compare failed: " "BACnet Address mismatch.\n");
"BACnet Address mismatch.\n");
return false; return false;
} }
@@ -991,7 +983,7 @@ bool dlmstp_init(char *ifname)
int rv = 0; int rv = 0;
pthread_condattr_init(&attr); pthread_condattr_init(&attr);
//TODO use mach_absolute_time() <mach/mach_time.h> for MONOTONIC clock // TODO use mach_absolute_time() <mach/mach_time.h> for MONOTONIC clock
if ((rv = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) != 0) { if ((rv = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) != 0) {
fprintf( fprintf(
stderr, "MS/TP Interface: %s\n failed to set MONOTONIC clock\n", stderr, "MS/TP Interface: %s\n failed to set MONOTONIC clock\n",
+29 -18
View File
@@ -864,8 +864,9 @@ bool dlmstp_init(void *poPort, char *ifname)
exit(-1); exit(-1);
} }
if (ioctl(poSharedData->RS485_Handle, TIOCEXCL) == -1) { if (ioctl(poSharedData->RS485_Handle, TIOCEXCL) == -1) {
printf("Error setting TIOCEXCL on %s - %s(%d).\n", poSharedData->RS485_Port_Name, printf(
strerror(errno), errno); "Error setting TIOCEXCL on %s - %s(%d).\n",
poSharedData->RS485_Port_Name, strerror(errno), errno);
exit(-1); exit(-1);
} }
#if 0 #if 0
@@ -887,13 +888,15 @@ bool dlmstp_init(void *poPort, char *ifname)
CREAD : enable receiving characters CREAD : enable receiving characters
*/ */
printf( printf(
"Default/current input baud rate is %d\n", (int)cfgetispeed(&poSharedData->RS485_oldtio)); "Default/current input baud rate is %d\n",
(int)cfgetispeed(&poSharedData->RS485_oldtio));
printf( printf(
"Default/current output baud rate is %d\n", (int)cfgetospeed(&poSharedData->RS485_oldtio)); "Default/current output baud rate is %d\n",
(int)cfgetospeed(&poSharedData->RS485_oldtio));
newtio.c_cc[VMIN] = 0; newtio.c_cc[VMIN] = 0;
newtio.c_cc[VTIME] = 10; newtio.c_cc[VTIME] = 10;
//newtio.c_cflag = // newtio.c_cflag =
// poSharedData->RS485_Baud | poSharedData->RS485MOD | CLOCAL | CREAD; // poSharedData->RS485_Baud | poSharedData->RS485MOD | CLOCAL | CREAD;
cfsetspeed(&newtio, poSharedData->RS485_Baud); cfsetspeed(&newtio, poSharedData->RS485_Baud);
newtio.c_cflag &= ~PARENB; /* No Parity */ newtio.c_cflag &= ~PARENB; /* No Parity */
newtio.c_cflag &= ~CSTOPB; /* 1 Stop Bit */ newtio.c_cflag &= ~CSTOPB; /* 1 Stop Bit */
@@ -905,8 +908,11 @@ bool dlmstp_init(void *poPort, char *ifname)
newtio.c_oflag = 0; newtio.c_oflag = 0;
/* no processing */ /* no processing */
newtio.c_lflag = 0; newtio.c_lflag = 0;
if (ioctl(poSharedData->RS485_Handle, IOSSIOSPEED, &poSharedData->RS485_Baud) == -1) { if (ioctl(
printf("Error calling ioctl(..., IOSSIOSPEED, ...) %s - %s(%d).\n", poSharedData->RS485_Handle, IOSSIOSPEED,
&poSharedData->RS485_Baud) == -1) {
printf(
"Error calling ioctl(..., IOSSIOSPEED, ...) %s - %s(%d).\n",
poSharedData->RS485_Port_Name, strerror(errno), errno); poSharedData->RS485_Port_Name, strerror(errno), errno);
} }
printf("Input baud rate changed to %d\n", (int)cfgetispeed(&newtio)); printf("Input baud rate changed to %d\n", (int)cfgetispeed(&newtio));
@@ -921,21 +927,24 @@ bool dlmstp_init(void *poPort, char *ifname)
/* Assert Data Terminal Ready (DTR) */ /* Assert Data Terminal Ready (DTR) */
if (ioctl(poSharedData->RS485_Handle, TIOCSDTR) == -1) { if (ioctl(poSharedData->RS485_Handle, TIOCSDTR) == -1) {
printf("Error asserting DTR %s - %s(%d).\n", poSharedData->RS485_Port_Name, strerror(errno), printf(
errno); "Error asserting DTR %s - %s(%d).\n", poSharedData->RS485_Port_Name,
strerror(errno), errno);
} }
/* Clear Data Terminal Ready (DTR) */ /* Clear Data Terminal Ready (DTR) */
if (ioctl(poSharedData->RS485_Handle, TIOCCDTR) == -1) { if (ioctl(poSharedData->RS485_Handle, TIOCCDTR) == -1) {
printf("Error clearing DTR %s - %s(%d).\n", poSharedData->RS485_Port_Name, strerror(errno), printf(
errno); "Error clearing DTR %s - %s(%d).\n", poSharedData->RS485_Port_Name,
strerror(errno), errno);
} }
/* Set the modem lines depending on the bits set in handshake */ /* Set the modem lines depending on the bits set in handshake */
handshake = TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR; handshake = TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR;
if (ioctl(poSharedData->RS485_Handle, TIOCMSET, &handshake) == -1) { if (ioctl(poSharedData->RS485_Handle, TIOCMSET, &handshake) == -1) {
printf("Error setting handshake lines %s - %s(%d).\n", poSharedData->RS485_Port_Name, printf(
strerror(errno), errno); "Error setting handshake lines %s - %s(%d).\n",
poSharedData->RS485_Port_Name, strerror(errno), errno);
} }
/* To read the state of the modem lines, use the following ioctl. /* To read the state of the modem lines, use the following ioctl.
@@ -944,16 +953,18 @@ bool dlmstp_init(void *poPort, char *ifname)
/* Store the state of the modem lines in handshake */ /* Store the state of the modem lines in handshake */
if (ioctl(poSharedData->RS485_Handle, TIOCMGET, &handshake) == -1) { if (ioctl(poSharedData->RS485_Handle, TIOCMGET, &handshake) == -1) {
printf("Error getting handshake lines %s - %s(%d).\n", poSharedData->RS485_Port_Name, printf(
strerror(errno), errno); "Error getting handshake lines %s - %s(%d).\n",
poSharedData->RS485_Port_Name, strerror(errno), errno);
} }
printf("Handshake lines currently set to %d\n", handshake); printf("Handshake lines currently set to %d\n", handshake);
if (ioctl(poSharedData->RS485_Handle, IOSSDATALAT, &mics) == -1) { if (ioctl(poSharedData->RS485_Handle, IOSSDATALAT, &mics) == -1) {
/* set latency to 1 microsecond */ /* set latency to 1 microsecond */
printf("Error setting read latency %s - %s(%d).\n", poSharedData->RS485_Port_Name, printf(
strerror(errno), errno); "Error setting read latency %s - %s(%d).\n",
poSharedData->RS485_Port_Name, strerror(errno), errno);
exit(-1); exit(-1);
} }
+4 -2
View File
@@ -111,14 +111,16 @@ void dlmstp_cleanup(void *poShared);
/* returns number of bytes sent on success, negative on failure */ /* returns number of bytes sent on success, negative on failure */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
int dlmstp_send_pdu(void *poShared, int dlmstp_send_pdu(
void *poShared,
BACNET_ADDRESS *dest, /* destination address */ BACNET_ADDRESS *dest, /* destination address */
uint8_t *pdu, /* any data to be sent - may be null */ uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len); /* number of bytes of data */ unsigned pdu_len); /* number of bytes of data */
/* returns the number of octets in the PDU, or zero on failure */ /* returns the number of octets in the PDU, or zero on failure */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
uint16_t dlmstp_receive(void *poShared, uint16_t dlmstp_receive(
void *poShared,
BACNET_ADDRESS *src, /* source address */ BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */ uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */ uint16_t max_pdu, /* amount of space available in the PDU */
+26 -23
View File
@@ -83,11 +83,13 @@ static int get_local_hwaddr(const char *ifname, unsigned char *mac)
int i; int i;
if (getifaddrs(&ifap) == 0) { if (getifaddrs(&ifap) == 0) {
for(ifaptr = ifap; ifaptr != NULL; ifaptr = (ifaptr)->ifa_next) { for (ifaptr = ifap; ifaptr != NULL; ifaptr = (ifaptr)->ifa_next) {
if (!strcmp((ifaptr)->ifa_name, ifname) && (((ifaptr)->ifa_addr)->sa_family == AF_LINK)) { if (!strcmp((ifaptr)->ifa_name, ifname) &&
ptr = (unsigned char *)LLADDR((struct sockaddr_dl *)(ifaptr)->ifa_addr); (((ifaptr)->ifa_addr)->sa_family == AF_LINK)) {
ptr = (unsigned char *)LLADDR(
(struct sockaddr_dl *)(ifaptr)->ifa_addr);
for (i = 0; i < 6; ++i) { for (i = 0; i < 6; ++i) {
mac[i] = *(ptr+i); mac[i] = *(ptr + i);
} }
break; break;
} }
@@ -99,7 +101,6 @@ static int get_local_hwaddr(const char *ifname, unsigned char *mac)
} }
} }
bool ethernet_init(char *if_name) bool ethernet_init(char *if_name)
{ {
pcap_if_t *pcap_all_if; pcap_if_t *pcap_all_if;
@@ -114,7 +115,8 @@ bool ethernet_init(char *if_name)
*/ */
/* Retrieve the device list */ /* Retrieve the device list */
if (pcap_findalldevs(&pcap_all_if, pcap_errbuf) == -1) { if (pcap_findalldevs(&pcap_all_if, pcap_errbuf) == -1) {
fprintf(stderr, "ethernet.c: error in pcap_findalldevs: %s\n", pcap_errbuf); fprintf(
stderr, "ethernet.c: error in pcap_findalldevs: %s\n", pcap_errbuf);
return false; return false;
} }
/* Scan the list printing every entry */ /* Scan the list printing every entry */
@@ -125,7 +127,8 @@ bool ethernet_init(char *if_name)
} }
pcap_freealldevs(pcap_all_if); /* we don't need it anymore */ pcap_freealldevs(pcap_all_if); /* we don't need it anymore */
if (dev == NULL) { if (dev == NULL) {
fprintf(stderr, "ethernet.c: specified interface not found: %s\n", if_name); fprintf(
stderr, "ethernet.c: specified interface not found: %s\n", if_name);
return false; return false;
} }
@@ -133,15 +136,11 @@ bool ethernet_init(char *if_name)
* Get local MAC address * Get local MAC address
*/ */
get_local_hwaddr(if_name, Ethernet_MAC_Address); get_local_hwaddr(if_name, Ethernet_MAC_Address);
fprintf(stderr, "ethernet: src mac %02x:%02x:%02x:%02x:%02x:%02x \n", fprintf(
Ethernet_MAC_Address[0], stderr, "ethernet: src mac %02x:%02x:%02x:%02x:%02x:%02x \n",
Ethernet_MAC_Address[1], Ethernet_MAC_Address[0], Ethernet_MAC_Address[1],
Ethernet_MAC_Address[2], Ethernet_MAC_Address[2], Ethernet_MAC_Address[3],
Ethernet_MAC_Address[3], Ethernet_MAC_Address[4], Ethernet_MAC_Address[5]);
Ethernet_MAC_Address[4],
Ethernet_MAC_Address[5]
);
/** /**
* Open interface for subsequent sending and receiving * Open interface for subsequent sending and receiving
@@ -152,12 +151,13 @@ bool ethernet_init(char *if_name)
ETHERNET_MPDU_MAX, /* portion of the packet to capture */ ETHERNET_MPDU_MAX, /* portion of the packet to capture */
PCAP_OPENFLAG_PROMISCUOUS, /* promiscuous mode */ PCAP_OPENFLAG_PROMISCUOUS, /* promiscuous mode */
eth_timeout, /* read timeout */ eth_timeout, /* read timeout */
//NULL, /* authentication on the remote machine */ // NULL, /* authentication on the remote machine */
pcap_errbuf /* error buffer */ pcap_errbuf /* error buffer */
); );
if (pcap_eth802_fp == NULL) { if (pcap_eth802_fp == NULL) {
ethernet_cleanup(); ethernet_cleanup();
fprintf(stderr, fprintf(
stderr,
"ethernet.c: unable to open the adapter. %s is not supported by " "ethernet.c: unable to open the adapter. %s is not supported by "
"Pcap\n", "Pcap\n",
if_name); if_name);
@@ -171,7 +171,6 @@ bool ethernet_init(char *if_name)
return ethernet_valid(); return ethernet_valid();
} }
/* function to send a packet out the 802.2 socket */ /* function to send a packet out the 802.2 socket */
/* returns bytes sent success, negative on failure */ /* returns bytes sent success, negative on failure */
int ethernet_send_addr( int ethernet_send_addr(
@@ -187,7 +186,8 @@ int ethernet_send_addr(
/* don't waste time if the socket is not valid */ /* don't waste time if the socket is not valid */
if (!ethernet_valid()) { if (!ethernet_valid()) {
fprintf(stderr, "ethernet: invalid 802.2 ethernet interface descriptor!\n"); fprintf(
stderr, "ethernet: invalid 802.2 ethernet interface descriptor!\n");
return -1; return -1;
} }
/* load destination ethernet MAC address */ /* load destination ethernet MAC address */
@@ -227,7 +227,8 @@ int ethernet_send_addr(
/* Send the packet */ /* Send the packet */
if (pcap_sendpacket(pcap_eth802_fp, mtu, mtu_len) != 0) { if (pcap_sendpacket(pcap_eth802_fp, mtu, mtu_len) != 0) {
/* did it get sent? */ /* did it get sent? */
fprintf(stderr, "ethernet: error in sending packet: %s\n", fprintf(
stderr, "ethernet: error in sending packet: %s\n",
pcap_geterr(pcap_eth802_fp)); pcap_geterr(pcap_eth802_fp));
return -5; return -5;
} }
@@ -282,14 +283,16 @@ uint16_t ethernet_receive(
/* Make sure the socket is open */ /* Make sure the socket is open */
if (!ethernet_valid()) { if (!ethernet_valid()) {
fprintf(stderr, "ethernet: invalid 802.2 ethernet interface descriptor!\n"); fprintf(
stderr, "ethernet: invalid 802.2 ethernet interface descriptor!\n");
return 0; return 0;
} }
/* Capture a packet */ /* Capture a packet */
res = pcap_next_ex(pcap_eth802_fp, &header, &pkt_data); res = pcap_next_ex(pcap_eth802_fp, &header, &pkt_data);
if (res < 0) { if (res < 0) {
fprintf(stderr, "ethernet: error in receiving packet: %s\n", fprintf(
stderr, "ethernet: error in receiving packet: %s\n",
pcap_geterr(pcap_eth802_fp)); pcap_geterr(pcap_eth802_fp));
return 0; return 0;
} else if (res == 0) { } else if (res == 0) {
+38 -21
View File
@@ -596,26 +596,30 @@ void RS485_Print_Ports(void)
valid_port = true; valid_port = true;
if (valid_port) { if (valid_port) {
/* print full absolute file path */ /* print full absolute file path */
printf("interface {value=/dev/%s}" printf(
"{display=MS/TP Capture on /dev/%s}\n", "interface {value=/dev/%s}"
"{display=MS/TP Capture on /dev/%s}\n",
namelist[n]->d_name, namelist[n]->d_name); namelist[n]->d_name, namelist[n]->d_name);
} }
} }
} else { } else {
snprintf(device_dir, sizeof(device_dir), "%s%s/device", snprintf(
sysdir, namelist[n]->d_name); device_dir, sizeof(device_dir), "%s%s/device", sysdir,
namelist[n]->d_name);
/* Stat the devicedir and handle it if it is a symlink */ /* Stat the devicedir and handle it if it is a symlink */
if (lstat(device_dir, &st) == 0 && S_ISLNK(st.st_mode)) { if (lstat(device_dir, &st) == 0 && S_ISLNK(st.st_mode)) {
memset(buffer, 0, sizeof(buffer)); memset(buffer, 0, sizeof(buffer));
snprintf(device_dir, sizeof(device_dir), snprintf(
device_dir, sizeof(device_dir),
"%s%s/device/driver", sysdir, namelist[n]->d_name); "%s%s/device/driver", sysdir, namelist[n]->d_name);
if (readlink(device_dir, buffer, sizeof(buffer)) > 0) { if (readlink(device_dir, buffer, sizeof(buffer)) > 0) {
valid_port = false; valid_port = false;
driver_name = basename(buffer); driver_name = basename(buffer);
if (strcmp(driver_name, "serial8250") == 0) { if (strcmp(driver_name, "serial8250") == 0) {
/* serial8250-devices must be probed */ /* serial8250-devices must be probed */
snprintf(device_dir, sizeof(device_dir), snprintf(
"/dev/%s", namelist[n]->d_name); device_dir, sizeof(device_dir), "/dev/%s",
namelist[n]->d_name);
fd = open( fd = open(
device_dir, O_RDWR | O_NONBLOCK | O_NOCTTY); device_dir, O_RDWR | O_NONBLOCK | O_NOCTTY);
if (fd >= 0) { if (fd >= 0) {
@@ -627,8 +631,9 @@ void RS485_Print_Ports(void)
} }
if (valid_port) { if (valid_port) {
/* print full absolute file path */ /* print full absolute file path */
printf("interface {value=/dev/%s}" printf(
"{display=MS/TP Capture on /dev/%s}\n", "interface {value=/dev/%s}"
"{display=MS/TP Capture on /dev/%s}\n",
namelist[n]->d_name, namelist[n]->d_name); namelist[n]->d_name, namelist[n]->d_name);
} }
} }
@@ -675,7 +680,8 @@ static int openSerialPort(const char *const bsdPath)
fileDescriptor = open(bsdPath, O_RDWR | O_NOCTTY | O_NONBLOCK); fileDescriptor = open(bsdPath, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fileDescriptor == -1) { if (fileDescriptor == -1) {
printf("Error opening serial port %s - %s(%d).\n", bsdPath, printf(
"Error opening serial port %s - %s(%d).\n", bsdPath,
strerror(errno), errno); strerror(errno), errno);
goto error; goto error;
} }
@@ -686,7 +692,8 @@ static int openSerialPort(const char *const bsdPath)
<x-man-page//4/tty> and ioctl(2) <x-man-page//2/ioctl> for details.*/ <x-man-page//4/tty> and ioctl(2) <x-man-page//2/ioctl> for details.*/
if (ioctl(fileDescriptor, TIOCEXCL) == -1) { if (ioctl(fileDescriptor, TIOCEXCL) == -1) {
printf("Error setting TIOCEXCL on %s - %s(%d).\n", bsdPath, printf(
"Error setting TIOCEXCL on %s - %s(%d).\n", bsdPath,
strerror(errno), errno); strerror(errno), errno);
goto error; goto error;
} }
@@ -695,7 +702,8 @@ static int openSerialPort(const char *const bsdPath)
will block. See fcntl(2) <x-man-page//2/fcntl> for details.*/ will block. See fcntl(2) <x-man-page//2/fcntl> for details.*/
if (fcntl(fileDescriptor, F_SETFL, 0) == -1) { if (fcntl(fileDescriptor, F_SETFL, 0) == -1) {
printf("Error clearing O_NONBLOCK %s - %s(%d).\n", bsdPath, printf(
"Error clearing O_NONBLOCK %s - %s(%d).\n", bsdPath,
strerror(errno), errno); strerror(errno), errno);
goto error; goto error;
} }
@@ -703,7 +711,8 @@ static int openSerialPort(const char *const bsdPath)
/* Get the current options and save them so we can restore the default /* Get the current options and save them so we can restore the default
* settings later.*/ * settings later.*/
if (tcgetattr(fileDescriptor, &RS485_oldtio) == -1) { if (tcgetattr(fileDescriptor, &RS485_oldtio) == -1) {
printf("Error getting tty attributes %s - %s(%d).\n", bsdPath, printf(
"Error getting tty attributes %s - %s(%d).\n", bsdPath,
strerror(errno), errno); strerror(errno), errno);
goto error; goto error;
} }
@@ -747,7 +756,8 @@ static int openSerialPort(const char *const bsdPath)
* the input and output speed. */ * the input and output speed. */
if (ioctl(fileDescriptor, IOSSIOSPEED, &speed) == -1) { if (ioctl(fileDescriptor, IOSSIOSPEED, &speed) == -1) {
printf("Error calling ioctl(..., IOSSIOSPEED, ...) %s - %s(%d).\n", printf(
"Error calling ioctl(..., IOSSIOSPEED, ...) %s - %s(%d).\n",
bsdPath, strerror(errno), errno); bsdPath, strerror(errno), errno);
} }
#endif #endif
@@ -763,7 +773,8 @@ static int openSerialPort(const char *const bsdPath)
/* Cause the new options to take effect immediately.*/ /* Cause the new options to take effect immediately.*/
if (tcsetattr(fileDescriptor, TCSANOW, &options) == -1) { if (tcsetattr(fileDescriptor, TCSANOW, &options) == -1) {
printf("Error setting tty attributes %s - %s(%d).\n", bsdPath, printf(
"Error setting tty attributes %s - %s(%d).\n", bsdPath,
strerror(errno), errno); strerror(errno), errno);
goto error; goto error;
} }
@@ -774,20 +785,23 @@ static int openSerialPort(const char *const bsdPath)
/* Assert Data Terminal Ready (DTR) */ /* Assert Data Terminal Ready (DTR) */
if (ioctl(fileDescriptor, TIOCSDTR) == -1) { if (ioctl(fileDescriptor, TIOCSDTR) == -1) {
printf("Error asserting DTR %s - %s(%d).\n", bsdPath, strerror(errno), printf(
"Error asserting DTR %s - %s(%d).\n", bsdPath, strerror(errno),
errno); errno);
} }
/* Clear Data Terminal Ready (DTR) */ /* Clear Data Terminal Ready (DTR) */
if (ioctl(fileDescriptor, TIOCCDTR) == -1) { if (ioctl(fileDescriptor, TIOCCDTR) == -1) {
printf("Error clearing DTR %s - %s(%d).\n", bsdPath, strerror(errno), printf(
"Error clearing DTR %s - %s(%d).\n", bsdPath, strerror(errno),
errno); errno);
} }
/* Set the modem lines depending on the bits set in handshake */ /* Set the modem lines depending on the bits set in handshake */
handshake = TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR; handshake = TIOCM_DTR | TIOCM_RTS | TIOCM_CTS | TIOCM_DSR;
if (ioctl(fileDescriptor, TIOCMSET, &handshake) == -1) { if (ioctl(fileDescriptor, TIOCMSET, &handshake) == -1) {
printf("Error setting handshake lines %s - %s(%d).\n", bsdPath, printf(
"Error setting handshake lines %s - %s(%d).\n", bsdPath,
strerror(errno), errno); strerror(errno), errno);
} }
@@ -797,7 +811,8 @@ static int openSerialPort(const char *const bsdPath)
/* Store the state of the modem lines in handshake */ /* Store the state of the modem lines in handshake */
if (ioctl(fileDescriptor, TIOCMGET, &handshake) == -1) { if (ioctl(fileDescriptor, TIOCMGET, &handshake) == -1) {
printf("Error getting handshake lines %s - %s(%d).\n", bsdPath, printf(
"Error getting handshake lines %s - %s(%d).\n", bsdPath,
strerror(errno), errno); strerror(errno), errno);
} }
@@ -814,7 +829,8 @@ static int openSerialPort(const char *const bsdPath)
if (ioctl(fileDescriptor, IOSSDATALAT, &mics) == -1) { if (ioctl(fileDescriptor, IOSSDATALAT, &mics) == -1) {
/* set latency to 1 microsecond */ /* set latency to 1 microsecond */
printf("Error setting read latency %s - %s(%d).\n", bsdPath, printf(
"Error setting read latency %s - %s(%d).\n", bsdPath,
strerror(errno), errno); strerror(errno), errno);
goto error; goto error;
} }
@@ -846,7 +862,8 @@ static void closeSerialPort(int fileDescriptor)
the state in which you found it. This is why the original termios struct the state in which you found it. This is why the original termios struct
was saved. */ was saved. */
if (tcsetattr(fileDescriptor, TCSANOW, &RS485_oldtio) == -1) { if (tcsetattr(fileDescriptor, TCSANOW, &RS485_oldtio) == -1) {
printf("Error resetting tty attributes - %s(%d).\n", strerror(errno), printf(
"Error resetting tty attributes - %s(%d).\n", strerror(errno),
errno); errno);
} }
+2 -2
View File
@@ -30,8 +30,8 @@ void RS485_Initialize(void);
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void RS485_Send_Frame( void RS485_Send_Frame(
struct mstp_port_struct_t *mstp_port, /* port specific data */ struct mstp_port_struct_t *mstp_port, /* port specific data */
const uint8_t *buffer, /* frame to send (up to 501 bytes of data) */ const uint8_t *buffer, /* frame to send (up to 501 bytes of data) */
uint16_t nbytes); /* number of bytes of data (up to 501) */ uint16_t nbytes); /* number of bytes of data (up to 501) */
BACNET_STACK_EXPORT BACNET_STACK_EXPORT
void RS485_Check_UART_Data( void RS485_Check_UART_Data(
+1 -1
View File
@@ -23,7 +23,7 @@
#endif #endif
#ifndef TRUE #ifndef TRUE
#define TRUE 1 #define TRUE 1
#endif #endif
#endif #endif
+51 -35
View File
@@ -57,7 +57,8 @@ typedef struct {
/* Some forward function declarations */ /* Some forward function declarations */
static int bws_cli_websocket_event(struct lws *wsi, static int bws_cli_websocket_event(
struct lws *wsi,
enum lws_callback_reasons reason, enum lws_callback_reasons reason,
void *user, void *user,
void *in, void *in,
@@ -72,13 +73,13 @@ static pthread_mutex_t bws_cli_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
static struct lws_protocols bws_cli_direct_protocol[] = { static struct lws_protocols bws_cli_direct_protocol[] = {
{ BSC_WEBSOCKET_DIRECT_PROTOCOL_STR, bws_cli_websocket_event, 0, 0, 0, NULL, { BSC_WEBSOCKET_DIRECT_PROTOCOL_STR, bws_cli_websocket_event, 0, 0, 0, NULL,
0 }, 0 },
LWS_PROTOCOL_LIST_TERM LWS_PROTOCOL_LIST_TERM
}; };
static struct lws_protocols bws_cli_hub_protocol[] = { static struct lws_protocols bws_cli_hub_protocol[] = {
{ BSC_WEBSOCKET_HUB_PROTOCOL_STR, bws_cli_websocket_event, 0, 0, 0, NULL, { BSC_WEBSOCKET_HUB_PROTOCOL_STR, bws_cli_websocket_event, 0, 0, 0, NULL,
0 }, 0 },
LWS_PROTOCOL_LIST_TERM LWS_PROTOCOL_LIST_TERM
}; };
@@ -205,7 +206,8 @@ static void bws_set_disconnect_reason(BSC_WEBSOCKET_HANDLE h, uint16_t err_code)
} }
} }
static int bws_cli_websocket_event(struct lws *wsi, static int bws_cli_websocket_event(
struct lws *wsi,
enum lws_callback_reasons reason, enum lws_callback_reasons reason,
void *user, void *user,
void *in, void *in,
@@ -267,8 +269,9 @@ static int bws_cli_websocket_event(struct lws *wsi,
the WebSocket connection shall be closed with a the WebSocket connection shall be closed with a
status code of 1003 -WEBSOCKET_DATA_NOT_ACCEPTED. status code of 1003 -WEBSOCKET_DATA_NOT_ACCEPTED.
*/ */
DEBUG_PRINTF("bws_cli_websocket_event() got non-binary frame, " DEBUG_PRINTF(
"close connection for socket %d\n", "bws_cli_websocket_event() got non-binary frame, "
"close connection for socket %d\n",
h); h);
lws_close_reason( lws_close_reason(
wsi, LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE, NULL, 0); wsi, LWS_CLOSE_STATUS_UNACCEPTABLE_OPCODE, NULL, 0);
@@ -280,16 +283,18 @@ static int bws_cli_websocket_event(struct lws *wsi,
pthread_mutex_unlock(&bws_cli_mutex); pthread_mutex_unlock(&bws_cli_mutex);
} else { } else {
if (!bws_cli_conn[h].fragment_buffer) { if (!bws_cli_conn[h].fragment_buffer) {
DEBUG_PRINTF("bws_cli_websocket_event() alloc %d bytes for " DEBUG_PRINTF(
"socket %d\n", "bws_cli_websocket_event() alloc %d bytes for "
"socket %d\n",
len, h); len, h);
bws_cli_conn[h].fragment_buffer = malloc(BSC_RX_BUFFER_LEN); bws_cli_conn[h].fragment_buffer = malloc(BSC_RX_BUFFER_LEN);
if (!bws_cli_conn[h].fragment_buffer) { if (!bws_cli_conn[h].fragment_buffer) {
lws_close_reason( lws_close_reason(
wsi, LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE, NULL, 0); wsi, LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE, NULL, 0);
pthread_mutex_unlock(&bws_cli_mutex); pthread_mutex_unlock(&bws_cli_mutex);
DEBUG_PRINTF("bws_cli_websocket_event() <<< ret = -1, " DEBUG_PRINTF(
"allocation of %d bytes failed\n", "bws_cli_websocket_event() <<< ret = -1, "
"allocation of %d bytes failed\n",
len <= BSC_RX_BUFFER_LEN ? BSC_RX_BUFFER_LEN : len); len <= BSC_RX_BUFFER_LEN ? BSC_RX_BUFFER_LEN : len);
return -1; return -1;
} }
@@ -303,26 +308,29 @@ static int bws_cli_websocket_event(struct lws *wsi,
"for socket %d to %d bytes\n", "for socket %d to %d bytes\n",
bws_cli_conn[h].fragment_buffer_len, h, bws_cli_conn[h].fragment_buffer_len, h,
bws_cli_conn[h].fragment_buffer_len + len); bws_cli_conn[h].fragment_buffer_len + len);
bws_cli_conn[h].fragment_buffer = bws_cli_conn[h].fragment_buffer = realloc(
realloc(bws_cli_conn[h].fragment_buffer, bws_cli_conn[h].fragment_buffer,
bws_cli_conn[h].fragment_buffer_len + len); bws_cli_conn[h].fragment_buffer_len + len);
if (!bws_cli_conn[h].fragment_buffer) { if (!bws_cli_conn[h].fragment_buffer) {
lws_close_reason( lws_close_reason(
wsi, LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE, NULL, 0); wsi, LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE, NULL, 0);
pthread_mutex_unlock(&bws_cli_mutex); pthread_mutex_unlock(&bws_cli_mutex);
DEBUG_PRINTF("bws_cli_websocket_event() <<< ret = -1, " DEBUG_PRINTF(
"re-allocation of %d bytes failed\n", "bws_cli_websocket_event() <<< ret = -1, "
"re-allocation of %d bytes failed\n",
bws_cli_conn[h].fragment_buffer_len + len); bws_cli_conn[h].fragment_buffer_len + len);
return -1; return -1;
} }
bws_cli_conn[h].fragment_buffer_size = bws_cli_conn[h].fragment_buffer_size =
bws_cli_conn[h].fragment_buffer_len + len; bws_cli_conn[h].fragment_buffer_len + len;
} }
DEBUG_PRINTF("bws_cli_websocket_event() got next %d bytes for " DEBUG_PRINTF(
"socket %d\n", "bws_cli_websocket_event() got next %d bytes for "
"socket %d\n",
len, h); len, h);
memcpy(&bws_cli_conn[h].fragment_buffer[ memcpy(
bws_cli_conn[h].fragment_buffer_len], &bws_cli_conn[h]
.fragment_buffer[bws_cli_conn[h].fragment_buffer_len],
in, len); in, len);
bws_cli_conn[h].fragment_buffer_len += len; bws_cli_conn[h].fragment_buffer_len += len;
@@ -332,7 +340,8 @@ static int bws_cli_websocket_event(struct lws *wsi,
dispatch_func = bws_cli_conn[h].dispatch_func; dispatch_func = bws_cli_conn[h].dispatch_func;
user_param = bws_cli_conn[h].user_param; user_param = bws_cli_conn[h].user_param;
pthread_mutex_unlock(&bws_cli_mutex); pthread_mutex_unlock(&bws_cli_mutex);
dispatch_func(h, BSC_WEBSOCKET_RECEIVED, 0, NULL, dispatch_func(
h, BSC_WEBSOCKET_RECEIVED, 0, NULL,
bws_cli_conn[h].fragment_buffer, bws_cli_conn[h].fragment_buffer,
bws_cli_conn[h].fragment_buffer_len, user_param); bws_cli_conn[h].fragment_buffer_len, user_param);
pthread_mutex_lock(&bws_cli_mutex); pthread_mutex_lock(&bws_cli_mutex);
@@ -358,9 +367,11 @@ static int bws_cli_websocket_event(struct lws *wsi,
return 0; return 0;
} }
DEBUG_PRINTF("bws_cli_websocket_event() can write, state = %d\n", DEBUG_PRINTF(
"bws_cli_websocket_event() can write, state = %d\n",
bws_cli_conn[h].state); bws_cli_conn[h].state);
DEBUG_PRINTF("bws_cli_websocket_event() ws = %d, cs = %d\n", DEBUG_PRINTF(
"bws_cli_websocket_event() ws = %d, cs = %d\n",
bws_cli_conn[h].want_send_data, bws_cli_conn[h].can_send_data); bws_cli_conn[h].want_send_data, bws_cli_conn[h].can_send_data);
if (bws_cli_conn[h].state == BSC_WEBSOCKET_STATE_CONNECTED && if (bws_cli_conn[h].state == BSC_WEBSOCKET_STATE_CONNECTED &&
bws_cli_conn[h].want_send_data) { bws_cli_conn[h].want_send_data) {
@@ -450,9 +461,9 @@ static void *bws_cli_worker(void *arg)
DEBUG_PRINTF("bws_cli_worker() process disconnecting event\n"); DEBUG_PRINTF("bws_cli_worker() process disconnecting event\n");
DEBUG_PRINTF("bws_cli_worker() destroy ctx %p\n", conn->ctx); DEBUG_PRINTF("bws_cli_worker() destroy ctx %p\n", conn->ctx);
/* TRICKY: Libwebsockets API is not designed to be used from /* TRICKY: Libwebsockets API is not designed to be used from
multipe service threads, as a result lws_context_destroy() multipe service threads, as a result
is not thread safe. More over, on different platforms the lws_context_destroy() is not thread safe. More over, on different
function behaves in different ways. Call of platforms the function behaves in different ways. Call of
lws_context_destroy() leads to several calls of lws_context_destroy() leads to several calls of
bws_cli_websocket_event() callback (LWS_CALLBACK_CLOSED, bws_cli_websocket_event() callback (LWS_CALLBACK_CLOSED,
etc..). But under some OS (MacOSx) that callback is etc..). But under some OS (MacOSx) that callback is
@@ -478,7 +489,8 @@ static void *bws_cli_worker(void *arg)
bws_cli_free_connection(h); bws_cli_free_connection(h);
pthread_mutex_unlock(&bws_cli_mutex); pthread_mutex_unlock(&bws_cli_mutex);
DEBUG_PRINTF("bws_cli_worker() unlock mutex\n"); DEBUG_PRINTF("bws_cli_worker() unlock mutex\n");
dispatch_func(h, BSC_WEBSOCKET_DISCONNECTED, err_code, dispatch_func(
h, BSC_WEBSOCKET_DISCONNECTED, err_code,
err_code != ERROR_CODE_SUCCESS ? err_desc : NULL, NULL, 0, err_code != ERROR_CODE_SUCCESS ? err_desc : NULL, NULL, 0,
user_param); user_param);
return NULL; return NULL;
@@ -492,7 +504,8 @@ static void *bws_cli_worker(void *arg)
return NULL; return NULL;
} }
BSC_WEBSOCKET_RET bws_cli_connect(BSC_WEBSOCKET_PROTOCOL proto, BSC_WEBSOCKET_RET bws_cli_connect(
BSC_WEBSOCKET_PROTOCOL proto,
char *url, char *url,
uint8_t *ca_cert, uint8_t *ca_cert,
size_t ca_cert_size, size_t ca_cert_size,
@@ -541,8 +554,8 @@ BSC_WEBSOCKET_RET bws_cli_connect(BSC_WEBSOCKET_PROTOCOL proto,
bsc_websocket_init_log(); bsc_websocket_init_log();
pthread_mutex_lock(&bws_cli_mutex); pthread_mutex_lock(&bws_cli_mutex);
if (lws_parse_uri(tmp_url, &prot, &addr, &port, &path) != 0 || if (lws_parse_uri(tmp_url, &prot, &addr, &port, &path) != 0 || port == -1 ||
port == -1 || !prot || !addr || !path) { !prot || !addr || !path) {
pthread_mutex_unlock(&bws_cli_mutex); pthread_mutex_unlock(&bws_cli_mutex);
DEBUG_PRINTF("bws_cli_connect() <<< ret = BSC_WEBSOCKET_BAD_PARAM\n"); DEBUG_PRINTF("bws_cli_connect() <<< ret = BSC_WEBSOCKET_BAD_PARAM\n");
return BSC_WEBSOCKET_BAD_PARAM; return BSC_WEBSOCKET_BAD_PARAM;
@@ -633,15 +646,16 @@ BSC_WEBSOCKET_RET bws_cli_connect(BSC_WEBSOCKET_PROTOCOL proto,
bsc_websocket_global_unlock(); bsc_websocket_global_unlock();
r = pthread_attr_init(&attr); r = pthread_attr_init(&attr);
if(!r) { if (!r) {
r = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); r = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
} }
if(!r) { if (!r) {
r = pthread_create(&thread_id, &attr, &bws_cli_worker, &bws_cli_conn[h]); r = pthread_create(
&thread_id, &attr, &bws_cli_worker, &bws_cli_conn[h]);
} }
if(r) { if (r) {
/* TRICKY: Libwebsockets API is not designed to be used from /* TRICKY: Libwebsockets API is not designed to be used from
multipe service threads, as a result lws_context_destroy() multipe service threads, as a result lws_context_destroy()
is not thread safe. More over, on different platforms the is not thread safe. More over, on different platforms the
@@ -679,7 +693,8 @@ void bws_cli_disconnect(BSC_WEBSOCKET_HANDLE h)
if (h >= 0 && h < BSC_CLIENT_WEBSOCKETS_MAX_NUM) { if (h >= 0 && h < BSC_CLIENT_WEBSOCKETS_MAX_NUM) {
pthread_mutex_lock(&bws_cli_mutex); pthread_mutex_lock(&bws_cli_mutex);
DEBUG_PRINTF("bws_cli_disconnect() state = %d\n", bws_cli_conn[h].state); DEBUG_PRINTF(
"bws_cli_disconnect() state = %d\n", bws_cli_conn[h].state);
if (bws_cli_conn[h].state == BSC_WEBSOCKET_STATE_CONNECTING || if (bws_cli_conn[h].state == BSC_WEBSOCKET_STATE_CONNECTING ||
bws_cli_conn[h].state == BSC_WEBSOCKET_STATE_CONNECTED) { bws_cli_conn[h].state == BSC_WEBSOCKET_STATE_CONNECTED) {
/* tell worker to process change of connection state */ /* tell worker to process change of connection state */
@@ -732,7 +747,8 @@ BSC_WEBSOCKET_RET bws_cli_dispatch_send(
if ((bws_cli_conn[h].state != BSC_WEBSOCKET_STATE_CONNECTED) || if ((bws_cli_conn[h].state != BSC_WEBSOCKET_STATE_CONNECTED) ||
!bws_cli_conn[h].want_send_data || !bws_cli_conn[h].can_send_data) { !bws_cli_conn[h].want_send_data || !bws_cli_conn[h].can_send_data) {
DEBUG_PRINTF("bws_cli_dispatch_send() state = %d, ws = %d, cs = %d\n", DEBUG_PRINTF(
"bws_cli_dispatch_send() state = %d, ws = %d, cs = %d\n",
bws_cli_conn[h].state, bws_cli_conn[h].want_send_data, bws_cli_conn[h].state, bws_cli_conn[h].want_send_data,
bws_cli_conn[h].can_send_data); bws_cli_conn[h].can_send_data);
DEBUG_PRINTF("bws_cli_dispatch_send() <<< ret = " DEBUG_PRINTF("bws_cli_dispatch_send() <<< ret = "
+57 -39
View File
@@ -14,72 +14,89 @@
#include "bacnet/basic/sys/debug.h" #include "bacnet/basic/sys/debug.h"
static pthread_mutex_t websocket_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; static pthread_mutex_t websocket_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
static pthread_mutex_t websocket_dispatch_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; static pthread_mutex_t websocket_dispatch_mutex =
PTHREAD_RECURSIVE_MUTEX_INITIALIZER;
#if (BSC_DEBUG_WEBSOCKET_MUTEX_ENABLED != 1) #if (BSC_DEBUG_WEBSOCKET_MUTEX_ENABLED != 1)
void bsc_websocket_global_lock(void) void bsc_websocket_global_lock(void)
{ {
pthread_mutex_lock(&websocket_mutex); pthread_mutex_lock(&websocket_mutex);
} }
void bsc_websocket_global_unlock(void) void bsc_websocket_global_unlock(void)
{ {
pthread_mutex_unlock(&websocket_mutex); pthread_mutex_unlock(&websocket_mutex);
} }
void bws_dispatch_lock(void) void bws_dispatch_lock(void)
{ {
pthread_mutex_lock(&websocket_dispatch_mutex); pthread_mutex_lock(&websocket_dispatch_mutex);
} }
void bws_dispatch_unlock(void) void bws_dispatch_unlock(void)
{ {
pthread_mutex_unlock(&websocket_dispatch_mutex); pthread_mutex_unlock(&websocket_dispatch_mutex);
} }
#else #else
static int volatile websocket_mutex_cnt = 0; static volatile int websocket_mutex_cnt = 0;
static int volatile websocket_dispatch_mutex_cnt = 0; static volatile int websocket_dispatch_mutex_cnt = 0;
void bsc_websocket_global_lock_dbg(char *f, int line) void bsc_websocket_global_lock_dbg(char *f, int line)
{ {
printf("bsc_websocket_global_lock_dbg() >>> %s:%d lock_cnt %d tid = %ld\n", f, line, websocket_mutex_cnt, pthread_self()); printf(
websocket_mutex_cnt++; "bsc_websocket_global_lock_dbg() >>> %s:%d lock_cnt %d tid = %ld\n", f,
fflush(stdout); line, websocket_mutex_cnt, pthread_self());
pthread_mutex_lock(&websocket_mutex); websocket_mutex_cnt++;
printf("bsc_websocket_global_lock_dbg() <<< lock_cnt %d tid = %ld\n", websocket_mutex_cnt, pthread_self()); fflush(stdout);
fflush(stdout); pthread_mutex_lock(&websocket_mutex);
printf(
"bsc_websocket_global_lock_dbg() <<< lock_cnt %d tid = %ld\n",
websocket_mutex_cnt, pthread_self());
fflush(stdout);
} }
void bsc_websocket_global_unlock_dbg(char *f, int line) void bsc_websocket_global_unlock_dbg(char *f, int line)
{ {
printf("bsc_websocket_global_unlock_dbg() >>> %s:%d lock_cnt %d tid = %ld\n", f, line, websocket_mutex_cnt, pthread_self()); printf(
websocket_mutex_cnt--; "bsc_websocket_global_unlock_dbg() >>> %s:%d lock_cnt %d tid = %ld\n",
fflush(stdout); f, line, websocket_mutex_cnt, pthread_self());
pthread_mutex_unlock(&websocket_mutex); websocket_mutex_cnt--;
printf("bsc_websocket_global_unlock_dbg() <<< lock_cnt %d tid = %ld\n", websocket_mutex_cnt, pthread_self()); fflush(stdout);
fflush(stdout); pthread_mutex_unlock(&websocket_mutex);
printf(
"bsc_websocket_global_unlock_dbg() <<< lock_cnt %d tid = %ld\n",
websocket_mutex_cnt, pthread_self());
fflush(stdout);
} }
void bws_dispatch_lock_dbg(char *f, int line) void bws_dispatch_lock_dbg(char *f, int line)
{ {
printf("bws_dispatch_lock_dbg() >>> %s:%d lock_cnt %d tid = %ld\n", f, line, websocket_dispatch_mutex_cnt, pthread_self()); printf(
websocket_dispatch_mutex_cnt++; "bws_dispatch_lock_dbg() >>> %s:%d lock_cnt %d tid = %ld\n", f, line,
fflush(stdout); websocket_dispatch_mutex_cnt, pthread_self());
pthread_mutex_lock(&websocket_dispatch_mutex); websocket_dispatch_mutex_cnt++;
printf("bws_dispatch_lock_dbg() <<< lock_cnt %d tid = %ld\n", websocket_dispatch_mutex_cnt, pthread_self()); fflush(stdout);
fflush(stdout); pthread_mutex_lock(&websocket_dispatch_mutex);
printf(
"bws_dispatch_lock_dbg() <<< lock_cnt %d tid = %ld\n",
websocket_dispatch_mutex_cnt, pthread_self());
fflush(stdout);
} }
void bws_dispatch_unlock_dbg(char *f, int line) void bws_dispatch_unlock_dbg(char *f, int line)
{ {
printf("bws_dispatch_unlock_dbg() >>> %s:%d lock_cnt %d tid = %ld\n", f, line, websocket_dispatch_mutex_cnt, pthread_self()); printf(
websocket_dispatch_mutex_cnt--; "bws_dispatch_unlock_dbg() >>> %s:%d lock_cnt %d tid = %ld\n", f, line,
fflush(stdout); websocket_dispatch_mutex_cnt, pthread_self());
pthread_mutex_unlock(&websocket_dispatch_mutex); websocket_dispatch_mutex_cnt--;
printf("bws_dispatch_unlock_dbg() <<< lock_cnt %d tid = %ld\n", websocket_dispatch_mutex_cnt, pthread_self()); fflush(stdout);
fflush(stdout); pthread_mutex_unlock(&websocket_dispatch_mutex);
printf(
"bws_dispatch_unlock_dbg() <<< lock_cnt %d tid = %ld\n",
websocket_dispatch_mutex_cnt, pthread_self());
fflush(stdout);
} }
#endif #endif
@@ -89,16 +106,17 @@ static bool bsc_websocket_log_initialized = false;
void bsc_websocket_init_log(void) void bsc_websocket_init_log(void)
{ {
bsc_websocket_global_lock(); bsc_websocket_global_lock();
if(!bsc_websocket_log_initialized) { if (!bsc_websocket_log_initialized) {
bsc_websocket_log_initialized = true; bsc_websocket_log_initialized = true;
#if DEBUG_LIBWEBSOCKETS_ENABLED == 1 #if DEBUG_LIBWEBSOCKETS_ENABLED == 1
printf("LWS_MAX_SMP = %d", LWS_MAX_SMP); printf("LWS_MAX_SMP = %d", LWS_MAX_SMP);
lws_set_log_level(LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_INFO | LLL_DEBUG | lws_set_log_level(
LLL_PARSER | LLL_HEADER | LLL_EXT | LLL_CLIENT | LLL_LATENCY | LLL_ERR | LLL_WARN | LLL_NOTICE | LLL_INFO | LLL_DEBUG |
LLL_USER | LLL_THREAD, LLL_PARSER | LLL_HEADER | LLL_EXT | LLL_CLIENT | LLL_LATENCY |
NULL); LLL_USER | LLL_THREAD,
NULL);
#else #else
lws_set_log_level(0, NULL); lws_set_log_level(0, NULL);
#endif #endif
} }
bsc_websocket_global_unlock(); bsc_websocket_global_unlock();
+4 -2
View File
@@ -18,8 +18,10 @@ void bsc_websocket_global_unlock(void);
#else #else
void bsc_websocket_global_lock_dbg(char *f, int line); void bsc_websocket_global_lock_dbg(char *f, int line);
void bsc_websocket_global_unlock_dbg(char *f, int line); void bsc_websocket_global_unlock_dbg(char *f, int line);
#define bsc_websocket_global_lock() bsc_websocket_global_lock_dbg(__FILE__, __LINE__); #define bsc_websocket_global_lock() \
#define bsc_websocket_global_unlock() bsc_websocket_global_unlock_dbg(__FILE__, __LINE__); bsc_websocket_global_lock_dbg(__FILE__, __LINE__);
#define bsc_websocket_global_unlock() \
bsc_websocket_global_unlock_dbg(__FILE__, __LINE__);
#endif #endif
void bsc_websocket_init_log(void); void bsc_websocket_init_log(void);
+99 -72
View File
@@ -42,7 +42,8 @@ typedef enum {
/* Some forward function declarations */ /* Some forward function declarations */
static int bws_srv_websocket_event(struct lws *wsi, static int bws_srv_websocket_event(
struct lws *wsi,
enum lws_callback_reasons reason, enum lws_callback_reasons reason,
void *user, void *user,
void *in, void *in,
@@ -289,8 +290,8 @@ static BSC_WEBSOCKET_HANDLE bws_srv_alloc_connection(BSC_WEBSOCKET_CONTEXT *ctx)
return BSC_WEBSOCKET_INVALID_HANDLE; return BSC_WEBSOCKET_INVALID_HANDLE;
} }
static void bws_srv_free_connection( static void
BSC_WEBSOCKET_CONTEXT *ctx, BSC_WEBSOCKET_HANDLE h) bws_srv_free_connection(BSC_WEBSOCKET_CONTEXT *ctx, BSC_WEBSOCKET_HANDLE h)
{ {
DEBUG_PRINTF("bws_srv_free_connection() >>> ctx = %p, h = %d\n", ctx, h); DEBUG_PRINTF("bws_srv_free_connection() >>> ctx = %p, h = %d\n", ctx, h);
@@ -309,8 +310,8 @@ static void bws_srv_free_connection(
DEBUG_PRINTF("bws_srv_free_connection() <<<\n"); DEBUG_PRINTF("bws_srv_free_connection() <<<\n");
} }
static BSC_WEBSOCKET_HANDLE bws_find_connnection( static BSC_WEBSOCKET_HANDLE
BSC_WEBSOCKET_CONTEXT *ctx, struct lws *ws) bws_find_connnection(BSC_WEBSOCKET_CONTEXT *ctx, struct lws *ws)
{ {
int i; int i;
for (i = 0; i < bws_srv_get_max_sockets(ctx->proto); i++) { for (i = 0; i < bws_srv_get_max_sockets(ctx->proto); i++) {
@@ -322,7 +323,8 @@ static BSC_WEBSOCKET_HANDLE bws_find_connnection(
return BSC_WEBSOCKET_INVALID_HANDLE; return BSC_WEBSOCKET_INVALID_HANDLE;
} }
static int bws_srv_websocket_event(struct lws *wsi, static int bws_srv_websocket_event(
struct lws *wsi,
enum lws_callback_reasons reason, enum lws_callback_reasons reason,
void *user, void *user,
void *in, void *in,
@@ -339,9 +341,10 @@ static int bws_srv_websocket_event(struct lws *wsi,
uint16_t err; uint16_t err;
(void)user; (void)user;
DEBUG_PRINTF("bws_srv_websocket_event() >>> ctx = %p, user_param = %p, " DEBUG_PRINTF(
"proto = %d, wsi = %p, " "bws_srv_websocket_event() >>> ctx = %p, user_param = %p, "
"reason = %d, in = %p, len = %d\n", "proto = %d, wsi = %p, "
"reason = %d, in = %p, len = %d\n",
ctx, ctx->user_param, ctx->proto, wsi, reason, in, len); ctx, ctx->user_param, ctx->proto, wsi, reason, in, len);
switch (reason) { switch (reason) {
@@ -365,8 +368,9 @@ static int bws_srv_websocket_event(struct lws *wsi,
dispatch_func = ctx->dispatch_func; dispatch_func = ctx->dispatch_func;
user_param = ctx->user_param; user_param = ctx->user_param;
pthread_mutex_unlock(ctx->mutex); pthread_mutex_unlock(ctx->mutex);
dispatch_func((BSC_WEBSOCKET_SRV_HANDLE)ctx, h, dispatch_func(
BSC_WEBSOCKET_CONNECTED, 0, NULL, NULL, 0, user_param); (BSC_WEBSOCKET_SRV_HANDLE)ctx, h, BSC_WEBSOCKET_CONNECTED, 0,
NULL, NULL, 0, user_param);
/* wakeup worker to process pending event */ /* wakeup worker to process pending event */
lws_cancel_service(ctx->wsctx); lws_cancel_service(ctx->wsctx);
break; break;
@@ -378,9 +382,10 @@ static int bws_srv_websocket_event(struct lws *wsi,
if (h == BSC_WEBSOCKET_INVALID_HANDLE) { if (h == BSC_WEBSOCKET_INVALID_HANDLE) {
pthread_mutex_unlock(ctx->mutex); pthread_mutex_unlock(ctx->mutex);
} else { } else {
DEBUG_PRINTF("bws_srv_websocket_event() ctx %p user_param = %p " DEBUG_PRINTF(
"proto %d state of " "bws_srv_websocket_event() ctx %p user_param = %p "
"socket %d is %d\n", "proto %d state of "
"socket %d is %d\n",
ctx, ctx->user_param, ctx->proto, h, ctx->conn[h].state); ctx, ctx->user_param, ctx->proto, h, ctx->conn[h].state);
dispatch_func = ctx->dispatch_func; dispatch_func = ctx->dispatch_func;
user_param = ctx->user_param; user_param = ctx->user_param;
@@ -389,7 +394,8 @@ static int bws_srv_websocket_event(struct lws *wsi,
bws_srv_free_connection(ctx, h); bws_srv_free_connection(ctx, h);
pthread_mutex_unlock(ctx->mutex); pthread_mutex_unlock(ctx->mutex);
if (!stop_worker) { if (!stop_worker) {
dispatch_func((BSC_WEBSOCKET_SRV_HANDLE)ctx, h, dispatch_func(
(BSC_WEBSOCKET_SRV_HANDLE)ctx, h,
BSC_WEBSOCKET_DISCONNECTED, err, NULL, NULL, 0, BSC_WEBSOCKET_DISCONNECTED, err, NULL, NULL, 0,
user_param); user_param);
} }
@@ -413,9 +419,10 @@ static int bws_srv_websocket_event(struct lws *wsi,
if (h == BSC_WEBSOCKET_INVALID_HANDLE) { if (h == BSC_WEBSOCKET_INVALID_HANDLE) {
pthread_mutex_unlock(ctx->mutex); pthread_mutex_unlock(ctx->mutex);
} else { } else {
DEBUG_PRINTF("bws_srv_websocket_event() ctx %p proto %d " DEBUG_PRINTF(
"received %d bytes of " "bws_srv_websocket_event() ctx %p proto %d "
"data for websocket %d\n", "received %d bytes of "
"data for websocket %d\n",
ctx, ctx->proto, len, h); ctx, ctx->proto, len, h);
if (!lws_frame_is_binary(wsi)) { if (!lws_frame_is_binary(wsi)) {
/* According AB.7.5.3 BACnet/SC BVLC Message Exchange, /* According AB.7.5.3 BACnet/SC BVLC Message Exchange,
@@ -441,11 +448,13 @@ static int bws_srv_websocket_event(struct lws *wsi,
ctx->conn[h].fragment_buffer = ctx->conn[h].fragment_buffer =
malloc(BSC_RX_BUFFER_LEN); malloc(BSC_RX_BUFFER_LEN);
if (!ctx->conn[h].fragment_buffer) { if (!ctx->conn[h].fragment_buffer) {
lws_close_reason(wsi, lws_close_reason(
LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE, NULL, 0); wsi, LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE, NULL,
0);
pthread_mutex_unlock(ctx->mutex); pthread_mutex_unlock(ctx->mutex);
DEBUG_PRINTF("bws_srv_websocket_event() <<< ret = " DEBUG_PRINTF(
"-1, allocation of %d bytes failed\n", "bws_srv_websocket_event() <<< ret = "
"-1, allocation of %d bytes failed\n",
len <= BSC_RX_BUFFER_LEN ? BSC_RX_BUFFER_LEN len <= BSC_RX_BUFFER_LEN ? BSC_RX_BUFFER_LEN
: len); : len);
return -1; return -1;
@@ -461,12 +470,13 @@ static int bws_srv_websocket_event(struct lws *wsi,
ctx->conn[h].fragment_buffer_len, h, ctx->conn[h].fragment_buffer_len, h,
ctx->conn[h].fragment_buffer_len + len); ctx->conn[h].fragment_buffer_len + len);
ctx->conn[h].fragment_buffer = ctx->conn[h].fragment_buffer = realloc(
realloc(ctx->conn[h].fragment_buffer, ctx->conn[h].fragment_buffer,
ctx->conn[h].fragment_buffer_len + len); ctx->conn[h].fragment_buffer_len + len);
if (!ctx->conn[h].fragment_buffer) { if (!ctx->conn[h].fragment_buffer) {
lws_close_reason(wsi, lws_close_reason(
LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE, NULL, 0); wsi, LWS_CLOSE_STATUS_MESSAGE_TOO_LARGE, NULL,
0);
pthread_mutex_unlock(ctx->mutex); pthread_mutex_unlock(ctx->mutex);
DEBUG_PRINTF( DEBUG_PRINTF(
"bws_srv_websocket_event() <<< ret = -1, " "bws_srv_websocket_event() <<< ret = -1, "
@@ -481,15 +491,17 @@ static int bws_srv_websocket_event(struct lws *wsi,
"bws_srv_websocket_event() got next %d bytes for " "bws_srv_websocket_event() got next %d bytes for "
"socket %d total_len %d\n", "socket %d total_len %d\n",
len, h, ctx->conn[h].fragment_buffer_len); len, h, ctx->conn[h].fragment_buffer_len);
memcpy(&ctx->conn[h].fragment_buffer[ memcpy(
ctx->conn[h].fragment_buffer_len], &ctx->conn[h]
.fragment_buffer[ctx->conn[h].fragment_buffer_len],
in, len); in, len);
ctx->conn[h].fragment_buffer_len += len; ctx->conn[h].fragment_buffer_len += len;
if (lws_is_final_fragment(wsi) && !ctx->stop_worker) { if (lws_is_final_fragment(wsi) && !ctx->stop_worker) {
dispatch_func = ctx->dispatch_func; dispatch_func = ctx->dispatch_func;
user_param = ctx->user_param; user_param = ctx->user_param;
pthread_mutex_unlock(ctx->mutex); pthread_mutex_unlock(ctx->mutex);
dispatch_func((BSC_WEBSOCKET_SRV_HANDLE)ctx, h, dispatch_func(
(BSC_WEBSOCKET_SRV_HANDLE)ctx, h,
BSC_WEBSOCKET_RECEIVED, 0, NULL, BSC_WEBSOCKET_RECEIVED, 0, NULL,
ctx->conn[h].fragment_buffer, ctx->conn[h].fragment_buffer,
ctx->conn[h].fragment_buffer_len, user_param); ctx->conn[h].fragment_buffer_len, user_param);
@@ -512,8 +524,9 @@ static int bws_srv_websocket_event(struct lws *wsi,
if (h == BSC_WEBSOCKET_INVALID_HANDLE) { if (h == BSC_WEBSOCKET_INVALID_HANDLE) {
pthread_mutex_unlock(ctx->mutex); pthread_mutex_unlock(ctx->mutex);
} else { } else {
DEBUG_PRINTF("bws_srv_websocket_event() ctx %p proto %d socket " DEBUG_PRINTF(
"%d state = %d\n", "bws_srv_websocket_event() ctx %p proto %d socket "
"%d state = %d\n",
ctx, ctx->proto, h, ctx->conn[h].state); ctx, ctx->proto, h, ctx->conn[h].state);
if (ctx->conn[h].state == BSC_WEBSOCKET_STATE_DISCONNECTING) { if (ctx->conn[h].state == BSC_WEBSOCKET_STATE_DISCONNECTING) {
@@ -530,7 +543,8 @@ static int bws_srv_websocket_event(struct lws *wsi,
stop_worker = ctx->stop_worker; stop_worker = ctx->stop_worker;
pthread_mutex_unlock(ctx->mutex); pthread_mutex_unlock(ctx->mutex);
if (!stop_worker) { if (!stop_worker) {
dispatch_func((BSC_WEBSOCKET_SRV_HANDLE)ctx, h, dispatch_func(
(BSC_WEBSOCKET_SRV_HANDLE)ctx, h,
BSC_WEBSOCKET_SENDABLE, 0, NULL, NULL, 0, BSC_WEBSOCKET_SENDABLE, 0, NULL, NULL, 0,
user_param); user_param);
} }
@@ -562,33 +576,38 @@ static void *bws_srv_worker(void *arg)
BSC_WEBSOCKET_SRV_DISPATCH dispatch_func; BSC_WEBSOCKET_SRV_DISPATCH dispatch_func;
void *user_param; void *user_param;
DEBUG_PRINTF("bws_srv_worker() started for ctx %p proto %d user_param %p\n", DEBUG_PRINTF(
ctx, ctx->proto, ctx->user_param); "bws_srv_worker() started for ctx %p proto %d user_param %p\n", ctx,
ctx->proto, ctx->user_param);
pthread_mutex_lock(ctx->mutex); pthread_mutex_lock(ctx->mutex);
dispatch_func = ctx->dispatch_func; dispatch_func = ctx->dispatch_func;
user_param = ctx->user_param; user_param = ctx->user_param;
pthread_mutex_unlock(ctx->mutex); pthread_mutex_unlock(ctx->mutex);
dispatch_func((BSC_WEBSOCKET_SRV_HANDLE)ctx, 0, dispatch_func(
BSC_WEBSOCKET_SERVER_STARTED, 0, NULL, NULL, 0, user_param); (BSC_WEBSOCKET_SRV_HANDLE)ctx, 0, BSC_WEBSOCKET_SERVER_STARTED, 0, NULL,
NULL, 0, user_param);
while (1) { while (1) {
DEBUG_PRINTF("bws_srv_worker() ctx %p proto %d blocked user_param %p\n", DEBUG_PRINTF(
ctx, ctx->proto, ctx->user_param); "bws_srv_worker() ctx %p proto %d blocked user_param %p\n", ctx,
ctx->proto, ctx->user_param);
pthread_mutex_lock(ctx->mutex); pthread_mutex_lock(ctx->mutex);
if (ctx->stop_worker) { if (ctx->stop_worker) {
DEBUG_PRINTF("bws_srv_worker() ctx %p user_param %p proto %d going " DEBUG_PRINTF(
"to stop\n", "bws_srv_worker() ctx %p user_param %p proto %d going "
"to stop\n",
ctx, ctx->user_param, ctx->proto); ctx, ctx->user_param, ctx->proto);
DEBUG_PRINTF("bws_srv_worker() destroy wsctx %p, ctx = %p, " DEBUG_PRINTF(
"user_param = %p\n", "bws_srv_worker() destroy wsctx %p, ctx = %p, "
"user_param = %p\n",
ctx->wsctx, ctx, ctx->user_param); ctx->wsctx, ctx, ctx->user_param);
/* TRICKY: Libwebsockets API is not designed to be used from /* TRICKY: Libwebsockets API is not designed to be used from
multipe service threads, as a result lws_context_destroy() multipe service threads, as a result
is not thread safe. More over, on different platforms the lws_context_destroy() is not thread safe. More over, on different
function behaves in different ways. Call of platforms the function behaves in different ways. Call of
lws_context_destroy() leads to several calls of lws_context_destroy() leads to several calls of
bws_srv_websocket_event() callback (LWS_CALLBACK_CLOSED, bws_srv_websocket_event() callback (LWS_CALLBACK_CLOSED,
etc..). But under some OS (MacOSx) that callback is etc..). But under some OS (MacOSx) that callback is
@@ -616,8 +635,9 @@ static void *bws_srv_worker(void *arg)
DEBUG_PRINTF( DEBUG_PRINTF(
"bws_srv_worker() ctx %p user_param = %p\n", ctx, user_param); "bws_srv_worker() ctx %p user_param = %p\n", ctx, user_param);
pthread_mutex_unlock(ctx->mutex); pthread_mutex_unlock(ctx->mutex);
dispatch_func(ctx, 0, BSC_WEBSOCKET_SERVER_STOPPED, 0, NULL, NULL, dispatch_func(
0, user_param); ctx, 0, BSC_WEBSOCKET_SERVER_STOPPED, 0, NULL, NULL, 0,
user_param);
bws_free_server_ctx(ctx); bws_free_server_ctx(ctx);
DEBUG_PRINTF( DEBUG_PRINTF(
"bws_srv_worker() ctx %p proto %d stopped\n", ctx, ctx->proto); "bws_srv_worker() ctx %p proto %d stopped\n", ctx, ctx->proto);
@@ -625,21 +645,24 @@ static void *bws_srv_worker(void *arg)
} }
for (i = 0; i < bws_srv_get_max_sockets(ctx->proto); i++) { for (i = 0; i < bws_srv_get_max_sockets(ctx->proto); i++) {
DEBUG_PRINTF("bws_srv_worker() ctx %p user_param %p proto %d " DEBUG_PRINTF(
"socket %d(%p) state = %d\n", "bws_srv_worker() ctx %p user_param %p proto %d "
"socket %d(%p) state = %d\n",
ctx, ctx->user_param, ctx->proto, i, &ctx->conn[i], ctx, ctx->user_param, ctx->proto, i, &ctx->conn[i],
ctx->conn[i].state); ctx->conn[i].state);
if (ctx->conn[i].state == BSC_WEBSOCKET_STATE_CONNECTED) { if (ctx->conn[i].state == BSC_WEBSOCKET_STATE_CONNECTED) {
if (ctx->conn[i].want_send_data) { if (ctx->conn[i].want_send_data) {
DEBUG_PRINTF("bws_srv_worker() process request for sending " DEBUG_PRINTF(
"data on socket %d\n", "bws_srv_worker() process request for sending "
"data on socket %d\n",
i); i);
lws_callback_on_writable(ctx->conn[i].ws); lws_callback_on_writable(ctx->conn[i].ws);
} }
} else if (ctx->conn[i].state == } else if (
BSC_WEBSOCKET_STATE_DISCONNECTING) { ctx->conn[i].state == BSC_WEBSOCKET_STATE_DISCONNECTING) {
DEBUG_PRINTF("bws_srv_worker() process disconnecting event on " DEBUG_PRINTF(
"socket %d\n", "bws_srv_worker() process disconnecting event on "
"socket %d\n",
i); i);
lws_callback_on_writable(ctx->conn[i].ws); lws_callback_on_writable(ctx->conn[i].ws);
} }
@@ -659,7 +682,8 @@ static void *bws_srv_worker(void *arg)
return NULL; return NULL;
} }
BSC_WEBSOCKET_RET bws_srv_start(BSC_WEBSOCKET_PROTOCOL proto, BSC_WEBSOCKET_RET bws_srv_start(
BSC_WEBSOCKET_PROTOCOL proto,
int port, int port,
char *iface, char *iface,
uint8_t *ca_cert, uint8_t *ca_cert,
@@ -678,16 +702,16 @@ BSC_WEBSOCKET_RET bws_srv_start(BSC_WEBSOCKET_PROTOCOL proto,
BSC_WEBSOCKET_CONTEXT *ctx; BSC_WEBSOCKET_CONTEXT *ctx;
pthread_attr_t attr; pthread_attr_t attr;
int r; int r;
struct lws_protocols protos[] = { struct lws_protocols protos[] = { { (proto == BSC_WEBSOCKET_HUB_PROTOCOL)
{ (proto == BSC_WEBSOCKET_HUB_PROTOCOL) ? BSC_WEBSOCKET_HUB_PROTOCOL_STR
? BSC_WEBSOCKET_HUB_PROTOCOL_STR : BSC_WEBSOCKET_DIRECT_PROTOCOL_STR,
: BSC_WEBSOCKET_DIRECT_PROTOCOL_STR, bws_srv_websocket_event, 0, 0, 0, NULL,
bws_srv_websocket_event, 0, 0, 0, NULL, 0 }, 0 },
LWS_PROTOCOL_LIST_TERM LWS_PROTOCOL_LIST_TERM };
};
DEBUG_PRINTF("bws_srv_start() >>> proto = %d port = %d " DEBUG_PRINTF(
"dispatch_func_user_param = %p\n", "bws_srv_start() >>> proto = %d port = %d "
"dispatch_func_user_param = %p\n",
proto, port, dispatch_func_user_param); proto, port, dispatch_func_user_param);
if (proto != BSC_WEBSOCKET_HUB_PROTOCOL && if (proto != BSC_WEBSOCKET_HUB_PROTOCOL &&
@@ -758,11 +782,11 @@ BSC_WEBSOCKET_RET bws_srv_start(BSC_WEBSOCKET_PROTOCOL proto,
ctx->proto = proto; ctx->proto = proto;
r = pthread_attr_init(&attr); r = pthread_attr_init(&attr);
if(!r) { if (!r) {
r = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); r = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
} }
if(!r) { if (!r) {
r = pthread_create(&thread_id, &attr, &bws_srv_worker, ctx); r = pthread_create(&thread_id, &attr, &bws_srv_worker, ctx);
} }
@@ -882,7 +906,8 @@ void bws_srv_send(BSC_WEBSOCKET_SRV_HANDLE sh, BSC_WEBSOCKET_HANDLE h)
DEBUG_PRINTF("bws_srv_send() <<<\n"); DEBUG_PRINTF("bws_srv_send() <<<\n");
} }
BSC_WEBSOCKET_RET bws_srv_dispatch_send(BSC_WEBSOCKET_SRV_HANDLE sh, BSC_WEBSOCKET_RET bws_srv_dispatch_send(
BSC_WEBSOCKET_SRV_HANDLE sh,
BSC_WEBSOCKET_HANDLE h, BSC_WEBSOCKET_HANDLE h,
uint8_t *payload, uint8_t *payload,
size_t payload_size) size_t payload_size)
@@ -891,8 +916,9 @@ BSC_WEBSOCKET_RET bws_srv_dispatch_send(BSC_WEBSOCKET_SRV_HANDLE sh,
BSC_WEBSOCKET_RET ret; BSC_WEBSOCKET_RET ret;
BSC_WEBSOCKET_CONTEXT *ctx = (BSC_WEBSOCKET_CONTEXT *)sh; BSC_WEBSOCKET_CONTEXT *ctx = (BSC_WEBSOCKET_CONTEXT *)sh;
DEBUG_PRINTF("bws_srv_dispatch_send() >>> ctx = %p h = %d payload %p " DEBUG_PRINTF(
"payload_size %d\n", "bws_srv_dispatch_send() >>> ctx = %p h = %d payload %p "
"payload_size %d\n",
ctx, h, payload, payload_size); ctx, h, payload, payload_size);
#if DEBUG_ENABLED == 1 #if DEBUG_ENABLED == 1
@@ -951,7 +977,8 @@ BSC_WEBSOCKET_RET bws_srv_dispatch_send(BSC_WEBSOCKET_SRV_HANDLE sh,
return ret; return ret;
} }
bool bws_srv_get_peer_ip_addr(BSC_WEBSOCKET_SRV_HANDLE sh, bool bws_srv_get_peer_ip_addr(
BSC_WEBSOCKET_SRV_HANDLE sh,
BSC_WEBSOCKET_HANDLE h, BSC_WEBSOCKET_HANDLE h,
uint8_t *ip_str, uint8_t *ip_str,
size_t ip_str_len, size_t ip_str_len,