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
+54 -60
View File
@@ -35,8 +35,8 @@
#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/bacint.h"
#include "bacnet/config.h"
@@ -75,8 +75,10 @@ static bool BIP_Debug = false;
* @param str - debug info string
* @param addr - IPv4 address
*/
static void debug_print_ipv4(const char *str, const struct in_addr *addr,
const unsigned int port, const unsigned int count)
static void debug_print_ipv4(const char *str,
const struct in_addr *addr,
const unsigned int port,
const unsigned int count)
{
if (BIP_Debug) {
fprintf(stderr, "BIP: %s %s:%hu (%u bytes)\n", str, inet_ntoa(*addr),
@@ -96,8 +98,7 @@ void bip_debug_enable(void)
/**
* @brief Get the text string for Windows Error Codes
*/
static char *winsock_error_code_text(
int code)
static char *winsock_error_code_text(int code)
{
switch (code) {
case WSAEACCES:
@@ -116,9 +117,9 @@ static char *winsock_error_code_text(
return "Operation would block.";
case WSAEINPROGRESS:
return "Operation now in progress. "
"This error is returned if any Windows Sockets API "
"function is called while a blocking function "
"is in progress.";
"This error is returned if any Windows Sockets API "
"function is called while a blocking function "
"is in progress.";
case WSAENOTSOCK:
return "Socket operation on nonsocket.";
case WSAEDESTADDRREQ:
@@ -145,9 +146,9 @@ static char *winsock_error_code_text(
return "Cannot assign requested address.";
case WSAENETDOWN:
return "Network is down. "
"This error may be reported at any time "
"if the Windows Sockets implementation "
"detects an underlying failure.";
"This error may be reported at any time "
"if the Windows Sockets implementation "
"detects an underlying failure.";
case WSAENETUNREACH:
return "Network is unreachable.";
case WSAENETRESET:
@@ -180,34 +181,35 @@ static char *winsock_error_code_text(
return "No route to host.";
case WSASYSNOTREADY:
return "Returned by WSAStartup(), "
"indicating that the network subsystem is unusable.";
"indicating that the network subsystem is unusable.";
case WSAVERNOTSUPPORTED:
return "Returned by WSAStartup(), "
"indicating that the Windows Sockets DLL cannot support "
"this application.";
"indicating that the Windows Sockets DLL cannot support "
"this application.";
case WSANOTINITIALISED:
return "Winsock not initialized. "
"This message is returned by any function "
"except WSAStartup(), "
"indicating that a successful WSAStartup() has not yet "
"been performed.";
"This message is returned by any function "
"except WSAStartup(), "
"indicating that a successful WSAStartup() has not yet "
"been performed.";
case WSAEDISCON:
return "Disconnect.";
case WSAHOST_NOT_FOUND:
return "Host not found. " "This message indicates that the key "
"(name, address, and so on) was not found.";
return "Host not found. "
"This message indicates that the key "
"(name, address, and so on) was not found.";
case WSATRY_AGAIN:
return "Nonauthoritative host not found. "
"This error may suggest that the name service itself "
"is not functioning.";
"This error may suggest that the name service itself "
"is not functioning.";
case WSANO_RECOVERY:
return "Nonrecoverable error. "
"This error may suggest that the name service itself "
"is not functioning.";
"This error may suggest that the name service itself "
"is not functioning.";
case WSANO_DATA:
return "Valid name, no data record of requested type. "
"This error indicates that the key "
"(name, address, and so on) was not found.";
"This error indicates that the key "
"(name, address, and so on) was not found.";
default:
return "unknown";
}
@@ -219,8 +221,8 @@ static char *winsock_error_code_text(
static void print_last_error(const char *info)
{
int Code = WSAGetLastError();
fprintf(stderr, "BIP: %s [error code %i] %s\n",
info, Code, winsock_error_code_text(Code));
fprintf(stderr, "BIP: %s [error code %i] %s\n", info, Code,
winsock_error_code_text(Code));
fflush(stderr);
}
@@ -392,7 +394,7 @@ uint8_t bip_get_subnet_prefix(void)
if (test_broadcast == broadcast) {
break;
}
mask = mask<<1;
mask = mask << 1;
}
return prefix;
@@ -427,8 +429,8 @@ int bip_send_mpdu(BACNET_IP_ADDRESS *dest, uint8_t *mtu, uint16_t mtu_len)
memcpy(&bip_dest.sin_addr.s_addr, &dest->address[0], 4);
bip_dest.sin_port = htons(dest->port);
/* Send the packet */
debug_print_ipv4("Sending MPDU->", &bip_dest.sin_addr, bip_dest.sin_port,
mtu_len);
debug_print_ipv4(
"Sending MPDU->", &bip_dest.sin_addr, bip_dest.sin_port, mtu_len);
rv = sendto(BIP_Socket, (char *)mtu, mtu_len, 0,
(struct sockaddr *)&bip_dest, sizeof(struct sockaddr));
if (rv == SOCKET_ERROR) {
@@ -506,8 +508,8 @@ uint16_t bip_receive(
*/
memcpy(&addr.address[0], &sin.sin_addr.s_addr, 4);
addr.port = ntohs(sin.sin_port);
debug_print_ipv4("Received MPDU->", &sin.sin_addr, sin.sin_port,
received_bytes);
debug_print_ipv4(
"Received MPDU->", &sin.sin_addr, sin.sin_port, received_bytes);
/* pass the packet into the BBMD handler */
offset = bvlc_handler(&addr, src, npdu, received_bytes);
if (offset > 0) {
@@ -575,8 +577,7 @@ bool bip_get_addr_by_name(const char *host_name, BACNET_IP_ADDRESS *addr)
}
/* To fill a need, we invent the gethostaddr() function. */
static long gethostaddr(
void)
static long gethostaddr(void)
{
struct hostent *host_ent;
char host_name[255];
@@ -591,20 +592,19 @@ static long gethostaddr(
}
if (BIP_Debug) {
fprintf(stderr, "BIP: host %s at %u.%u.%u.%u\n", host_name,
(unsigned) ((uint8_t *) host_ent->h_addr)[0],
(unsigned) ((uint8_t *) host_ent->h_addr)[1],
(unsigned) ((uint8_t *) host_ent->h_addr)[2],
(unsigned) ((uint8_t *) host_ent->h_addr)[3]);
(unsigned)((uint8_t *)host_ent->h_addr)[0],
(unsigned)((uint8_t *)host_ent->h_addr)[1],
(unsigned)((uint8_t *)host_ent->h_addr)[2],
(unsigned)((uint8_t *)host_ent->h_addr)[3]);
fflush(stderr);
}
/* note: network byte order */
return *(long *) host_ent->h_addr;
return *(long *)host_ent->h_addr;
}
#if ((USE_INADDR == 0) || (USE_CLASSADDR == 0))
/* returns the subnet mask in network byte order */
static uint32_t getIpMaskForIpAddress(
uint32_t ipAddress)
static uint32_t getIpMaskForIpAddress(uint32_t ipAddress)
{
/* Allocate information for up to 16 NICs */
IP_ADAPTER_INFO AdapterInfo[16];
@@ -618,8 +618,7 @@ static uint32_t getIpMaskForIpAddress(
/* GetAdapterInfo:
[out] buffer to receive data
[in] size of receive data buffer */
DWORD dwStatus = GetAdaptersInfo(AdapterInfo,
&dwBufLen);
DWORD dwStatus = GetAdaptersInfo(AdapterInfo, &dwBufLen);
if (dwStatus == ERROR_SUCCESS) {
/* Verify return value is valid, no buffer overflow
Contains pointer to current adapter info */
@@ -648,8 +647,7 @@ static uint32_t getIpMaskForIpAddress(
}
#endif
static void set_broadcast_address(
uint32_t net_address)
static void set_broadcast_address(uint32_t net_address)
{
#if USE_INADDR
/* Note: sometimes INADDR_BROADCAST does not let me get
@@ -698,8 +696,7 @@ static void set_broadcast_address(
* @param ifname [in] The named interface to use for the network layer.
* Eg, for Windows, ifname is the dotted ip address of the interface
*/
void bip_set_interface(
char *ifname)
void bip_set_interface(char *ifname)
{
bip_init_windows();
/* setup local address */
@@ -734,8 +731,7 @@ void bip_set_interface(
* @return True if the socket is successfully opened for BACnet/IP,
* else False if the socket functions fail.
*/
bool bip_init(
char *ifname)
bool bip_init(char *ifname)
{
int rv = 0; /* return from socket lib calls */
struct sockaddr_in sin = { -1 };
@@ -771,8 +767,8 @@ bool bip_init(
}
/* Allow us to use the same socket for sending and receiving */
/* This makes sure that the src port is correct when sending */
rv = setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *) &value,
sizeof(value));
rv = setsockopt(
sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(value));
if (rv < 0) {
print_last_error("failed to set REUSEADDR socket option");
closesocket(sock_fd);
@@ -780,8 +776,8 @@ bool bip_init(
return false;
}
/* Enables transmission and receipt of broadcast messages on the socket. */
rv = setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, (char *) &value,
sizeof(value));
rv = setsockopt(
sock_fd, SOL_SOCKET, SO_BROADCAST, (char *)&value, sizeof(value));
if (rv < 0) {
print_last_error("failed to set BROADCAST socket option");
closesocket(sock_fd);
@@ -816,8 +812,7 @@ bool bip_init(
ntohs(sin.sin_port));
fflush(stderr);
}
rv = bind(sock_fd, (const struct sockaddr *) &sin,
sizeof(struct sockaddr));
rv = bind(sock_fd, (const struct sockaddr *)&sin, sizeof(struct sockaddr));
if (rv < 0) {
print_last_error("failed to bind");
closesocket(sock_fd);
@@ -839,9 +834,8 @@ bool bip_valid(void)
/** Cleanup and close out the BACnet/IP services by closing the socket.
* @ingroup DLBIP
*/
void bip_cleanup(
void)
*/
void bip_cleanup(void)
{
SOCKET sock_fd = 0;
+62 -83
View File
@@ -34,8 +34,8 @@
#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/basic/sys/debug.h"
@@ -50,16 +50,16 @@ static SOCKET BIP6_Socket = INVALID_SOCKET;
static BACNET_IP6_ADDRESS BIP6_Addr;
static BACNET_IP6_ADDRESS BIP6_Broadcast_Addr;
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]);
}
@@ -72,19 +72,18 @@ static LPSTR PrintError(int ErrorCode)
// (And of course, free the buffer when we were done with it)
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, ErrorCode,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR) Message, 1024, NULL);
FORMAT_MESSAGE_MAX_WIDTH_MASK,
NULL, ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)Message, 1024, NULL);
return Message;
}
/* on Windows, ifname is the IPv6 address of the interface */
void bip6_set_interface(
char *ifname)
void bip6_set_interface(char *ifname)
{
int i, RetVal;
struct addrinfo Hints, *AddrInfo, *AI;
struct sockaddr_in6* sin;
struct sockaddr_in6 *sin;
struct sockaddr_in6 server;
struct in6_addr broadcast_address;
struct ipv6_mreq join_request;
@@ -99,7 +98,7 @@ void bip6_set_interface(
// entry per allowed protocol family containing the unspecified address
// for that family.
//
memset(&Hints, 0, sizeof (Hints));
memset(&Hints, 0, sizeof(Hints));
Hints.ai_family = PF_INET6;
Hints.ai_socktype = SOCK_DGRAM;
Hints.ai_protocol = IPPROTO_UDP;
@@ -108,8 +107,8 @@ void bip6_set_interface(
debug_printf("BIP6: getaddrinfo - IPv6 address %s port %s\n", ifname, port);
RetVal = getaddrinfo(ifname, &port[0], &Hints, &AddrInfo);
if (RetVal != 0) {
fprintf(stderr, "BIP6: getaddrinfo failed with error %d: %s\n",
RetVal, gai_strerror(RetVal));
fprintf(stderr, "BIP6: getaddrinfo failed with error %d: %s\n", RetVal,
gai_strerror(RetVal));
WSACleanup();
return;
}
@@ -122,7 +121,8 @@ void bip6_set_interface(
// Highly unlikely, but check anyway.
if (i == FD_SETSIZE) {
fprintf(stderr,
"BIP6: getaddrinfo returned more addresses than we could use.\n");
"BIP6: getaddrinfo returned more addresses than we could "
"use.\n");
break;
}
// only support PF_INET6.
@@ -140,20 +140,18 @@ void bip6_set_interface(
BIP6_Socket = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (BIP6_Socket == INVALID_SOCKET) {
fprintf(stderr, "BIP6: socket() failed with error %d: %s\n",
WSAGetLastError(), PrintError(WSAGetLastError()));
WSAGetLastError(), PrintError(WSAGetLastError()));
continue;
}
if ((AI->ai_family == PF_INET6) &&
IN6_IS_ADDR_LINKLOCAL(AI->ai_addr) &&
(((SOCKADDR_IN6 *) (AI->ai_addr))->sin6_scope_id == 0)) {
fprintf(stderr,
"BIP6: IPv6 link local addresses needs a scope ID!\n");
if ((AI->ai_family == PF_INET6) && IN6_IS_ADDR_LINKLOCAL(AI->ai_addr) &&
(((SOCKADDR_IN6 *)(AI->ai_addr))->sin6_scope_id == 0)) {
fprintf(
stderr, "BIP6: IPv6 link local addresses needs a scope ID!\n");
}
/* Allow us to use the same socket for sending and receiving */
/* This makes sure that the src port is correct when sending */
sockopt = 1;
RetVal =
setsockopt(BIP6_Socket, SOL_SOCKET, SO_REUSEADDR,
RetVal = setsockopt(BIP6_Socket, SOL_SOCKET, SO_REUSEADDR,
(char *)&sockopt, sizeof(sockopt));
if (RetVal < 0) {
closesocket(BIP6_Socket);
@@ -161,13 +159,13 @@ void bip6_set_interface(
continue;
}
/* allow us to send a broadcast */
RetVal =
setsockopt(BIP6_Socket, SOL_SOCKET, SO_BROADCAST,
RetVal = setsockopt(BIP6_Socket, SOL_SOCKET, SO_BROADCAST,
(char *)&sockopt, sizeof(sockopt));
if (RetVal < 0) {
closesocket(BIP6_Socket);
BIP6_Socket = INVALID_SOCKET;
fprintf(stderr, "BIP6: setsockopt(SO_BROADCAST) failed "
fprintf(stderr,
"BIP6: setsockopt(SO_BROADCAST) failed "
"with error %d: %s\n",
WSAGetLastError(), PrintError(WSAGetLastError()));
continue;
@@ -182,7 +180,8 @@ void bip6_set_interface(
RetVal = setsockopt(BIP6_Socket, IPPROTO_IPV6, IPV6_JOIN_GROUP,
(char *)&join_request, sizeof(join_request));
if (RetVal < 0) {
fprintf(stderr, "BIP6: setsockopt(IPV6_JOIN_GROUP) failed "
fprintf(stderr,
"BIP6: setsockopt(IPV6_JOIN_GROUP) failed "
"with error %d: %s\n",
WSAGetLastError(), PrintError(WSAGetLastError()));
}
@@ -196,16 +195,15 @@ void bip6_set_interface(
server.sin6_family = PF_INET6;
server.sin6_port = htons(BIP6_Addr.port);
server.sin6_addr = in6addr_any;
if (bind(BIP6_Socket, (struct sockaddr *) &server, sizeof(server)) ==
if (bind(BIP6_Socket, (struct sockaddr *)&server, sizeof(server)) ==
SOCKET_ERROR) {
fprintf(stderr, "BIP6: bind() failed with error %d: %s\n",
WSAGetLastError(), PrintError(WSAGetLastError()));
WSAGetLastError(), PrintError(WSAGetLastError()));
closesocket(ServSock[i]);
continue;
} else {
sin = (struct sockaddr_in6*)AI->ai_addr;
bvlc6_address_set(&BIP6_Addr,
ntohs(sin->sin6_addr.s6_addr16[0]),
sin = (struct sockaddr_in6 *)AI->ai_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]),
@@ -213,7 +211,8 @@ void bip6_set_interface(
ntohs(sin->sin6_addr.s6_addr16[5]),
ntohs(sin->sin6_addr.s6_addr16[6]),
ntohs(sin->sin6_addr.s6_addr16[7]));
/* https://msdn.microsoft.com/en-us/library/windows/desktop/ms740496(v=vs.85).aspx */
/* https://msdn.microsoft.com/en-us/library/windows/desktop/ms740496(v=vs.85).aspx
*/
}
i++;
if (BIP6_Socket != INVALID_SOCKET) {
@@ -228,8 +227,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;
@@ -240,8 +238,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;
}
@@ -252,8 +249,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;
@@ -267,8 +263,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;
@@ -283,8 +278,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);
}
@@ -294,13 +288,11 @@ 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);
}
/**
* Determine if the BACnet/IPv6 address matches our own address
*
@@ -308,8 +300,7 @@ bool bip6_get_addr(
*
* @return true if the BACnet/IPv6 address matches our own address
*/
bool bip6_address_match_self(
BACNET_IP6_ADDRESS *addr)
bool bip6_address_match_self(BACNET_IP6_ADDRESS *addr)
{
return !bvlc6_address_different(addr, &BIP6_Addr);
}
@@ -319,8 +310,7 @@ bool bip6_address_match_self(
*
* @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);
}
@@ -330,8 +320,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);
}
@@ -347,10 +336,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];
@@ -374,8 +360,8 @@ int bip6_send_mpdu(
bvlc_dest.sin6_port = htons(dest->port);
debug_print_ipv6("BIP6: 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));
}
/**
@@ -409,17 +395,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;
@@ -445,9 +428,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;
}
@@ -484,9 +466,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);
@@ -516,16 +497,15 @@ void bip6_cleanup(
* @return True if the socket is successfully opened for BACnet/IPv6,
* else False if the socket functions fail.
*/
bool bip6_init(
char *ifname)
bool bip6_init(char *ifname)
{
WSADATA wd;
int RetVal;
// Ask for Winsock version 2.2.
if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wd)) != 0) {
fprintf(stderr, "BIP6: WSAStartup failed with error %d: %s\n",
RetVal, PrintError(RetVal));
fprintf(stderr, "BIP6: WSAStartup failed with error %d: %s\n", RetVal,
PrintError(RetVal));
WSACleanup();
exit(1);
}
@@ -535,9 +515,8 @@ bool bip6_init(
debug_printf("BIP6: IPv6 UDP port: 0x%04X\n", BIP6_Addr.port);
bip6_set_interface(ifname);
if (BIP6_Broadcast_Addr.address[0] == 0) {
bvlc6_address_set(&BIP6_Broadcast_Addr,
BIP6_MULTICAST_LINK_LOCAL, 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_GROUP_ID);
bvlc6_address_set(&BIP6_Broadcast_Addr, BIP6_MULTICAST_LINK_LOCAL, 0, 0,
0, 0, 0, 0, BIP6_MULTICAST_GROUP_ID);
}
if (BIP6_Socket == INVALID_SOCKET) {
fprintf(stderr, "BIP6: Fatal error: unable to serve on any address.\n");
+25 -29
View File
@@ -21,9 +21,9 @@
/* Offset between Windows epoch 1/1/1601 and
Unix epoch 1/1/1970 in 100 nanosec units */
#if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) || defined(__BORLANDC__)
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
#endif
#if defined(__BORLANDC__) || defined(_WIN32)
@@ -35,21 +35,19 @@ long int timezone;
#if defined(_MSC_VER) || defined(__BORLANDC__)
struct timezone {
int tz_minuteswest; /* minutes W of Greenwich */
int tz_dsttime; /* type of dst correction */
int tz_dsttime; /* type of dst correction */
};
/*************************************************************************
* Description: simulate the gettimeofday Linux function
* Returns: zero
* Note: The resolution of GetSystemTimeAsFileTime() is 15625 microseconds.
* The resolution of _ftime() is about 16 milliseconds.
* To get microseconds accuracy we need to use QueryPerformanceCounter or
* timeGetTime for the elapsed time.
*************************************************************************/
* Description: simulate the gettimeofday Linux function
* Returns: zero
* Note: The resolution of GetSystemTimeAsFileTime() is 15625 microseconds.
* The resolution of _ftime() is about 16 milliseconds.
* To get microseconds accuracy we need to use QueryPerformanceCounter or
* timeGetTime for the elapsed time.
*************************************************************************/
int gettimeofday(
struct timeval *tp,
void *tzp)
int gettimeofday(struct timeval *tp, void *tzp)
{
static int tzflag = 0;
struct timezone *tz;
@@ -71,16 +69,16 @@ int gettimeofday(
usec_timer <<= 32;
usec_timer |= ft.dwLowDateTime;
/*converting file time to unix epoch 1970 */
usec_timer /= 10; /*convert into microseconds */
usec_timer /= 10; /*convert into microseconds */
usec_timer -= DELTA_EPOCH_IN_MICROSECS;
tp->tv_sec = (long) (usec_timer / 1000000UL);
tp->tv_usec = (long) (usec_timer % 1000000UL);
tp->tv_sec = (long)(usec_timer / 1000000UL);
tp->tv_usec = (long)(usec_timer % 1000000UL);
time_start = timeGetTime();
} else {
elapsed_milliseconds = timeGetTime() - time_start;
usec_elapsed = usec_timer + ((LONGLONG) elapsed_milliseconds * 1000UL);
tp->tv_sec = (long) (usec_elapsed / 1000000UL);
tp->tv_usec = (long) (usec_elapsed % 1000000UL);
usec_elapsed = usec_timer + ((LONGLONG)elapsed_milliseconds * 1000UL);
tp->tv_sec = (long)(usec_elapsed / 1000000UL);
tp->tv_usec = (long)(usec_elapsed % 1000000UL);
}
if (tzp) {
if (!tzflag) {
@@ -105,11 +103,10 @@ int gettimeofday(
* @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;
@@ -141,15 +138,14 @@ 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);
#if !defined(_MSC_VER)
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));
#else
datetime_set_time(btime, (uint8_t)tblock->tm_hour,
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, 0);
(uint8_t)tblock->tm_min, (uint8_t)tblock->tm_sec, 0);
#endif
if (dst_active) {
/* The value of tm_isdst is:
+107 -140
View File
@@ -1,28 +1,28 @@
/**************************************************************************
*
* Copyright (C) 2006 Steve Karg <skarg@users.sourceforge.net>
* Multimedia Timer contribution by Cameron Crothers, 2008
*
* 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) 2006 Steve Karg <skarg@users.sourceforge.net>
* Multimedia Timer contribution by Cameron Crothers, 2008
*
* 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>
@@ -40,7 +40,7 @@
#define WIN32_LEAN_AND_MEAN
#define STRICT 1
#include <windows.h>
#include <MMSystem.h> /* for multimedia timers */
#include <MMSystem.h> /* for multimedia timers */
/* Number of MS/TP Packets Rx/Tx */
uint16_t MSTP_Packets = 0;
@@ -62,8 +62,7 @@ static uint32_t TimeBeginPeriod;
/* 1-millisecond target resolution */
#define TARGET_RESOLUTION 1
static uint16_t Timer_Silence(
void)
static uint16_t Timer_Silence(void)
{
uint32_t now = timeGetTime();
uint32_t delta_time = 0;
@@ -77,17 +76,15 @@ static uint16_t Timer_Silence(
delta_time = 0xFFFF;
}
return (uint16_t) delta_time;
return (uint16_t)delta_time;
}
static void Timer_Silence_Reset(
void)
static void Timer_Silence_Reset(void)
{
SilenceStartTime = timeGetTime();
}
void dlmstp_reinit(
void)
void dlmstp_reinit(void)
{
/*RS485_Reinit(); */
dlmstp_set_mac_address(DEFAULT_MAC_ADDRESS);
@@ -97,8 +94,7 @@ void dlmstp_reinit(
timeEndPeriod(TimeBeginPeriod);
}
void dlmstp_cleanup(
void)
void dlmstp_cleanup(void)
{
/* nothing to do for static buffers */
if (Received_Frame_Flag) {
@@ -110,19 +106,17 @@ 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;
unsigned i = 0;
if (!Transmit_Packet.ready) {
if (npdu_data->data_expecting_reply) {
Transmit_Packet.frame_type =
FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
Transmit_Packet.frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else {
Transmit_Packet.frame_type =
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
@@ -139,16 +133,15 @@ 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;
DWORD wait_status = 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 */
wait_status = WaitForSingleObject(Receive_Packet_Flag, timeout);
@@ -161,8 +154,8 @@ 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;
}
@@ -173,14 +166,12 @@ uint16_t dlmstp_receive(
return pdu_len;
}
static void dlmstp_receive_fsm_task(
void *pArg)
static void dlmstp_receive_fsm_task(void *pArg)
{
bool received_frame;
(void) pArg;
(void) SetThreadPriority(GetCurrentThread(),
THREAD_PRIORITY_TIME_CRITICAL);
(void)pArg;
(void)SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
while (TRUE) {
/* only do receive state machine while we don't have a frame */
if ((MSTP_Port.ReceivedValidFrame == false) &&
@@ -199,14 +190,12 @@ static void dlmstp_receive_fsm_task(
}
}
static void dlmstp_master_fsm_task(
void *pArg)
static void dlmstp_master_fsm_task(void *pArg)
{
DWORD dwMilliseconds = 0;
(void) pArg;
(void) SetThreadPriority(GetCurrentThread(),
THREAD_PRIORITY_TIME_CRITICAL);
(void)pArg;
(void)SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
while (TRUE) {
switch (MSTP_Port.master_state) {
case MSTP_MASTER_STATE_IDLE:
@@ -228,9 +217,7 @@ static void dlmstp_master_fsm_task(
}
}
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;
@@ -254,8 +241,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;
BOOL rc;
@@ -265,10 +251,10 @@ uint16_t MSTP_Put_Receive(
pdu_len = mstp_port->DataLength;
if (pdu_len > sizeof(Receive_Packet.pdu))
pdu_len = sizeof(Receive_Packet.pdu);
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;
rc = ReleaseSemaphore(Receive_Packet_Flag, 1, NULL);
@@ -280,13 +266,12 @@ 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 destination = 0; /* destination address */
uint8_t destination = 0; /* destination address */
(void) timeout;
(void)timeout;
if (!Transmit_Packet.ready) {
return 0;
}
@@ -301,22 +286,22 @@ uint16_t MSTP_Get_Send(
return 0;
}
/* convert the PDU into the MSTP Frame */
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, Transmit_Packet.frame_type, destination,
mstp_port->This_Station, &Transmit_Packet.pdu[0],
Transmit_Packet.pdu_len);
pdu_len =
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, Transmit_Packet.frame_type,
destination, mstp_port->This_Station, &Transmit_Packet.pdu[0],
Transmit_Packet.pdu_len);
Transmit_Packet.ready = false;
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,
BACNET_ADDRESS * dest_address)
BACNET_ADDRESS *dest_address)
{
uint16_t offset;
/* One way to check the message is to compare NPDU
@@ -338,9 +323,8 @@ 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) {
return false;
}
@@ -356,8 +340,7 @@ bool dlmstp_compare_data_expecting_reply(
request.service_choice = request_pdu[offset + 3];
/* decode the reply data */
bacnet_address_copy(&reply.address, dest_address);
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) {
return false;
}
@@ -402,7 +385,8 @@ bool dlmstp_compare_data_expecting_reply(
return false;
}
}
if (request.npdu_data.protocol_version != reply.npdu_data.protocol_version) {
if (request.npdu_data.protocol_version !=
reply.npdu_data.protocol_version) {
return false;
}
#if 0
@@ -421,14 +405,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 */
uint8_t destination = 0; /* destination address */
volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */
uint16_t pdu_len = 0; /* return value */
uint8_t destination = 0; /* destination address */
bool matched = false;
(void) timeout;
(void)timeout;
if (!Transmit_Packet.ready) {
return 0;
}
@@ -442,25 +425,24 @@ uint16_t MSTP_Get_Reply(
return 0;
}
/* 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,
&Transmit_Packet.pdu[0], Transmit_Packet.pdu_len,
&Transmit_Packet.address);
if (!matched)
return 0;
/* convert the PDU into the MSTP Frame */
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, Transmit_Packet.frame_type, destination,
mstp_port->This_Station, &Transmit_Packet.pdu[0],
Transmit_Packet.pdu_len);
pdu_len =
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, Transmit_Packet.frame_type,
destination, mstp_port->This_Station, &Transmit_Packet.pdu[0],
Transmit_Packet.pdu_len);
Transmit_Packet.ready = false;
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) {
@@ -477,8 +459,7 @@ void dlmstp_set_mac_address(
return;
}
uint8_t dlmstp_mac_address(
void)
uint8_t dlmstp_mac_address(void)
{
return MSTP_Port.This_Station;
}
@@ -490,8 +471,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;
@@ -505,8 +485,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;
}
@@ -516,8 +495,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) {
@@ -533,33 +511,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;
@@ -568,16 +542,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;
}
@@ -586,8 +559,7 @@ void dlmstp_get_broadcast_address(
return;
}
bool dlmstp_init(
char *ifname)
bool dlmstp_init(char *ifname)
{
unsigned long hThread = 0;
uint32_t arg_value = 0;
@@ -658,8 +630,7 @@ bool dlmstp_init(
if (timeGetDevCaps(&tc, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
fprintf(stderr, "Failed to set timer resolution\n");
}
TimeBeginPeriod =
min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
TimeBeginPeriod = min(max(tc.wPeriodMin, TARGET_RESOLUTION), tc.wPeriodMax);
timeBeginPeriod(TimeBeginPeriod);
/* start the threads */
@@ -678,19 +649,17 @@ 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;
}
/* returns a delta timestamp */
uint32_t timestamp_ms(
void)
uint32_t timestamp_ms(void)
{
DWORD ticks = 0, delta_ticks = 0;
static DWORD last_ticks = 0;
@@ -705,9 +674,7 @@ uint32_t timestamp_ms(
static char *Network_Interface = "COM3";
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
uint16_t pdu_len = 0;
+106 -137
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2006 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) 2006 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 <process.h>
#include <stdbool.h>
@@ -69,20 +69,17 @@ static uint8_t Tusage_timeout = 30;
static struct mstimer Silence_Timer;
/* Timer that indicates line silence - and functions */
static uint32_t Timer_Silence(
void *pArg)
static uint32_t Timer_Silence(void *pArg)
{
return mstimer_elapsed(&Silence_Timer);
}
static void Timer_Silence_Reset(
void *pArg)
static void Timer_Silence_Reset(void *pArg)
{
mstimer_set(&Silence_Timer, 0);
}
void dlmstp_cleanup(
void)
void dlmstp_cleanup(void)
{
/* nothing to do for static buffers */
if (Received_Frame_Flag) {
@@ -94,24 +91,22 @@ 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;
unsigned i = 0;
if (!Transmit_Packet.ready) {
if (npdu_data->data_expecting_reply) {
Transmit_Packet.frame_type =
FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
Transmit_Packet.frame_type = FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY;
} else {
Transmit_Packet.frame_type =
FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY;
}
Transmit_Packet.pdu_len = (uint16_t) pdu_len;
Transmit_Packet.pdu_len = (uint16_t)pdu_len;
for (i = 0; i < pdu_len; i++) {
Transmit_Packet.pdu[i] = pdu[i];
}
@@ -123,16 +118,15 @@ 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;
DWORD wait_status = 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 */
wait_status = WaitForSingleObject(Receive_Packet_Flag, timeout);
@@ -145,8 +139,8 @@ 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;
}
@@ -157,14 +151,12 @@ uint16_t dlmstp_receive(
return pdu_len;
}
static void dlmstp_receive_fsm_task(
void *pArg)
static void dlmstp_receive_fsm_task(void *pArg)
{
bool received_frame;
(void) pArg;
(void) SetThreadPriority(GetCurrentThread(),
THREAD_PRIORITY_TIME_CRITICAL);
(void)pArg;
(void)SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
for (;;) {
/* only do receive state machine while we don't have a frame */
if ((MSTP_Port.ReceivedValidFrame == false) &&
@@ -183,14 +175,12 @@ static void dlmstp_receive_fsm_task(
}
}
static void dlmstp_master_fsm_task(
void *pArg)
static void dlmstp_master_fsm_task(void *pArg)
{
DWORD dwMilliseconds = 0;
(void) pArg;
(void) SetThreadPriority(GetCurrentThread(),
THREAD_PRIORITY_TIME_CRITICAL);
(void)pArg;
(void)SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
for (;;) {
switch (MSTP_Port.master_state) {
case MSTP_MASTER_STATE_IDLE:
@@ -212,9 +202,7 @@ static void dlmstp_master_fsm_task(
}
}
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;
@@ -238,8 +226,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;
BOOL rc;
@@ -249,14 +236,14 @@ uint16_t MSTP_Put_Receive(
pdu_len = mstp_port->DataLength;
if (pdu_len > sizeof(Receive_Packet.pdu))
pdu_len = sizeof(Receive_Packet.pdu);
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;
rc = ReleaseSemaphore(Receive_Packet_Flag, 1, NULL);
(void) rc;
(void)rc;
}
return pdu_len;
@@ -265,13 +252,12 @@ 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 destination = 0; /* destination address */
uint8_t destination = 0; /* destination address */
(void) timeout;
(void)timeout;
if (!Transmit_Packet.ready) {
return 0;
}
@@ -285,22 +271,22 @@ uint16_t MSTP_Get_Send(
return 0;
}
/* convert the PDU into the MSTP Frame */
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, Transmit_Packet.frame_type, destination,
mstp_port->This_Station, &Transmit_Packet.pdu[0],
Transmit_Packet.pdu_len);
pdu_len =
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, Transmit_Packet.frame_type,
destination, mstp_port->This_Station, &Transmit_Packet.pdu[0],
Transmit_Packet.pdu_len);
Transmit_Packet.ready = false;
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,
BACNET_ADDRESS * dest_address)
BACNET_ADDRESS *dest_address)
{
uint16_t offset;
/* One way to check the message is to compare NPDU
@@ -322,9 +308,8 @@ static bool dlmstp_compare_data_expecting_reply(
/* decode the request data */
request.address.mac[0] = src_address;
request.address.mac_len = 1;
offset =
(uint16_t) npdu_decode(&request_pdu[0], NULL, &request.address,
&request.npdu_data);
offset = (uint16_t)npdu_decode(
&request_pdu[0], NULL, &request.address, &request.npdu_data);
if (request.npdu_data.network_layer_message) {
return false;
}
@@ -340,9 +325,8 @@ static bool dlmstp_compare_data_expecting_reply(
request.service_choice = request_pdu[offset + 3];
/* decode the reply data */
bacnet_address_copy(&reply.address, dest_address);
offset =
(uint16_t) npdu_decode(&reply_pdu[0], &reply.address, NULL,
&reply.npdu_data);
offset = (uint16_t)npdu_decode(
&reply_pdu[0], &reply.address, NULL, &reply.npdu_data);
if (reply.npdu_data.network_layer_message) {
return false;
}
@@ -387,7 +371,8 @@ static bool dlmstp_compare_data_expecting_reply(
return false;
}
}
if (request.npdu_data.protocol_version != reply.npdu_data.protocol_version) {
if (request.npdu_data.protocol_version !=
reply.npdu_data.protocol_version) {
return false;
}
#if 0
@@ -406,14 +391,13 @@ 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 */
uint8_t destination = 0; /* destination address */
volatile struct mstp_port_struct_t *mstp_port, unsigned timeout)
{ /* milliseconds to wait for a packet */
uint16_t pdu_len = 0; /* return value */
uint8_t destination = 0; /* destination address */
bool matched = false;
(void) timeout;
(void)timeout;
if (!Transmit_Packet.ready) {
return 0;
}
@@ -427,25 +411,24 @@ uint16_t MSTP_Get_Reply(
return 0;
}
/* 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,
&Transmit_Packet.pdu[0], Transmit_Packet.pdu_len,
&Transmit_Packet.address);
if (!matched)
return 0;
/* convert the PDU into the MSTP Frame */
pdu_len = MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, Transmit_Packet.frame_type, destination,
mstp_port->This_Station, &Transmit_Packet.pdu[0],
Transmit_Packet.pdu_len);
pdu_len =
MSTP_Create_Frame(&mstp_port->OutputBuffer[0], /* <-- loading this */
mstp_port->OutputBufferSize, Transmit_Packet.frame_type,
destination, mstp_port->This_Station, &Transmit_Packet.pdu[0],
Transmit_Packet.pdu_len);
Transmit_Packet.ready = false;
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) {
@@ -462,8 +445,7 @@ void dlmstp_set_mac_address(
return;
}
uint8_t dlmstp_mac_address(
void)
uint8_t dlmstp_mac_address(void)
{
return MSTP_Port.This_Station;
}
@@ -475,8 +457,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;
@@ -490,8 +471,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;
}
@@ -501,8 +481,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) {
@@ -518,33 +497,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;
@@ -553,16 +528,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;
}
@@ -571,8 +545,7 @@ void dlmstp_get_broadcast_address(
return;
}
bool dlmstp_init(
char *ifname)
bool dlmstp_init(char *ifname)
{
unsigned long hThread = 0;
uint32_t arg_value = 0;
@@ -634,7 +607,7 @@ bool dlmstp_init(
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",
(unsigned) MSTP_Port.Nmax_info_frames);
(unsigned)MSTP_Port.Nmax_info_frames);
#endif
hThread = _beginthread(dlmstp_receive_fsm_task, 4096, &arg_value);
if (hThread == 0) {
@@ -651,19 +624,17 @@ 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;
}
/* returns a delta timestamp */
uint32_t timestamp_ms(
void)
uint32_t timestamp_ms(void)
{
DWORD ticks = 0, delta_ticks = 0;
static DWORD last_ticks = 0;
@@ -678,9 +649,7 @@ uint32_t timestamp_ms(
static char *Network_Interface = NULL;
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
uint16_t pdu_len = 0;
+71 -88
View File
@@ -32,8 +32,8 @@
-------------------------------------------
####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 <assert.h>
#include <direct.h>
#include <io.h>
@@ -42,7 +42,6 @@
#include "bacnet/datalink/ethernet.h"
#include "bacnet/bacdcode.h"
/* Uses WinPCap to access raw ethernet */
/* Notes: */
/* To make ethernet.c work under win32, you have to: */
@@ -59,10 +58,9 @@
#include "ntddndis.h"
#include "remote-ext.h"
/* 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 };
@@ -71,31 +69,24 @@ uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0 };
/* couple of var for using winpcap */
static char pcap_errbuf[PCAP_ERRBUF_SIZE + 1];
static pcap_t *pcap_eth802_fp = NULL; /* 802.2 file handle, from winpcap */
static pcap_t *pcap_eth802_fp = NULL; /* 802.2 file handle, from winpcap */
static unsigned eth_timeout = 100;
/* couple of external func for runtime error logging, you can simply */
/* replace them with standard "printf(...)" */
/* Logging extern functions: Info level */
extern void LogInfo(
const char *msg);
extern void LogInfo(const char *msg);
/* Logging extern functions: Error level*/
extern void LogError(
const char *msg);
extern void LogError(const char *msg);
/* Logging extern functions: Debug level*/
extern void LogDebug(
const char *msg);
extern void LogDebug(const char *msg);
bool ethernet_valid(
void)
bool ethernet_valid(void)
{
return (pcap_eth802_fp != NULL);
}
void ethernet_cleanup(
void)
void ethernet_cleanup(void)
{
if (pcap_eth802_fp) {
pcap_close(pcap_eth802_fp);
@@ -104,8 +95,7 @@ void ethernet_cleanup(
LogInfo("ethernet.c: ethernet_cleanup() ok.\n");
}
void ethernet_set_timeout(
unsigned timeout)
void ethernet_set_timeout(unsigned timeout)
{
eth_timeout = timeout;
}
@@ -113,7 +103,7 @@ void ethernet_set_timeout(
/*----------------------------------------------------------------------
Portable function to set a socket into nonblocking mode.
Calling this on a socket causes all future read() and write() calls on
that socket to do only as much as they can immediately, and return
that socket to do only as much as they can immediately, and return
without waiting.
If no data can be read or written, they return -1 and set errno
to EAGAIN (or EWOULDBLOCK).
@@ -135,8 +125,7 @@ int setNonblocking(int fd)
}
*/
bool ethernet_init(
char *if_name)
bool ethernet_init(char *if_name)
{
PPACKET_OID_DATA pOidData;
LPADAPTER lpAdapter;
@@ -155,8 +144,8 @@ bool ethernet_init(
*/
/* Retrieve the device list */
if (pcap_findalldevs(&pcap_all_if, pcap_errbuf) == -1) {
sprintf(msgBuf, "ethernet.c: error in pcap_findalldevs: %s\n",
pcap_errbuf);
sprintf(
msgBuf, "ethernet.c: error in pcap_findalldevs: %s\n", pcap_errbuf);
LogError(msgBuf);
return false;
}
@@ -165,10 +154,10 @@ bool ethernet_init(
if (strcmp(if_name, dev->name) == 0)
break;
}
pcap_freealldevs(pcap_all_if); /* we don't need it anymore */
pcap_freealldevs(pcap_all_if); /* we don't need it anymore */
if (dev == NULL) {
sprintf(msgBuf, "ethernet.c: specified interface not found: %s\n",
if_name);
sprintf(
msgBuf, "ethernet.c: specified interface not found: %s\n", if_name);
LogError(msgBuf);
return false;
}
@@ -185,7 +174,7 @@ bool ethernet_init(
LogError(msgBuf);
return false;
}
pOidData = (PPACKET_OID_DATA) str;
pOidData = (PPACKET_OID_DATA)str;
pOidData->Oid = OID_802_3_CURRENT_ADDRESS;
pOidData->Length = 6;
result = PacketRequest(lpAdapter, FALSE, pOidData);
@@ -204,17 +193,18 @@ bool ethernet_init(
*/
/* Open the output device */
pcap_eth802_fp = pcap_open(if_name, /* name of the device */
MAX_MPDU, /* portion of the packet to capture */
PCAP_OPENFLAG_PROMISCUOUS, /* promiscuous mode */
eth_timeout, /* read timeout */
NULL, /* authentication on the remote machine */
pcap_errbuf /* error buffer */
);
MAX_MPDU, /* portion of the packet to capture */
PCAP_OPENFLAG_PROMISCUOUS, /* promiscuous mode */
eth_timeout, /* read timeout */
NULL, /* authentication on the remote machine */
pcap_errbuf /* error buffer */
);
if (pcap_eth802_fp == NULL) {
PacketCloseAdapter(lpAdapter);
ethernet_cleanup();
sprintf(msgBuf,
"ethernet.c: unable to open the adapter. %s is not supported by WinPcap\n",
"ethernet.c: unable to open the adapter. %s is not supported by "
"WinPcap\n",
if_name);
LogError(msgBuf);
return false;
@@ -229,12 +219,11 @@ bool ethernet_init(
/* function to send a packet out the 802.2 socket */
/* returns bytes sent success, negative on failure */
int ethernet_send(
BACNET_ADDRESS * dest, /* destination address */
BACNET_ADDRESS * src, /* source address */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len /* number of bytes of data */
)
int ethernet_send(BACNET_ADDRESS *dest, /* destination address */
BACNET_ADDRESS *src, /* source address */
uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len /* number of bytes of data */
)
{
int bytes = 0;
uint8_t mtu[MAX_MPDU] = { 0 };
@@ -272,11 +261,11 @@ int ethernet_send(
return -4;
}
/* packet length */
mtu_len += encode_unsigned16(&mtu[12], 3 /*DSAP,SSAP,LLC */ + pdu_len);
mtu_len += encode_unsigned16(&mtu[12], 3 /*DSAP,SSAP,LLC */ + pdu_len);
/* Logical PDU portion */
mtu[mtu_len++] = 0x82; /* DSAP for BACnet */
mtu[mtu_len++] = 0x82; /* SSAP for BACnet */
mtu[mtu_len++] = 0x03; /* Control byte in header */
mtu[mtu_len++] = 0x82; /* DSAP for BACnet */
mtu[mtu_len++] = 0x82; /* SSAP for BACnet */
mtu[mtu_len++] = 0x03; /* Control byte in header */
memcpy(&mtu[mtu_len], pdu, pdu_len);
mtu_len += pdu_len;
@@ -295,13 +284,12 @@ int ethernet_send(
/* 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 */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len /* number of bytes of data */
)
int ethernet_send_pdu(BACNET_ADDRESS *dest, /* destination address */
uint8_t *pdu, /* any data to be sent - may be null */
unsigned pdu_len /* number of bytes of data */
)
{
int i = 0; /* counter */
int i = 0; /* counter */
BACNET_ADDRESS src = { 0 }; /* source address */
for (i = 0; i < 6; i++) {
@@ -310,26 +298,26 @@ int ethernet_send_pdu(
}
/* function to send a packet out the 802.2 socket */
/* returns 1 on success, 0 on failure */
return ethernet_send(dest, /* destination address */
&src, /* source address */
pdu, /* any data to be sent - may be null */
return ethernet_send(dest, /* destination address */
&src, /* source address */
pdu, /* any data to be sent - may be null */
pdu_len /* number of bytes of data */
);
);
}
/* 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 */
unsigned timeout /* number of milliseconds to wait for a packet. we ommit it due to winpcap API. */
)
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. we ommit it
due to winpcap API. */
)
{
struct pcap_pkthdr *header;
int res;
u_char *pkt_data;
uint16_t pdu_len = 0; /* return value */
uint16_t pdu_len = 0; /* return value */
/* Make sure the socket is open */
if (!ethernet_valid()) {
@@ -361,14 +349,14 @@ uint16_t ethernet_receive(
/* check destination address for when */
/* the Ethernet card is in promiscious mode */
if ((memcmp(&pkt_data[0], Ethernet_MAC_Address, 6) != 0)
&& (memcmp(&pkt_data[0], Ethernet_Broadcast, 6) != 0)) {
if ((memcmp(&pkt_data[0], Ethernet_MAC_Address, 6) != 0) &&
(memcmp(&pkt_data[0], Ethernet_Broadcast, 6) != 0)) {
/*eth_log_error( "ethernet.c: This packet isn't for us\n"); */
return 0;
}
(void) decode_unsigned16(&pkt_data[12], &pdu_len);
pdu_len -= 3 /* DSAP, SSAP, LLC Control */ ;
(void)decode_unsigned16(&pkt_data[12], &pdu_len);
pdu_len -= 3 /* DSAP, SSAP, LLC Control */;
/* copy the buffer into the PDU */
if (pdu_len < max_pdu)
memmove(&pdu[0], &pkt_data[17], pdu_len);
@@ -379,8 +367,7 @@ uint16_t ethernet_receive(
return pdu_len;
}
void ethernet_set_my_address(
BACNET_ADDRESS * my_address)
void ethernet_set_my_address(BACNET_ADDRESS *my_address)
{
int i = 0;
@@ -391,8 +378,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;
@@ -401,7 +387,7 @@ void ethernet_get_my_address(
my_address->mac[i] = Ethernet_MAC_Address[i];
my_address->mac_len++;
}
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;
@@ -410,10 +396,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++) {
@@ -421,7 +406,7 @@ void ethernet_get_broadcast_address(
}
dest->mac_len = 6;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; /* denotes broadcast address */
dest->len = 0; /* denotes broadcast address */
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
@@ -430,11 +415,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 */
char msgBuf[200];
if (info) {
@@ -443,20 +426,20 @@ void ethernet_debug_address(
}
/* if */
if (dest) {
sprintf(msgBuf, "Address:\n MAC Length=%d\n MAC Address=",
dest->mac_len);
sprintf(
msgBuf, "Address:\n MAC Length=%d\n MAC Address=", dest->mac_len);
LogInfo(msgBuf);
for (i = 0; i < MAX_MAC_LEN; i++) {
sprintf(msgBuf, "%02X ", (unsigned) dest->mac[i]);
sprintf(msgBuf, "%02X ", (unsigned)dest->mac[i]);
LogInfo(msgBuf);
} /* for */
} /* for */
LogInfo("\n");
sprintf(msgBuf, " Net=%hu\n Len=%d\n Adr=", dest->net, dest->len);
LogInfo(msgBuf);
for (i = 0; i < MAX_MAC_LEN; i++) {
sprintf(msgBuf, "%02X ", (unsigned) dest->adr[i]);
sprintf(msgBuf, "%02X ", (unsigned)dest->adr[i]);
LogInfo(msgBuf);
} /* for */
} /* for */
LogInfo("\n");
}
/* if ( dest ) */
+65 -93
View File
@@ -1,27 +1,27 @@
/**************************************************************************
*
* Copyright (C) 2005 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) 2005 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.
*
*********************************************************************/
/* This is one way to use the embedded BACnet stack under Win32 */
/* compiled with Borland C++ 5.02 or Visual C++ 6.0 */
@@ -29,7 +29,7 @@
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <conio.h> /* for kbhit and getch */
#include <conio.h> /* for kbhit and getch */
#include "bacnet/iam.h"
#include "bacnet/basic/binding/address.h"
#include "bacnet/config.h"
@@ -66,8 +66,7 @@ static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
static bool Who_Is_Request = true;
bool I_Am_Request = true;
static void Read_Properties(
void)
static void Read_Properties(void)
{
uint32_t device_id = 0;
bool status = false;
@@ -80,47 +79,32 @@ static void Read_Properties(
Device Object
note: you could just loop through
all the properties in all the objects. */
const int object_props[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_SYSTEM_STATUS,
PROP_VENDOR_NAME,
PROP_VENDOR_IDENTIFIER,
PROP_MODEL_NAME,
PROP_FIRMWARE_REVISION,
PROP_APPLICATION_SOFTWARE_VERSION,
PROP_PROTOCOL_VERSION,
PROP_PROTOCOL_SERVICES_SUPPORTED,
PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
PROP_MAX_APDU_LENGTH_ACCEPTED,
PROP_SEGMENTATION_SUPPORTED,
PROP_LOCAL_TIME,
PROP_LOCAL_DATE,
PROP_UTC_OFFSET,
PROP_DAYLIGHT_SAVINGS_STATUS,
PROP_APDU_SEGMENT_TIMEOUT,
PROP_APDU_TIMEOUT,
PROP_NUMBER_OF_APDU_RETRIES,
PROP_TIME_SYNCHRONIZATION_RECIPIENTS,
PROP_MAX_MASTER,
PROP_MAX_INFO_FRAMES,
PROP_DEVICE_ADDRESS_BINDING,
const int object_props[] = { PROP_OBJECT_IDENTIFIER, PROP_OBJECT_NAME,
PROP_OBJECT_TYPE, PROP_SYSTEM_STATUS, PROP_VENDOR_NAME,
PROP_VENDOR_IDENTIFIER, PROP_MODEL_NAME, PROP_FIRMWARE_REVISION,
PROP_APPLICATION_SOFTWARE_VERSION, PROP_PROTOCOL_VERSION,
PROP_PROTOCOL_SERVICES_SUPPORTED, PROP_PROTOCOL_OBJECT_TYPES_SUPPORTED,
PROP_MAX_APDU_LENGTH_ACCEPTED, PROP_SEGMENTATION_SUPPORTED,
PROP_LOCAL_TIME, PROP_LOCAL_DATE, PROP_UTC_OFFSET,
PROP_DAYLIGHT_SAVINGS_STATUS, PROP_APDU_SEGMENT_TIMEOUT,
PROP_APDU_TIMEOUT, PROP_NUMBER_OF_APDU_RETRIES,
PROP_TIME_SYNCHRONIZATION_RECIPIENTS, PROP_MAX_MASTER,
PROP_MAX_INFO_FRAMES, PROP_DEVICE_ADDRESS_BINDING,
/* note: PROP_OBJECT_LIST is missing cause
we need to get it with an index method since
the list could be very large */
/* some proprietary properties */
514, 515,
/* end of list */
-1
};
-1 };
if (address_count()) {
if (address_get_by_index(index, &device_id, &max_apdu, &src)) {
if (object_props[property] < 0)
next_device = true;
else {
status = Send_Read_Property_Request(device_id, /* destination device */
status = Send_Read_Property_Request(
device_id, /* destination device */
OBJECT_DEVICE, device_id, object_props[property],
BACNET_ARRAY_ALL);
if (status)
@@ -141,9 +125,7 @@ static void Read_Properties(
}
static void LocalIAmHandler(
uint8_t * service_request,
uint16_t service_len,
BACNET_ADDRESS * src)
uint8_t *service_request, uint16_t service_len, BACNET_ADDRESS *src)
{
int len = 0;
uint32_t device_id = 0;
@@ -151,11 +133,10 @@ static void LocalIAmHandler(
int segmentation = 0;
uint16_t vendor_id = 0;
(void) src;
(void) service_len;
len =
iam_decode_service_request(service_request, &device_id, &max_apdu,
&segmentation, &vendor_id);
(void)src;
(void)service_len;
len = iam_decode_service_request(
service_request, &device_id, &max_apdu, &segmentation, &vendor_id);
fprintf(stderr, "Received I-Am Request");
if (len != -1) {
fprintf(stderr, " from %u!\n", device_id);
@@ -166,8 +147,7 @@ static void LocalIAmHandler(
return;
}
static void Init_Service_Handlers(
void)
static void Init_Service_Handlers(void)
{
Device_Init(NULL);
@@ -177,22 +157,21 @@ static void Init_Service_Handlers(
/* set the handler for all the services we don't implement */
/* It is required to send the proper reject message... */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
apdu_set_unrecognized_service_handler_handler(handler_unrecognized_service);
/* we must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
handler_read_property_multiple);
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property);
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_READ_PROP_MULTIPLE, handler_read_property_multiple);
/* handle the data coming back from confirmed requests */
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property_ack);
apdu_set_confirmed_ack_handler(
SERVICE_CONFIRMED_READ_PROPERTY, handler_read_property_ack);
#if defined(BACFILE)
apdu_set_confirmed_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE,
handler_atomic_read_file);
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_ATOMIC_READ_FILE, handler_atomic_read_file);
#endif
apdu_set_confirmed_handler(SERVICE_CONFIRMED_SUBSCRIBE_COV,
handler_cov_subscribe);
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_SUBSCRIBE_COV, handler_cov_subscribe);
#if 0
/* Adding these handlers require the project(s) to change. */
@@ -216,11 +195,9 @@ static void Init_Service_Handlers(
#endif
}
static void print_address(
char *name,
BACNET_ADDRESS * dest)
{ /* destination address */
int i = 0; /* counter */
static void print_address(char *name, BACNET_ADDRESS *dest)
{ /* destination address */
int i = 0; /* counter */
if (dest) {
printf("%s: ", name);
@@ -231,8 +208,7 @@ static void print_address(
}
}
static void print_address_cache(
void)
static void print_address_cache(void)
{
int i, j;
BACNET_ADDRESS address;
@@ -253,19 +229,15 @@ static void print_address_cache(
}
}
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
BACNET_ADDRESS src = {
0
}; /* address where message came from */
BACNET_ADDRESS src = { 0 }; /* address where message came from */
uint16_t pdu_len = 0;
unsigned timeout = 100; /* milliseconds */
unsigned timeout = 100; /* milliseconds */
BACNET_ADDRESS my_address, broadcast_address;
(void) argc;
(void) argv;
(void)argc;
(void)argv;
Device_Set_Object_Instance_Number(4194300);
address_init();
Init_Service_Handlers();
+35 -36
View File
@@ -1,28 +1,28 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
* Multimedia Timer contribution by Cameron Crothers, 2008
*
* 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>
* Multimedia Timer contribution by Cameron Crothers, 2008
*
* 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>
@@ -39,15 +39,14 @@ static volatile unsigned long Millisecond_Counter;
static unsigned long Timer_Period = 1;
/**
* @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();
unsigned long delta_time = 0;
if (Millisecond_Counter <= now) {
delta_time = now - Millisecond_Counter;
} else {
@@ -58,17 +57,16 @@ unsigned long mstimer_now(void)
}
/**
* @brief Shut down for timer
*/
static void timer_cleanup(
void)
* @brief Shut down for timer
*/
static void timer_cleanup(void)
{
timeEndPeriod(Timer_Period);
}
/**
* @brief Initialization for timer
*/
* @brief Initialization for timer
*/
void mstimer_init(void)
{
TIMECAPS tc;
@@ -81,8 +79,9 @@ void mstimer_init(void)
Timer_Period = min(max(tc.wPeriodMin, 1L), tc.wPeriodMax);
if (Timer_Period != 1L) {
fprintf(stderr,
"Failed to set timer to 1ms. " "Time period set to %ums\n",
(unsigned) Timer_Period);
"Failed to set timer to 1ms. "
"Time period set to %ums\n",
(unsigned)Timer_Period);
}
timeBeginPeriod(Timer_Period);
atexit(timer_cleanup);
+73 -93
View File
@@ -86,29 +86,27 @@ static DWORD RS485_DTRControl = DTR_CONTROL_DISABLE;
static DWORD RS485_RTSControl = RTS_CONTROL_DISABLE;
/****************************************************************************
* DESCRIPTION: Change the characters in a string to uppercase
* RETURN: nothing
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
static void strupper(
char *str)
* DESCRIPTION: Change the characters in a string to uppercase
* RETURN: nothing
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
static void strupper(char *str)
{
char *p;
for (p = str; *p != '\0'; ++p) {
*p = (char) toupper(*p);
*p = (char)toupper(*p);
}
}
/****************************************************************************
* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in
* receive mode.
* RETURN: none
* ALGORITHM: none
* NOTES: expects a constant char ifname, or char from the heap
*****************************************************************************/
void RS485_Set_Interface(
char *ifname)
* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in
* receive mode.
* RETURN: none
* ALGORITHM: none
* NOTES: expects a constant char ifname, or char from the heap
*****************************************************************************/
void RS485_Set_Interface(char *ifname)
{
/* For COM ports greater than 9 you have to use a special syntax
for CreateFile. The syntax also works for COM ports 1-9. */
@@ -126,13 +124,12 @@ void RS485_Set_Interface(
}
/****************************************************************************
* DESCRIPTION: Check the serial port to see if port exists
* RETURN: true if port exists
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
bool RS485_Interface_Valid(
unsigned port_number)
* DESCRIPTION: Check the serial port to see if port exists
* RETURN: true if port exists
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
bool RS485_Interface_Valid(unsigned port_number)
{
HANDLE h = 0;
DWORD err = 0;
@@ -140,8 +137,8 @@ bool RS485_Interface_Valid(
char ifname[255] = "";
sprintf(ifname, "\\\\.\\COM%u", port_number);
h = CreateFile(ifname, GENERIC_READ | GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, 0, NULL);
h = CreateFile(
ifname, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (h == INVALID_HANDLE_VALUE) {
err = GetLastError();
if ((err == ERROR_ACCESS_DENIED) || (err == ERROR_GEN_FAILURE) ||
@@ -156,33 +153,29 @@ bool RS485_Interface_Valid(
return status;
}
const char *RS485_Interface(
void)
const char *RS485_Interface(void)
{
return RS485_Port_Name;
}
void RS485_Print_Error(
void)
void RS485_Print_Error(void)
{
LPVOID lpMsgBuf;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) & lpMsgBuf, 0, NULL);
(LPTSTR)&lpMsgBuf, 0, NULL);
MessageBox(NULL, lpMsgBuf, "GetLastError", MB_OK | MB_ICONINFORMATION);
LocalFree(lpMsgBuf);
return;
}
static void RS485_Configure_Status(
void)
static void RS485_Configure_Status(void)
{
DCB dcb = { 0 };
COMMTIMEOUTS ctNew;
dcb.DCBlength = sizeof(dcb);
/* get current DCB settings */
if (!GetCommState(RS485_Handle, &dcb)) {
@@ -193,9 +186,9 @@ static void RS485_Configure_Status(
/* update DCB rate, byte size, parity, and stop bits size */
dcb.BaudRate = RS485_Baud;
dcb.ByteSize = (unsigned char) RS485_ByteSize;
dcb.Parity = (unsigned char) RS485_Parity;
dcb.StopBits = (unsigned char) RS485_StopBits;
dcb.ByteSize = (unsigned char)RS485_ByteSize;
dcb.Parity = (unsigned char)RS485_Parity;
dcb.StopBits = (unsigned char)RS485_StopBits;
/* update flow control settings */
dcb.fDtrControl = RS485_DTRControl;
@@ -242,13 +235,12 @@ static void RS485_Configure_Status(
}
/****************************************************************************
* DESCRIPTION: Cleans up any handles that were created at startup.
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
static void RS485_Cleanup(
void)
* DESCRIPTION: Cleans up any handles that were created at startup.
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
static void RS485_Cleanup(void)
{
if (!EscapeCommFunction(RS485_Handle, CLRDTR)) {
RS485_Print_Error();
@@ -262,20 +254,17 @@ static void RS485_Cleanup(
}
/****************************************************************************
* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in
* receive mode.
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Initialize(
void)
* DESCRIPTION: Initializes the RS485 hardware and variables, and starts in
* receive mode.
* RETURN: none
* ALGORITHM: none
* NOTES: none
*****************************************************************************/
void RS485_Initialize(void)
{
RS485_Handle =
CreateFile(RS485_Port_Name, GENERIC_READ | GENERIC_WRITE, 0, 0,
OPEN_EXISTING,
/*FILE_FLAG_OVERLAPPED */ 0,
0);
RS485_Handle = CreateFile(RS485_Port_Name, GENERIC_READ | GENERIC_WRITE, 0,
0, OPEN_EXISTING,
/*FILE_FLAG_OVERLAPPED */ 0, 0);
if (RS485_Handle == INVALID_HANDLE_VALUE) {
fprintf(stderr, "Unable to open %s\n", RS485_Port_Name);
RS485_Print_Error();
@@ -295,13 +284,12 @@ void RS485_Initialize(
}
/****************************************************************************
* 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)
{
switch (RS485_Baud) {
case CBR_19200:
@@ -347,13 +335,12 @@ uint32_t RS485_Get_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;
@@ -432,10 +419,10 @@ bool RS485_Set_Baud_Rate(
/* Transmits a Frame on the wire */
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) */
DWORD dwWritten = 0;
if (mstp_port) {
@@ -464,8 +451,7 @@ void RS485_Send_Frame(
}
/* called by timer, interrupt(?) or other thread */
void RS485_Check_UART_Data(
volatile struct mstp_port_struct_t *mstp_port)
void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port)
{
char lpBuf[1];
DWORD dwRead = 0;
@@ -490,12 +476,11 @@ void RS485_Check_UART_Data(
}
/*************************************************************************
* Description: print available COM ports
* Returns: none
* Notes: none
**************************************************************************/
void RS485_Print_Ports(
void)
* Description: print available COM ports
* Returns: none
* Notes: none
**************************************************************************/
void RS485_Print_Ports(void)
{
unsigned i = 0;
@@ -504,7 +489,8 @@ void RS485_Print_Ports(
if (RS485_Interface_Valid(i)) {
/* note: format for Wireshark ExtCap */
printf("interface {value=COM%u}"
"{display=BACnet MS/TP on COM%u}\n", i, i);
"{display=BACnet MS/TP on COM%u}\n",
i, i);
}
}
}
@@ -513,9 +499,7 @@ void RS485_Print_Ports(
#include "bacnet/datalink/mstpdef.h"
static void test_transmit_task(
void *pArg)
static void test_transmit_task(void *pArg)
{
char *TxBuf = "BACnet MS/TP";
size_t len = strlen(TxBuf) + 1;
@@ -527,8 +511,7 @@ static void test_transmit_task(
}
#if defined(_WIN32)
static BOOL WINAPI CtrlCHandler(
DWORD dwCtrlType)
static BOOL WINAPI CtrlCHandler(DWORD dwCtrlType)
{
dwCtrlType = dwCtrlType;
exit(0);
@@ -536,8 +519,7 @@ static BOOL WINAPI CtrlCHandler(
}
#endif
static int ascii_hex_to_int(
char ch)
static int ascii_hex_to_int(char ch)
{
int rv = -1;
@@ -552,9 +534,7 @@ static int ascii_hex_to_int(
return rv;
}
int main(
int argc,
char *argv[])
int main(int argc, char *argv[])
{
unsigned long hThread = 0;
uint32_t arg_value = 0;
@@ -577,7 +557,7 @@ int main(
RS485_Initialize();
#if defined(_WIN32)
SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT);
SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlCHandler, TRUE);
SetConsoleCtrlHandler((PHANDLER_ROUTINE)CtrlCHandler, TRUE);
#endif
#ifdef TEST_RS485_TRANSMIT
/* read a stream of characters from stdin or argument */
+53 -63
View File
@@ -53,27 +53,27 @@
#include "crc.h"
#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
/* file format for libpcap/winpcap */
/* from http://wiki.wireshark.org/Development/LibpcapFileFormat */
typedef struct pcap_hdr_s {
uint32_t magic_number; /* magic number */
uint16_t version_major; /* major version number */
uint16_t version_minor; /* minor version number */
int32_t thiszone; /* GMT to local correction */
uint32_t sigfigs; /* accuracy of timestamps */
uint32_t snaplen; /* max length of captured packets, in octets */
uint32_t network; /* data link type */
uint32_t magic_number; /* magic number */
uint16_t version_major; /* major version number */
uint16_t version_minor; /* minor version number */
int32_t thiszone; /* GMT to local correction */
uint32_t sigfigs; /* accuracy of timestamps */
uint32_t snaplen; /* max length of captured packets, in octets */
uint32_t network; /* data link type */
} pcap_hdr_t;
typedef struct pcaprec_hdr_s {
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 */
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 */
} pcaprec_hdr_t;
/* local port data - shared with RS-485 */
@@ -81,29 +81,29 @@ 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)
{
(void) pArg;
(void)pArg;
for (;;) {
Sleep(1);
dlmstp_millisecond_timer();
@@ -113,10 +113,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;
}
@@ -124,20 +123,18 @@ 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;
}
@@ -175,10 +172,9 @@ static void print_received_packet(
#endif
/* returns a delta timestamp */
void timestamp(
uint32_t * ts_sec, /* timestamp seconds since epoch (Unix) */
uint32_t * ts_usec)
{ /* timestamp microseconds (unix) */
void timestamp(uint32_t *ts_sec, /* timestamp seconds since epoch (Unix) */
uint32_t *ts_usec)
{ /* timestamp microseconds (unix) */
DWORD ticks = 0;
static DWORD initial_ticks = 0;
static time_t initial_seconds = 0;
@@ -202,19 +198,18 @@ void timestamp(
}
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 */
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 */
/* create a new file. */
pFile = fopen(Capture_Filename, "wb");
@@ -232,14 +227,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 */
if (pFile) {
timestamp(&ts_sec, &ts_usec);
@@ -274,20 +268,17 @@ static void write_received_packet(
static char *Network_Interface = NULL;
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;
}
/* 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;
@@ -332,8 +323,7 @@ int main(
}
atexit(cleanup);
write_global_header();
(void) SetThreadPriority(GetCurrentThread(),
THREAD_PRIORITY_TIME_CRITICAL);
(void)SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
/* run forever */
for (;;) {
RS485_Check_UART_Data(mstp_port);