Format ports/bsd for standard style.
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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(
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -23,7 +23,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef TRUE
|
#ifndef TRUE
|
||||||
#define TRUE 1
|
#define TRUE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+51
-35
@@ -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 = "
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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
@@ -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,
|
||||||
|
|||||||
Reference in New Issue
Block a user