From bc21625461eaec2abe482f06dee410b491d03cd7 Mon Sep 17 00:00:00 2001 From: skarg Date: Fri, 12 Aug 2005 15:44:42 +0000 Subject: [PATCH] refactored the BACnet/IP for each of the ports --- bacnet-stack/Makefile | 3 +- bacnet-stack/{ports/linux => }/bip.c | 84 ++-- bacnet-stack/bip.h | 9 +- bacnet-stack/handlers.c | 3 +- bacnet-stack/iam.h | 1 + bacnet-stack/ports/linux/bip-init.c | 91 +++++ bacnet-stack/ports/linux/main.c | 1 + .../ports/rtos32/{bip.c => bip-init.c} | 0 bacnet-stack/ports/rtos32/makefile.mak | 3 +- bacnet-stack/ports/win32/bacnet.ide | Bin 49144 -> 50668 bytes bacnet-stack/ports/win32/bip-init.c | 95 +++++ bacnet-stack/ports/win32/bip.c | 373 ------------------ bacnet-stack/ports/win32/main.c | 117 +++++- bacnet-stack/ports/win32/net.h | 33 ++ 14 files changed, 373 insertions(+), 440 deletions(-) rename bacnet-stack/{ports/linux => }/bip.c (85%) create mode 100644 bacnet-stack/ports/linux/bip-init.c rename bacnet-stack/ports/rtos32/{bip.c => bip-init.c} (100%) create mode 100644 bacnet-stack/ports/win32/bip-init.c delete mode 100644 bacnet-stack/ports/win32/bip.c create mode 100644 bacnet-stack/ports/win32/net.h diff --git a/bacnet-stack/Makefile b/bacnet-stack/Makefile index 7749fd5c..2b2b43d4 100644 --- a/bacnet-stack/Makefile +++ b/bacnet-stack/Makefile @@ -12,7 +12,8 @@ CFLAGS = -Wall -I. -Iports/linux -g -DBACDL_BIP=1 SRCS = ports/linux/main.c \ ports/linux/ethernet.c \ - ports/linux/bip.c \ + ports/linux/bip-init.c \ + bip.c \ dlmstp.c \ handlers.c \ bacdcode.c \ diff --git a/bacnet-stack/ports/linux/bip.c b/bacnet-stack/bip.c similarity index 85% rename from bacnet-stack/ports/linux/bip.c rename to bacnet-stack/bip.c index 6469b4ed..6cd3b70f 100644 --- a/bacnet-stack/ports/linux/bip.c +++ b/bacnet-stack/bip.c @@ -36,7 +36,7 @@ #include // for the standard bool type. #include "bacdcode.h" #include "bip.h" -#include "net.h" +#include "net.h" // custom per port static int BIP_Socket = -1; /* port to use - stored in network byte order */ @@ -46,6 +46,11 @@ static struct in_addr BIP_Address; /* Broadcast Address */ static struct in_addr BIP_Broadcast_Address; +void bip_set_socket(int sock_fd) +{ + BIP_Socket = sock_fd; +} + bool bip_valid(void) { return (BIP_Socket != -1); @@ -57,7 +62,7 @@ void bip_cleanup(void) close(BIP_Socket); BIP_Socket = -1; - return; + return; } static void set_network_address(struct in_addr *net_address, @@ -72,80 +77,49 @@ static void set_network_address(struct in_addr *net_address, long_data.byte[1] = octet2; long_data.byte[2] = octet3; long_data.byte[3] = octet4; - + net_address->s_addr = long_data.value; } void bip_set_address( - uint8_t octet1, - uint8_t octet2, - uint8_t octet3, + uint8_t octet1, + uint8_t octet2, + uint8_t octet3, uint8_t octet4) { set_network_address(&BIP_Address, octet1, octet2, octet3, octet4); } +// Win32 shortcut +void bip_set_addr(struct in_addr *net_address) +{ + BIP_Address.s_addr = htonl(net_address->s_addr); +} + void bip_set_broadcast_address( - uint8_t octet1, - uint8_t octet2, - uint8_t octet3, + uint8_t octet1, + uint8_t octet2, + uint8_t octet3, uint8_t octet4) { set_network_address(&BIP_Broadcast_Address, octet1, octet2, octet3, octet4); } +// Win32 shortcut +void bip_set_ipv4_broadcast_s_addr( + unsigned long address) +{ + BIP_Broadcast_Address.s_addr = address; +} + void bip_set_port(uint16_t port) { BIP_Port = htons(port); } -bool bip_init(void) +uint16_t bip_get_port(void) { - int status = 0; // return from socket lib calls - struct sockaddr_in sin; - int sockopt = 0; - - /* configure standard BACnet/IP receive port */ - bip_set_port(0xBAC0); - - // assumes that the driver has already been initialized - BIP_Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (BIP_Socket < 0) - return false; - // Allow us to use the same socket for sending and receiving - // This makes sure that the src port is correct when sending - sockopt = 1; - status = setsockopt(BIP_Socket, SOL_SOCKET, SO_REUSEADDR, - &sockopt, sizeof(sockopt)); - if (status < 0) - { - close(BIP_Socket); - return status; - } - // allow us to send a broadcast - status = setsockopt(BIP_Socket, SOL_SOCKET, SO_BROADCAST, - &sockopt, sizeof(sockopt)); - if (status < 0) - { - close(BIP_Socket); - return status; - } - - // bind the socket to the local port number and IP address - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(INADDR_ANY); - sin.sin_port = BIP_Port; - memset(&(sin.sin_zero), '\0', 8); - status = bind(BIP_Socket, - (const struct sockaddr*)&sin, sizeof(struct sockaddr)); - if (status < 0) - { - close(BIP_Socket); - BIP_Socket = -1; - return false; - } - - return true; + return BIP_Port; } /* function to send a packet out the 802.2 socket */ diff --git a/bacnet-stack/bip.h b/bacnet-stack/bip.h index 3b5b42a7..1a1b42c9 100644 --- a/bacnet-stack/bip.h +++ b/bacnet-stack/bip.h @@ -43,9 +43,13 @@ #define MAX_HEADER (1 + 1 + 2) #define MAX_MPDU (MAX_HEADER+MAX_PDU) -bool bip_valid(void); -void bip_cleanup(void); +// note: define init and cleanup in your ports section bool bip_init(void); + +// normal functions... +void bip_cleanup(void); +void bip_set_socket(int sock_fd); +bool bip_valid(void); void bip_get_broadcast_address( BACNET_ADDRESS *dest); // destination address void bip_get_my_address(BACNET_ADDRESS *my_address); @@ -71,6 +75,7 @@ void bip_set_broadcast_address(uint8_t octet1, uint8_t octet2, uint8_t octet3, uint8_t octet4); void bip_set_port(uint16_t port); +uint16_t bip_get_port(void); void bip_set_interface_name(char *ifname); #endif diff --git a/bacnet-stack/handlers.c b/bacnet-stack/handlers.c index b3022250..d28bddcd 100644 --- a/bacnet-stack/handlers.c +++ b/bacnet-stack/handlers.c @@ -258,7 +258,6 @@ void ReadPropertyHandler( BACNET_READ_PROPERTY_DATA data; int len = 0; int pdu_len = 0; - uint32_t object_instance; BACNET_ADDRESS my_address; bool send = false; bool error = false; @@ -399,7 +398,7 @@ void ReadPropertyHandler( error = true; break; case OBJECT_FILE: - if (bacfile_valid_instance(object_instance)) + if (bacfile_valid_instance(data.object_instance)) { len = bacfile_encode_property_apdu( &Temp_Buf[0], diff --git a/bacnet-stack/iam.h b/bacnet-stack/iam.h index 7425834d..1cadf969 100644 --- a/bacnet-stack/iam.h +++ b/bacnet-stack/iam.h @@ -36,6 +36,7 @@ #include #include +#include "bacdef.h" int iam_encode_apdu( uint8_t *apdu, diff --git a/bacnet-stack/ports/linux/bip-init.c b/bacnet-stack/ports/linux/bip-init.c new file mode 100644 index 00000000..51bc21de --- /dev/null +++ b/bacnet-stack/ports/linux/bip-init.c @@ -0,0 +1,91 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2005 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + +#include // for standard integer types uint8_t etc. +#include // for the standard bool type. +#include "bacdcode.h" +#include "bip.h" +#include "net.h" + +bool bip_init(void) +{ + int status = 0; // return from socket lib calls + struct sockaddr_in sin; + int sockopt = 0; + int sock_fd = -1; + + // assumes that the driver has already been initialized + sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + bip_set_socket(sock_fd); + if (sock_fd < 0) + return false; + // Allow us to use the same socket for sending and receiving + // This makes sure that the src port is correct when sending + sockopt = 1; + status = setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, + &sockopt, sizeof(sockopt)); + if (status < 0) + { + close(sock_fd); + bip_set_socket(-1); + return status; + } + // allow us to send a broadcast + status = setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, + &sockopt, sizeof(sockopt)); + if (status < 0) + { + close(sock_fd); + bip_set_socket(-1); + return status; + } + + // bind the socket to the local port number and IP address + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = bip_get_port(); + memset(&(sin.sin_zero), '\0', 8); + status = bind(sock_fd, + (const struct sockaddr*)&sin, sizeof(struct sockaddr)); + if (status < 0) + { + close(sock_fd); + bip_set_socket(-1); + return false; + } + + return true; +} + + diff --git a/bacnet-stack/ports/linux/main.c b/bacnet-stack/ports/linux/main.c index f1c87148..459d599b 100644 --- a/bacnet-stack/ports/linux/main.c +++ b/bacnet-stack/ports/linux/main.c @@ -314,6 +314,7 @@ int main(int argc, char *argv[]) #endif #ifdef BACDL_BIP Init_Network("eth0"); + bip_set_port(0xBAC0); if (!bip_init()) return 1; #endif diff --git a/bacnet-stack/ports/rtos32/bip.c b/bacnet-stack/ports/rtos32/bip-init.c similarity index 100% rename from bacnet-stack/ports/rtos32/bip.c rename to bacnet-stack/ports/rtos32/bip-init.c diff --git a/bacnet-stack/ports/rtos32/makefile.mak b/bacnet-stack/ports/rtos32/makefile.mak index 777604da..f5ac8906 100644 --- a/bacnet-stack/ports/rtos32/makefile.mak +++ b/bacnet-stack/ports/rtos32/makefile.mak @@ -26,8 +26,9 @@ DEFINES = -DDOC;BACDL_BIP=1 #DEFINES = -DDOC;BACDL_ETHERNET=1 #DEFINES = -DDOC;BACDL_MSTP=1 -SRCS = init.c main.c ethernet.c bip.c \ +SRCS = init.c main.c ethernet.c bip-init.c \ rs485.c \ + ..\..\bip.c \ ..\..\mstp.c \ ..\..\crc.c \ ..\..\handlers.c \ diff --git a/bacnet-stack/ports/win32/bacnet.ide b/bacnet-stack/ports/win32/bacnet.ide index 1c93f152f2f27daaa49a952fa1aa0b938c24c861..5eda6d06e68579bb200ce9dbf5d0d7c603b9b761 100644 GIT binary patch delta 9773 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 O@{s_fi9fr{=zjrKy2|qa delta 9003 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 w9EP +#include +#include // for standard integer types uint8_t etc. +#include // for the standard bool type. +#include "bacdcode.h" +#include "bip.h" +#include "net.h" + +bool bip_init(void) +{ + int rv = 0; // return from socket lib calls + struct sockaddr_in sin = {-1}; + int value = 1; + int sock_fd = -1; + + // assumes that the driver has already been initialized + sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + bip_set_socket(sock_fd); + if (sock_fd < 0) + return false; + + // 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)); + if (rv < 0) + { + close(sock_fd); + bip_set_socket(-1); + return false; + } + // allow us to send a broadcast + rv = setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST, + (char *)&value, sizeof(value)); + if (rv < 0) + { + close(sock_fd); + bip_set_socket(-1); + return false; + } + + // bind the socket to the local port number and IP address + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = htonl(INADDR_ANY); + sin.sin_port = bip_get_port(); + memset(&(sin.sin_zero), '\0', 8); + rv = bind(sock_fd, + (const struct sockaddr*)&sin, sizeof(struct sockaddr)); + if (rv < 0) + { + close(sock_fd); + bip_set_socket(-1); + return false; + } + + return true; +} + diff --git a/bacnet-stack/ports/win32/bip.c b/bacnet-stack/ports/win32/bip.c deleted file mode 100644 index ec2658ce..00000000 --- a/bacnet-stack/ports/win32/bip.c +++ /dev/null @@ -1,373 +0,0 @@ -/*####COPYRIGHTBEGIN#### - ------------------------------------------- - Copyright (C) 2005 Steve Karg - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - as published by the Free Software Foundation; either version 2 - of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to: - The Free Software Foundation, Inc. - 59 Temple Place - Suite 330 - Boston, MA 02111-1307, USA. - - As a special exception, if other files instantiate templates or - use macros or inline functions from this file, or you compile - this file and link it with other works to produce a work based - on this file, this file does not by itself cause the resulting - work to be covered by the GNU General Public License. However - the source code for this file must still be made available in - accordance with section (3) of the GNU General Public License. - - This exception does not invalidate any other reasons why a work - based on this file might be covered by the GNU General Public - License. - ------------------------------------------- -####COPYRIGHTEND####*/ - -#define WIN32_LEAN_AND_MEAN -#define STRICT - -#include -#include -#include -#include // for standard integer types uint8_t etc. -#include // for the standard bool type. -#include "bacdcode.h" -#include "bip.h" - -#define close closesocket - -static int BIP_Socket = -1; -/* port to use - stored in network byte order */ -static uint16_t BIP_Port = 0; -/* IP Address - stored in network byte order */ -static struct in_addr BIP_Address; -/* Broadcast Address */ -static struct in_addr BIP_Broadcast_Address; -/* Subnet Mask */ -static struct in_addr BIP_Subnet_Mask; - -bool bip_valid(void) -{ - return (BIP_Socket != -1); -} - -void bip_cleanup(void) -{ - if (bip_valid()) - close(BIP_Socket); - BIP_Socket = -1; - - return; -} - -static void set_network_address(struct in_addr *net_address, - uint8_t octet1, uint8_t octet2, uint8_t octet3, uint8_t octet4) -{ - union { - uint8_t byte[4]; - uint32_t value; - } long_data = {{0}}; - - long_data.byte[0] = octet1; - long_data.byte[1] = octet2; - long_data.byte[2] = octet3; - long_data.byte[3] = octet4; - - net_address->s_addr = htonl(long_data.value); -} - -void bip_set_address(uint8_t octet1, uint8_t octet2, - uint8_t octet3, uint8_t octet4) -{ - set_network_address(&BIP_Address, octet1, octet2, octet3, octet4); -} - -void bip_set_addr(struct in_addr *net_address) -{ - BIP_Address.s_addr = htonl(net_address->s_addr); -} - -void bip_set_broadcast_address(uint8_t octet1, uint8_t octet2, - uint8_t octet3, uint8_t octet4) -{ - set_network_address(&BIP_Broadcast_Address, - octet1, octet2, octet3, octet4); -} - -void bip_set_subnet_mask(uint8_t octet1, uint8_t octet2, - uint8_t octet3, uint8_t octet4) -{ - set_network_address(&BIP_Subnet_Mask, - octet1, octet2, octet3, octet4); -} - -void bip_set_port(uint16_t port) -{ - BIP_Port = htons(port); -} - -bool bip_init(void) -{ - int rv = 0; // return from socket lib calls - struct sockaddr_in sin = {-1}; - int value = 1; - - /* local broadcast address */ - BIP_Broadcast_Address.s_addr = INADDR_BROADCAST; - /* configure standard BACnet/IP port */ - bip_set_port(0xBAC0); - - // assumes that the driver has already been initialized - BIP_Socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (BIP_Socket < 0) - return false; - - // Allow us to use the same socket for sending and receiving - // This makes sure that the src port is correct when sending - rv = setsockopt(BIP_Socket, SOL_SOCKET, SO_REUSEADDR, - (char *)&value, sizeof(value)); - if (rv < 0) - { - close(BIP_Socket); - BIP_Socket = -1; - return false; - } - // allow us to send a broadcast - rv = setsockopt(BIP_Socket, SOL_SOCKET, SO_BROADCAST, - (char *)&value, sizeof(value)); - if (rv < 0) - { - close(BIP_Socket); - BIP_Socket = -1; - return false; - } - - // bind the socket to the local port number and IP address - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(INADDR_ANY); - sin.sin_port = BIP_Port; - memset(&(sin.sin_zero), '\0', 8); - rv = bind(BIP_Socket, - (const struct sockaddr*)&sin, sizeof(struct sockaddr)); - if (rv < 0) - { - close(BIP_Socket); - BIP_Socket = -1; - return false; - } - - return true; -} - -/* function to send a packet out the BACnet/IP socket (Annex J) */ -/* returns number of bytes sent on success, negative number on failure */ -static int bip_send( - struct sockaddr_in *bip_dest, - 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 }; - int mtu_len = 0; - int i = 0; - - // assumes that the driver has already been initialized - if (BIP_Socket < 0) - return BIP_Socket; - - mtu[0] = 0x81; /* BVLL for BACnet/IP */ - if (bip_dest->sin_addr.s_addr == BIP_Broadcast_Address.s_addr) - mtu[1] = 0x0B; /* Original-Broadcast-NPDU */ - else - mtu[1] = 0x0A; /* Original-Unicast-NPDU */ - mtu_len = 2; - mtu_len += encode_unsigned16(&mtu[mtu_len], pdu_len + 4 /*inclusive*/); - memcpy(&mtu[mtu_len], pdu, pdu_len); - mtu_len += pdu_len; - - /* Send the packet */ - bytes = sendto(BIP_Socket, (char *)mtu, mtu_len, 0, - (struct sockaddr *)bip_dest, - sizeof(struct sockaddr)); - - return bytes; -} - -/* function to send a packet out the BACnet/IP socket (Annex J) */ -/* returns number of bytes sent on success, negative number on failure */ -int bip_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 - struct sockaddr_in bip_dest; - uint32_t network_address = 0; - uint16_t network_port = 0; - - /* load destination IP address */ - bip_dest.sin_family = AF_INET; - if (dest->mac_len == 6) - { - (void)decode_unsigned32(&dest->mac[0], &(bip_dest.sin_addr.s_addr)); - (void)decode_unsigned16(&dest->mac[4], &(bip_dest.sin_port)); - memset(&(bip_dest.sin_zero), '\0', 8); - } - /* broadcast */ - else if (dest->mac_len == 0) - { - bip_dest.sin_addr.s_addr = BIP_Broadcast_Address.s_addr; - bip_dest.sin_port = BIP_Port; - memset(&(bip_dest.sin_zero), '\0', 8); - } - else - return -1; - - /* function to send a packet out the BACnet/IP socket */ - /* returns 1 on success, 0 on failure */ - return bip_send(&bip_dest, // destination address - pdu, // any data to be sent - may be null - pdu_len); // number of bytes of data -} - -// receives a BACnet/IP packet -// returns the number of octets in the PDU, or zero on failure -uint16_t bip_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 -{ - int received_bytes; - uint8_t buf[MAX_MPDU] = {0}; // data - uint16_t pdu_len = 0; // return value - fd_set read_fds; - int max; - struct timeval select_timeout; - struct sockaddr_in sin = {-1}; - int sin_len = sizeof(sin); - - /* Make sure the socket is open */ - if (BIP_Socket < 0) - return 0; - - /* we could just use a non-blocking socket, but that consumes all - the CPU time. We can use a timeout; it is only supported as - a select. */ - if (timeout >= 1000) - { - select_timeout.tv_sec = timeout / 1000; - select_timeout.tv_usec = - 1000 * (timeout - select_timeout.tv_sec * 1000); - } - else - { - select_timeout.tv_sec = 0; - select_timeout.tv_usec = 1000 * timeout; - } - FD_ZERO(&read_fds); - FD_SET(BIP_Socket, &read_fds); - max = BIP_Socket; - /* see if there is a packet for us */ - if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) - received_bytes = recvfrom(BIP_Socket, - (char *)&buf[0], MAX_MPDU, 0, - (struct sockaddr *)&sin, &sin_len); - else - return 0; - - /* See if there is a problem */ - if (received_bytes < 0) { - return 0; - } - - /* no problem, just no bytes */ - if (received_bytes == 0) - return 0; - - /* the signature of a BACnet/IP packet */ - if (buf[0] != 0x81) - return 0; - /* Original-Broadcast-NPDU or Original-Unicast-NPDU */ - if ((buf[1] == 0x0B) || (buf[1] == 0x0A)) - { - if (sin.sin_addr.s_addr == BIP_Address.s_addr) - pdu_len = 0; - else - { - // copy the source address - src->mac_len = 6; - (void)encode_unsigned32(&src->mac[0], - sin.sin_addr.s_addr); - (void)encode_unsigned16(&src->mac[4], - sin.sin_port); - // FIXME: check destination address - // see if it is broadcast or for us - /* decode the length of the PDU - length is inclusive of BVLC */ - (void)decode_unsigned16(&buf[2],&pdu_len); - /* copy the buffer into the PDU */ - pdu_len -= 4; /* BVLC header */ - if (pdu_len < max_pdu) - memmove(&pdu[0],&buf[4],pdu_len); - // ignore packets that are too large - // clients should check my max-apdu first - else - pdu_len = 0; - } - } - - return pdu_len; -} - -void bip_get_my_address(BACNET_ADDRESS *my_address) -{ - int i = 0; - - my_address->mac_len = 6; - (void)encode_unsigned32(&my_address->mac[0], - BIP_Address.s_addr); - (void)encode_unsigned16(&my_address->mac[4], - BIP_Port); - my_address->net = 0; /* local only, no routing */ - my_address->len = 0; /* no SLEN */ - for (i = 0; i < MAX_MAC_LEN; i++) - { - /* no SADR */ - my_address->adr[i] = 0; - } - - return; -} - -void bip_get_broadcast_address( - BACNET_ADDRESS *dest) // destination address -{ - int i = 0; // counter - - if (dest) - { - dest->mac_len = 6; - (void)encode_unsigned32(&dest->mac[0], - BIP_Broadcast_Address.s_addr); - (void)encode_unsigned16(&dest->mac[4], - BIP_Port); - dest->net = BACNET_BROADCAST_NETWORK; - dest->len = 0; /* no SLEN */ - for (i = 0; i < MAX_MAC_LEN; i++) - { - /* no SADR */ - dest->adr[i] = 0; - } - } - - return; -} diff --git a/bacnet-stack/ports/win32/main.c b/bacnet-stack/ports/win32/main.c index 502dcd7d..9b68d41c 100644 --- a/bacnet-stack/ports/win32/main.c +++ b/bacnet-stack/ports/win32/main.c @@ -29,6 +29,8 @@ #include #include #include +#include "iam.h" +#include "address.h" #include "config.h" #include "bacdef.h" #include "npdu.h" @@ -40,6 +42,89 @@ // buffer used for receive static uint8_t Rx_Buf[MAX_MPDU] = {0}; +static void Read_Properties(void) +{ + uint32_t device_id = 0; + unsigned max_apdu = 0; + BACNET_ADDRESS src; + bool next_device = false; + static unsigned index = 0; + static unsigned property = 0; + // list of required (and some optional) properties in the + // Device Object + const int object_props[] = + { + 75,77,79,112,121,120,70,44,12,98,95,97,96, + 62,107,57,56,119,24,10,11,73,116,64,63,30, + 514,515, + // note: 76 is missing cause we get it special below + -1 + }; + + if (address_count()) + { + if (address_get_by_index(index, &device_id, &max_apdu, &src)) + { + if (object_props[property] < 0) + next_device = true; + else + { + (void)Send_Read_Property_Request( + device_id, // destination device + OBJECT_DEVICE, + device_id, + object_props[property], + BACNET_ARRAY_ALL); + property++; + } + } + else + next_device = true; + if (next_device) + { + index++; + if (index >= MAX_ADDRESS_CACHE) + index = 0; + property = 0; + } + } + + return; +} + +static void LocalIAmHandler( + uint8_t *service_request, + uint16_t service_len, + BACNET_ADDRESS *src) +{ + int len = 0; + uint32_t device_id = 0; + unsigned max_apdu = 0; + 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); + fprintf(stderr,"Received I-Am Request"); + if (len != -1) + { + fprintf(stderr," from %u!\n",device_id); + address_add(device_id, + max_apdu, + src); + } + else + fprintf(stderr,"!\n"); + + return; +} + static void Init_Device_Parameters(void) { // configure my initial values @@ -53,13 +138,17 @@ static void Init_Device_Parameters(void) return; } - + static void Init_Service_Handlers(void) { // we need to handle who-is to support dynamic device binding apdu_set_unconfirmed_handler( SERVICE_UNCONFIRMED_WHO_IS, WhoIsHandler); + apdu_set_unconfirmed_handler( + SERVICE_UNCONFIRMED_I_AM, + LocalIAmHandler); + // 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( @@ -71,25 +160,32 @@ static void Init_Service_Handlers(void) apdu_set_confirmed_handler( SERVICE_CONFIRMED_WRITE_PROPERTY, WritePropertyHandler); + // handle the data coming back from confirmed requests + apdu_set_confirmed_ack_handler( + SERVICE_CONFIRMED_READ_PROPERTY, + ReadPropertyAckHandler); } /* To fill a need, we invent the gethostaddr() function. */ -long gethostaddr(void) +long gethostaddr(void) { struct hostent *host_ent; char host_name[255]; - - if (gethostname(host_name, sizeof(host_name)) == 0) + + if (gethostname(host_name, sizeof(host_name)) == 0) return -1; if ((host_ent = gethostbyname(host_name)) == NULL) return -1; - + return *(long *)host_ent->h_addr; } extern void bip_set_addr(struct in_addr *net_address); +extern void bip_set_ipv4_broadcast_s_addr( + unsigned long address); + static void NetInitialize(void) // initialize the TCP/IP stack { @@ -104,12 +200,16 @@ static void NetInitialize(void) if (Result != 0) { Code = WSAGetLastError(); - printf("TCP/IP stack initialization failed, error code: %i\n", + printf("TCP/IP stack initialization failed, error code: %i\n", Code); exit(1); } address.s_addr = gethostaddr(); bip_set_addr(&address); + /* local broadcast address */ + bip_set_ipv4_broadcast_s_addr(INADDR_BROADCAST); + /* configure standard BACnet/IP port */ + bip_set_port(0xBAC0); } int main(int argc, char *argv[]) @@ -132,6 +232,7 @@ int main(int argc, char *argv[]) for (;;) { // input + //Read_Properties(); // returns 0 bytes on timeout pdu_len = bip_receive( @@ -153,6 +254,10 @@ int main(int argc, char *argv[]) { I_Am_Request = false; Send_IAm(); + } else if (Who_Is_Request) + { + Who_Is_Request = false; + Send_WhoIs(); } // output diff --git a/bacnet-stack/ports/win32/net.h b/bacnet-stack/ports/win32/net.h new file mode 100644 index 00000000..09e589c2 --- /dev/null +++ b/bacnet-stack/ports/win32/net.h @@ -0,0 +1,33 @@ +/************************************************************************** +* +* Copyright (C) 2005 Steve Karg +* +* 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. +* +*********************************************************************/ + +#ifndef NET_H +#define NET_H + +#include + +#define close closesocket + +#endif