Feature/make pretty apps and ports (#80)

* Added pretty-apps and pretty-ports make targets

* pretty-fied apps folder C files

* Pretty-fied ports folder C and H files

Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2020-04-30 10:13:11 -05:00
committed by GitHub
parent 0abcbea971
commit fdd49f1791
152 changed files with 9668 additions and 11674 deletions
+50 -56
View File
@@ -50,7 +50,7 @@ static struct sockaddr ARCNET_Socket_Address;
#define ARCNET_BROADCAST 0
/*
Hints:
Hints:
When using a PCI20-485D ARCNET card from Contemporary Controls,
you might need to know about the following settings:
@@ -62,7 +62,7 @@ clockp Clock Prescaler DataRate
0 8 2.5 Mbps
1 16 1.25 Mbps
2 32 625 Kbps
3 64 312.5 Kbps
3 64 312.5 Kbps
4 128 156.25Kbps
1. Install the arcnet driver and arcnet raw mode driver:
@@ -76,20 +76,18 @@ clockp Clock Prescaler DataRate
on the back of the card. 0 is broadcast, so don't use 0.
4. The backplane mode on the PCI20-485D card is done in hardware,
so the driver does not need to do backplane mode. If you
use another type of PCI20 card, you could pass in backplane=1 or
so the driver does not need to do backplane mode. If you
use another type of PCI20 card, you could pass in backplane=1 or
backplane=0 as an option to the modprobe of com20020_pci.
*/
bool arcnet_valid(
void)
bool arcnet_valid(void)
{
return (ARCNET_Sock_FD >= 0);
}
void arcnet_cleanup(
void)
void arcnet_cleanup(void)
{
if (arcnet_valid())
close(ARCNET_Sock_FD);
@@ -98,12 +96,11 @@ void arcnet_cleanup(
return;
}
static int arcnet_bind(
char *interface_name)
static int arcnet_bind(char *interface_name)
{
int sock_fd = -1; /* return value */
int sock_fd = -1; /* return value */
struct ifreq ifr;
int rv; /* return value - error value from df or ioctl call */
int rv; /* return value - error value from df or ioctl call */
int uid = 0;
/* check to see if we are being run as root */
@@ -126,13 +123,15 @@ static int arcnet_bind(
"You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n" "Then follow it by:\n"
"Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n"
"# modprobe af_packet\n");
exit(-1);
}
if (ARCNET_Sock_FD >= 0) {
/* Bind the socket to an interface name so we only get packets from it */
/* Bind the socket to an interface name so we only get packets from it
*/
ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET;
/*ARCNET_Socket_Address.sa_family = PF_INET; */
/* Clear the memory before copying */
@@ -141,8 +140,8 @@ static int arcnet_bind(
/* Strcpy the interface name into the address */
strncpy(ARCNET_Socket_Address.sa_data, interface_name,
sizeof(ARCNET_Socket_Address.sa_data) - 1);
fprintf(stderr, "arcnet: binding \"%s\"\n",
ARCNET_Socket_Address.sa_data);
fprintf(
stderr, "arcnet: binding \"%s\"\n", ARCNET_Socket_Address.sa_data);
if (bind(sock_fd, &ARCNET_Socket_Address,
sizeof(ARCNET_Socket_Address)) != 0) {
/* Bind problem, close socket and return */
@@ -152,7 +151,8 @@ static int arcnet_bind(
"You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n" "Then follow it by:\n"
"Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n"
"# modprobe af_packet\n");
/* Close the socket */
close(sock_fd);
@@ -161,7 +161,7 @@ static int arcnet_bind(
}
strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name));
rv = ioctl(sock_fd, SIOCGIFHWADDR, &ifr);
if (rv != -1) /* worked okay */
if (rv != -1) /* worked okay */
ARCNET_MAC_Address = ifr.ifr_hwaddr.sa_data[0];
/* copy this info into the local copy since bind wiped it out */
ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET;
@@ -180,8 +180,7 @@ static int arcnet_bind(
return sock_fd;
}
bool arcnet_init(
char *interface_name)
bool arcnet_init(char *interface_name)
{
if (interface_name)
ARCNET_Sock_FD = arcnet_bind(interface_name);
@@ -193,19 +192,18 @@ bool arcnet_init(
/* function to send a PDU out the socket */
/* returns number of bytes sent on success, negative on failure */
int arcnet_send_pdu(
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
int arcnet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len)
{ /* number of bytes of data */
{ /* number of bytes of data */
BACNET_ADDRESS src = { 0 }; /* source address */
int bytes = 0;
uint8_t mtu[512] = { 0 };
int mtu_len = 0;
struct archdr *pkt = (struct archdr *) mtu;
struct archdr *pkt = (struct archdr *)mtu;
(void) npdu_data;
(void)npdu_data;
src.mac[0] = ARCNET_MAC_Address;
src.mac_len = 1;
@@ -228,21 +226,20 @@ int arcnet_send_pdu(
return -3;
}
/* Logical PDU portion */
pkt->soft.raw[0] = 0xCD; /* SC for BACnet */
pkt->soft.raw[1] = 0x82; /* DSAP for BACnet */
pkt->soft.raw[2] = 0x82; /* SSAP for BACnet */
pkt->soft.raw[3] = 0x03; /* LLC Control byte in header */
pkt->soft.raw[0] = 0xCD; /* SC for BACnet */
pkt->soft.raw[1] = 0x82; /* DSAP for BACnet */
pkt->soft.raw[2] = 0x82; /* SSAP for BACnet */
pkt->soft.raw[3] = 0x03; /* LLC Control byte in header */
/* packet length */
mtu_len = ARC_HDR_SIZE + 4 /*SC,DSAP,SSAP,LLC */ + pdu_len;
mtu_len = ARC_HDR_SIZE + 4 /*SC,DSAP,SSAP,LLC */ + pdu_len;
if (mtu_len > 512) {
fprintf(stderr, "arcnet: PDU is too big to send!\n");
return -4;
}
memcpy(&pkt->soft.raw[4], pdu, pdu_len);
/* Send the packet */
bytes =
sendto(ARCNET_Sock_FD, &mtu, mtu_len, 0,
(struct sockaddr *) &ARCNET_Socket_Address,
bytes = sendto(ARCNET_Sock_FD, &mtu, mtu_len, 0,
(struct sockaddr *)&ARCNET_Socket_Address,
sizeof(ARCNET_Socket_Address));
/* did it get sent? */
if (bytes < 0)
@@ -253,19 +250,18 @@ int arcnet_send_pdu(
/* receives an framed packet */
/* returns the number of octets in the PDU, or zero on failure */
uint16_t arcnet_receive(
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
uint16_t arcnet_receive(BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout)
{ /* milliseconds to wait for a packet */
{ /* milliseconds to wait for a packet */
int received_bytes;
uint8_t buf[512] = { 0 }; /* data */
uint16_t pdu_len = 0; /* return value */
uint8_t buf[512] = { 0 }; /* data */
uint16_t pdu_len = 0; /* return value */
fd_set read_fds;
int max;
struct timeval select_timeout;
struct archdr *pkt = (struct archdr *) buf;
struct archdr *pkt = (struct archdr *)buf;
/* Make sure the socket is open */
if (ARCNET_Sock_FD <= 0)
@@ -307,7 +303,7 @@ uint16_t arcnet_receive(
/* printf("arcnet: received %u bytes (offset=%02Xh %02Xh) "
"from %02Xh (proto==%02Xh)\n",
received_bytes, pkt->offset[0], pkt->offset[1],
received_bytes, pkt->offset[0], pkt->offset[1],
pkt->hard.source, pkt->soft.raw[0]);
*/
@@ -324,9 +320,9 @@ uint16_t arcnet_receive(
fprintf(stderr, "arcnet: This packet is not for us.\n");
return 0;
}
if ((pkt->soft.raw[1] != 0x82) || /* DSAP */
(pkt->soft.raw[2] != 0x82) || /* LSAP */
(pkt->soft.raw[3] != 0x03)) { /* LLC Control */
if ((pkt->soft.raw[1] != 0x82) || /* DSAP */
(pkt->soft.raw[2] != 0x82) || /* LSAP */
(pkt->soft.raw[3] != 0x03)) { /* LLC Control */
fprintf(stderr, "arcnet: BACnet packet has invalid LLC.\n");
return 0;
}
@@ -341,7 +337,7 @@ uint16_t arcnet_receive(
src->mac[0] = pkt->hard.source;
/* compute the PDU length */
pdu_len = received_bytes - ARC_HDR_SIZE;
pdu_len -= 4 /* SC, DSAP, SSAP, LLC Control */ ;
pdu_len -= 4 /* SC, DSAP, SSAP, LLC Control */;
/* copy the buffer into the PDU */
if (pdu_len < max_pdu)
memmove(&pdu[0], &pkt->soft.raw[4], pdu_len);
@@ -352,14 +348,13 @@ uint16_t arcnet_receive(
return pdu_len;
}
void arcnet_get_my_address(
BACNET_ADDRESS * my_address)
void arcnet_get_my_address(BACNET_ADDRESS *my_address)
{
int i = 0;
my_address->mac_len = 1;
my_address->mac[0] = ARCNET_MAC_Address;
my_address->net = 0; /* DNET=0 is local only, no routing */
my_address->net = 0; /* DNET=0 is local only, no routing */
my_address->len = 0;
for (i = 0; i < MAX_MAC_LEN; i++) {
my_address->adr[i] = 0;
@@ -368,16 +363,15 @@ void arcnet_get_my_address(
return;
}
void arcnet_get_broadcast_address(
BACNET_ADDRESS * dest)
{ /* destination address */
int i = 0; /* counter */
void arcnet_get_broadcast_address(BACNET_ADDRESS *dest)
{ /* destination address */
int i = 0; /* counter */
if (dest) {
dest->mac[0] = ARCNET_BROADCAST;
dest->mac_len = 1;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; /* always zero when DNET is broadcast */
dest->len = 0; /* always zero when DNET is broadcast */
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
+53 -79
View File
@@ -35,8 +35,8 @@
#include <ifaddrs.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h> /* for standard integer types uint8_t etc. */
#include <stdbool.h> /* for the standard bool type. */
#include <stdint.h> /* for standard integer types uint8_t etc. */
#include <stdbool.h> /* for the standard bool type. */
#include "bacnet/bacdcode.h"
#include "bacnet/config.h"
#include "bacnet/datalink/bip6.h"
@@ -45,16 +45,16 @@
#include "bacnet/basic/bbmd6/h_bbmd6.h"
#include "bacport.h"
static void debug_print_ipv6(const char *str, const struct in6_addr * addr) {
debug_printf( "BIP6: %s %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\n",
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[4], (int)addr->s6_addr[5],
(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[11],
(int)addr->s6_addr[12], (int)addr->s6_addr[13],
static void debug_print_ipv6(const char *str, const struct in6_addr *addr)
{
debug_printf("BIP6: %s "
"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%"
"02x:%02x%02x\n",
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[4],
(int)addr->s6_addr[5], (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[11], (int)addr->s6_addr[12], (int)addr->s6_addr[13],
(int)addr->s6_addr[14], (int)addr->s6_addr[15]);
}
@@ -71,8 +71,7 @@ static BACNET_IP6_ADDRESS BIP6_Broadcast_Addr;
*
* @param ifname - C string for name or text address
*/
void bip6_set_interface(
char *ifname)
void bip6_set_interface(char *ifname)
{
struct ifaddrs *ifa, *ifa_tmp;
struct sockaddr_in6 *sin;
@@ -85,16 +84,13 @@ void bip6_set_interface(
ifa_tmp = ifa;
debug_printf("BIP6: seeking interface: %s\n", ifname);
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_printf("BIP6: found interface: %s\n", ifa_tmp->ifa_name);
}
if ((ifa_tmp->ifa_addr) &&
(ifa_tmp->ifa_addr->sa_family == AF_INET6) &&
(strcasecmp(ifa_tmp->ifa_name,ifname) == 0)) {
sin = (struct sockaddr_in6*) ifa_tmp->ifa_addr;
bvlc6_address_set(&BIP6_Addr,
ntohs(sin->sin6_addr.s6_addr16[0]),
if ((ifa_tmp->ifa_addr) && (ifa_tmp->ifa_addr->sa_family == AF_INET6) &&
(strcasecmp(ifa_tmp->ifa_name, ifname) == 0)) {
sin = (struct sockaddr_in6 *)ifa_tmp->ifa_addr;
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[2]),
ntohs(sin->sin6_addr.s6_addr16[3]),
@@ -119,8 +115,7 @@ void bip6_set_interface(
*
* @param port - IPv6 UDP port number
*/
void bip6_set_port(
uint16_t port)
void bip6_set_port(uint16_t port)
{
BIP6_Addr.port = port;
BIP6_Broadcast_Addr.port = port;
@@ -131,8 +126,7 @@ void bip6_set_port(
*
* @return IPv6 UDP port number
*/
uint16_t bip6_get_port(
void)
uint16_t bip6_get_port(void)
{
return BIP6_Addr.port;
}
@@ -143,8 +137,7 @@ uint16_t bip6_get_port(
*
* @param addr - IPv6 source address
*/
void bip6_get_broadcast_address(
BACNET_ADDRESS * addr)
void bip6_get_broadcast_address(BACNET_ADDRESS *addr)
{
if (addr) {
addr->net = BACNET_BROADCAST_NETWORK;
@@ -158,8 +151,7 @@ void bip6_get_broadcast_address(
*
* @param addr - IPv6 source address
*/
void bip6_get_my_address(
BACNET_ADDRESS * addr)
void bip6_get_my_address(BACNET_ADDRESS *addr)
{
uint32_t device_id = 0;
@@ -174,8 +166,7 @@ void bip6_get_my_address(
*
* @param addr - network IPv6 address
*/
bool bip6_set_addr(
BACNET_IP6_ADDRESS *addr)
bool bip6_set_addr(BACNET_IP6_ADDRESS *addr)
{
return bvlc6_address_copy(&BIP6_Addr, addr);
}
@@ -185,8 +176,7 @@ bool bip6_set_addr(
*
* @return BACnet/IP address
*/
bool bip6_get_addr(
BACNET_IP6_ADDRESS *addr)
bool bip6_get_addr(BACNET_IP6_ADDRESS *addr)
{
return bvlc6_address_copy(addr, &BIP6_Addr);
}
@@ -196,8 +186,7 @@ bool bip6_get_addr(
*
* @param addr - network IPv6 address
*/
bool bip6_set_broadcast_addr(
BACNET_IP6_ADDRESS *addr)
bool bip6_set_broadcast_addr(BACNET_IP6_ADDRESS *addr)
{
return bvlc6_address_copy(&BIP6_Broadcast_Addr, addr);
}
@@ -207,8 +196,7 @@ bool bip6_set_broadcast_addr(
*
* @return BACnet/IP address
*/
bool bip6_get_broadcast_addr(
BACNET_IP6_ADDRESS *addr)
bool bip6_get_broadcast_addr(BACNET_IP6_ADDRESS *addr)
{
return bvlc6_address_copy(addr, &BIP6_Broadcast_Addr);
}
@@ -224,10 +212,7 @@ bool bip6_get_broadcast_addr(
* @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error.
*/
int bip6_send_mpdu(
BACNET_IP6_ADDRESS *dest,
uint8_t * mtu,
uint16_t mtu_len)
int bip6_send_mpdu(BACNET_IP6_ADDRESS *dest, uint8_t *mtu, uint16_t mtu_len)
{
struct sockaddr_in6 bvlc_dest = { 0 };
uint16_t addr16[8];
@@ -251,8 +236,8 @@ int bip6_send_mpdu(
bvlc_dest.sin6_port = htons(dest->port);
debug_print_ipv6("Sending MPDU->", &bvlc_dest.sin6_addr);
/* Send the packet */
return sendto(BIP6_Socket, (char *) mtu, mtu_len, 0,
(struct sockaddr *) &bvlc_dest, sizeof(bvlc_dest));
return sendto(BIP6_Socket, (char *)mtu, mtu_len, 0,
(struct sockaddr *)&bvlc_dest, sizeof(bvlc_dest));
}
/**
@@ -286,17 +271,14 @@ int bip6_send_pdu(BACNET_ADDRESS *dest,
* @return Number of bytes received, or 0 if none or timeout.
*/
uint16_t bip6_receive(
BACNET_ADDRESS * src,
uint8_t * npdu,
uint16_t max_npdu,
unsigned timeout)
BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, unsigned timeout)
{
uint16_t npdu_len = 0; /* return value */
fd_set read_fds;
int max = 0;
struct timeval select_timeout;
struct sockaddr_in6 sin = { 0 };
BACNET_IP6_ADDRESS addr = {{ 0 }};
BACNET_IP6_ADDRESS addr = { { 0 } };
socklen_t sin_len = sizeof(sin);
int received_bytes = 0;
int offset = 0;
@@ -322,9 +304,8 @@ uint16_t bip6_receive(
max = BIP6_Socket;
/* see if there is a packet for us */
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
received_bytes =
recvfrom(BIP6_Socket, (char *) &npdu[0], max_npdu, 0,
(struct sockaddr *) &sin, &sin_len);
received_bytes = recvfrom(BIP6_Socket, (char *)&npdu[0], max_npdu, 0,
(struct sockaddr *)&sin, &sin_len);
} else {
return 0;
}
@@ -342,14 +323,10 @@ uint16_t bip6_receive(
}
/* pass the packet into the BBMD handler */
debug_print_ipv6("Received MPDU->", &sin.sin6_addr);
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[3]),
ntohs(sin.sin6_addr.s6_addr16[4]),
ntohs(sin.sin6_addr.s6_addr16[5]),
ntohs(sin.sin6_addr.s6_addr16[6]),
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[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[7]));
addr.port = ntohs(sin.sin6_port);
offset = bvlc6_handler(&addr, src, npdu, received_bytes);
@@ -370,9 +347,8 @@ uint16_t bip6_receive(
/** Cleanup and close out the BACnet/IP services by closing the socket.
* @ingroup DLBIP6
*/
void bip6_cleanup(
void)
*/
void bip6_cleanup(void)
{
if (BIP6_Socket != -1) {
close(BIP6_Socket);
@@ -399,11 +375,10 @@ void bip6_cleanup(
* @return True if the socket is successfully opened for BACnet/IP,
* else False if the socket functions fail.
*/
bool bip6_init(
char *ifname)
bool bip6_init(char *ifname)
{
int status = 0; /* return from socket lib calls */
struct sockaddr_in6 server = {0};
int status = 0; /* return from socket lib calls */
struct sockaddr_in6 server = { 0 };
struct in6_addr broadcast_address;
struct ipv6_mreq join_request;
int sockopt = 0;
@@ -418,9 +393,8 @@ bool bip6_init(
}
debug_printf("BIP6: IPv6 UDP port: 0x%04X\n", htons(BIP6_Addr.port));
if (BIP6_Broadcast_Addr.address[0] == 0) {
bvlc6_address_set(&BIP6_Broadcast_Addr,
BIP6_MULTICAST_SITE_LOCAL, 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_GROUP_ID);
bvlc6_address_set(&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 */
BIP6_Socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
@@ -429,26 +403,26 @@ bool bip6_init(
/* Allow us to use the same socket for sending and receiving */
/* This makes sure that the src port is correct when sending */
sockopt = 1;
status =
setsockopt(BIP6_Socket, SOL_SOCKET, SO_REUSEADDR, &sockopt,
sizeof(sockopt));
status = setsockopt(
BIP6_Socket, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt));
if (status < 0) {
close(BIP6_Socket);
BIP6_Socket = -1;
return status;
}
/* allow us to send a broadcast */
status =
setsockopt(BIP6_Socket, SOL_SOCKET, SO_BROADCAST, &sockopt,
sizeof(sockopt));
status = setsockopt(
BIP6_Socket, SOL_SOCKET, SO_BROADCAST, &sockopt, sizeof(sockopt));
if (status < 0) {
close(BIP6_Socket);
BIP6_Socket = -1;
return false;
}
/* subscribe to a multicast address */
memcpy(&broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0], IP6_ADDRESS_MAX);
memcpy(&join_request.ipv6mr_multiaddr, &broadcast_address, sizeof(struct in6_addr));
memcpy(&broadcast_address.s6_addr[0], &BIP6_Broadcast_Addr.address[0],
IP6_ADDRESS_MAX);
memcpy(&join_request.ipv6mr_multiaddr, &broadcast_address,
sizeof(struct in6_addr));
/* Let system choose the interface */
join_request.ipv6mr_interface = 0;
status = setsockopt(BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP,
@@ -461,7 +435,7 @@ bool bip6_init(
server.sin6_family = AF_INET6;
server.sin6_addr = in6addr_any;
server.sin6_port = htons(BIP6_Addr.port);
status = bind(BIP6_Socket, (const void*)&server, sizeof(server));
status = bind(BIP6_Socket, (const void *)&server, sizeof(server));
if (status < 0) {
perror("BIP: bind");
close(BIP6_Socket);
+7 -9
View File
@@ -27,11 +27,10 @@
* @param true if DST is enabled and active
* @return true if local time was retrieved
*/
bool datetime_local(
BACNET_DATE * bdate,
BACNET_TIME * btime,
int16_t * utc_offset_minutes,
bool * dst_active)
bool datetime_local(BACNET_DATE *bdate,
BACNET_TIME *btime,
int16_t *utc_offset_minutes,
bool *dst_active)
{
bool status = false;
struct tm *tblock = NULL;
@@ -54,11 +53,10 @@ bool datetime_local(
* int tm_isdst Daylight Savings flag.
*/
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,
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec,
(uint8_t)(tv.tv_usec / 10000));
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec,
(uint8_t)(tv.tv_usec / 10000));
if (dst_active) {
/* The value of tm_isdst is:
- positive if Daylight Saving Time is in effect,
+140 -162
View File
@@ -1,28 +1,28 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
* Updated by Nikola Jelic 2011 <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
* Updated by Nikola Jelic 2011 <nikola.jelic@euroicc.com>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
@@ -42,7 +42,8 @@
/* OS Specific include */
#include "bacport.h"
/** @file linux/dlmstp.c Provides Linux-specific DataLink functions for MS/TP. */
/** @file linux/dlmstp.c Provides Linux-specific DataLink functions for MS/TP.
*/
/* Number of MS/TP Packets Rx/Tx */
uint16_t MSTP_Packets = 0;
@@ -108,24 +109,23 @@ static struct timespec start;
*
* @returns True if the difference is negative, otherwise 0.
*/
static int timespec_subtract(struct timespec *result,
const struct timespec *l,
const struct timespec *r)
static int timespec_subtract(
struct timespec *result, const struct timespec *l, const struct timespec *r)
{
# define NS_PER_S 1000000000 // nano-seconds per second
#define NS_PER_S 1000000000 // nano-seconds per second
struct timespec right = *r;
int secs;
// Perform the carry for the later subtraction by updating y.
if (l->tv_nsec < right.tv_nsec) {
secs = (right.tv_nsec - l->tv_nsec) / NS_PER_S + 1;
right.tv_nsec -= NS_PER_S * secs;
right.tv_sec += secs;
secs = (right.tv_nsec - l->tv_nsec) / NS_PER_S + 1;
right.tv_nsec -= NS_PER_S * secs;
right.tv_sec += secs;
}
if (l->tv_nsec - right.tv_nsec > NS_PER_S) {
secs = (l->tv_nsec - right.tv_nsec) / NS_PER_S;
right.tv_nsec += NS_PER_S * secs;
right.tv_sec -= secs;
secs = (l->tv_nsec - right.tv_nsec) / NS_PER_S;
right.tv_nsec += NS_PER_S * secs;
right.tv_sec -= secs;
}
// Compute the time remaining. tv_nsec is certainly positive.
@@ -144,18 +144,17 @@ static int timespec_subtract(struct timespec *result,
*/
static void timespec_add_ns(struct timespec *ts, long ns)
{
ts->tv_nsec += ns;
if (ts->tv_nsec > NS_PER_S) {
ts->tv_nsec -= NS_PER_S;
ts->tv_sec += 1;
} else if (ts->tv_nsec < 0) {
ts->tv_nsec += NS_PER_S;
ts->tv_sec -= 1;
}
ts->tv_nsec += ns;
if (ts->tv_nsec > NS_PER_S) {
ts->tv_nsec -= NS_PER_S;
ts->tv_sec += 1;
} else if (ts->tv_nsec < 0) {
ts->tv_nsec += NS_PER_S;
ts->tv_sec -= 1;
}
}
static uint32_t Timer_Silence(
void *pArg)
static uint32_t Timer_Silence(void *pArg)
{
struct timespec now, diff;
int32_t res;
@@ -167,27 +166,23 @@ static uint32_t Timer_Silence(
return (res >= 0 ? res : 0);
}
static void Timer_Silence_Reset(
void *pArg)
static void Timer_Silence_Reset(void *pArg)
{
clock_gettime(CLOCK_MONOTONIC, &start);
}
static void get_abstime(
struct timespec *abstime,
unsigned long milliseconds)
static void get_abstime(struct timespec *abstime, unsigned long milliseconds)
{
clock_gettime(CLOCK_MONOTONIC, abstime);
if (milliseconds > 1000) {
fprintf(stderr, "DLMSTP: limited timeout of %lums to 1000ms\n",
milliseconds);
milliseconds = 1000;
fprintf(stderr, "DLMSTP: limited timeout of %lums to 1000ms\n",
milliseconds);
milliseconds = 1000;
}
timespec_add_ns(abstime, 1000000 * milliseconds);
}
void dlmstp_cleanup(
void)
void dlmstp_cleanup(void)
{
pthread_cond_destroy(&Received_Frame_Flag);
pthread_cond_destroy(&Receive_Packet_Flag);
@@ -198,17 +193,16 @@ void dlmstp_cleanup(
}
/* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu(
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
int dlmstp_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len)
{ /* number of bytes of data */
{ /* number of bytes of data */
int bytes_sent = 0;
struct mstp_pdu_packet *pkt;
unsigned i = 0;
pkt = (struct mstp_pdu_packet *) Ringbuf_Data_Peek(&PDU_Queue);
pkt = (struct mstp_pdu_packet *)Ringbuf_Data_Peek(&PDU_Queue);
if (pkt) {
pkt->data_expecting_reply = npdu_data->data_expecting_reply;
for (i = 0; i < pdu_len; i++) {
@@ -229,22 +223,21 @@ int dlmstp_send_pdu(
return bytes_sent;
}
uint16_t dlmstp_receive(
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
uint16_t dlmstp_receive(BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout)
{ /* milliseconds to wait for a packet */
{ /* milliseconds to wait for a packet */
uint16_t pdu_len = 0;
struct timespec abstime;
(void) max_pdu;
(void)max_pdu;
/* see if there is a packet available, and a place
to put the reply (if necessary) and process it */
pthread_mutex_lock(&Receive_Packet_Mutex);
get_abstime(&abstime, timeout);
pthread_cond_timedwait(&Receive_Packet_Flag, &Receive_Packet_Mutex,
&abstime);
pthread_cond_timedwait(
&Receive_Packet_Flag, &Receive_Packet_Mutex, &abstime);
if (Receive_Packet.ready) {
if (Receive_Packet.pdu_len) {
MSTP_Packets++;
@@ -253,8 +246,7 @@ uint16_t dlmstp_receive(
sizeof(Receive_Packet.address));
}
if (pdu) {
memmove(pdu, &Receive_Packet.pdu,
sizeof(Receive_Packet.pdu));
memmove(pdu, &Receive_Packet.pdu, sizeof(Receive_Packet.pdu));
}
pdu_len = Receive_Packet.pdu_len;
}
@@ -265,13 +257,12 @@ uint16_t dlmstp_receive(
return pdu_len;
}
static void *dlmstp_master_fsm_task(
void *pArg)
static void *dlmstp_master_fsm_task(void *pArg)
{
uint32_t silence = 0;
bool run_master = false;
(void) pArg;
(void)pArg;
for (;;) {
if (MSTP_Port.ReceivedValidFrame == false &&
MSTP_Port.ReceivedInvalidFrame == false) {
@@ -314,9 +305,7 @@ static void *dlmstp_master_fsm_task(
return NULL;
}
void dlmstp_fill_bacnet_address(
BACNET_ADDRESS * src,
uint8_t mstp_address)
void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address)
{
int i = 0;
@@ -340,8 +329,7 @@ void dlmstp_fill_bacnet_address(
}
/* for the MS/TP state machine to use for putting received data */
uint16_t MSTP_Put_Receive(
volatile struct mstp_port_struct_t *mstp_port)
uint16_t MSTP_Put_Receive(volatile struct mstp_port_struct_t *mstp_port)
{
uint16_t pdu_len = 0;
@@ -357,10 +345,10 @@ uint16_t MSTP_Put_Receive(
if (pdu_len == 0) {
debug_printf("MS/TP: PDU Length is 0!\n");
}
memmove((void *) &Receive_Packet.pdu[0],
(void *) &mstp_port->InputBuffer[0], pdu_len);
dlmstp_fill_bacnet_address(&Receive_Packet.address,
mstp_port->SourceAddress);
memmove((void *)&Receive_Packet.pdu[0],
(void *)&mstp_port->InputBuffer[0], pdu_len);
dlmstp_fill_bacnet_address(
&Receive_Packet.address, mstp_port->SourceAddress);
Receive_Packet.pdu_len = mstp_port->DataLength;
Receive_Packet.ready = true;
pthread_cond_signal(&Receive_Packet_Flag);
@@ -373,37 +361,36 @@ uint16_t MSTP_Put_Receive(
/* for the MS/TP state machine to use for getting data to send */
/* Return: amount of PDU data */
uint16_t MSTP_Get_Send(
volatile struct mstp_port_struct_t * mstp_port,
unsigned timeout)
{ /* milliseconds to wait for a packet */
volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */
uint16_t pdu_len = 0;
uint8_t frame_type = 0;
struct mstp_pdu_packet *pkt;
(void) timeout;
(void)timeout;
if (Ringbuf_Empty(&PDU_Queue)) {
return 0;
}
pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue);
if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else {
frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
}
/* convert the PDU into the MSTP Frame */
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *) & pkt->buffer[0], pkt->length);
(void) Ringbuf_Pop(&PDU_Queue, NULL);
pdu_len =
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *)&pkt->buffer[0], pkt->length);
(void)Ringbuf_Pop(&PDU_Queue, NULL);
return pdu_len;
}
static bool dlmstp_compare_data_expecting_reply(
uint8_t * request_pdu,
static bool dlmstp_compare_data_expecting_reply(uint8_t *request_pdu,
uint16_t request_pdu_len,
uint8_t src_address,
uint8_t * reply_pdu,
uint8_t *reply_pdu,
uint16_t reply_pdu_len,
uint8_t dest_address)
{
@@ -427,13 +414,13 @@ static bool dlmstp_compare_data_expecting_reply(
/* decode the request data */
request.address.mac[0] = src_address;
request.address.mac_len = 1;
offset =
npdu_decode(&request_pdu[0], NULL, &request.address,
&request.npdu_data);
offset = npdu_decode(
&request_pdu[0], NULL, &request.address, &request.npdu_data);
if (request.npdu_data.network_layer_message) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "Request is Network message.\n");
"DLMSTP: DER Compare failed: "
"Request is Network message.\n");
#endif
return false;
}
@@ -441,7 +428,8 @@ static bool dlmstp_compare_data_expecting_reply(
if (request.pdu_type != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "Not Confirmed Request.\n");
"DLMSTP: DER Compare failed: "
"Not Confirmed Request.\n");
#endif
return false;
}
@@ -455,12 +443,12 @@ static bool dlmstp_compare_data_expecting_reply(
/* decode the reply data */
reply.address.mac[0] = dest_address;
reply.address.mac_len = 1;
offset =
npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
offset = npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
if (reply.npdu_data.network_layer_message) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "Reply is Network message.\n");
"DLMSTP: DER Compare failed: "
"Reply is Network message.\n");
#endif
return false;
}
@@ -498,7 +486,8 @@ static bool dlmstp_compare_data_expecting_reply(
if (request.invoke_id != reply.invoke_id) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "Invoke ID mismatch.\n");
"DLMSTP: DER Compare failed: "
"Invoke ID mismatch.\n");
#endif
return false;
}
@@ -506,19 +495,22 @@ static bool dlmstp_compare_data_expecting_reply(
if (request.invoke_id != reply.invoke_id) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "Invoke ID mismatch.\n");
"DLMSTP: DER Compare failed: "
"Invoke ID mismatch.\n");
#endif
return false;
}
if (request.service_choice != reply.service_choice) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "Service choice mismatch.\n");
"DLMSTP: DER Compare failed: "
"Service choice mismatch.\n");
#endif
return false;
}
}
if (request.npdu_data.protocol_version != reply.npdu_data.protocol_version) {
if (request.npdu_data.protocol_version !=
reply.npdu_data.protocol_version) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: "
@@ -540,7 +532,8 @@ static bool dlmstp_compare_data_expecting_reply(
if (!bacnet_address_same(&request.address, &reply.address)) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "BACnet Address mismatch.\n");
"DLMSTP: DER Compare failed: "
"BACnet Address mismatch.\n");
#endif
return false;
}
@@ -550,24 +543,22 @@ static bool dlmstp_compare_data_expecting_reply(
/* Get the reply to a DATA_EXPECTING_REPLY frame, or nothing */
uint16_t MSTP_Get_Reply(
volatile struct mstp_port_struct_t * mstp_port,
unsigned timeout)
{ /* milliseconds to wait for a packet */
uint16_t pdu_len = 0; /* return value */
volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */
uint16_t pdu_len = 0; /* return value */
bool matched = false;
uint8_t frame_type = 0;
struct mstp_pdu_packet *pkt;
(void) timeout;
(void)timeout;
if (Ringbuf_Empty(&PDU_Queue)) {
return 0;
}
pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&PDU_Queue);
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&PDU_Queue);
/* is this the reply to the DER? */
matched =
dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
matched = dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
mstp_port->DataLength, mstp_port->SourceAddress,
(uint8_t *) & pkt->buffer[0], pkt->length, pkt->destination_mac);
(uint8_t *)&pkt->buffer[0], pkt->length, pkt->destination_mac);
if (!matched) {
return 0;
}
@@ -577,16 +568,16 @@ uint16_t MSTP_Get_Reply(
frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
}
/* convert the PDU into the MSTP Frame */
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *) & pkt->buffer[0], pkt->length);
(void) Ringbuf_Pop(&PDU_Queue, NULL);
pdu_len =
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *)&pkt->buffer[0], pkt->length);
(void)Ringbuf_Pop(&PDU_Queue, NULL);
return pdu_len;
}
void dlmstp_set_mac_address(
uint8_t mac_address)
void dlmstp_set_mac_address(uint8_t mac_address)
{
/* Master Nodes can only have address 0-127 */
if (mac_address <= 127) {
@@ -603,8 +594,7 @@ void dlmstp_set_mac_address(
return;
}
uint8_t dlmstp_mac_address(
void)
uint8_t dlmstp_mac_address(void)
{
return MSTP_Port.This_Station;
}
@@ -616,8 +606,7 @@ uint8_t dlmstp_mac_address(
/* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */
void dlmstp_set_max_info_frames(
uint8_t max_info_frames)
void dlmstp_set_max_info_frames(uint8_t max_info_frames)
{
if (max_info_frames >= 1) {
MSTP_Port.Nmax_info_frames = max_info_frames;
@@ -631,8 +620,7 @@ void dlmstp_set_max_info_frames(
return;
}
uint8_t dlmstp_max_info_frames(
void)
uint8_t dlmstp_max_info_frames(void)
{
return MSTP_Port.Nmax_info_frames;
}
@@ -642,8 +630,7 @@ uint8_t dlmstp_max_info_frames(
/* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */
void dlmstp_set_max_master(
uint8_t max_master)
void dlmstp_set_max_master(uint8_t max_master)
{
if (max_master <= 127) {
if (MSTP_Port.This_Station <= max_master) {
@@ -659,33 +646,29 @@ void dlmstp_set_max_master(
return;
}
uint8_t dlmstp_max_master(
void)
uint8_t dlmstp_max_master(void)
{
return MSTP_Port.Nmax_master;
}
/* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */
void dlmstp_set_baud_rate(
uint32_t baud)
void dlmstp_set_baud_rate(uint32_t baud)
{
RS485_Set_Baud_Rate(baud);
}
uint32_t dlmstp_baud_rate(
void)
uint32_t dlmstp_baud_rate(void)
{
return RS485_Get_Baud_Rate();
}
void dlmstp_get_my_address(
BACNET_ADDRESS * my_address)
void dlmstp_get_my_address(BACNET_ADDRESS *my_address)
{
int i = 0; /* counter */
int i = 0; /* counter */
my_address->mac_len = 1;
my_address->mac[0] = MSTP_Port.This_Station;
my_address->net = 0; /* local only, no routing */
my_address->net = 0; /* local only, no routing */
my_address->len = 0;
for (i = 0; i < MAX_MAC_LEN; i++) {
my_address->adr[i] = 0;
@@ -694,16 +677,15 @@ void dlmstp_get_my_address(
return;
}
void dlmstp_get_broadcast_address(
BACNET_ADDRESS * dest)
{ /* destination address */
int i = 0; /* counter */
void dlmstp_get_broadcast_address(BACNET_ADDRESS *dest)
{ /* destination address */
int i = 0; /* counter */
if (dest) {
dest->mac_len = 1;
dest->mac[0] = MSTP_BROADCAST_ADDRESS;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; /* always zero when DNET is broadcast */
dest->len = 0; /* always zero when DNET is broadcast */
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
@@ -712,8 +694,7 @@ void dlmstp_get_broadcast_address(
return;
}
bool dlmstp_init(
char *ifname)
bool dlmstp_init(char *ifname)
{
unsigned long hThread = 0;
pthread_condattr_t attr;
@@ -721,13 +702,13 @@ bool dlmstp_init(
pthread_condattr_init(&attr);
if ((rv = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) != 0) {
fprintf(stderr, "MS/TP Interface: %s\n failed to set MONOTONIC clock\n",
ifname);
exit(1);
fprintf(stderr, "MS/TP Interface: %s\n failed to set MONOTONIC clock\n",
ifname);
exit(1);
}
/* initialize PDU queue */
Ringbuf_Init(&PDU_Queue, (uint8_t *) & PDU_Buffer,
Ringbuf_Init(&PDU_Queue, (uint8_t *)&PDU_Buffer,
sizeof(struct mstp_pdu_packet), MSTP_PDU_PACKET_COUNT);
/* initialize packet queue */
Receive_Packet.ready = false;
@@ -782,21 +763,18 @@ bool dlmstp_init(
#ifdef TEST_DLMSTP
#include <stdio.h>
void apdu_handler(
BACNET_ADDRESS * src, /* source address */
uint8_t * apdu, /* APDU data */
void apdu_handler(BACNET_ADDRESS *src, /* source address */
uint8_t *apdu, /* APDU data */
uint16_t pdu_len)
{ /* for confirmed messages */
(void) src;
(void) apdu;
(void) pdu_len;
{ /* for confirmed messages */
(void)src;
(void)apdu;
(void)pdu_len;
}
static char *Network_Interface = NULL;
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
uint16_t pdu_len = 0;
+205 -245
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2008 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
@@ -41,24 +41,28 @@
#include "bacport.h"
#include "bacnet/basic/sys/ringbuf.h"
/** @file linux/dlmstp.c Provides Linux-specific DataLink functions for MS/TP. */
/** @file linux/dlmstp.c Provides Linux-specific DataLink functions for MS/TP.
*/
#define BACNET_PDU_CONTROL_BYTE_OFFSET 1
#define BACNET_DATA_EXPECTING_REPLY_BIT 2
#define BACNET_DATA_EXPECTING_REPLY(control) ( (control & (1 << BACNET_DATA_EXPECTING_REPLY_BIT) ) > 0 )
#define BACNET_DATA_EXPECTING_REPLY(control) \
((control & (1 << BACNET_DATA_EXPECTING_REPLY_BIT)) > 0)
#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;}
uint32_t Timer_Silence(
void *poPort)
#define INCREMENT_AND_LIMIT_UINT16(x) \
{ \
if (x < 0xFFFF) \
x++; \
}
uint32_t Timer_Silence(void *poPort)
{
struct timeval now, tmp_diff;
SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return -1;
}
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
return -1;
}
@@ -72,16 +76,14 @@ uint32_t Timer_Silence(
return (res >= 0 ? res : -res);
}
void Timer_Silence_Reset(
void *poPort)
void Timer_Silence_Reset(void *poPort)
{
SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return;
}
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
return;
}
@@ -89,9 +91,7 @@ void Timer_Silence_Reset(
gettimeofday(&poSharedData->start, NULL);
}
void get_abstime(
struct timespec *abstime,
unsigned long milliseconds)
void get_abstime(struct timespec *abstime, unsigned long milliseconds)
{
struct timeval now, offset, result;
@@ -103,23 +103,20 @@ void get_abstime(
abstime->tv_nsec = result.tv_usec * 1000;
}
void dlmstp_cleanup(
void *poPort)
void dlmstp_cleanup(void *poPort)
{
SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return;
}
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
return;
}
/* restore the old port settings */
tcsetattr(poSharedData->RS485_Handle, TCSANOW,
&poSharedData->RS485_oldtio);
tcsetattr(poSharedData->RS485_Handle, TCSANOW, &poSharedData->RS485_oldtio);
close(poSharedData->RS485_Handle);
pthread_cond_destroy(&poSharedData->Received_Frame_Flag);
@@ -130,27 +127,25 @@ void dlmstp_cleanup(
}
/* returns number of bytes sent on success, zero on failure */
int dlmstp_send_pdu(
void *poPort,
BACNET_ADDRESS * dest, /* destination address */
uint8_t * pdu, /* any data to be sent - may be null */
int dlmstp_send_pdu(void *poPort,
BACNET_ADDRESS *dest, /* destination address */
uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len)
{ /* number of bytes of data */
{ /* number of bytes of data */
int bytes_sent = 0;
struct mstp_pdu_packet *pkt;
unsigned i = 0;
SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return 0;
}
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
return 0;
}
pkt = (struct mstp_pdu_packet *) Ringbuf_Data_Peek(&poSharedData->PDU_Queue);
pkt = (struct mstp_pdu_packet *)Ringbuf_Data_Peek(&poSharedData->PDU_Queue);
if (pkt) {
pkt->data_expecting_reply =
BACNET_DATA_EXPECTING_REPLY(pdu[BACNET_PDU_CONTROL_BYTE_OFFSET]);
@@ -167,27 +162,25 @@ int dlmstp_send_pdu(
return bytes_sent;
}
uint16_t dlmstp_receive(
void *poPort,
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
uint16_t dlmstp_receive(void *poPort,
BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout)
{ /* milliseconds to wait for a packet */
{ /* milliseconds to wait for a packet */
uint16_t pdu_len = 0;
struct timespec abstime;
int rv = 0;
SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return 0;
}
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
return 0;
}
(void) max_pdu;
(void)max_pdu;
/* see if there is a packet available, and a place
to put the reply (if necessary) and process it */
get_abstime(&abstime, timeout);
@@ -213,18 +206,17 @@ uint16_t dlmstp_receive(
return pdu_len;
}
void *dlmstp_receive_fsm_task(
void *pArg)
void *dlmstp_receive_fsm_task(void *pArg)
{
bool received_frame;
SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *) pArg;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)pArg;
if (!mstp_port) {
return NULL;
}
poSharedData =
(SHARED_MSTP_DATA *) ((struct mstp_port_struct_t *) pArg)->UserData;
(SHARED_MSTP_DATA *)((struct mstp_port_struct_t *)pArg)->UserData;
if (!poSharedData) {
return NULL;
}
@@ -235,8 +227,8 @@ void *dlmstp_receive_fsm_task(
(mstp_port->ReceivedInvalidFrame == false)) {
do {
RS485_Check_UART_Data(mstp_port);
MSTP_Receive_Frame_FSM((volatile struct mstp_port_struct_t *)
pArg);
MSTP_Receive_Frame_FSM(
(volatile struct mstp_port_struct_t *)pArg);
received_frame = mstp_port->ReceivedValidFrame ||
mstp_port->ReceivedInvalidFrame;
if (received_frame) {
@@ -250,19 +242,18 @@ void *dlmstp_receive_fsm_task(
return NULL;
}
void *dlmstp_master_fsm_task(
void *pArg)
void *dlmstp_master_fsm_task(void *pArg)
{
uint32_t silence = 0;
bool run_master = false;
SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *) pArg;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)pArg;
if (!mstp_port) {
return NULL;
}
poSharedData =
(SHARED_MSTP_DATA *) ((struct mstp_port_struct_t *) pArg)->UserData;
(SHARED_MSTP_DATA *)((struct mstp_port_struct_t *)pArg)->UserData;
if (!poSharedData) {
return NULL;
}
@@ -309,9 +300,7 @@ void *dlmstp_master_fsm_task(
return NULL;
}
void dlmstp_fill_bacnet_address(
BACNET_ADDRESS * src,
uint8_t mstp_address)
void dlmstp_fill_bacnet_address(BACNET_ADDRESS *src, uint8_t mstp_address)
{
int i = 0;
@@ -335,11 +324,10 @@ void dlmstp_fill_bacnet_address(
}
/* for the MS/TP state machine to use for putting received data */
uint16_t MSTP_Put_Receive(
volatile struct mstp_port_struct_t *mstp_port)
uint16_t MSTP_Put_Receive(volatile struct mstp_port_struct_t *mstp_port)
{
uint16_t pdu_len = 0;
SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
return 0;
@@ -350,10 +338,10 @@ uint16_t MSTP_Put_Receive(
pdu_len = mstp_port->DataLength;
if (pdu_len > sizeof(poSharedData->Receive_Packet.pdu))
pdu_len = sizeof(poSharedData->Receive_Packet.pdu);
memmove((void *) &poSharedData->Receive_Packet.pdu[0],
(void *) &mstp_port->InputBuffer[0], pdu_len);
dlmstp_fill_bacnet_address(&poSharedData->Receive_Packet.address,
mstp_port->SourceAddress);
memmove((void *)&poSharedData->Receive_Packet.pdu[0],
(void *)&mstp_port->InputBuffer[0], pdu_len);
dlmstp_fill_bacnet_address(
&poSharedData->Receive_Packet.address, mstp_port->SourceAddress);
poSharedData->Receive_Packet.pdu_len = mstp_port->DataLength;
poSharedData->Receive_Packet.ready = true;
sem_post(&poSharedData->Receive_Packet_Flag);
@@ -365,42 +353,41 @@ uint16_t MSTP_Put_Receive(
/* for the MS/TP state machine to use for getting data to send */
/* Return: amount of PDU data */
uint16_t MSTP_Get_Send(
volatile struct mstp_port_struct_t * mstp_port,
unsigned timeout)
{ /* milliseconds to wait for a packet */
volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */
uint16_t pdu_len = 0;
uint8_t frame_type = 0;
struct mstp_pdu_packet *pkt;
SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
return 0;
}
(void) timeout;
(void)timeout;
if (Ringbuf_Empty(&poSharedData->PDU_Queue)) {
return 0;
}
pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&poSharedData->PDU_Queue);
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&poSharedData->PDU_Queue);
if (pkt->data_expecting_reply) {
frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else {
frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
}
/* convert the PDU into the MSTP Frame */
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *) & pkt->buffer[0], pkt->length);
(void) Ringbuf_Pop(&poSharedData->PDU_Queue, NULL);
pdu_len =
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *)&pkt->buffer[0], pkt->length);
(void)Ringbuf_Pop(&poSharedData->PDU_Queue, NULL);
return pdu_len;
}
bool dlmstp_compare_data_expecting_reply(
uint8_t * request_pdu,
bool dlmstp_compare_data_expecting_reply(uint8_t *request_pdu,
uint16_t request_pdu_len,
uint8_t src_address,
uint8_t * reply_pdu,
uint8_t *reply_pdu,
uint16_t reply_pdu_len,
uint8_t dest_address)
{
@@ -424,13 +411,13 @@ bool dlmstp_compare_data_expecting_reply(
/* decode the request data */
request.address.mac[0] = src_address;
request.address.mac_len = 1;
offset =
npdu_decode(&request_pdu[0], NULL, &request.address,
&request.npdu_data);
offset = npdu_decode(
&request_pdu[0], NULL, &request.address, &request.npdu_data);
if (request.npdu_data.network_layer_message) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "Request is Network message.\n");
"DLMSTP: DER Compare failed: "
"Request is Network message.\n");
#endif
return false;
}
@@ -438,7 +425,8 @@ bool dlmstp_compare_data_expecting_reply(
if (request.pdu_type != PDU_TYPE_CONFIRMED_SERVICE_REQUEST) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "Not Confirmed Request.\n");
"DLMSTP: DER Compare failed: "
"Not Confirmed Request.\n");
#endif
return false;
}
@@ -452,12 +440,12 @@ bool dlmstp_compare_data_expecting_reply(
/* decode the reply data */
reply.address.mac[0] = dest_address;
reply.address.mac_len = 1;
offset =
npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
offset = npdu_decode(&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
if (reply.npdu_data.network_layer_message) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "Reply is Network message.\n");
"DLMSTP: DER Compare failed: "
"Reply is Network message.\n");
#endif
return false;
}
@@ -495,7 +483,8 @@ bool dlmstp_compare_data_expecting_reply(
if (request.invoke_id != reply.invoke_id) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "Invoke ID mismatch.\n");
"DLMSTP: DER Compare failed: "
"Invoke ID mismatch.\n");
#endif
return false;
}
@@ -503,19 +492,22 @@ bool dlmstp_compare_data_expecting_reply(
if (request.invoke_id != reply.invoke_id) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "Invoke ID mismatch.\n");
"DLMSTP: DER Compare failed: "
"Invoke ID mismatch.\n");
#endif
return false;
}
if (request.service_choice != reply.service_choice) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "Service choice mismatch.\n");
"DLMSTP: DER Compare failed: "
"Service choice mismatch.\n");
#endif
return false;
}
}
if (request.npdu_data.protocol_version != reply.npdu_data.protocol_version) {
if (request.npdu_data.protocol_version !=
reply.npdu_data.protocol_version) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: "
@@ -537,7 +529,8 @@ bool dlmstp_compare_data_expecting_reply(
if (!bacnet_address_same(&request.address, &reply.address)) {
#if PRINT_ENABLED
fprintf(stderr,
"DLMSTP: DER Compare failed: " "BACnet Address mismatch.\n");
"DLMSTP: DER Compare failed: "
"BACnet Address mismatch.\n");
#endif
return false;
}
@@ -547,14 +540,13 @@ bool dlmstp_compare_data_expecting_reply(
/* Get the reply to a DATA_EXPECTING_REPLY frame, or nothing */
uint16_t MSTP_Get_Reply(
volatile struct mstp_port_struct_t * mstp_port,
unsigned timeout)
{ /* milliseconds to wait for a packet */
uint16_t pdu_len = 0; /* return value */
volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */
uint16_t pdu_len = 0; /* return value */
bool matched = false;
uint8_t frame_type = 0;
struct mstp_pdu_packet *pkt;
SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
return 0;
@@ -563,23 +555,20 @@ uint16_t MSTP_Get_Reply(
if (Ringbuf_Empty(&poSharedData->PDU_Queue)) {
return 0;
}
pkt = (struct mstp_pdu_packet *) Ringbuf_Peek(&poSharedData->PDU_Queue);
pkt = (struct mstp_pdu_packet *)Ringbuf_Peek(&poSharedData->PDU_Queue);
/* is this the reply to the DER? */
matched =
dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
matched = dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
mstp_port->DataLength, mstp_port->SourceAddress,
(uint8_t *) & pkt->buffer[0], pkt->length, pkt->destination_mac);
(uint8_t *)&pkt->buffer[0], pkt->length, pkt->destination_mac);
if (!matched) {
/* Walk the rest of the ring buffer to see if we can find a match */
while (!matched &&
(pkt = (struct mstp_pdu_packet *)Ringbuf_Peek_Next(&poSharedData->PDU_Queue, (uint8_t *)pkt)) != NULL) {
matched =
dlmstp_compare_data_expecting_reply(&mstp_port->InputBuffer[0],
mstp_port->DataLength,
mstp_port->SourceAddress,
(uint8_t *) & pkt->buffer[0],
pkt->length,
pkt->destination_mac);
(pkt = (struct mstp_pdu_packet *)Ringbuf_Peek_Next(
&poSharedData->PDU_Queue, (uint8_t *)pkt)) != NULL) {
matched = dlmstp_compare_data_expecting_reply(
&mstp_port->InputBuffer[0], mstp_port->DataLength,
mstp_port->SourceAddress, (uint8_t *)&pkt->buffer[0],
pkt->length, pkt->destination_mac);
}
if (!matched) {
/* Still didn't find a match so just bail out */
@@ -592,32 +581,30 @@ uint16_t MSTP_Get_Reply(
frame_type = FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
}
/* convert the PDU into the MSTP Frame */
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *) & pkt->buffer[0], pkt->length);
pdu_len =
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, frame_type, pkt->destination_mac,
mstp_port->This_Station, (uint8_t *)&pkt->buffer[0], pkt->length);
/* This will pop the element no matter where we found it */
(void) Ringbuf_Pop_Element(&poSharedData->PDU_Queue, (uint8_t *)pkt, NULL);
(void)Ringbuf_Pop_Element(&poSharedData->PDU_Queue, (uint8_t *)pkt, NULL);
return pdu_len;
}
void dlmstp_set_mac_address(
void *poPort,
uint8_t mac_address)
void dlmstp_set_mac_address(void *poPort, uint8_t mac_address)
{
/* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
/* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return;
}
/*
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return;
}
*/
/*
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return;
}
*/
/* Master Nodes can only have address 0-127 */
if (mac_address <= 127) {
mstp_port->This_Station = mac_address;
@@ -633,21 +620,19 @@ void dlmstp_set_mac_address(
return;
}
uint8_t dlmstp_mac_address(
void *poPort)
uint8_t dlmstp_mac_address(void *poPort)
{
/* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
/* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return 0;
}
/* poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return 0;
}
*/
/* poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return 0;
}
*/
return mstp_port->This_Station;
}
@@ -659,23 +644,20 @@ uint8_t dlmstp_mac_address(
/* nodes. This may be used to allocate more or less of the available link */
/* bandwidth to particular nodes. If Max_Info_Frames is not writable in a */
/* node, its value shall be 1. */
void dlmstp_set_max_info_frames(
void *poPort,
uint8_t max_info_frames)
void dlmstp_set_max_info_frames(void *poPort, uint8_t max_info_frames)
{
/* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
/* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return;
}
/*
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return;
}
*/
/*
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return;
}
*/
if (max_info_frames >= 1) {
mstp_port->Nmax_info_frames = max_info_frames;
/* FIXME: implement your data storage */
@@ -688,22 +670,20 @@ void dlmstp_set_max_info_frames(
return;
}
uint8_t dlmstp_max_info_frames(
void *poPort)
uint8_t dlmstp_max_info_frames(void *poPort)
{
/* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
/* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return 0;
}
/*
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return 0;
}
*/
/*
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return 0;
}
*/
return mstp_port->Nmax_info_frames;
}
@@ -712,23 +692,20 @@ uint8_t dlmstp_max_info_frames(
/* allowable address for master nodes. The value of Max_Master shall be */
/* less than or equal to 127. If Max_Master is not writable in a node, */
/* its value shall be 127. */
void dlmstp_set_max_master(
void *poPort,
uint8_t max_master)
void dlmstp_set_max_master(void *poPort, uint8_t max_master)
{
/* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
/* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return;
}
/*
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return;
}
*/
/*
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return;
}
*/
if (max_master <= 127) {
if (mstp_port->This_Station <= max_master) {
mstp_port->Nmax_master = max_master;
@@ -743,37 +720,32 @@ void dlmstp_set_max_master(
return;
}
uint8_t dlmstp_max_master(
void *poPort)
uint8_t dlmstp_max_master(void *poPort)
{
/* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
/* SHARED_MSTP_DATA * poSharedData; */
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return 0;
}
/*
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return 0;
}
*/
/*
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
if(!poSharedData)
{
return 0;
}
*/
return mstp_port->Nmax_master;
}
/* RS485 Baud Rate 9600, 19200, 38400, 57600, 115200 */
void dlmstp_set_baud_rate(
void *poPort,
uint32_t baud)
void dlmstp_set_baud_rate(void *poPort, uint32_t baud)
{
SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return;
}
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
return;
}
@@ -799,16 +771,14 @@ void dlmstp_set_baud_rate(
}
}
uint32_t dlmstp_baud_rate(
void *poPort)
uint32_t dlmstp_baud_rate(void *poPort)
{
SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return false;
}
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
return false;
}
@@ -828,24 +798,21 @@ uint32_t dlmstp_baud_rate(
}
}
void dlmstp_get_my_address(
void *poPort,
BACNET_ADDRESS * my_address)
void dlmstp_get_my_address(void *poPort, BACNET_ADDRESS *my_address)
{
int i = 0; /* counter */
int i = 0; /* counter */
SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return;
}
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
return;
}
my_address->mac_len = 1;
my_address->mac[0] = mstp_port->This_Station;
my_address->net = 0; /* local only, no routing */
my_address->net = 0; /* local only, no routing */
my_address->len = 0;
for (i = 0; i < MAX_MAC_LEN; i++) {
my_address->adr[i] = 0;
@@ -854,16 +821,15 @@ void dlmstp_get_my_address(
return;
}
void dlmstp_get_broadcast_address(
BACNET_ADDRESS * dest)
{ /* destination address */
int i = 0; /* counter */
void dlmstp_get_broadcast_address(BACNET_ADDRESS *dest)
{ /* destination address */
int i = 0; /* counter */
if (dest) {
dest->mac_len = 1;
dest->mac[0] = MSTP_BROADCAST_ADDRESS;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; /* always zero when DNET is broadcast */
dest->len = 0; /* always zero when DNET is broadcast */
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
@@ -872,30 +838,26 @@ void dlmstp_get_broadcast_address(
return;
}
bool dlmstp_init(
void *poPort,
char *ifname)
bool dlmstp_init(void *poPort, char *ifname)
{
unsigned long hThread = 0;
int rv = 0;
SHARED_MSTP_DATA *poSharedData;
struct mstp_port_struct_t *mstp_port =
(struct mstp_port_struct_t *) poPort;
struct mstp_port_struct_t *mstp_port = (struct mstp_port_struct_t *)poPort;
if (!mstp_port) {
return false;
}
poSharedData = (SHARED_MSTP_DATA *) ((struct mstp_port_struct_t *)
mstp_port)->UserData;
poSharedData =
(SHARED_MSTP_DATA *)((struct mstp_port_struct_t *)mstp_port)->UserData;
if (!poSharedData) {
return false;
}
poSharedData->RS485_Port_Name = ifname;
/* initialize PDU queue */
Ringbuf_Init(&poSharedData->PDU_Queue,
(uint8_t *) & poSharedData->PDU_Buffer, sizeof(struct mstp_pdu_packet),
MSTP_PDU_PACKET_COUNT);
Ringbuf_Init(&poSharedData->PDU_Queue, (uint8_t *)&poSharedData->PDU_Buffer,
sizeof(struct mstp_pdu_packet), MSTP_PDU_PACKET_COUNT);
/* initialize packet queue */
poSharedData->Receive_Packet.ready = false;
poSharedData->Receive_Packet.pdu_len = 0;
@@ -913,9 +875,8 @@ bool dlmstp_init(
Open device for reading and writing.
Blocking mode - more CPU effecient
*/
poSharedData->RS485_Handle =
open(poSharedData->RS485_Port_Name,
O_RDWR | O_NOCTTY | O_NONBLOCK /*| O_NDELAY */ );
poSharedData->RS485_Handle = open(poSharedData->RS485_Port_Name,
O_RDWR | O_NOCTTY | O_NONBLOCK /*| O_NDELAY */);
if (poSharedData->RS485_Handle < 0) {
perror(poSharedData->RS485_Port_Name);
exit(-1);
@@ -966,8 +927,7 @@ bool dlmstp_init(
#if PRINT_ENABLED
fprintf(stderr, "MS/TP MAC: %02X\n", mstp_port->This_Station);
fprintf(stderr, "MS/TP Max_Master: %02X\n", mstp_port->Nmax_master);
fprintf(stderr, "MS/TP Max_Info_Frames: %u\n",
mstp_port->Nmax_info_frames);
fprintf(stderr, "MS/TP Max_Info_Frames: %u\n", mstp_port->Nmax_info_frames);
#endif
rv = pthread_create(&hThread, NULL, dlmstp_master_fsm_task, mstp_port);
+62 -79
View File
@@ -32,36 +32,35 @@
-------------------------------------------
####COPYRIGHTEND####*/
#include <stdint.h> /* for standard integer types uint8_t etc. */
#include <stdbool.h> /* for the standard bool type. */
#include <stdint.h> /* for standard integer types uint8_t etc. */
#include <stdbool.h> /* for the standard bool type. */
#include "bacport.h"
#include "bacnet/bacdef.h"
#include "bacnet/datalink/ethernet.h"
#include "bacnet/bacint.h"
/** @file linux/ethernet.c Provides Linux-specific functions for BACnet/Ethernet. */
/** @file linux/ethernet.c Provides Linux-specific functions for
* BACnet/Ethernet. */
/* commonly used comparison address for ethernet */
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] =
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
uint8_t Ethernet_Broadcast[MAX_MAC_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF };
/* commonly used empty address for ethernet quick compare */
uint8_t Ethernet_Empty_MAC[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 };
/* my local device data - MAC address */
uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0 };
static int eth802_sockfd = -1; /* 802.2 file handle */
static struct sockaddr eth_addr = { 0 }; /* used for binding 802.2 */
static int eth802_sockfd = -1; /* 802.2 file handle */
static struct sockaddr eth_addr = { 0 }; /* used for binding 802.2 */
bool ethernet_valid(
void)
bool ethernet_valid(void)
{
return (eth802_sockfd >= 0);
}
void ethernet_cleanup(
void)
void ethernet_cleanup(void)
{
if (ethernet_valid())
close(eth802_sockfd);
@@ -92,11 +91,9 @@ int setNonblocking(
#endif
/* opens an 802.2 socket to receive and send packets */
static int ethernet_bind(
struct sockaddr *eth_addr,
char *interface_name)
static int ethernet_bind(struct sockaddr *eth_addr, char *interface_name)
{
int sock_fd = -1; /* return value */
int sock_fd = -1; /* return value */
#if 0
int sockopt = 0;
#endif
@@ -121,13 +118,14 @@ static int ethernet_bind(
/* Attempt to open the socket for 802.2 ethernet frames */
if ((sock_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_802_2))) < 0) {
/* Error occured */
fprintf(stderr, "ethernet: Error opening socket: %s\n",
strerror(errno));
fprintf(
stderr, "ethernet: Error opening socket: %s\n", strerror(errno));
fprintf(stderr,
"You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n" "Then follow it by:\n"
"Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n"
"# modprobe af_packet\n");
exit(-1);
}
@@ -156,7 +154,8 @@ static int ethernet_bind(
"You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n" "Then follow it by:\n"
"Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n"
"# modprobe af_packet\n");
/* Close the socket */
close(sock_fd);
@@ -169,13 +168,11 @@ static int ethernet_bind(
}
/* function to find the local ethernet MAC address */
static int get_local_hwaddr(
const char *ifname,
unsigned char *mac)
static int get_local_hwaddr(const char *ifname, unsigned char *mac)
{
struct ifreq ifr;
int fd;
int rv; /* return value - error value from df or ioctl call */
int rv; /* return value - error value from df or ioctl call */
/* determine the local MAC address */
strcpy(ifr.ifr_name, ifname);
@@ -184,15 +181,14 @@ static int get_local_hwaddr(
rv = fd;
else {
rv = ioctl(fd, SIOCGIFHWADDR, &ifr);
if (rv >= 0) /* worked okay */
if (rv >= 0) /* worked okay */
memcpy(mac, ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
}
return rv;
}
bool ethernet_init(
char *interface_name)
bool ethernet_init(char *interface_name)
{
if (interface_name) {
get_local_hwaddr(interface_name, Ethernet_MAC_Address);
@@ -205,40 +201,35 @@ bool ethernet_init(
return ethernet_valid();
}
int ethernet_send(
uint8_t * mtu,
int mtu_len)
int ethernet_send(uint8_t *mtu, int mtu_len)
{
int bytes = 0;
/* Send the packet */
bytes =
sendto(eth802_sockfd, &mtu, mtu_len, 0, (struct sockaddr *) &eth_addr,
sizeof(struct sockaddr));
bytes = sendto(eth802_sockfd, &mtu, mtu_len, 0,
(struct sockaddr *)&eth_addr, sizeof(struct sockaddr));
/* did it get sent? */
if (bytes < 0)
fprintf(stderr, "ethernet: Error sending packet: %s\n",
strerror(errno));
fprintf(
stderr, "ethernet: Error sending packet: %s\n", strerror(errno));
return bytes;
}
/* function to send a packet out the 802.2 socket */
/* returns number of bytes sent on success, negative on failure */
int ethernet_send_pdu(
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
int ethernet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
BACNET_NPDU_DATA *npdu_data, /* network information */
uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len)
{ /* number of bytes of data */
int i = 0; /* counter */
{ /* number of bytes of data */
int i = 0; /* counter */
int bytes = 0;
BACNET_ADDRESS src = { 0 }; /* source address for npdu */
uint8_t mtu[MAX_MPDU] = { 0 }; /* our buffer */
uint8_t mtu[MAX_MPDU] = { 0 }; /* our buffer */
int mtu_len = 0;
(void) npdu_data;
(void)npdu_data;
/* load the BACnet address for NPDU data */
for (i = 0; i < 6; i++) {
src.mac[i] = Ethernet_MAC_Address[i];
@@ -270,9 +261,9 @@ int ethernet_send_pdu(
return -3;
}
/* Logical PDU portion */
mtu[14] = 0x82; /* DSAP for BACnet */
mtu[15] = 0x82; /* SSAP for BACnet */
mtu[16] = 0x03; /* Control byte in header */
mtu[14] = 0x82; /* DSAP for BACnet */
mtu[15] = 0x82; /* SSAP for BACnet */
mtu[16] = 0x03; /* Control byte in header */
mtu_len = 17;
if ((mtu_len + pdu_len) > MAX_MPDU) {
fprintf(stderr, "ethernet: PDU is too big to send!\n");
@@ -284,28 +275,26 @@ int ethernet_send_pdu(
encode_unsigned16(&mtu[12], 3 + pdu_len);
/* Send the packet */
bytes =
sendto(eth802_sockfd, &mtu, mtu_len, 0, (struct sockaddr *) &eth_addr,
sizeof(struct sockaddr));
bytes = sendto(eth802_sockfd, &mtu, mtu_len, 0,
(struct sockaddr *)&eth_addr, sizeof(struct sockaddr));
/* did it get sent? */
if (bytes < 0)
fprintf(stderr, "ethernet: Error sending packet: %s\n",
strerror(errno));
fprintf(
stderr, "ethernet: Error sending packet: %s\n", strerror(errno));
return bytes;
}
/* receives an 802.2 framed packet */
/* returns the number of octets in the PDU, or zero on failure */
uint16_t ethernet_receive(
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
uint16_t ethernet_receive(BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* PDU data */
uint16_t max_pdu, /* amount of space available in the PDU */
unsigned timeout)
{ /* number of milliseconds to wait for a packet */
{ /* number of milliseconds to wait for a packet */
int received_bytes;
uint8_t buf[MAX_MPDU] = { 0 }; /* data */
uint16_t pdu_len = 0; /* return value */
uint8_t buf[MAX_MPDU] = { 0 }; /* data */
uint16_t pdu_len = 0; /* return value */
fd_set read_fds;
int max;
struct timeval select_timeout;
@@ -359,14 +348,14 @@ uint16_t ethernet_receive(
/* check destination address for when */
/* the Ethernet card is in promiscious mode */
if ((memcmp(&buf[0], Ethernet_MAC_Address, 6) != 0)
&& (memcmp(&buf[0], Ethernet_Broadcast, 6) != 0)) {
if ((memcmp(&buf[0], Ethernet_MAC_Address, 6) != 0) &&
(memcmp(&buf[0], Ethernet_Broadcast, 6) != 0)) {
/*fprintf(stderr, "ethernet: This packet isn't for us\n"); */
return 0;
}
(void) decode_unsigned16(&buf[12], &pdu_len);
pdu_len -= 3 /* DSAP, SSAP, LLC Control */ ;
(void)decode_unsigned16(&buf[12], &pdu_len);
pdu_len -= 3 /* DSAP, SSAP, LLC Control */;
/* copy the buffer into the PDU */
if (pdu_len < max_pdu)
memmove(&pdu[0], &buf[17], pdu_len);
@@ -374,12 +363,10 @@ uint16_t ethernet_receive(
else
pdu_len = 0;
return pdu_len;
}
void ethernet_set_my_address(
BACNET_ADDRESS * my_address)
void ethernet_set_my_address(BACNET_ADDRESS *my_address)
{
int i = 0;
@@ -390,8 +377,7 @@ void ethernet_set_my_address(
return;
}
void ethernet_get_my_address(
BACNET_ADDRESS * my_address)
void ethernet_get_my_address(BACNET_ADDRESS *my_address)
{
int i = 0;
@@ -400,7 +386,7 @@ void ethernet_get_my_address(
my_address->mac[i] = Ethernet_MAC_Address[i];
my_address->mac_len++;
}
my_address->net = 0; /* DNET=0 is local only, no routing */
my_address->net = 0; /* DNET=0 is local only, no routing */
my_address->len = 0;
for (i = 0; i < MAX_MAC_LEN; i++) {
my_address->adr[i] = 0;
@@ -409,10 +395,9 @@ void ethernet_get_my_address(
return;
}
void ethernet_get_broadcast_address(
BACNET_ADDRESS * dest)
{ /* destination address */
int i = 0; /* counter */
void ethernet_get_broadcast_address(BACNET_ADDRESS *dest)
{ /* destination address */
int i = 0; /* counter */
if (dest) {
for (i = 0; i < 6; i++) {
@@ -420,7 +405,7 @@ void ethernet_get_broadcast_address(
}
dest->mac_len = 6;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; /* always zero when DNET is broadcast */
dest->len = 0; /* always zero when DNET is broadcast */
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
@@ -429,11 +414,9 @@ void ethernet_get_broadcast_address(
return;
}
void ethernet_debug_address(
const char *info,
BACNET_ADDRESS * dest)
void ethernet_debug_address(const char *info, BACNET_ADDRESS *dest)
{
int i = 0; /* counter */
int i = 0; /* counter */
if (info)
fprintf(stderr, "%s", info);
@@ -442,14 +425,14 @@ void ethernet_debug_address(
fprintf(stderr, " MAC Length=%d\n", dest->mac_len);
fprintf(stderr, " MAC Address=");
for (i = 0; i < MAX_MAC_LEN; i++) {
fprintf(stderr, "%02X ", (unsigned) dest->mac[i]);
fprintf(stderr, "%02X ", (unsigned)dest->mac[i]);
}
fprintf(stderr, "\n");
fprintf(stderr, " Net=%hu\n", dest->net);
fprintf(stderr, " Len=%d\n", dest->len);
fprintf(stderr, " Adr=");
for (i = 0; i < MAX_MAC_LEN; i++) {
fprintf(stderr, "%02X ", (unsigned) dest->adr[i]);
fprintf(stderr, "%02X ", (unsigned)dest->adr[i]);
}
fprintf(stderr, "\n");
}
+32 -35
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
@@ -41,25 +41,23 @@ static struct timespec start;
/** @brief The timeGetTime function retrieves the system time, in milliseconds.
* The system time is the time elapsed since Windows was started.
*/
static unsigned long timeGetTime(
void)
static unsigned long timeGetTime(void)
{
struct timespec now;
unsigned long ticks;
clock_gettime(CLOCK_MONOTONIC, &now);
ticks =
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec -
start.tv_nsec) / 1000000;
ticks = (now.tv_sec - start.tv_sec) * 1000 +
(now.tv_nsec - start.tv_nsec) / 1000000;
return ticks;
}
/**
* @brief returns the current millisecond count
* @return millisecond counter
*/
* @brief returns the current millisecond count
* @return millisecond counter
*/
unsigned long mstimer_now(void)
{
unsigned long now = timeGetTime();
@@ -75,10 +73,9 @@ unsigned long mstimer_now(void)
}
/**
* @brief Initialization for timer
*/
void mstimer_init(
void)
* @brief Initialization for timer
*/
void mstimer_init(void)
{
clock_gettime(CLOCK_MONOTONIC, &start);
}
+52 -61
View File
@@ -50,11 +50,12 @@
#include "bacnet/datalink/mstptext.h"
#include "bacnet/bacint.h"
/** @file linux/mstpsnap.c Example application testing BACnet MS/TP on Linux. */
/** @file linux/mstpsnap.c Example application testing BACnet MS/TP on Linux.
*/
#ifndef max
#define max(a,b) (((a) (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a)(b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
/* local port data - shared with RS-485 */
@@ -64,8 +65,7 @@ static uint8_t RxBuffer[MAX_MPDU];
static uint8_t TxBuffer[MAX_MPDU];
static struct mstimer Silence_Timer;
static uint32_t Timer_Silence(
void *pArg)
static uint32_t Timer_Silence(void *pArg)
{
uint32_t delta_time = 0;
@@ -77,17 +77,15 @@ static uint32_t Timer_Silence(
return delta_time;
}
static void Timer_Silence_Reset(
void *pArg)
static void Timer_Silence_Reset(void *pArg)
{
mstimer_set(&Silence_Timer, 0);
}
/* functions used by the MS/TP state machine to put or get data */
uint16_t MSTP_Put_Receive(
volatile struct mstp_port_struct_t *mstp_port)
uint16_t MSTP_Put_Receive(volatile struct mstp_port_struct_t *mstp_port)
{
(void) mstp_port;
(void)mstp_port;
return 0;
}
@@ -95,26 +93,22 @@ uint16_t MSTP_Put_Receive(
/* for the MS/TP state machine to use for getting data to send */
/* Return: amount of PDU data */
uint16_t MSTP_Get_Send(
volatile struct mstp_port_struct_t * mstp_port,
unsigned timeout)
{ /* milliseconds to wait for a packet */
(void) mstp_port;
(void) timeout;
volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */
(void)mstp_port;
(void)timeout;
return 0;
}
uint16_t MSTP_Get_Reply(
volatile struct mstp_port_struct_t * mstp_port,
unsigned timeout)
{ /* milliseconds to wait for a packet */
(void) mstp_port;
(void) timeout;
volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */
(void)mstp_port;
(void)timeout;
return 0;
}
static int network_init(
const char *name,
int protocol)
static int network_init(const char *name, int protocol)
{
/* check to see if we are being run as root */
if (getuid() != 0) {
@@ -146,7 +140,7 @@ static int network_init(
sll.sll_ifindex = ifr.ifr_ifindex;
sll.sll_protocol = htons(protocol);
if (bind(sockfd, (struct sockaddr *) &sll, sizeof(sll)) == -1) {
if (bind(sockfd, (struct sockaddr *)&sll, sizeof(sll)) == -1) {
perror("Unable to bind socket");
return -1;
}
@@ -155,11 +149,10 @@ static int network_init(
}
static void snap_received_packet(
volatile struct mstp_port_struct_t *mstp_port,
int sockfd)
volatile struct mstp_port_struct_t *mstp_port, int sockfd)
{
uint16_t mtu_len = 0; /* number of octets of packet saved in file */
unsigned i = 0; /* counter */
uint16_t mtu_len = 0; /* number of octets of packet saved in file */
unsigned i = 0; /* counter */
static uint8_t mtu[1500] = { 0 };
uint16_t max_data = 0;
@@ -176,17 +169,17 @@ static void snap_received_packet(
mtu[10] = 0;
mtu[11] = mstp_port->SourceAddress;
/* length - 12, 13 */
mtu[14] = 0xaa; /* DSAP for SNAP */
mtu[15] = 0xaa; /* SSAP for SNAP */
mtu[16] = 0x03; /* Control Field for SNAP */
mtu[17] = 0x00; /* Organization Code: Cimetrics */
mtu[18] = 0x10; /* Organization Code: Cimetrics */
mtu[19] = 0x90; /* Organization Code: Cimetrics */
mtu[20] = 0x00; /* Protocol ID */
mtu[21] = 0x01; /* Protocol ID */
mtu[22] = 0x00; /* delta time */
mtu[23] = 0x00; /* delta time */
mtu[24] = 0x80; /* unknown byte */
mtu[14] = 0xaa; /* DSAP for SNAP */
mtu[15] = 0xaa; /* SSAP for SNAP */
mtu[16] = 0x03; /* Control Field for SNAP */
mtu[17] = 0x00; /* Organization Code: Cimetrics */
mtu[18] = 0x10; /* Organization Code: Cimetrics */
mtu[19] = 0x90; /* Organization Code: Cimetrics */
mtu[20] = 0x00; /* Protocol ID */
mtu[21] = 0x01; /* Protocol ID */
mtu[22] = 0x00; /* delta time */
mtu[23] = 0x00; /* delta time */
mtu[24] = 0x80; /* unknown byte */
mtu[25] = mstp_port->FrameType;
mtu[26] = mstp_port->DestinationAddress;
mtu[27] = mstp_port->SourceAddress;
@@ -205,27 +198,23 @@ static void snap_received_packet(
}
/* Ethernet length is data only - not address or length bytes */
encode_unsigned16(&mtu[12], mtu_len - 14);
(void) write(sockfd, &mtu[0], mtu_len);
(void)write(sockfd, &mtu[0], mtu_len);
}
static void cleanup(
void)
static void cleanup(void)
{
}
#if (!defined(_WIN32))
static void sig_int(
int signo)
static void sig_int(int signo)
{
(void) signo;
(void)signo;
cleanup();
exit(0);
}
void signal_init(
void)
void signal_init(void)
{
signal(SIGINT, sig_int);
signal(SIGHUP, sig_int);
@@ -234,9 +223,7 @@ void signal_init(
#endif
/* simple test to packetize the data and print it */
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
volatile struct mstp_port_struct_t *mstp_port;
long my_baud = 38400;
@@ -248,14 +235,18 @@ int main(
mstp_port = &MSTP_Port;
if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) {
printf("mstsnap [serial] [baud] [network]\r\n"
"Captures MS/TP packets from a serial interface\r\n"
"and sends them to a network interface using SNAP \r\n"
"protocol packets (mimics Cimetrics U+4 packet).\r\n" "\r\n"
"Command line options:\r\n" "[serial] - serial interface.\r\n"
" defaults to /dev/ttyUSB0.\r\n"
"[baud] - baud rate. 9600, 19200, 38400, 57600, 115200\r\n"
" defaults to 38400.\r\n" "[network] - network interface.\r\n"
" defaults to eth0.\r\n" "");
"Captures MS/TP packets from a serial interface\r\n"
"and sends them to a network interface using SNAP \r\n"
"protocol packets (mimics Cimetrics U+4 packet).\r\n"
"\r\n"
"Command line options:\r\n"
"[serial] - serial interface.\r\n"
" defaults to /dev/ttyUSB0.\r\n"
"[baud] - baud rate. 9600, 19200, 38400, 57600, 115200\r\n"
" defaults to 38400.\r\n"
"[network] - network interface.\r\n"
" defaults to eth0.\r\n"
"");
return 0;
}
/* initialize our interface */
@@ -285,11 +276,11 @@ int main(
MSTP_Port.SilenceTimerReset = Timer_Silence_Reset;
MSTP_Init(mstp_port);
fprintf(stdout, "mstpcap: Using %s for capture at %ld bps.\n",
RS485_Interface(), (long) RS485_Get_Baud_Rate());
RS485_Interface(), (long)RS485_Get_Baud_Rate());
atexit(cleanup);
#if defined(_WIN32)
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT);
SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlCHandler, TRUE);
SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlCHandler, TRUE);
#else
signal_init();
#endif
+92 -106
View File
@@ -54,8 +54,8 @@
#include <termios.h>
#include <unistd.h>
#include <sched.h>
#include <linux/serial.h> /* for struct serial_struct */
#include <math.h> /* for calculation of custom divisor */
#include <linux/serial.h> /* for struct serial_struct */
#include <math.h> /* for calculation of custom divisor */
#include <sys/ioctl.h>
/* for scandir */
#include <dirent.h>
@@ -106,13 +106,12 @@ static uint8_t Rx_Buffer[4096];
#define _POSIX_SOURCE 1 /* POSIX compliant source */
/*********************************************************************
* DESCRIPTION: Configures the interface name
* RETURN: none
* ALGORITHM: none
* NOTES: none
*********************************************************************/
void RS485_Set_Interface(
char *ifname)
* DESCRIPTION: Configures the interface name
* RETURN: none
* ALGORITHM: none
* NOTES: none
*********************************************************************/
void RS485_Set_Interface(char *ifname)
{
/* note: expects a constant char, or char from the heap */
if (ifname) {
@@ -121,25 +120,23 @@ void RS485_Set_Interface(
}
/*********************************************************************
* DESCRIPTION: Returns the interface name
* RETURN: none
* ALGORITHM: none
* NOTES: none
*********************************************************************/
const char *RS485_Interface(
void)
* DESCRIPTION: Returns the interface name
* RETURN: none
* ALGORITHM: none
* NOTES: none
*********************************************************************/
const char *RS485_Interface(void)
{
return RS485_Port_Name;
}
/****************************************************************************
* DESCRIPTION: Returns the baud rate that we are currently running at
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
uint32_t RS485_Get_Baud_Rate(
void)
* DESCRIPTION: Returns the baud rate that we are currently running at
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
uint32_t RS485_Get_Baud_Rate(void)
{
uint32_t baud = 0;
@@ -215,16 +212,15 @@ uint32_t RS485_Get_Baud_Rate(
}
/****************************************************************************
* DESCRIPTION: Returns the baud rate that we are currently running at
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
uint32_t RS485_Get_Port_Baud_Rate(
volatile struct mstp_port_struct_t * mstp_port)
* DESCRIPTION: Returns the baud rate that we are currently running at
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
uint32_t RS485_Get_Port_Baud_Rate(volatile struct mstp_port_struct_t *mstp_port)
{
uint32_t baud = 0;
SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
return 0;
}
@@ -295,13 +291,12 @@ uint32_t RS485_Get_Port_Baud_Rate(
}
/****************************************************************************
* DESCRIPTION: Sets the baud rate for the chip USART
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
bool RS485_Set_Baud_Rate(
uint32_t baud)
* DESCRIPTION: Sets the baud rate for the chip USART
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
bool RS485_Set_Baud_Rate(uint32_t baud)
{
bool valid = true;
@@ -381,16 +376,16 @@ bool RS485_Set_Baud_Rate(
}
/****************************************************************************
* DESCRIPTION: Transmit a frame on the wire
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
* DESCRIPTION: Transmit a frame on the wire
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Send_Frame(
volatile struct mstp_port_struct_t *mstp_port, /* port specific data */
uint8_t * buffer, /* frame to send (up to 501 bytes of data) */
volatile struct mstp_port_struct_t *mstp_port, /* port specific data */
uint8_t *buffer, /* frame to send (up to 501 bytes of data) */
uint16_t nbytes)
{ /* number of bytes of data (up to 501) */
{ /* number of bytes of data (up to 501) */
uint32_t turnaround_time = Tturnaround * 1000;
uint32_t baud;
ssize_t written = 0;
@@ -398,7 +393,7 @@ void RS485_Send_Frame(
SHARED_MSTP_DATA *poSharedData = NULL;
if (mstp_port) {
poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
}
if (!poSharedData) {
baud = RS485_Get_Baud_Rate();
@@ -406,11 +401,12 @@ void RS485_Send_Frame(
time to change from sending to receiving state. */
usleep(turnaround_time / baud);
/*
On success, the number of bytes written are returned (zero indicates
nothing was written). On error, -1 is returned, and errno is set
appropriately. If count is zero and the file descriptor refers to a
regular file, 0 will be returned without causing any other effect. For
a special file, the results are not portable.
On success, the number of bytes written are returned (zero
indicates nothing was written). On error, -1 is returned, and
errno is set appropriately. If count is zero and the file
descriptor refers to a regular file, 0 will be returned without
causing any other effect. For a special file, the results are not
portable.
*/
written = write(RS485_Handle, buffer, nbytes);
greska = errno;
@@ -423,7 +419,7 @@ void RS485_Send_Frame(
/* tcdrain(RS485_Handle); */
/* per MSTP spec, sort of */
if (mstp_port) {
mstp_port->SilenceTimerReset((void *) mstp_port);
mstp_port->SilenceTimerReset((void *)mstp_port);
}
} else {
baud = RS485_Get_Port_Baud_Rate(mstp_port);
@@ -431,11 +427,12 @@ void RS485_Send_Frame(
time to change from sending to receiving state. */
usleep(turnaround_time / baud);
/*
On success, the number of bytes written are returned (zero indicates
nothing was written). On error, -1 is returned, and errno is set
appropriately. If count is zero and the file descriptor refers to a
regular file, 0 will be returned without causing any other effect. For
a special file, the results are not portable.
On success, the number of bytes written are returned (zero
indicates nothing was written). On error, -1 is returned, and
errno is set appropriately. If count is zero and the file
descriptor refers to a regular file, 0 will be returned without
causing any other effect. For a special file, the results are not
portable.
*/
written = write(poSharedData->RS485_Handle, buffer, nbytes);
greska = errno;
@@ -448,7 +445,7 @@ void RS485_Send_Frame(
/* tcdrain(RS485_Handle); */
/* per MSTP spec, sort of */
if (mstp_port) {
mstp_port->SilenceTimerReset((void *) mstp_port);
mstp_port->SilenceTimerReset((void *)mstp_port);
}
}
@@ -456,20 +453,19 @@ void RS485_Send_Frame(
}
/****************************************************************************
* DESCRIPTION: Get a byte of receive data
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Check_UART_Data(
volatile struct mstp_port_struct_t *mstp_port)
* DESCRIPTION: Get a byte of receive data
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
{
fd_set input;
struct timeval waiter;
uint8_t buf[2048];
int n;
SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *) mstp_port->UserData;
SHARED_MSTP_DATA *poSharedData = (SHARED_MSTP_DATA *)mstp_port->UserData;
if (!poSharedData) {
if (mstp_port->ReceiveError == true) {
/* do nothing but wait for state machine to clear the error */
@@ -526,8 +522,7 @@ void RS485_Check_UART_Data(
/* grab bytes and stuff them into the FIFO every time */
FD_ZERO(&input);
FD_SET(poSharedData->RS485_Handle, &input);
n = select(poSharedData->RS485_Handle + 1, &input, NULL, NULL,
&waiter);
n = select(poSharedData->RS485_Handle + 1, &input, NULL, NULL, &waiter);
if (n < 0) {
return;
}
@@ -538,8 +533,7 @@ void RS485_Check_UART_Data(
}
}
void RS485_Cleanup(
void)
void RS485_Cleanup(void)
{
/* restore the old port settings */
tcsetattr(RS485_Handle, TCSANOW, &RS485_oldtio);
@@ -547,9 +541,7 @@ void RS485_Cleanup(
close(RS485_Handle);
}
void RS485_Initialize(
void)
void RS485_Initialize(void)
{
struct termios newtio;
struct serial_struct newserial;
@@ -560,7 +552,7 @@ void RS485_Initialize(
Open device for reading and writing.
Blocking mode - more CPU effecient
*/
RS485_Handle = open(RS485_Port_Name, O_RDWR | O_NOCTTY /*| O_NDELAY */ );
RS485_Handle = open(RS485_Port_Name, O_RDWR | O_NOCTTY /*| O_NDELAY */);
if (RS485_Handle < 0) {
perror(RS485_Port_Name);
exit(-1);
@@ -600,14 +592,12 @@ void RS485_Initialize(
if (RS485_SpecBaud) {
/* 76800, custom divisor must be set */
newserial.flags |= ASYNC_SPD_CUST;
newserial.custom_divisor =
round(((float) newserial.baud_base) / 76800);
newserial.custom_divisor = round(((float)newserial.baud_base) / 76800);
/* we must check that we calculated some sane value;
small baud bases yield bad custom divisor values */
baud_error =
fabs(1 -
((float) newserial.baud_base) /
((float) newserial.custom_divisor) / 76800);
baud_error = fabs(1 -
((float)newserial.baud_base) / ((float)newserial.custom_divisor) /
76800);
if ((newserial.custom_divisor == 0) || (baud_error > 0.02)) {
/* bad divisor */
fprintf(stderr, "bad custom divisor %d, base baud %d\n",
@@ -633,7 +623,7 @@ void RS485_Print_Ports(void)
{
int n;
struct dirent **namelist;
const char* sysdir = "/sys/class/tty/";
const char *sysdir = "/sys/class/tty/";
struct stat st;
char buffer[1024];
char device_dir[1024];
@@ -648,29 +638,27 @@ void RS485_Print_Ports(void)
perror("RS485: scandir");
} else {
while (n--) {
if (strcmp(namelist[n]->d_name,"..") &&
strcmp(namelist[n]->d_name,".")) {
snprintf(device_dir, sizeof(device_dir),
"%s%s/device",
sysdir, namelist[n]->d_name);
if (strcmp(namelist[n]->d_name, "..") &&
strcmp(namelist[n]->d_name, ".")) {
snprintf(device_dir, sizeof(device_dir), "%s%s/device", sysdir,
namelist[n]->d_name);
// 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));
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) {
valid_port = false;
driver_name=basename(buffer);
if (strcmp(driver_name,"serial8250") == 0) {
driver_name = basename(buffer);
if (strcmp(driver_name, "serial8250") == 0) {
// serial8250-devices must be probed
snprintf(device_dir, sizeof(device_dir),
"/dev/%s", namelist[n]->d_name);
fd = open(device_dir,
O_RDWR | O_NONBLOCK | O_NOCTTY);
snprintf(device_dir, sizeof(device_dir), "/dev/%s",
namelist[n]->d_name);
fd = open(
device_dir, O_RDWR | O_NONBLOCK | O_NOCTTY);
if (fd >= 0) {
// Get serial_info
if (ioctl(fd, TIOCGSERIAL, &serinfo)==0) {
if (ioctl(fd, TIOCGSERIAL, &serinfo) == 0) {
// If device type is not PORT_UNKNOWN
// we accept the port
if (serinfo.type != PORT_UNKNOWN) {
@@ -685,7 +673,7 @@ void RS485_Print_Ports(void)
if (valid_port) {
// print full absolute file path
printf("interface {value=/dev/%s}"
"{display=MS/TP Capture on /dev/%s}\n",
"{display=MS/TP Capture on /dev/%s}\n",
namelist[n]->d_name, namelist[n]->d_name);
}
}
@@ -699,13 +687,11 @@ void RS485_Print_Ports(void)
#ifdef TEST_RS485
#include <string.h>
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
volatile struct mstp_port_struct_t mstp_port = {0};
uint8_t token_buf[8] = {0x55, 0xFF, 0x00, 0x7E, 0x07, 0x00, 0x00, 0xFD};
uint8_t pfm_buf[8] = {0x55, 0xFF, 0x01, 0x67, 0x07, 0x00, 0x00, 0x3E};
volatile struct mstp_port_struct_t mstp_port = { 0 };
uint8_t token_buf[8] = { 0x55, 0xFF, 0x00, 0x7E, 0x07, 0x00, 0x00, 0xFD };
uint8_t pfm_buf[8] = { 0x55, 0xFF, 0x01, 0x67, 0x07, 0x00, 0x00, 0x3E };
long baud = 38400;
bool write_token = false;
bool write_pfm = false;
@@ -729,10 +715,10 @@ int main(
RS485_Initialize();
for (;;) {
if (write_token) {
RS485_Send_Frame(NULL,token_buf, sizeof(token_buf));
RS485_Send_Frame(NULL, token_buf, sizeof(token_buf));
usleep(25000);
} else if (write_pfm) {
RS485_Send_Frame(NULL,pfm_buf, sizeof(pfm_buf));
RS485_Send_Frame(NULL, pfm_buf, sizeof(pfm_buf));
usleep(100000);
} else {
RS485_Check_UART_Data(&mstp_port);
+50 -61
View File
@@ -45,7 +45,7 @@
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <signal.h> /* signal handling functions */
#include <signal.h> /* signal handling functions */
/* local includes */
#include "bacnet/bytes.h"
@@ -54,11 +54,12 @@
#include "bacnet/datalink/mstp.h"
#include "bacnet/datalink/mstptext.h"
/** @file linux/rx_fsm.c Example app testing MS/TP Rx State Machine on Linux. */
/** @file linux/rx_fsm.c Example app testing MS/TP Rx State Machine on Linux.
*/
#ifndef max
#define max(a,b) (((a) (b)) ? (a) : (b))
#define min(a,b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a)(b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef LOCAL_PRINT
@@ -71,27 +72,27 @@ static volatile struct mstp_port_struct_t MSTP_Port;
static uint8_t RxBuffer[MAX_MPDU];
static uint8_t TxBuffer[MAX_MPDU];
static uint16_t SilenceTime;
#define INCREMENT_AND_LIMIT_UINT16(x) {if (x < 0xFFFF) x++;}
static uint16_t Timer_Silence(
void)
#define INCREMENT_AND_LIMIT_UINT16(x) \
{ \
if (x < 0xFFFF) \
x++; \
}
static uint16_t Timer_Silence(void)
{
return SilenceTime;
}
static void Timer_Silence_Reset(
void)
static void Timer_Silence_Reset(void)
{
SilenceTime = 0;
}
static void dlmstp_millisecond_timer(
void)
static void dlmstp_millisecond_timer(void)
{
INCREMENT_AND_LIMIT_UINT16(SilenceTime);
}
void *milliseconds_task(
void *pArg)
void *milliseconds_task(void *pArg)
{
struct timespec timeOut, remains;
@@ -107,10 +108,9 @@ void *milliseconds_task(
}
/* functions used by the MS/TP state machine to put or get data */
uint16_t MSTP_Put_Receive(
volatile struct mstp_port_struct_t * mstp_port)
uint16_t MSTP_Put_Receive(volatile struct mstp_port_struct_t *mstp_port)
{
(void) mstp_port;
(void)mstp_port;
return 0;
}
@@ -118,26 +118,23 @@ uint16_t MSTP_Put_Receive(
/* for the MS/TP state machine to use for getting data to send */
/* Return: amount of PDU data */
uint16_t MSTP_Get_Send(
volatile struct mstp_port_struct_t * mstp_port,
unsigned timeout)
{ /* milliseconds to wait for a packet */
(void) mstp_port;
(void) timeout;
volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */
(void)mstp_port;
(void)timeout;
return 0;
}
uint16_t MSTP_Get_Reply(
volatile struct mstp_port_struct_t * mstp_port,
unsigned timeout)
{ /* milliseconds to wait for a packet */
(void) mstp_port;
(void) timeout;
volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */
(void)mstp_port;
(void)timeout;
return 0;
}
/* returns a delta timestamp */
int timestamp_ms(
void)
int timestamp_ms(void)
{
struct timeval tv;
int delta_ticks = 0;
@@ -158,19 +155,18 @@ int timestamp_ms(
}
static const char *Capture_Filename = "mstp.cap";
static FILE *pFile = NULL; /* stream pointer */
static FILE *pFile = NULL; /* stream pointer */
/* write packet to file in libpcap format */
static void write_global_header(
void)
static void write_global_header(void)
{
uint32_t magic_number = 0xa1b2c3d4; /* magic number */
uint16_t version_major = 2; /* major version number */
uint16_t version_minor = 4; /* minor version number */
int32_t thiszone = 0; /* GMT to local correction */
uint32_t sigfigs = 0; /* accuracy of timestamps */
uint32_t snaplen = 65535; /* max length of captured packets, in octets */
uint32_t network = 165; /* data link type - BACNET_MS_TP */
int32_t thiszone = 0; /* GMT to local correction */
uint32_t sigfigs = 0; /* accuracy of timestamps */
uint32_t snaplen = 65535; /* max length of captured packets, in octets */
uint32_t network = 165; /* data link type - BACNET_MS_TP */
/* create a new file. */
pFile = fopen(Capture_Filename, "wb");
@@ -188,14 +184,13 @@ static void write_global_header(
}
}
static void write_received_packet(
volatile struct mstp_port_struct_t *mstp_port)
static void write_received_packet(volatile struct mstp_port_struct_t *mstp_port)
{
uint32_t ts_sec; /* timestamp seconds */
uint32_t ts_usec; /* timestamp microseconds */
uint32_t incl_len; /* number of octets of packet saved in file */
uint32_t orig_len; /* actual length of packet */
uint8_t header[8]; /* MS/TP header */
uint32_t ts_sec; /* timestamp seconds */
uint32_t ts_usec; /* timestamp microseconds */
uint32_t incl_len; /* number of octets of packet saved in file */
uint32_t orig_len; /* actual length of packet */
uint8_t header[8]; /* MS/TP header */
struct timeval tv;
size_t max_data = 0;
@@ -224,8 +219,8 @@ static void write_received_packet(
fwrite(header, sizeof(header), 1, pFile);
if (mstp_port->DataLength) {
fwrite(mstp_port->InputBuffer, max_data, 1, pFile);
fwrite((char *) &(mstp_port->DataCRCActualMSB), 1, 1, pFile);
fwrite((char *) &(mstp_port->DataCRCActualLSB), 1, 1, pFile);
fwrite((char *)&(mstp_port->DataCRCActualMSB), 1, 1, pFile);
fwrite((char *)&(mstp_port->DataCRCActualLSB), 1, 1, pFile);
}
} else {
fprintf(stderr, "rx_fsm: failed to open %s: %s\n", Capture_Filename,
@@ -233,19 +228,17 @@ static void write_received_packet(
}
}
static void cleanup(
void)
static void cleanup(void)
{
if (pFile) {
fflush(pFile); /* stream pointer */
fclose(pFile); /* stream pointer */
fflush(pFile); /* stream pointer */
fclose(pFile); /* stream pointer */
}
pFile = NULL;
}
#if LOCAL_PRINT
static void print_received_packet(
volatile struct mstp_port_struct_t *mstp_port)
static void print_received_packet(volatile struct mstp_port_struct_t *mstp_port)
{
unsigned i = 0;
int timestamp = 0;
@@ -280,17 +273,15 @@ static void print_received_packet(
}
#endif
static void sig_int(
int signo)
static void sig_int(int signo)
{
(void) signo;
(void)signo;
cleanup();
exit(0);
}
void signal_init(
void)
void signal_init(void)
{
signal(SIGINT, sig_int);
signal(SIGHUP, sig_int);
@@ -298,9 +289,7 @@ void signal_init(
}
/* simple test to packetize the data and print it */
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
volatile struct mstp_port_struct_t *mstp_port;
int rc = 0;
@@ -339,7 +328,7 @@ int main(
rc = pthread_create(&hThread, NULL, milliseconds_task, NULL);
atexit(cleanup);
write_global_header();
fflush(pFile); /* stream pointer */
fflush(pFile); /* stream pointer */
/* run forever */
for (;;) {
RS485_Check_UART_Data(mstp_port);
@@ -351,7 +340,7 @@ int main(
print_received_packet(mstp_port);
#endif
write_received_packet(mstp_port);
fflush(pFile); /* stream pointer */
fflush(pFile); /* stream pointer */
} else if (mstp_port->ReceivedInvalidFrame) {
mstp_port->ReceivedInvalidFrame = false;
fprintf(stderr, "ReceivedInvalidFrame\n");
@@ -359,7 +348,7 @@ int main(
print_received_packet(mstp_port);
#endif
write_received_packet(mstp_port);
fflush(pFile); /* stream pointer */
fflush(pFile); /* stream pointer */
}
}