running the indent on the files.

This commit is contained in:
skarg
2006-02-18 23:11:25 +00:00
parent b1d46ffa8c
commit d6a891f0d1
58 changed files with 4781 additions and 5862 deletions
+167 -191
View File
@@ -40,7 +40,7 @@
// my local device data - MAC address
uint8_t ARCNET_MAC_Address = 0;
// ARCNET file handle
static int ARCNET_Sock_FD = -1;
static int ARCNET_Sock_FD = -1;
// ARCNET socket address (has the interface name)
static struct sockaddr ARCNET_Socket_Address;
// Broadcast address
@@ -81,206 +81,192 @@ clockp Clock Prescaler DataRate
bool arcnet_valid(void)
{
return (ARCNET_Sock_FD >= 0);
return (ARCNET_Sock_FD >= 0);
}
void arcnet_cleanup(void)
{
if (arcnet_valid())
close(ARCNET_Sock_FD);
ARCNET_Sock_FD = -1;
if (arcnet_valid())
close(ARCNET_Sock_FD);
ARCNET_Sock_FD = -1;
return;
return;
}
static int arcnet_bind(char *interface_name)
{
int sock_fd = -1; // return value
struct ifreq ifr;
int rv; // return value - error value from df or ioctl call
int uid = 0;
int sock_fd = -1; // return value
struct ifreq ifr;
int rv; // return value - error value from df or ioctl call
int uid = 0;
/* check to see if we are being run as root */
uid = getuid();
if (uid != 0) {
fprintf(stderr,
"arcnet: Unable to open an af_packet socket. "
"Try running with root priveleges.\n");
return sock_fd;
}
fprintf(stderr,"arcnet: opening \"%s\"\n",interface_name);
// note: on some systems you may have to add or enable in
// modules.conf (or in modutils/alias on Debian with update-modules)
// alias net-pf-17 af_packet
// Then follow it by: # modprobe af_packet
if ((sock_fd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))) < 0)
{
/* Error occured */
fprintf(stderr,
"arcnet: Error opening socket: %s\n",
strerror(errno));
fprintf(stderr,
"You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n"
"# modprobe af_packet\n");
exit(-1);
}
if (ARCNET_Sock_FD >= 0)
{
/* Bind the socket to an interface name so we only get packets from it */
/* check to see if we are being run as root */
uid = getuid();
if (uid != 0) {
fprintf(stderr,
"arcnet: Unable to open an af_packet socket. "
"Try running with root priveleges.\n");
return sock_fd;
}
fprintf(stderr, "arcnet: opening \"%s\"\n", interface_name);
// note: on some systems you may have to add or enable in
// modules.conf (or in modutils/alias on Debian with update-modules)
// alias net-pf-17 af_packet
// Then follow it by: # modprobe af_packet
if ((sock_fd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ALL))) < 0) {
/* Error occured */
fprintf(stderr,
"arcnet: Error opening socket: %s\n", strerror(errno));
fprintf(stderr,
"You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n" "# modprobe af_packet\n");
exit(-1);
}
if (ARCNET_Sock_FD >= 0) {
/* Bind the socket to an interface name so we only get packets from it */
ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET;
//ARCNET_Socket_Address.sa_family = PF_INET;
/* Clear the memory before copying */
memset(ARCNET_Socket_Address.sa_data, '\0',
sizeof(ARCNET_Socket_Address.sa_data));
/* Strcpy the interface name into the address */
strncpy(ARCNET_Socket_Address.sa_data, interface_name,
sizeof(ARCNET_Socket_Address.sa_data) - 1);
fprintf(stderr, "arcnet: binding \"%s\"\n",
ARCNET_Socket_Address.sa_data);
if (bind(sock_fd, &ARCNET_Socket_Address,
sizeof(ARCNET_Socket_Address)) != 0) {
/* Bind problem, close socket and return */
fprintf(stderr,
"arcnet: Unable to bind socket : %s\n", strerror(errno));
fprintf(stderr,
"You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n" "# modprobe af_packet\n");
/* Close the socket */
close(sock_fd);
exit(-1);
}
}
strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name));
rv = ioctl(sock_fd, SIOCGIFHWADDR, &ifr);
if (rv != -1) /* worked okay */
ARCNET_MAC_Address = ifr.ifr_hwaddr.sa_data[0];
// copy this info into the local copy since bind wiped it out
ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET;
//ARCNET_Socket_Address.sa_family = PF_INET;
/* Clear the memory before copying */
memset(ARCNET_Socket_Address.sa_data, '\0',
sizeof(ARCNET_Socket_Address.sa_data));
sizeof(ARCNET_Socket_Address.sa_data));
/* Strcpy the interface name into the address */
strncpy(ARCNET_Socket_Address.sa_data, interface_name,
sizeof(ARCNET_Socket_Address.sa_data)-1);
fprintf(stderr,"arcnet: binding \"%s\"\n",ARCNET_Socket_Address.sa_data);
if (bind(sock_fd, &ARCNET_Socket_Address,
sizeof(ARCNET_Socket_Address)) != 0)
{
/* Bind problem, close socket and return */
fprintf(stderr,
"arcnet: Unable to bind socket : %s\n",
strerror(errno));
fprintf(stderr,
"You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n"
"# modprobe af_packet\n");
/* Close the socket */
close(sock_fd);
exit(-1);
}
}
strncpy(ifr.ifr_name, interface_name, sizeof(ifr.ifr_name));
rv = ioctl(sock_fd, SIOCGIFHWADDR, &ifr);
if (rv != -1) /* worked okay */
ARCNET_MAC_Address = ifr.ifr_hwaddr.sa_data[0];
// copy this info into the local copy since bind wiped it out
ARCNET_Socket_Address.sa_family = ARPHRD_ARCNET;
//ARCNET_Socket_Address.sa_family = PF_INET;
/* Clear the memory before copying */
memset(ARCNET_Socket_Address.sa_data, '\0',
sizeof(ARCNET_Socket_Address.sa_data));
/* Strcpy the interface name into the address */
strncpy(ARCNET_Socket_Address.sa_data, interface_name,
sizeof(ARCNET_Socket_Address.sa_data)-1);
fprintf(stderr,"arcnet: MAC=%02Xh iface=\"%s\"\n",
ARCNET_MAC_Address,
ARCNET_Socket_Address.sa_data);
strncpy(ARCNET_Socket_Address.sa_data, interface_name,
sizeof(ARCNET_Socket_Address.sa_data) - 1);
fprintf(stderr, "arcnet: MAC=%02Xh iface=\"%s\"\n",
ARCNET_MAC_Address, ARCNET_Socket_Address.sa_data);
atexit(arcnet_cleanup);
atexit(arcnet_cleanup);
return sock_fd;
return sock_fd;
}
bool arcnet_init(char *interface_name)
{
ARCNET_Sock_FD = arcnet_bind(interface_name);
ARCNET_Sock_FD = arcnet_bind(interface_name);
return arcnet_valid();
return arcnet_valid();
}
/* function to send a packet out the socket */
/* returns number of bytes sent on success, negative on failure */
int arcnet_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 arcnet_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[512] = { 0 };
int mtu_len = 0;
struct archdr *pkt = (struct archdr *)mtu;
struct archdr *pkt = (struct archdr *) mtu;
// don't waste time if the socket is not valid
if (ARCNET_Sock_FD < 0)
{
if (ARCNET_Sock_FD < 0) {
fprintf(stderr, "arcnet: socket is invalid!\n");
return -1;
}
/* load destination MAC address */
if (dest->mac_len == 1)
pkt->hard.dest = dest->mac[0];
else
{
pkt->hard.dest = dest->mac[0];
else {
fprintf(stderr, "arcnet: invalid destination MAC address!\n");
return -2;
}
if (src->mac_len == 1)
pkt->hard.source = src->mac[0];
else
{
pkt->hard.source = src->mac[0];
else {
fprintf(stderr, "arcnet: invalid source MAC address!\n");
return -3;
}
if ((ARC_HDR_SIZE + pdu_len) > 512)
{
if ((ARC_HDR_SIZE + pdu_len) > 512) {
fprintf(stderr, "arcnet: PDU is too big to send!\n");
return -4;
}
/* Logical PDU portion */
pkt->soft.raw[0] = 0xCD; /* SC for BACnet */
pkt->soft.raw[1] = 0x82; /* DSAP for BACnet */
pkt->soft.raw[2] = 0x82; /* SSAP for BACnet */
pkt->soft.raw[3] = 0x03; /* Control byte in header */
pkt->soft.raw[0] = 0xCD; /* SC for BACnet */
pkt->soft.raw[1] = 0x82; /* DSAP for BACnet */
pkt->soft.raw[2] = 0x82; /* SSAP for BACnet */
pkt->soft.raw[3] = 0x03; /* Control byte in header */
memcpy(&pkt->soft.raw[4], pdu, pdu_len);
/* packet length */
mtu_len = ARC_HDR_SIZE + 4 /*SC,DSAP,SSAP,LLC*/ + pdu_len;
mtu_len = ARC_HDR_SIZE + 4 /*SC,DSAP,SSAP,LLC */ + pdu_len;
/* Send the packet */
bytes =
sendto(ARCNET_Sock_FD, &mtu, mtu_len, 0,
(struct sockaddr *) &ARCNET_Socket_Address,
sizeof(ARCNET_Socket_Address));
(struct sockaddr *) &ARCNET_Socket_Address,
sizeof(ARCNET_Socket_Address));
/* did it get sent? */
if (bytes < 0)
fprintf(stderr,"arcnet: Error sending packet: %s\n",
strerror(errno));
fprintf(stderr, "arcnet: Error sending packet: %s\n",
strerror(errno));
return bytes;
}
/* function to send a PDU out the socket */
/* returns number of bytes sent on success, negative on failure */
int arcnet_send_pdu(
BACNET_ADDRESS *dest, // destination address
uint8_t *pdu, // any data to be sent - may be null
unsigned pdu_len) // number of bytes of data
int arcnet_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
{
BACNET_ADDRESS src = {0}; // source address
src.mac[0] = ARCNET_MAC_Address;
src.mac_len = 1;
return arcnet_send(dest, // destination address
&src, // source address
pdu, // any data to be sent - may be null
pdu_len); // number of bytes of data
BACNET_ADDRESS src = { 0 }; // source address
src.mac[0] = ARCNET_MAC_Address;
src.mac_len = 1;
return arcnet_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 framed packet
// returns the number of octets in the PDU, or zero on failure
uint16_t arcnet_receive(
BACNET_ADDRESS *src, // source address
uint8_t *pdu, // PDU data
uint16_t max_pdu, // amount of space available in the PDU
unsigned timeout) // milliseconds to wait for a packet
uint16_t arcnet_receive(BACNET_ADDRESS * src, // source address
uint8_t * pdu, // PDU data
uint16_t max_pdu, // amount of space available in the PDU
unsigned timeout) // milliseconds to wait for a packet
{
int received_bytes;
uint8_t buf[512] = {0}; // data
uint16_t pdu_len = 0; // return value
uint8_t buf[512] = { 0 }; // data
uint16_t pdu_len = 0; // return value
fd_set read_fds;
int max;
struct timeval select_timeout;
struct archdr *pkt = (struct archdr *)buf;
struct archdr *pkt = (struct archdr *) buf;
/* Make sure the socket is open */
if (ARCNET_Sock_FD <= 0)
@@ -289,14 +275,11 @@ uint16_t arcnet_receive(
/* 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)
{
if (timeout >= 1000) {
select_timeout.tv_sec = timeout / 1000;
select_timeout.tv_usec =
1000 * (timeout - select_timeout.tv_sec * 1000);
}
else
{
select_timeout.tv_usec =
1000 * (timeout - select_timeout.tv_sec * 1000);
} else {
select_timeout.tv_sec = 0;
select_timeout.tv_usec = 1000 * timeout;
}
@@ -315,46 +298,44 @@ uint16_t arcnet_receive(
// using O_NONBLOCK and no data
// was immediately available for reading.
if (errno != EAGAIN)
fprintf(stderr,"ethernet: Read error in receiving packet: %s\n",
fprintf(stderr,
"ethernet: Read error in receiving packet: %s\n",
strerror(errno));
return 0;
}
if (received_bytes == 0)
return 0;
return 0;
/* printf("arcnet: received %u bytes (offset=%02Xh %02Xh) "
"from %02Xh (proto==%02Xh)\n",
received_bytes, pkt->offset[0], pkt->offset[1],
pkt->hard.source, pkt->soft.raw[0]);
*/
"from %02Xh (proto==%02Xh)\n",
received_bytes, pkt->offset[0], pkt->offset[1],
pkt->hard.source, pkt->soft.raw[0]);
*/
if (pkt->hard.source == ARCNET_MAC_Address) {
fprintf(stderr,"arcnet: self sent packet?\n");
fprintf(stderr, "arcnet: self sent packet?\n");
return 0;
}
if (pkt->soft.raw[0] != 0xCD) {
/* fprintf(stderr,"arcnet: Non-BACnet packet.\n"); */
return 0;
}
if ((pkt->hard.dest != ARCNET_MAC_Address) &&
(pkt->hard.dest != ARCNET_BROADCAST))
{
fprintf(stderr,"arcnet: This packet is not for us.\n");
if ((pkt->hard.dest != ARCNET_MAC_Address) &&
(pkt->hard.dest != ARCNET_BROADCAST)) {
fprintf(stderr, "arcnet: This packet is not for us.\n");
return 0;
}
if ((pkt->soft.raw[1] != 0x82) || /* DSAP */
(pkt->soft.raw[2] != 0x82) || /* LSAP */
(pkt->soft.raw[3] != 0x03)) /* LLC Control */
{
fprintf(stderr,"arcnet: BACnet packet has invalid LLC.\n");
if ((pkt->soft.raw[1] != 0x82) || /* DSAP */
(pkt->soft.raw[2] != 0x82) || /* LSAP */
(pkt->soft.raw[3] != 0x03)) { /* LLC Control */
fprintf(stderr, "arcnet: BACnet packet has invalid LLC.\n");
return 0;
}
/* It must be addressed to us or be a Broadcast */
if ((pkt->hard.dest != ARCNET_MAC_Address) &&
(pkt->hard.dest != ARCNET_BROADCAST))
{
fprintf(stderr,"arcnet: This packet is not for us.\n");
if ((pkt->hard.dest != ARCNET_MAC_Address) &&
(pkt->hard.dest != ARCNET_BROADCAST)) {
fprintf(stderr, "arcnet: This packet is not for us.\n");
return 0;
}
/* copy the source address */
@@ -365,47 +346,42 @@ uint16_t arcnet_receive(
pdu_len -= 4 /* SC, DSAP, SSAP, LLC Control */ ;
// copy the buffer into the PDU
if (pdu_len < max_pdu)
memmove(&pdu[0],&pkt->soft.raw[4],pdu_len);
memmove(&pdu[0], &pkt->soft.raw[4], pdu_len);
// silently ignore packets that are too large
else
pdu_len = 0;
pdu_len = 0;
return pdu_len;
}
void arcnet_get_my_address(BACNET_ADDRESS *my_address)
void arcnet_get_my_address(BACNET_ADDRESS * my_address)
{
int i = 0;
my_address->mac_len = 1;
my_address->mac[0] = ARCNET_MAC_Address;
my_address->net = 0; // local only, no routing
my_address->len = 0;
for (i = 0; i < MAX_MAC_LEN; i++)
{
my_address->adr[i] = 0;
}
int i = 0;
return;
}
void arcnet_get_broadcast_address(
BACNET_ADDRESS *dest) // destination address
{
int i = 0; // counter
if (dest)
{
dest->mac[0] = ARCNET_BROADCAST;
dest->mac_len = 1;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; // len=0 denotes broadcast address
for (i = 0; i < MAX_MAC_LEN; i++)
{
dest->adr[i] = 0;
my_address->mac_len = 1;
my_address->mac[0] = ARCNET_MAC_Address;
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;
}
}
return;
return;
}
void arcnet_get_broadcast_address(BACNET_ADDRESS * dest) // destination address
{
int i = 0; // counter
if (dest) {
dest->mac[0] = ARCNET_BROADCAST;
dest->mac_len = 1;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; // len=0 denotes broadcast address
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
}
return;
}
+17 -21
View File
@@ -39,7 +39,8 @@
#include "net.h"
static int get_local_ifr_ioctl(char *ifname, struct ifreq *ifr, int request)
static int get_local_ifr_ioctl(char *ifname, struct ifreq *ifr,
int request)
{
int fd;
int rv; // return value
@@ -54,16 +55,14 @@ static int get_local_ifr_ioctl(char *ifname, struct ifreq *ifr, int request)
return rv;
}
static int get_local_address_ioctl(
char *ifname,
struct in_addr *addr,
int request)
static int get_local_address_ioctl(char *ifname,
struct in_addr *addr, int request)
{
struct ifreq ifr = { {{0}} };
struct sockaddr_in *tcpip_address;
int rv; // return value
rv = get_local_ifr_ioctl(ifname,&ifr,request);
rv = get_local_ifr_ioctl(ifname, &ifr, request);
if (rv >= 0) {
tcpip_address = (struct sockaddr_in *) &ifr.ifr_addr;
memcpy(addr, &tcpip_address->sin_addr, sizeof(struct in_addr));
@@ -80,20 +79,21 @@ void bip_set_interface(char *ifname)
/* setup local address */
get_local_address_ioctl(ifname, &local_address, SIOCGIFADDR);
bip_set_addr(local_address.s_addr);
#ifdef BIP_DEBUG
fprintf(stderr,"IP Address: %s\n",inet_ntoa(local_address));
#endif
#ifdef BIP_DEBUG
fprintf(stderr, "IP Address: %s\n", inet_ntoa(local_address));
#endif
/* setup local broadcast address */
get_local_address_ioctl(ifname, &broadcast_address, SIOCGIFBRDADDR);
bip_set_broadcast_addr(broadcast_address.s_addr);
#ifdef BIP_DEBUG
fprintf(stderr,"Broadcast Address: %s\n",inet_ntoa(broadcast_address));
#endif
#ifdef BIP_DEBUG
fprintf(stderr, "Broadcast Address: %s\n",
inet_ntoa(broadcast_address));
#endif
}
bool bip_init(void)
{
int status = 0; // return from socket lib calls
int status = 0; // return from socket lib calls
struct sockaddr_in sin;
int sockopt = 0;
int sock_fd = -1;
@@ -108,8 +108,7 @@ bool bip_init(void)
sockopt = 1;
status = setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR,
&sockopt, sizeof(sockopt));
if (status < 0)
{
if (status < 0) {
close(sock_fd);
bip_set_socket(-1);
return status;
@@ -117,22 +116,19 @@ bool bip_init(void)
// allow us to send a broadcast
status = setsockopt(sock_fd, SOL_SOCKET, SO_BROADCAST,
&sockopt, sizeof(sockopt));
if (status < 0)
{
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 = htons(bip_get_port());
memset(&(sin.sin_zero), '\0', sizeof(sin.sin_zero));
status = bind(sock_fd,
(const struct sockaddr*)&sin, sizeof(struct sockaddr));
if (status < 0)
{
(const struct sockaddr *) &sin, sizeof(struct sockaddr));
if (status < 0) {
close(sock_fd);
bip_set_socket(-1);
return false;
+147 -181
View File
@@ -45,24 +45,25 @@ uint8_t Ethernet_Broadcast[MAX_MAC_LEN] =
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
// commonly used empty address for ethernet quick compare
uint8_t Ethernet_Empty_MAC[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 };
// my local device data - MAC address
uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0 };
static int eth802_sockfd = -1; /* 802.2 file handle */
static struct sockaddr eth_addr = { 0 }; // used for binding 802.2
static int eth802_sockfd = -1; /* 802.2 file handle */
static struct sockaddr eth_addr = { 0 }; // used for binding 802.2
bool ethernet_valid(void)
{
return (eth802_sockfd >= 0);
return (eth802_sockfd >= 0);
}
void ethernet_cleanup(void)
{
if (ethernet_valid())
close(eth802_sockfd);
eth802_sockfd = -1;
if (ethernet_valid())
close(eth802_sockfd);
eth802_sockfd = -1;
return;
return;
}
/*----------------------------------------------------------------------
@@ -76,23 +77,23 @@ void ethernet_cleanup(void)
----------------------------------------------------------------------*/
int setNonblocking(int fd)
{
int flags;
int flags;
if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
flags = 0;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
if (-1 == (flags = fcntl(fd, F_GETFL, 0)))
flags = 0;
return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
}
/* opens an 802.2 socket to receive and send packets */
static int ethernet_bind(struct sockaddr *eth_addr, char *interface_name)
{
int sock_fd = -1; // return value
int sock_fd = -1; // return value
int uid = 0;
fprintf(stderr,"ethernet: opening \"%s\"\n",interface_name);
fprintf(stderr, "ethernet: opening \"%s\"\n", interface_name);
/* check to see if we are being run as root */
uid = getuid();
if (uid != 0) {
if (uid != 0) {
fprintf(stderr,
"ethernet: Unable to open an 802.2 socket. "
"Try running with root priveleges.\n");
@@ -102,21 +103,18 @@ static int ethernet_bind(struct sockaddr *eth_addr, char *interface_name)
// modules.conf (or in modutils/alias on Debian with update-modules)
// alias net-pf-17 af_packet
// Then follow it by: # modprobe af_packet
/* Attempt to open the socket for 802.2 ethernet frames */
if ((sock_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_802_2))) < 0)
{
if ((sock_fd = socket(PF_INET, SOCK_PACKET, htons(ETH_P_802_2))) < 0) {
/* Error occured */
fprintf(stderr,
"ethernet: Error opening socket: %s\n",
strerror(errno));
"ethernet: Error opening socket: %s\n", strerror(errno));
fprintf(stderr,
"You might need to add the following to modules.conf\n"
"(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n"
"# modprobe af_packet\n");
"Then follow it by:\n" "# modprobe af_packet\n");
exit(-1);
}
/* Bind the socket to an address */
@@ -124,11 +122,11 @@ static int ethernet_bind(struct sockaddr *eth_addr, char *interface_name)
/* Clear the memory before copying */
memset(eth_addr->sa_data, '\0', sizeof(eth_addr->sa_data));
/* Strcpy the interface name into the address */
strncpy(eth_addr->sa_data, interface_name, sizeof(eth_addr->sa_data)-1);
fprintf(stderr,"ethernet: binding \"%s\"\n",eth_addr->sa_data);
strncpy(eth_addr->sa_data, interface_name,
sizeof(eth_addr->sa_data) - 1);
fprintf(stderr, "ethernet: binding \"%s\"\n", eth_addr->sa_data);
/* Attempt to bind the socket to the interface */
if (bind(sock_fd, eth_addr, sizeof(struct sockaddr)) != 0)
{
if (bind(sock_fd, eth_addr, sizeof(struct sockaddr)) != 0) {
/* Bind problem, close socket and return */
fprintf(stderr,
"ethernet: Unable to bind 802.2 socket : %s\n",
@@ -138,8 +136,7 @@ static int ethernet_bind(struct sockaddr *eth_addr, char *interface_name)
"(or in /etc/modutils/alias on Debian with update-modules):\n"
"alias net-pf-17 af_packet\n"
"Also, add af_packet to /etc/modules.\n"
"Then follow it by:\n"
"# modprobe af_packet\n");
"Then follow it by:\n" "# modprobe af_packet\n");
/* Close the socket */
close(sock_fd);
exit(-1);
@@ -155,7 +152,7 @@ static int get_local_hwaddr(const char *ifname, unsigned char *mac)
{
struct ifreq ifr;
int fd;
int rv; // return value - error value from df or ioctl call
int rv; // return value - error value from df or ioctl call
/* determine the local MAC address */
strcpy(ifr.ifr_name, ifname);
@@ -174,19 +171,17 @@ static int get_local_hwaddr(const char *ifname, unsigned char *mac)
bool ethernet_init(char *interface_name)
{
get_local_hwaddr(interface_name, Ethernet_MAC_Address);
eth802_sockfd =
ethernet_bind(&eth_addr, interface_name);
eth802_sockfd = ethernet_bind(&eth_addr, interface_name);
return ethernet_valid();
return ethernet_valid();
}
/* 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 };
@@ -194,101 +189,88 @@ int ethernet_send(
int i = 0;
// don't waste time if the socket is not valid
if (eth802_sockfd < 0)
{
if (eth802_sockfd < 0) {
fprintf(stderr, "ethernet: 802.2 socket is invalid!\n");
return -1;
}
/* load destination ethernet MAC address */
if (dest->mac_len == 6)
{
for (i = 0; i < 6; i++)
{
mtu[mtu_len] = dest->mac[i];
mtu_len++;
}
}
else
{
if (dest->mac_len == 6) {
for (i = 0; i < 6; i++) {
mtu[mtu_len] = dest->mac[i];
mtu_len++;
}
} else {
fprintf(stderr, "ethernet: invalid destination MAC address!\n");
return -2;
}
/* load source ethernet MAC address */
if (src->mac_len == 6)
{
for (i = 0; i < 6; i++)
{
mtu[mtu_len] = src->mac[i];
mtu_len++;
}
}
else
{
if (src->mac_len == 6) {
for (i = 0; i < 6; i++) {
mtu[mtu_len] = src->mac[i];
mtu_len++;
}
} else {
fprintf(stderr, "ethernet: invalid source MAC address!\n");
return -3;
}
if ((14 + 3 + pdu_len) > MAX_MPDU)
{
if ((14 + 3 + pdu_len) > MAX_MPDU) {
fprintf(stderr, "ethernet: PDU is too big to send!\n");
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;
/* Send the packet */
bytes =
sendto(eth802_sockfd, &mtu, mtu_len, 0,
(struct sockaddr *) &eth_addr, sizeof(struct sockaddr));
/* did it get sent? */
if (bytes < 0)
fprintf(stderr,"ethernet: Error sending packet: %s\n",
strerror(errno));
fprintf(stderr, "ethernet: Error sending packet: %s\n",
strerror(errno));
return bytes;
}
/* function to send a packet out the 802.2 socket */
/* returns number of bytes sent on success, negative on failure */
int ethernet_send_pdu(
BACNET_ADDRESS *dest, // destination address
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
BACNET_ADDRESS src = {0}; // source address
for (i = 0; i < 6; i++)
{
src.mac[i] = Ethernet_MAC_Address[i];
src.mac_len++;
}
/* 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
pdu_len); // number of bytes of data
int i = 0; // counter
BACNET_ADDRESS src = { 0 }; // source address
for (i = 0; i < 6; i++) {
src.mac[i] = Ethernet_MAC_Address[i];
src.mac_len++;
}
/* 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
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
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
{
int received_bytes;
uint8_t buf[MAX_MPDU] = {0}; // data
uint16_t pdu_len = 0; // return value
uint8_t buf[MAX_MPDU] = { 0 }; // data
uint16_t pdu_len = 0; // return value
fd_set read_fds;
int max;
struct timeval select_timeout;
@@ -300,14 +282,11 @@ uint16_t ethernet_receive(
/* 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)
{
if (timeout >= 1000) {
select_timeout.tv_sec = timeout / 1000;
select_timeout.tv_usec =
1000 * (timeout - select_timeout.tv_sec * 1000);
}
else
{
select_timeout.tv_usec =
1000 * (timeout - select_timeout.tv_sec * 1000);
} else {
select_timeout.tv_sec = 0;
select_timeout.tv_usec = 1000 * timeout;
}
@@ -326,14 +305,15 @@ uint16_t ethernet_receive(
// using O_NONBLOCK and no data
// was immediately available for reading.
if (errno != EAGAIN)
fprintf(stderr,"ethernet: Read error in receiving packet: %s\n",
fprintf(stderr,
"ethernet: Read error in receiving packet: %s\n",
strerror(errno));
return 0;
}
if (received_bytes == 0)
return 0;
return 0;
/* the signature of an 802.2 BACnet packet */
if ((buf[14] != 0x82) && (buf[15] != 0x82)) {
//fprintf(stderr,"ethernet: Non-BACnet packet\n");
@@ -345,109 +325,95 @@ uint16_t ethernet_receive(
// check destination address for when
// the Ethernet card is in promiscious mode
if ((memcmp(&buf[0], Ethernet_MAC_Address,6) != 0)
&& (memcmp(&buf[0], Ethernet_Broadcast, 6) != 0))
{
if ((memcmp(&buf[0], Ethernet_MAC_Address, 6) != 0)
&& (memcmp(&buf[0], Ethernet_Broadcast, 6) != 0)) {
//fprintf(stderr, "ethernet: This packet isn't for us\n");
return 0;
}
(void)decode_unsigned16(&buf[12],&pdu_len);
(void) decode_unsigned16(&buf[12], &pdu_len);
pdu_len -= 3 /* DSAP, SSAP, LLC Control */ ;
// copy the buffer into the PDU
if (pdu_len < max_pdu)
memmove(&pdu[0],&buf[17],pdu_len);
memmove(&pdu[0], &buf[17], pdu_len);
// ignore packets that are too large
else
pdu_len = 0;
pdu_len = 0;
return pdu_len;
}
void ethernet_set_my_address(BACNET_ADDRESS *my_address)
void ethernet_set_my_address(BACNET_ADDRESS * my_address)
{
int i = 0;
for (i = 0; i < 6; i++)
{
Ethernet_MAC_Address[i] = my_address->mac[i];
}
int i = 0;
return;
for (i = 0; i < 6; i++) {
Ethernet_MAC_Address[i] = my_address->mac[i];
}
return;
}
void ethernet_get_my_address(BACNET_ADDRESS *my_address)
void ethernet_get_my_address(BACNET_ADDRESS * my_address)
{
int i = 0;
my_address->mac_len = 0;
for (i = 0; i < 6; i++)
{
my_address->mac[i] = Ethernet_MAC_Address[i];
my_address->mac_len++;
}
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;
}
int i = 0;
return;
my_address->mac_len = 0;
for (i = 0; i < 6; i++) {
my_address->mac[i] = Ethernet_MAC_Address[i];
my_address->mac_len++;
}
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;
}
return;
}
void ethernet_get_broadcast_address(
BACNET_ADDRESS *dest) // destination address
void ethernet_get_broadcast_address(BACNET_ADDRESS * dest) // destination address
{
int i = 0; // counter
if (dest)
{
for (i = 0; i < 6; i++)
{
dest->mac[i] = Ethernet_Broadcast[i];
}
dest->mac_len = 6;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; // denotes broadcast address
for (i = 0; i < MAX_MAC_LEN; i++)
{
dest->adr[i] = 0;
}
}
int i = 0; // counter
return;
if (dest) {
for (i = 0; i < 6; i++) {
dest->mac[i] = Ethernet_Broadcast[i];
}
dest->mac_len = 6;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; // denotes broadcast address
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
}
return;
}
void ethernet_debug_address(
const char *info,
BACNET_ADDRESS *dest)
void ethernet_debug_address(const char *info, BACNET_ADDRESS * dest)
{
int i = 0; // counter
int i = 0; // counter
if (info)
fprintf(stderr,"%s",info);
if (dest)
{
fprintf(stderr,"Address:\n");
fprintf(stderr," MAC Length=%d\n",dest->mac_len);
fprintf(stderr," MAC Address=");
for (i = 0; i < MAX_MAC_LEN; i++)
{
fprintf(stderr,"%02X ",(unsigned)dest->mac[i]);
if (info)
fprintf(stderr, "%s", info);
if (dest) {
fprintf(stderr, "Address:\n");
fprintf(stderr, " MAC Length=%d\n", dest->mac_len);
fprintf(stderr, " MAC Address=");
for (i = 0; i < MAX_MAC_LEN; i++) {
fprintf(stderr, "%02X ", (unsigned) dest->mac[i]);
}
fprintf(stderr, "\n");
fprintf(stderr, " Net=%hu\n", dest->net);
fprintf(stderr, " Len=%d\n", dest->len);
fprintf(stderr, " Adr=");
for (i = 0; i < MAX_MAC_LEN; i++) {
fprintf(stderr, "%02X ", (unsigned) dest->adr[i]);
}
fprintf(stderr, "\n");
}
fprintf(stderr,"\n");
fprintf(stderr," Net=%hu\n",dest->net);
fprintf(stderr," Len=%d\n",dest->len);
fprintf(stderr," Adr=");
for (i = 0; i < MAX_MAC_LEN; i++)
{
fprintf(stderr,"%02X ",(unsigned)dest->adr[i]);
}
fprintf(stderr,"\n");
}
return;
return;
}
+210 -252
View File
@@ -48,293 +48,251 @@
bool Who_Is_Request = true;
// buffers used for receiving
static uint8_t Rx_Buf[MAX_MPDU] = {0};
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
static void LocalIAmHandler(
uint8_t *service_request,
uint16_t service_len,
BACNET_ADDRESS *src)
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;
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");
(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;
return;
}
static void Read_Properties(void)
{
uint32_t device_id = 0;
bool status = false;
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 and proprietary)
properties in the Device Object. Note that this demo
tests for error messages so that the device doesn't have
to have all the properties listed here. */
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_CONFORMANCE_CLASS,
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 because
the result can be very large. Read index 0
which gives us the number of objects in the list,
and then we can read index 1, 2.. n one by one,
rather than trying to read the entire object
list in one message. */
/* some proprietary properties */
514,515,
/* end of list */
-1
};
uint32_t device_id = 0;
bool status = false;
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 and proprietary)
properties in the Device Object. Note that this demo
tests for error messages so that the device doesn't have
to have all the properties listed here. */
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_CONFORMANCE_CLASS,
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 because
the result can be very large. Read index 0
which gives us the number of objects in the list,
and then we can read index 1, 2.. n one by one,
rather than trying to read the entire object
list in one message. */
/* some proprietary properties */
514, 515,
/* end of list */
-1
};
if (address_count())
{
if (address_get_by_index(index, &device_id, &max_apdu, &src))
{
if (object_props[property] < 0)
next_device = true;
else
{
/* note: if we wanted to do this synchronously, we would get the
invoke ID from the sending of the request, and wait until we
got the reply with matching invoke ID or the TSM of the
invoke ID expired. This demo is doing things asynchronously. */
status = Send_Read_Property_Request(
device_id, // destination device
OBJECT_DEVICE,
device_id,
object_props[property],
BACNET_ARRAY_ALL);
if (status)
property++;
}
if (address_count()) {
if (address_get_by_index(index, &device_id, &max_apdu, &src)) {
if (object_props[property] < 0)
next_device = true;
else {
/* note: if we wanted to do this synchronously, we would get the
invoke ID from the sending of the request, and wait until we
got the reply with matching invoke ID or the TSM of the
invoke ID expired. This demo is doing things asynchronously. */
status = Send_Read_Property_Request(device_id, // destination device
OBJECT_DEVICE,
device_id, object_props[property], BACNET_ARRAY_ALL);
if (status)
property++;
}
} else
next_device = true;
if (next_device) {
next_device = false;
index++;
if (index >= MAX_ADDRESS_CACHE)
index = 0;
property = 0;
}
}
else
next_device = true;
if (next_device)
{
next_device = false;
index++;
if (index >= MAX_ADDRESS_CACHE)
index = 0;
property = 0;
}
}
return;
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,
handler_who_is);
apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_I_AM,
LocalIAmHandler);
// we need to handle who-is to support dynamic device binding
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
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(
handler_unrecognized_service);
// Set the handlers for any confirmed services that we support.
// 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_WRITE_PROPERTY,
handler_write_property);
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_ATOMIC_READ_FILE,
handler_atomic_read_file);
// 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_ATOMIC_READ_FILE,
handler_atomic_read_file_ack);
// 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);
// Set the handlers for any confirmed services that we support.
// 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_WRITE_PROPERTY,
handler_write_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_ATOMIC_READ_FILE,
handler_atomic_read_file);
// 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_ATOMIC_READ_FILE,
handler_atomic_read_file_ack);
}
static void print_address_cache(void)
{
unsigned i,j;
BACNET_ADDRESS address;
uint32_t device_id = 0;
unsigned max_apdu = 0;
fprintf(stderr,"Device\tMAC\tMaxAPDU\tNet\n");
for (i = 0; i < MAX_ADDRESS_CACHE; i++)
{
if (address_get_by_index(i,&device_id, &max_apdu, &address))
{
fprintf(stderr,"%u\t",device_id);
for (j = 0; j < address.mac_len; j++)
{
fprintf(stderr,"%02X",address.mac[j]);
}
fprintf(stderr,"\t");
fprintf(stderr,"%hu\t",max_apdu);
fprintf(stderr,"%hu\n",address.net);
unsigned i, j;
BACNET_ADDRESS address;
uint32_t device_id = 0;
unsigned max_apdu = 0;
fprintf(stderr, "Device\tMAC\tMaxAPDU\tNet\n");
for (i = 0; i < MAX_ADDRESS_CACHE; i++) {
if (address_get_by_index(i, &device_id, &max_apdu, &address)) {
fprintf(stderr, "%u\t", device_id);
for (j = 0; j < address.mac_len; j++) {
fprintf(stderr, "%02X", address.mac[j]);
}
fprintf(stderr, "\t");
fprintf(stderr, "%hu\t", max_apdu);
fprintf(stderr, "%hu\n", address.net);
}
}
}
}
static void print_tsm_stats(void)
{
int idle = 0;
int total = 0;
int idle = 0;
int total = 0;
idle = tsm_transaction_idle_count();
total = MAX_TSM_TRANSACTIONS;
fprintf(stderr,"TSM: %d idle of %d transactions\n",idle,total);
idle = tsm_transaction_idle_count();
total = MAX_TSM_TRANSACTIONS;
fprintf(stderr, "TSM: %d idle of %d transactions\n", idle, total);
}
static void sig_handler(int signo)
{
datalink_cleanup();
print_address_cache();
print_tsm_stats();
exit(0);
datalink_cleanup();
print_address_cache();
print_tsm_stats();
exit(0);
}
int main(int argc, char *argv[])
{
BACNET_ADDRESS src = {0}; // address where message came from
uint16_t pdu_len = 0;
unsigned timeout = 100; // milliseconds
unsigned count = 0; // milliseconds
time_t start_time;
time_t new_time = 0;
start_time = time(NULL); /* get current time */
// Linux specials
signal(SIGINT, sig_handler);
signal(SIGHUP, sig_handler);
signal(SIGTERM, sig_handler);
// setup this BACnet Server device
Device_Set_Object_Instance_Number(111);
Init_Service_Handlers();
#ifdef BACDL_ETHERNET
// init the physical layer
if (!ethernet_init("eth0"))
return 1;
#endif
#ifdef BACDL_BIP
bip_set_interface("eth0");
bip_set_port(0xBAC0);
if (!bip_init())
return 1;
#endif
#ifdef BACDL_ARCNET
if (!arcnet_init("arc0"))
return 1;
#endif
BACNET_ADDRESS src = { 0 }; // address where message came from
uint16_t pdu_len = 0;
unsigned timeout = 100; // milliseconds
unsigned count = 0; // milliseconds
time_t start_time;
time_t new_time = 0;
// loop forever
for (;;)
{
// input
new_time = time(NULL);
// returns 0 bytes on timeout
pdu_len = datalink_receive(
&src,
&Rx_Buf[0],
MAX_MPDU,
timeout);
start_time = time(NULL); /* get current time */
// Linux specials
signal(SIGINT, sig_handler);
signal(SIGHUP, sig_handler);
signal(SIGTERM, sig_handler);
// setup this BACnet Server device
Device_Set_Object_Instance_Number(111);
Init_Service_Handlers();
#ifdef BACDL_ETHERNET
// init the physical layer
if (!ethernet_init("eth0"))
return 1;
#endif
#ifdef BACDL_BIP
bip_set_interface("eth0");
bip_set_port(0xBAC0);
if (!bip_init())
return 1;
#endif
#ifdef BACDL_ARCNET
if (!arcnet_init("arc0"))
return 1;
#endif
// process
if (pdu_len)
{
npdu_handler(
&src,
&Rx_Buf[0],
pdu_len);
}
if (new_time > start_time)
{
tsm_timer_milliseconds(new_time - start_time * 1000);
start_time = new_time;
}
if (I_Am_Request)
{
I_Am_Request = false;
iam_send(&Handler_Transmit_Buffer[0]);
} else if (Who_Is_Request)
{
Who_Is_Request = false;
Send_WhoIs(-1,-1);
}
// output
// some round robin task switching
count++;
switch (count)
{
case 1:
// used for testing, but kind of noisy on the network
//Read_Properties();
break;
case 2:
break;
default:
count = 0;
break;
// loop forever
for (;;) {
// input
new_time = time(NULL);
// returns 0 bytes on timeout
pdu_len = datalink_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
// process
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (new_time > start_time) {
tsm_timer_milliseconds(new_time - start_time * 1000);
start_time = new_time;
}
if (I_Am_Request) {
I_Am_Request = false;
iam_send(&Handler_Transmit_Buffer[0]);
} else if (Who_Is_Request) {
Who_Is_Request = false;
Send_WhoIs(-1, -1);
}
// output
// some round robin task switching
count++;
switch (count) {
case 1:
// used for testing, but kind of noisy on the network
//Read_Properties();
break;
case 2:
break;
default:
count = 0;
break;
}
// blink LEDs, Turn on or off outputs, etc
}
// blink LEDs, Turn on or off outputs, etc
}
return 0;
return 0;
}
+12 -12
View File
@@ -27,34 +27,34 @@
#define NET_H
/* common unix sockets headers needed */
#include <sys/types.h> /* basic system data types */
#include <sys/time.h> /* timeval{} for select() */
#include <time.h> /* timespec{} for pselect() */
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h> /* inet(3) functions */
#include <fcntl.h> /* for nonblocking */
#include <sys/types.h> /* basic system data types */
#include <sys/time.h> /* timeval{} for select() */
#include <time.h> /* timespec{} for pselect() */
#include <netinet/in.h> /* sockaddr_in{} and other Internet defns */
#include <arpa/inet.h> /* inet(3) functions */
#include <fcntl.h> /* for nonblocking */
#include <netdb.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h> /* for S_xxx file mode constants */
#include <sys/uio.h> /* for iovec{} and readv/writev */
#include <sys/stat.h> /* for S_xxx file mode constants */
#include <sys/uio.h> /* for iovec{} and readv/writev */
#include <unistd.h>
#include <sys/wait.h>
#include <sys/un.h> /* for Unix domain sockets */
#include <sys/un.h> /* for Unix domain sockets */
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h> /* for convenience */
# include <sys/select.h> /* for convenience */
#endif
#ifdef HAVE_POLL_H
# include <poll.h> /* for convenience */
# include <poll.h> /* for convenience */
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h> /* for convenience */
# include <strings.h> /* for convenience */
#endif
/* Three headers are normally needed for socket/file ioctl's:
+32 -38
View File
@@ -40,60 +40,54 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include "mstp.h"
// Transmits a Frame on the wire
void RS485_Send_Frame(
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)
void RS485_Send_Frame(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)
{
// in order to avoid line contention
while (mstp_port->Turn_Around_Waiting)
{
// wait, yield, or whatever
}
// in order to avoid line contention
while (mstp_port->Turn_Around_Waiting) {
// wait, yield, or whatever
}
// Disable the receiver, and enable the transmit line driver.
// Disable the receiver, and enable the transmit line driver.
while (nbytes)
{
putc(*buffer,stderr);
buffer++;
nbytes--;
}
while (nbytes) {
putc(*buffer, stderr);
buffer++;
nbytes--;
}
// Wait until the final stop bit of the most significant CRC octet
// has been transmitted but not more than Tpostdrive.
// Wait until the final stop bit of the most significant CRC octet
// has been transmitted but not more than Tpostdrive.
// Disable the transmit line driver.
// Disable the transmit line driver.
return;
return;
}
// called by timer, interrupt(?) or other thread
void RS485_Check_UART_Data(struct mstp_port_struct_t *mstp_port)
{
if (mstp_port->ReceiveError == true)
{
// wait for state machine to clear this
}
// wait for state machine to read from the DataRegister
else if (mstp_port->DataAvailable == false)
{
// check for data
if (mstp_port->ReceiveError == true) {
// wait for state machine to clear this
}
// wait for state machine to read from the DataRegister
else if (mstp_port->DataAvailable == false) {
// check for data
// if error,
// ReceiveError = TRUE;
// return;
// if error,
// ReceiveError = TRUE;
// return;
mstp_port->DataRegister = 0; // FIXME: Get this data from UART or buffer
mstp_port->DataRegister = 0; // FIXME: Get this data from UART or buffer
// if data is ready,
// DataAvailable = TRUE;
// return;
}
// if data is ready,
// DataAvailable = TRUE;
// return;
}
}
+116 -111
View File
@@ -37,174 +37,180 @@
#include "bip.h"
#if (defined(BACDL_ETHERNET) || defined(BACDL_BIP))
static int interface = SOCKET_ERROR; // SOCKET_ERROR means no open interface
static int interface = SOCKET_ERROR; // SOCKET_ERROR means no open interface
#endif
void bip_set_interface(char *ifname)
{
/*dummy function - to make the demos compile easier */
/*dummy function - to make the demos compile easier */
}
#if (defined(BACDL_ETHERNET) || defined(BACDL_BIP))
/*-----------------------------------*/
static void Error(const char * Msg)
static void Error(const char *Msg)
{
int Code = WSAGetLastError();
int Code = WSAGetLastError();
#ifdef HOST
printf("%s, error code: %i\n", Msg, Code);
printf("%s, error code: %i\n", Msg, Code);
#else
printf("%s, error code: %s\n", Msg, xn_geterror_string(Code));
printf("%s, error code: %s\n", Msg, xn_geterror_string(Code));
#endif
exit(1);
exit(1);
}
#ifndef HOST
/*-----------------------------------*/
void InterfaceCleanup(void)
{
if (interface != SOCKET_ERROR)
{
xn_interface_close(interface);
interface = SOCKET_ERROR;
if (interface != SOCKET_ERROR) {
xn_interface_close(interface);
interface = SOCKET_ERROR;
#if DEVICE_ID == PRISM_PCMCIA_DEVICE
RTPCShutDown();
RTPCShutDown();
#endif
}
}
}
#endif
static void NetInitialize(void)
// initialize the TCP/IP stack
{
int Result;
int Result;
#ifndef HOST
RTKernelInit(0); // get the kernel going
RTKernelInit(0); // get the kernel going
if (!RTKDebugVersion()) // switch of all diagnostics and error messages of RTIP-32
xn_callbacks()->cb_wr_screen_string_fnc = NULL;
if (!RTKDebugVersion()) // switch of all diagnostics and error messages of RTIP-32
xn_callbacks()->cb_wr_screen_string_fnc = NULL;
CLKSetTimerIntVal(10*1000); // 10 millisecond tick
RTKDelay(1);
RTCMOSSetSystemTime(); // get the right time-of-day
CLKSetTimerIntVal(10 * 1000); // 10 millisecond tick
RTKDelay(1);
RTCMOSSetSystemTime(); // get the right time-of-day
#ifdef RTUSB_VER
RTURegisterCallback(USBAX172); // ax172 and ax772 drivers
RTURegisterCallback(USBAX772);
RTURegisterCallback(USBKeyboard); // support USB keyboards
FindUSBControllers(); // install USB host controllers
Sleep(2000); // give the USB stack time to enumerate devices
RTURegisterCallback(USBAX172); // ax172 and ax772 drivers
RTURegisterCallback(USBAX772);
RTURegisterCallback(USBKeyboard); // support USB keyboards
FindUSBControllers(); // install USB host controllers
Sleep(2000); // give the USB stack time to enumerate devices
#endif
#ifdef DHCP
XN_REGISTER_DHCP_CLI() // and optionally the DHCP client
XN_REGISTER_DHCP_CLI() // and optionally the DHCP client
#endif
Result = xn_rtip_init(); // Initialize the RTIP stack
if (Result != 0)
Error("xn_rtip_init failed");
Result = xn_rtip_init(); // Initialize the RTIP stack
if (Result != 0)
Error("xn_rtip_init failed");
atexit(InterfaceCleanup); // make sure the driver is shut down properly
RTCallDebugger(RT_DBG_CALLRESET, (DWORD) exit, 0); // even if we get restarted by the debugger
atexit(InterfaceCleanup); // make sure the driver is shut down properly
RTCallDebugger(RT_DBG_CALLRESET, (DWORD)exit, 0); // even if we get restarted by the debugger
Result = BIND_DRIVER(MINOR_0); // tell RTIP what Ethernet driver we want (see netcfg.h)
if (Result != 0)
Error("driver initialization failed");
Result = BIND_DRIVER(MINOR_0); // tell RTIP what Ethernet driver we want (see netcfg.h)
if (Result != 0)
Error("driver initialization failed");
#if DEVICE_ID == PRISM_PCMCIA_DEVICE
// if this is a PCMCIA device, start the PCMCIA driver
if (RTPCInit(-1, 0, 2, NULL) == 0)
Error("No PCMCIA controller found");
// if this is a PCMCIA device, start the PCMCIA driver
if (RTPCInit(-1, 0, 2, NULL) == 0)
Error("No PCMCIA controller found");
#endif
// Open the interface
interface = xn_interface_open_config(DEVICE_ID, MINOR_0, ED_IO_ADD, ED_IRQ, ED_MEM_ADD);
if (interface == SOCKET_ERROR)
Error("xn_interface_open_config failed");
else
{
struct _iface_info ii;
// Open the interface
interface =
xn_interface_open_config(DEVICE_ID, MINOR_0, ED_IO_ADD, ED_IRQ,
ED_MEM_ADD);
if (interface == SOCKET_ERROR)
Error("xn_interface_open_config failed");
else {
struct _iface_info ii;
#ifdef BACDL_ETHERNET
BACNET_ADDRESS my_address;
unsigned i;
BACNET_ADDRESS my_address;
unsigned i;
#endif
xn_interface_info(interface, &ii);
printf("Interface opened, MAC address: %02x-%02x-%02x-%02x-%02x-%02x\n",
ii.my_ethernet_address[0], ii.my_ethernet_address[1], ii.my_ethernet_address[2],
ii.my_ethernet_address[3], ii.my_ethernet_address[4], ii.my_ethernet_address[5]);
xn_interface_info(interface, &ii);
printf
("Interface opened, MAC address: %02x-%02x-%02x-%02x-%02x-%02x\n",
ii.my_ethernet_address[0], ii.my_ethernet_address[1],
ii.my_ethernet_address[2], ii.my_ethernet_address[3],
ii.my_ethernet_address[4], ii.my_ethernet_address[5]);
#ifdef BACDL_ETHERNET
for (i = 0; i < 6; i++)
{
my_address.mac[i] = ii.my_ethernet_address[i];
}
ethernet_set_my_address(&my_address);
for (i = 0; i < 6; i++) {
my_address.mac[i] = ii.my_ethernet_address[i];
}
ethernet_set_my_address(&my_address);
#endif
}
}
#if DEVICE_ID == PRISM_PCMCIA_DEVICE || DEVICE_ID == PRISM_DEVICE
xn_wlan_setup(interface, // iface_no: value returned by xn_interface_open_config()
"network name", // SSID : network name set in the access point
"station name", // Name : name of this node
0, // Channel : 0 for access points, 1..14 for ad-hoc
0, // KeyIndex: 0 .. 3
"12345", // WEP Key : key to use (5 or 13 bytes)
0); // Flags : see manual and Wlanapi.h for details
Sleep(1000); // wireless devices need a little time before they can be used
#endif // WLAN device
xn_wlan_setup(interface, // iface_no: value returned by xn_interface_open_config()
"network name", // SSID : network name set in the access point
"station name", // Name : name of this node
0, // Channel : 0 for access points, 1..14 for ad-hoc
0, // KeyIndex: 0 .. 3
"12345", // WEP Key : key to use (5 or 13 bytes)
0); // Flags : see manual and Wlanapi.h for details
Sleep(1000); // wireless devices need a little time before they can be used
#endif // WLAN device
#if defined(AUTO_IP) // use xn_autoip() to get an IP address
Result = xn_autoip(interface, MinIP, MaxIP, NetMask, TargetIP);
if (Result == SOCKET_ERROR)
Error("xn_autoip failed");
else
{
printf("Auto-assigned IP address %i.%i.%i.%i\n", TargetIP[0], TargetIP[1], TargetIP[2], TargetIP[3]);
// define default gateway and DNS server
xn_rt_add(RT_DEFAULT, ip_ffaddr, DefaultGateway, 1, interface, RT_INF);
xn_set_server_list((DWORD*)DNSServer, 1);
}
#elif defined(DHCP) // use DHCP
{
DHCP_param param[] = {{SUBNET_MASK, 1}, {DNS_OP, 1}, {ROUTER_OPTION, 1}};
DHCP_session DS;
DHCP_conf DC;
#if defined(AUTO_IP) // use xn_autoip() to get an IP address
Result = xn_autoip(interface, MinIP, MaxIP, NetMask, TargetIP);
if (Result == SOCKET_ERROR)
Error("xn_autoip failed");
else {
printf("Auto-assigned IP address %i.%i.%i.%i\n", TargetIP[0],
TargetIP[1], TargetIP[2], TargetIP[3]);
// define default gateway and DNS server
xn_rt_add(RT_DEFAULT, ip_ffaddr, DefaultGateway, 1, interface,
RT_INF);
xn_set_server_list((DWORD *) DNSServer, 1);
}
#elif defined(DHCP) // use DHCP
{
DHCP_param param[] = { {SUBNET_MASK, 1}
, {DNS_OP, 1}
, {ROUTER_OPTION, 1}
};
DHCP_session DS;
DHCP_conf DC;
xn_init_dhcp_conf(&DC); // load default DHCP options
DC.plist = param; // add MASK, DNS, and gateway options
DC.plist_entries = sizeof(param) / sizeof(param[0]);
printf("Contacting DHCP server, please wait...\n");
Result = xn_dhcp(interface, &DS, &DC); // contact DHCP server
if (Result == SOCKET_ERROR)
Error("xn_dhcp failed");
memcpy(TargetIP, DS.client_ip, 4);
printf("My IP address is: %i.%i.%i.%i\n", TargetIP[0], TargetIP[1], TargetIP[2], TargetIP[3]);
}
xn_init_dhcp_conf(&DC); // load default DHCP options
DC.plist = param; // add MASK, DNS, and gateway options
DC.plist_entries = sizeof(param) / sizeof(param[0]);
printf("Contacting DHCP server, please wait...\n");
Result = xn_dhcp(interface, &DS, &DC); // contact DHCP server
if (Result == SOCKET_ERROR)
Error("xn_dhcp failed");
memcpy(TargetIP, DS.client_ip, 4);
printf("My IP address is: %i.%i.%i.%i\n", TargetIP[0], TargetIP[1],
TargetIP[2], TargetIP[3]);
}
#else
// Set the IP address and interface
printf("Using static IP address %i.%i.%i.%i\n", TargetIP[0], TargetIP[1], TargetIP[2], TargetIP[3]);
Result = xn_set_ip(interface, TargetIP, NetMask);
// define default gateway and DNS server
xn_rt_add(RT_DEFAULT, ip_ffaddr, DefaultGateway, 1, interface, RT_INF);
xn_set_server_list((DWORD*)DNSServer, 1);
// Set the IP address and interface
printf("Using static IP address %i.%i.%i.%i\n", TargetIP[0],
TargetIP[1], TargetIP[2], TargetIP[3]);
Result = xn_set_ip(interface, TargetIP, NetMask);
// define default gateway and DNS server
xn_rt_add(RT_DEFAULT, ip_ffaddr, DefaultGateway, 1, interface, RT_INF);
xn_set_server_list((DWORD *) DNSServer, 1);
#endif
#else // HOST defined, run on Windows
#else // HOST defined, run on Windows
WSADATA wd;
Result = WSAStartup(0x0101, &wd);
WSADATA wd;
Result = WSAStartup(0x0101, &wd);
#endif
if (Result != 0)
Error("TCP/IP stack initialization failed");
if (Result != 0)
Error("TCP/IP stack initialization failed");
}
#endif
bool bip_init(void)
{
int rv = 0; // return from socket lib calls
struct sockaddr_in sin = {-1};
int rv = 0; // return from socket lib calls
struct sockaddr_in sin = { -1 };
int value = 1;
int sock_fd = -1;
@@ -212,7 +218,7 @@ bool bip_init(void)
bip_set_address(TargetIP[0], TargetIP[1], TargetIP[2], TargetIP[3]);
// FIXME:
// FIXME:
#if 0
bip_set_address(NetMask[0], NetMask[1], NetMask[2], NetMask[3]);
extern unsigned long bip_get_addr(void);
@@ -237,14 +243,13 @@ bool bip_init(void)
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(bip_get_port());
memset(&(sin.sin_zero), '\0', 8);
rv = bind(sock_fd,
(const struct sockaddr*)&sin, sizeof(struct sockaddr));
if (rv < 0)
{
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;
return true;
}
+138 -166
View File
@@ -25,8 +25,8 @@
#include <stdint.h> // for standard integer types uint8_t etc.
#include <stdbool.h> // for the standard bool type.
#include <stdio.h> // for the standard bool type.
#include <stdlib.h> // for the standard bool type.
#include <stdio.h> // for the standard bool type.
#include <stdlib.h> // for the standard bool type.
#include <rttarget.h>
#include <rtk32.h>
#include <clock.h>
@@ -40,6 +40,7 @@ uint8_t Ethernet_Broadcast[MAX_MAC_LEN] =
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
// commonly used empty address for ethernet quick compare
uint8_t Ethernet_Empty_MAC[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 };
// my local device data - MAC address
uint8_t Ethernet_MAC_Address[MAX_MAC_LEN] = { 0, 0, 0, 0, 0, 0 };
@@ -49,45 +50,44 @@ static struct sockaddr Ethernet_Address = { 0 };
bool ethernet_valid(void)
{
return (Ethernet_Socket != -1);
return (Ethernet_Socket != -1);
}
void ethernet_cleanup(void)
{
if (ethernet_valid())
closesocket(Ethernet_Socket);
Ethernet_Socket = -1;
if (ethernet_valid())
closesocket(Ethernet_Socket);
Ethernet_Socket = -1;
return;
return;
}
bool ethernet_init(char *interface_name)
{
int value = 1;
(void)interface_name;
int value = 1;
(void) interface_name;
// setup the socket
Ethernet_Socket = socket(AF_INET, SOCK_RAW, 0);
//Ethernet_Socket = socket(AF_INET, SOCK_STREAM, 0);
if (Ethernet_Socket < 0)
fprintf(stderr,"ethernet: failed to bind to socket!\r\n");
fprintf(stderr, "ethernet: failed to bind to socket!\r\n");
Ethernet_Address.sa_family = AF_INET;
memset(Ethernet_Address.sa_data,0,sizeof(Ethernet_Address.sa_data));
if (bind(Ethernet_Socket,
&Ethernet_Address, sizeof(Ethernet_Address)) == SOCKET_ERROR)
fprintf(stderr,"ethernet: failed to bind to socket!\r\n");
memset(Ethernet_Address.sa_data, 0, sizeof(Ethernet_Address.sa_data));
if (bind(Ethernet_Socket,
&Ethernet_Address, sizeof(Ethernet_Address)) == SOCKET_ERROR)
fprintf(stderr, "ethernet: failed to bind to socket!\r\n");
//setsockopt(Ethernet_Socket,SOL_SOCKET,SO_802_2,(char *)&value,sizeof(value));
return ethernet_valid();
return ethernet_valid();
}
/* function to send a packet out the 802.2 socket */
/* returns bytes sent on success, negative number 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 };
@@ -95,100 +95,86 @@ int ethernet_send(
int i = 0;
// don't waste time if the socket is not valid
if (Ethernet_Socket < 0)
{
if (Ethernet_Socket < 0) {
fprintf(stderr, "ethernet: 802.2 socket is invalid!\n");
return -1;
}
/* load destination ethernet MAC address */
if (dest->mac_len == 6)
{
for (i = 0; i < 6; i++)
{
mtu[mtu_len] = dest->mac[i];
mtu_len++;
}
}
else
{
if (dest->mac_len == 6) {
for (i = 0; i < 6; i++) {
mtu[mtu_len] = dest->mac[i];
mtu_len++;
}
} else {
fprintf(stderr, "ethernet: invalid destination MAC address!\n");
return -2;
}
/* load source ethernet MAC address */
if (src->mac_len == 6)
{
for (i = 0; i < 6; i++)
{
mtu[mtu_len] = src->mac[i];
mtu_len++;
}
}
else
{
if (src->mac_len == 6) {
for (i = 0; i < 6; i++) {
mtu[mtu_len] = src->mac[i];
mtu_len++;
}
} else {
fprintf(stderr, "ethernet: invalid source MAC address!\n");
return -3;
}
if ((14 + 3 + pdu_len) > MAX_MPDU)
{
if ((14 + 3 + pdu_len) > MAX_MPDU) {
fprintf(stderr, "ethernet: PDU is too big to send!\n");
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;
/* Send the packet */
bytes =
send(Ethernet_Socket, (const char *)&mtu, mtu_len, 0);
bytes = send(Ethernet_Socket, (const char *) &mtu, mtu_len, 0);
/* did it get sent? */
if (bytes < 0)
fprintf(stderr,"ethernet: Error sending packet: %s\n",
strerror(errno));
fprintf(stderr, "ethernet: Error sending packet: %s\n",
strerror(errno));
return bytes;
}
/* function to send a packet out the 802.2 socket */
/* returns bytes sent on success, negative number 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
BACNET_ADDRESS src = {0}; // source address
for (i = 0; i < 6; i++)
{
src.mac[i] = Ethernet_MAC_Address[i];
src.mac_len++;
}
/* 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
pdu_len); // number of bytes of data
int i = 0; // counter
BACNET_ADDRESS src = { 0 }; // source address
for (i = 0; i < 6; i++) {
src.mac[i] = Ethernet_MAC_Address[i];
src.mac_len++;
}
/* 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
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
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
{
int received_bytes;
uint8_t buf[MAX_MPDU] = {0}; // data
uint16_t pdu_len = 0; // return value
uint8_t buf[MAX_MPDU] = { 0 }; // data
uint16_t pdu_len = 0; // return value
fd_set read_fds;
int max;
struct timeval select_timeout;
@@ -200,14 +186,11 @@ uint16_t ethernet_receive(
/* 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)
{
if (timeout >= 1000) {
select_timeout.tv_sec = timeout / 1000;
select_timeout.tv_usec =
1000 * (timeout - select_timeout.tv_sec * 1000);
}
else
{
select_timeout.tv_usec =
1000 * (timeout - select_timeout.tv_sec * 1000);
} else {
select_timeout.tv_sec = 0;
select_timeout.tv_usec = 1000 * timeout;
}
@@ -216,7 +199,8 @@ uint16_t ethernet_receive(
max = Ethernet_Socket;
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0)
received_bytes = recv(Ethernet_Socket, (char *)&buf[0], MAX_MPDU, 0);
received_bytes =
recv(Ethernet_Socket, (char *) &buf[0], MAX_MPDU, 0);
else
return 0;
@@ -226,14 +210,15 @@ uint16_t ethernet_receive(
// using O_NONBLOCK and no data
// was immediately available for reading.
if (errno != EAGAIN)
fprintf(stderr,"ethernet: Read error in receiving packet: %s\n",
fprintf(stderr,
"ethernet: Read error in receiving packet: %s\n",
strerror(errno));
return 0;
}
if (received_bytes == 0)
return 0;
return 0;
/* the signature of an 802.2 BACnet packet */
if ((buf[14] != 0x82) && (buf[15] != 0x82)) {
//fprintf(stderr,"ethernet: Non-BACnet packet\n");
@@ -245,108 +230,95 @@ uint16_t ethernet_receive(
// check destination address for when
// the Ethernet card is in promiscious mode
if ((memcmp(&buf[0], Ethernet_MAC_Address,6) != 0)
&& (memcmp(&buf[0], Ethernet_Broadcast, 6) != 0))
{
if ((memcmp(&buf[0], Ethernet_MAC_Address, 6) != 0)
&& (memcmp(&buf[0], Ethernet_Broadcast, 6) != 0)) {
//fprintf(stderr, "ethernet: This packet isn't for us\n");
return 0;
}
(void)decode_unsigned16(&buf[12],&pdu_len);
(void) decode_unsigned16(&buf[12], &pdu_len);
pdu_len -= 3 /* DSAP, SSAP, LLC Control */ ;
// copy the buffer into the PDU
if (pdu_len < max_pdu)
memmove(&pdu[0],&buf[17],pdu_len);
memmove(&pdu[0], &buf[17], pdu_len);
// ignore packets that are too large
// client should check my max apdu first
else
pdu_len = 0;
pdu_len = 0;
return pdu_len;
}
void ethernet_get_my_address(BACNET_ADDRESS *my_address)
void ethernet_get_my_address(BACNET_ADDRESS * my_address)
{
int i = 0;
my_address->mac_len = 0;
for (i = 0; i < 6; i++)
{
my_address->mac[i] = Ethernet_MAC_Address[i];
my_address->mac_len++;
}
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;
}
int i = 0;
return;
my_address->mac_len = 0;
for (i = 0; i < 6; i++) {
my_address->mac[i] = Ethernet_MAC_Address[i];
my_address->mac_len++;
}
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;
}
return;
}
void ethernet_set_my_address(BACNET_ADDRESS *my_address)
void ethernet_set_my_address(BACNET_ADDRESS * my_address)
{
int i = 0;
for (i = 0; i < 6; i++)
{
Ethernet_MAC_Address[i] = my_address->mac[i];
}
int i = 0;
return;
for (i = 0; i < 6; i++) {
Ethernet_MAC_Address[i] = my_address->mac[i];
}
return;
}
void ethernet_get_broadcast_address(
BACNET_ADDRESS *dest) // destination address
void ethernet_get_broadcast_address(BACNET_ADDRESS * dest) // destination address
{
int i = 0; // counter
if (dest)
{
for (i = 0; i < 6; i++)
{
dest->mac[i] = Ethernet_Broadcast[i];
}
dest->mac_len = 6;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; // denotes broadcast address
for (i = 0; i < MAX_MAC_LEN; i++)
{
dest->adr[i] = 0;
}
}
int i = 0; // counter
return;
if (dest) {
for (i = 0; i < 6; i++) {
dest->mac[i] = Ethernet_Broadcast[i];
}
dest->mac_len = 6;
dest->net = BACNET_BROADCAST_NETWORK;
dest->len = 0; // denotes broadcast address
for (i = 0; i < MAX_MAC_LEN; i++) {
dest->adr[i] = 0;
}
}
return;
}
void ethernet_debug_address(
const char *info,
BACNET_ADDRESS *dest)
void ethernet_debug_address(const char *info, BACNET_ADDRESS * dest)
{
int i = 0; // counter
int i = 0; // counter
if (info)
fprintf(stderr,"%s",info);
if (dest)
{
fprintf(stderr,"Address:\n");
fprintf(stderr," MAC Length=%d\n",dest->mac_len);
fprintf(stderr," MAC Address=");
for (i = 0; i < MAX_MAC_LEN; i++)
{
fprintf(stderr,"%02X ",(unsigned)dest->mac[i]);
if (info)
fprintf(stderr, "%s", info);
if (dest) {
fprintf(stderr, "Address:\n");
fprintf(stderr, " MAC Length=%d\n", dest->mac_len);
fprintf(stderr, " MAC Address=");
for (i = 0; i < MAX_MAC_LEN; i++) {
fprintf(stderr, "%02X ", (unsigned) dest->mac[i]);
}
fprintf(stderr, "\n");
fprintf(stderr, " Net=%hu\n", dest->net);
fprintf(stderr, " Len=%d\n", dest->len);
fprintf(stderr, " Adr=");
for (i = 0; i < MAX_MAC_LEN; i++) {
fprintf(stderr, "%02X ", (unsigned) dest->adr[i]);
}
fprintf(stderr, "\n");
}
fprintf(stderr,"\n");
fprintf(stderr," Net=%hu\n",dest->net);
fprintf(stderr," Len=%d\n",dest->len);
fprintf(stderr," Adr=");
for (i = 0; i < MAX_MAC_LEN; i++)
{
fprintf(stderr,"%02X ",(unsigned)dest->adr[i]);
}
fprintf(stderr,"\n");
}
return;
return;
}
+45 -49
View File
@@ -30,34 +30,33 @@
extern void RTEmuInit(void);
#ifdef _MSC_VER
#define VOIDEXPORT _declspec(dllexport) void __cdecl
#define VOIDEXPORT _declspec(dllexport) void __cdecl
#else
#define VOIDEXPORT void __export __cdecl
#define VOIDEXPORT void __export __cdecl
#endif
/* DISK SYSTEM */
#ifdef DOC // include DiskOnChip driver
#include <rtfiles.h>
#define RTF_MAX_FILES 16 // support for more open files (default is 8)
#define RTF_BUFFERS_IN_BSS // we do not need file I/O before the run-time
#include <rtfdata.c> // system is initialized
#ifdef DOC // include DiskOnChip driver
#include <rtfiles.h>
#define RTF_MAX_FILES 16 // support for more open files (default is 8)
#define RTF_BUFFERS_IN_BSS // we do not need file I/O before the run-time
#include <rtfdata.c> // system is initialized
//#define READ_HEAD_BUFFER_SIZE 2048+4
//static BYTE ReadAheadBuffer[READ_HEAD_BUFFER_SIZE];
static RTFDrvFLPYData FLPYDriveAData = {0};
static RTFDrvDOCData DOCDriveData = {0};
static RTFDrvIDEData IDEDriveData = {0};
static RTFDrvFLPYData FLPYDriveAData = { 0 };
static RTFDrvDOCData DOCDriveData = { 0 };
static RTFDrvIDEData IDEDriveData = { 0 };
RTFDevice RTFDeviceList[] =
{
RTFDevice RTFDeviceList[] = {
/* type,number,flags,driver,driverdata */
{ RTF_DEVICE_FLOPPY, 0, 0, &RTFDrvFloppy, &FLPYDriveAData},
{ RTF_DEVICE_FDISK , 0, 0, &RTFDrvDOC, &DOCDriveData},
{ RTF_DEVICE_FDISK , 0, 0, &RTFDrvIDE, &IDEDriveData},
{ 0 , 0, 0, NULL, NULL}
};
{RTF_DEVICE_FLOPPY, 0, 0, &RTFDrvFloppy, &FLPYDriveAData},
{RTF_DEVICE_FDISK, 0, 0, &RTFDrvDOC, &DOCDriveData},
{RTF_DEVICE_FDISK, 0, 0, &RTFDrvIDE, &IDEDriveData},
{0, 0, 0, NULL, NULL}
};
#endif
/* END OF DISK SYSTEM */
@@ -67,14 +66,14 @@ extern void RTEmuInit(void);
#define MAXOBJECTS 1024
#define MAXTYPES 32
RTW32Handle RTHandleTable[MAXHANDLES] = {{0}};
int RTHandleCount = MAXHANDLES;
RTW32Handle RTHandleTable[MAXHANDLES] = { {0} };
int RTHandleCount = MAXHANDLES;
RTW32Object RTObjectTable[MAXOBJECTS] = {{0}};
int RTObjectCount = MAXOBJECTS;
RTW32Object RTObjectTable[MAXOBJECTS] = { {0} };
int RTObjectCount = MAXOBJECTS;
RTW32Types RTTypeTable[MAXTYPES] = {{0}};
int RTTypeCount = MAXTYPES;
RTW32Types RTTypeTable[MAXTYPES] = { {0} };
int RTTypeCount = MAXTYPES;
#if 0
/* We can embed some files in the RTB file, like a binary
@@ -85,44 +84,41 @@ int RTTypeCount = MAXTYPES;
that here, as well as the LPT, console, and FAT.
From RTFiles-32 manual, ch. 7, "Using RTFiles-32 with
RTTarget-32" */
RTFileSystem Console =
{ RT_FS_CONSOLE, 0, 0, &RTConsoleFileSystem };
RTFileSystem Console = { RT_FS_CONSOLE, 0, 0, &RTConsoleFileSystem };
RTFileSystem LPTFiles =
{ RT_FS_LPT_DEVICE, 0, 0, &RTLPTFileSystem };
RTFileSystem LPTFiles = { RT_FS_LPT_DEVICE, 0, 0, &RTLPTFileSystem };
/* logical drive Z: can be used to access the RAM drive */
RTFileSystem RAMFiles =
{ RT_FS_FILE,1 << ('Z'-'A'), 0, &RTRAMFileSystem };
{ RT_FS_FILE, 1 << ('Z' - 'A'), 0, &RTRAMFileSystem };
/* logical drive A: through D: are reserved for FAT */
RTFileSystem FATFiles =
{ RT_FS_FILE | RT_FS_IS_DEFAULT, 0x0F, 0x03, &RTFilesFileSystem };
{ RT_FS_FILE | RT_FS_IS_DEFAULT, 0x0F, 0x03, &RTFilesFileSystem };
RTFileSystem *RTFileSystemList[] =
{
&Console,
&LPTFiles,
&RAMFiles,
&FATFiles,
NULL,
RTFileSystem *RTFileSystemList[] = {
&Console,
&LPTFiles,
&RAMFiles,
&FATFiles,
NULL,
};
#endif
/*-----------------------------------*/
VOIDEXPORT Init(void)
{
(void)RTSetFlags(RT_MM_VIRTUAL, 1); // this is the better method
(void)RTCMOSExtendHeap(); // get as much memory as we can
RTCMOSSetSystemTime(); // get the right date and time
RTEmuInit(); // set up floating point emulation
// pizza - RTHaltCPL3 appears to cause problems with file handling
//RTIdleHandler = (void RTTAPI *)RTHaltCPL3; // low power when idle
// not needed with pre-emptive
//RTKTimeSlice(2); // allow same priority task switch
RTKConfig.Flags |= RF_PREEMPTIVE; // preemptive multitasking
RTKConfig.Flags |= RF_WIN32MUTEX_MUTEX; // Win32 mutexes are RTK32 mutexes
RTKConfig.Flags |= RF_FPCONTEXT; // saves floating point context for tasks
RTKConfig.HookedIRQs |= 1 << 1; // hook the keyboard IRQ
RTKConfig.DefaultTaskStackSize = 1024*8; // for Win32 task stacks req = 0
(void) RTSetFlags(RT_MM_VIRTUAL, 1); // this is the better method
(void) RTCMOSExtendHeap(); // get as much memory as we can
RTCMOSSetSystemTime(); // get the right date and time
RTEmuInit(); // set up floating point emulation
// pizza - RTHaltCPL3 appears to cause problems with file handling
//RTIdleHandler = (void RTTAPI *)RTHaltCPL3; // low power when idle
// not needed with pre-emptive
//RTKTimeSlice(2); // allow same priority task switch
RTKConfig.Flags |= RF_PREEMPTIVE; // preemptive multitasking
RTKConfig.Flags |= RF_WIN32MUTEX_MUTEX; // Win32 mutexes are RTK32 mutexes
RTKConfig.Flags |= RF_FPCONTEXT; // saves floating point context for tasks
RTKConfig.HookedIRQs |= 1 << 1; // hook the keyboard IRQ
RTKConfig.DefaultTaskStackSize = 1024 * 8; // for Win32 task stacks req = 0
}
+62 -75
View File
@@ -37,95 +37,82 @@
#include "net.h"
// buffers used for transmit and receive
static uint8_t Rx_Buf[MAX_MPDU] = {0};
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
#ifdef BACDL_MSTP
volatile struct mstp_port_struct_t MSTP_Port; // port data
volatile struct mstp_port_struct_t MSTP_Port; // port data
static uint8_t MSTP_MAC_Address = 0x05; // local MAC address
#endif
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);
// 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(
UnrecognizedServiceHandler);
// we must implement read property - it's required!
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_READ_PROPERTY,
ReadPropertyHandler);
apdu_set_confirmed_handler(
SERVICE_CONFIRMED_WRITE_PROPERTY,
WritePropertyHandler);
// we need to handle who-is to support dynamic device binding
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, WhoIsHandler);
// 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
(UnrecognizedServiceHandler);
// we must implement read property - it's required!
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
ReadPropertyHandler);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
WritePropertyHandler);
}
int main(int argc, char *argv[])
{
BACNET_ADDRESS src = {0}; // address where message came from
uint16_t pdu_len = 0;
unsigned timeout = 100; // milliseconds
BACNET_ADDRESS src = { 0 }; // address where message came from
uint16_t pdu_len = 0;
unsigned timeout = 100; // milliseconds
(void)argc;
(void)argv;
Device_Set_Object_Instance_Number(126);
Init_Service_Handlers();
// init the physical layer
#ifdef BACDL_BIP
if (!bip_init())
return 1;
#endif
#ifdef BACDL_ETHERNET
if (!ethernet_init(NULL))
return 1;
#endif
#ifdef BACDL_MSTP
RS485_Initialize();
MSTP_Init(&MSTP_Port,MSTP_MAC_Address);
#endif
(void) argc;
(void) argv;
Device_Set_Object_Instance_Number(126);
Init_Service_Handlers();
// init the physical layer
#ifdef BACDL_BIP
if (!bip_init())
return 1;
#endif
#ifdef BACDL_ETHERNET
if (!ethernet_init(NULL))
return 1;
#endif
#ifdef BACDL_MSTP
RS485_Initialize();
MSTP_Init(&MSTP_Port, MSTP_MAC_Address);
#endif
// loop forever
for (;;)
{
// input
#ifdef BACDL_MSTP
MSTP_Millisecond_Timer(&MSTP_Port);
// note: also called by RS-485 Receive ISR
RS485_Check_UART_Data(&MSTP_Port);
MSTP_Receive_Frame_FSM(&MSTP_Port);
#endif
#if (defined(BACDL_ETHERNET) || defined(BACDL_BIP))
// returns 0 bytes on timeout
pdu_len = bacdl_receive(
&src,
&Rx_Buf[0],
MAX_MPDU,
timeout);
#endif
// loop forever
for (;;) {
// input
#ifdef BACDL_MSTP
MSTP_Millisecond_Timer(&MSTP_Port);
// note: also called by RS-485 Receive ISR
RS485_Check_UART_Data(&MSTP_Port);
MSTP_Receive_Frame_FSM(&MSTP_Port);
#endif
// process
#if (defined(BACDL_ETHERNET) || defined(BACDL_BIP))
// returns 0 bytes on timeout
pdu_len = bacdl_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
#endif
if (pdu_len)
{
npdu_handler(
&src,
&Rx_Buf[0],
pdu_len);
// process
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (I_Am_Request) {
I_Am_Request = false;
Send_IAm();
}
// output
#ifdef BACDL_MSTP
MSTP_Master_Node_FSM(&MSTP_Port);
#endif
// blink LEDs, Turn on or off outputs, etc
}
if (I_Am_Request)
{
I_Am_Request = false;
Send_IAm();
}
// output
#ifdef BACDL_MSTP
MSTP_Master_Node_FSM(&MSTP_Port);
#endif
// blink LEDs, Turn on or off outputs, etc
}
}
+11 -11
View File
@@ -35,17 +35,17 @@
#include <process.h>
#ifdef BACDL_BIP
#include "bip.h"
#ifndef HOST
#include "netcfg.h"
#include <rttarget.h>
#include <rtk32.h>
#include <clock.h>
#include <socket.h>
#else
#include <winsock.h>
#endif
#define close closesocket
#include "bip.h"
#ifndef HOST
#include "netcfg.h"
#include <rttarget.h>
#include <rtk32.h>
#include <clock.h>
#include <socket.h>
#else
#include <winsock.h>
#endif
#define close closesocket
#endif
#endif
+41 -41
View File
@@ -31,74 +31,74 @@
// #define AUTO_IP // use xn_autoip() to get an IP address
// #define DHCP // if you enable this, you must also link library dhcpc.lib
#if defined(AUTO_IP) // use xn_autoip() to get an IP address
static BYTE TargetIP[] = { 0, 0, 0, 0}; // will be filled at run-time
static BYTE NetMask[] = {255, 255, 255, 0};
static BYTE MinIP[] = {192, 168, 1, 128};
static BYTE MaxIP[] = {192, 168, 1, 255};
static BYTE DefaultGateway[] = {192, 168, 1, 1}; // set to zero if not available or required
static BYTE DNSServer[] = {192, 168, 1, 1}; // ditto
#elif defined(DHCP) // use DHCP
#include <dhcpcapi.h>
static BYTE TargetIP[] = { 0, 0, 0, 0}; // will be filled at run-time
#else // static IP address assignment (default)
static BYTE TargetIP[] = {192, 168, 0, 50};
static BYTE NetMask[] = {255, 255, 255, 0};
static BYTE DefaultGateway[] = {192, 168, 0, 1}; // set to zero if not available or required
static BYTE DNSServer[] = {192, 168, 0, 1}; // ditto
#if defined(AUTO_IP) // use xn_autoip() to get an IP address
static BYTE TargetIP[] = { 0, 0, 0, 0 }; // will be filled at run-time
static BYTE NetMask[] = { 255, 255, 255, 0 };
static BYTE MinIP[] = { 192, 168, 1, 128 };
static BYTE MaxIP[] = { 192, 168, 1, 255 };
static BYTE DefaultGateway[] = { 192, 168, 1, 1 }; // set to zero if not available or required
static BYTE DNSServer[] = { 192, 168, 1, 1 }; // ditto
#elif defined(DHCP) // use DHCP
#include <dhcpcapi.h>
static BYTE TargetIP[] = { 0, 0, 0, 0 }; // will be filled at run-time
#else // static IP address assignment (default)
static BYTE TargetIP[] = { 192, 168, 0, 50 };
static BYTE NetMask[] = { 255, 255, 255, 0 };
static BYTE DefaultGateway[] = { 192, 168, 0, 1 }; // set to zero if not available or required
static BYTE DNSServer[] = { 192, 168, 0, 1 }; // ditto
#endif
#define DEVICE_ID DAVICOM_DEVICE // define your device type here
#define DEVICE_ID DAVICOM_DEVICE // define your device type here
#ifndef DEVICE_ID
#error You must define Ethernet driver/resources and IP address/net mask here
#error You must define Ethernet driver/resources and IP address/net mask here
#endif
// The following values are ignored for PCI devices (the BIOS supplies
// them), but they must be set correctly for ISA/PCMCIA systems and for
// PCI devices if you do not have a BIOS
#define ED_IO_ADD 0x300 // I/O address of the device
#define ED_IRQ 5 // IRQ of the device
#define ED_MEM_ADD 0 // Memory Window (only some devices)
#define ED_IO_ADD 0x300 // I/O address of the device
#define ED_IRQ 5 // IRQ of the device
#define ED_MEM_ADD 0 // Memory Window (only some devices)
// Define function to pull in the required driver
#if DEVICE_ID == NE2000_DEVICE
#define BIND_DRIVER xn_bind_ne2000
#define BIND_DRIVER xn_bind_ne2000
#elif DEVICE_ID == N83815_DEVICE
#define BIND_DRIVER xn_bind_n83815
#define BIND_DRIVER xn_bind_n83815
#elif DEVICE_ID == TC90X_DEVICE
#define BIND_DRIVER xn_bind_tc90x
#define BIND_DRIVER xn_bind_tc90x
#elif DEVICE_ID == SMC91C9X_DEVICE
#define BIND_DRIVER xn_bind_smc91c9x
#define BIND_DRIVER xn_bind_smc91c9x
#elif DEVICE_ID == LANCE_DEVICE
#define BIND_DRIVER xn_bind_rtlance
#define BIND_DRIVER xn_bind_rtlance
#elif DEVICE_ID == LANCE_ISA_DEVICE
#define BIND_DRIVER xn_bind_lance_isa
#define BIND_DRIVER xn_bind_lance_isa
#elif DEVICE_ID == LAN_CS89X0_DEVICE
#define BIND_DRIVER xn_bind_cs
#define BIND_DRIVER xn_bind_cs
#elif DEVICE_ID == I82559_DEVICE
#define BIND_DRIVER xn_bind_i82559
#define BIND_DRIVER xn_bind_i82559
#elif DEVICE_ID == R8139_DEVICE
#define BIND_DRIVER xn_bind_r8139
#define BIND_DRIVER xn_bind_r8139
#elif DEVICE_ID == DAVICOM_DEVICE
#define BIND_DRIVER xn_bind_davicom
#define BIND_DRIVER xn_bind_davicom
#elif DEVICE_ID == RHINE_DEVICE
#define BIND_DRIVER xn_bind_rhine
#define BIND_DRIVER xn_bind_rhine
#elif DEVICE_ID == AX172_DEVICE
#include <rtusb.h> // must also link Rtusb.lib and UsbInit.cpp
#define BIND_DRIVER xn_bind_ax172
#include <rtusb.h> // must also link Rtusb.lib and UsbInit.cpp
#define BIND_DRIVER xn_bind_ax172
#elif DEVICE_ID == AX772_DEVICE
#include <rtusb.h> // must also link Rtusb.lib and UsbInit.cpp
#define BIND_DRIVER xn_bind_ax772
#include <rtusb.h> // must also link Rtusb.lib and UsbInit.cpp
#define BIND_DRIVER xn_bind_ax772
#elif DEVICE_ID == PRISM_DEVICE
#include <wlanapi.h> // must also link Wlan.lib
#define BIND_DRIVER xn_bind_prism
#include <wlanapi.h> // must also link Wlan.lib
#define BIND_DRIVER xn_bind_prism
#elif DEVICE_ID == PRISM_PCMCIA_DEVICE
#include <rtpcmcia.h>
#include <wlanapi.h> // must also link Wlan.lib
#define BIND_DRIVER xn_bind_prism_pcmcia
#include <rtpcmcia.h>
#include <wlanapi.h> // must also link Wlan.lib
#define BIND_DRIVER xn_bind_prism_pcmcia
#else
#error Invalid DEVICE_ID value
#error Invalid DEVICE_ID value
#endif
+77 -84
View File
@@ -40,122 +40,115 @@ static int RS485_Port = COM2;
/* baud rate */
static long RS485_Baud = 38400;
/* io base address */
static long RS485_Base = 0;
static long RS485_Base = 0;
/* hardware IRQ number */
static long RS485_IRQ_Number = 0;
static long RS485_IRQ_Number = 0;
static void RS485_Standard_Port_Settings(long port, long *pIRQ, long *pBase)
static void RS485_Standard_Port_Settings(long port, long *pIRQ,
long *pBase)
{
switch (port)
{
switch (port) {
case COM1:
*pBase = (long)0x3F8;
*pIRQ = 4L;
break;
*pBase = (long) 0x3F8;
*pIRQ = 4L;
break;
case COM2:
*pBase = (long)0x2F8;
*pIRQ = 3L;
break;
*pBase = (long) 0x2F8;
*pIRQ = 3L;
break;
case COM3:
*pBase = (long)0x3E8;
*pIRQ = 4L;
break;
*pBase = (long) 0x3E8;
*pIRQ = 4L;
break;
case COM4:
*pBase = (long)0x2E8;
*pIRQ = 3L;
break;
*pBase = (long) 0x2E8;
*pIRQ = 3L;
break;
default:
break;
}
break;
}
}
static RS485_Open_Port(
int port, /* COM port number - COM1 = 0 */
long baud, /* baud rate */
unsigned base, /* io base address */
int irq) /* hardware IRQ number */
{
/* setup the COM IO */
SetIOBase(port, base);
SetIRQ(port, irq);
static RS485_Open_Port(int port, /* COM port number - COM1 = 0 */
long baud, /* baud rate */
unsigned base, /* io base address */
int irq)
{ /* hardware IRQ number */
/* setup the COM IO */
SetIOBase(port, base);
SetIRQ(port, irq);
if (irq < 8)
RTKIRQTopPriority(irq,9);
if (irq < 8)
RTKIRQTopPriority(irq, 9);
InitPort(port, baud, PARITY_NONE, 1, 8);
InitPort(port, baud, PARITY_NONE, 1, 8);
if (HasFIFO(port))
EnableFIFO(port,8);
EnableCOMInterrupt(port, 1024*4);
if (HasFIFO(port))
EnableFIFO(port, 8);
EnableCOMInterrupt(port, 1024 * 4);
/* enable the 485 via the DTR pin */
RS485_IO_ENABLE(port);
RS485_RECEIVE_ENABLE(port);
/* enable the 485 via the DTR pin */
RS485_IO_ENABLE(port);
RS485_RECEIVE_ENABLE(port);
return;
return;
}
void RS485_Initialize(void)
{
RS485_Standard_Port_Settings(RS485_Port, &RS485_IRQ_Number, &RS485_Base);
RS485_Open_Port(RS485_Port, RS485_Baud, RS485_Base, RS485_IRQ_Number);
RS485_Standard_Port_Settings(RS485_Port, &RS485_IRQ_Number,
&RS485_Base);
RS485_Open_Port(RS485_Port, RS485_Baud, RS485_Base, RS485_IRQ_Number);
}
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)
uint16_t nbytes) // number of bytes of data (up to 501)
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)
uint16_t nbytes) // number of bytes of data (up to 501)
{
bool status = true; // return value
bool status = true; // return value
(void)mstp_port;
RS485_TRANSMIT_ENABLE(RS485_Port);
SendBlock(RS485_Port, (char *)buffer, nbytes);
/* need to wait at least 9600 baud * 512 bytes = 54mS */
(void)WaitSendBufferEmpty(RS485_Port,MilliSecsToTicks(200));
while (!(LineStatus(RS485_Port) & TX_SHIFT_EMPTY))
RTKScheduler();
RS485_RECEIVE_ENABLE(RS485_Port);
(void) mstp_port;
RS485_TRANSMIT_ENABLE(RS485_Port);
SendBlock(RS485_Port, (char *) buffer, nbytes);
/* need to wait at least 9600 baud * 512 bytes = 54mS */
(void) WaitSendBufferEmpty(RS485_Port, MilliSecsToTicks(200));
while (!(LineStatus(RS485_Port) & TX_SHIFT_EMPTY))
RTKScheduler();
RS485_RECEIVE_ENABLE(RS485_Port);
return;
return;
}
void RS485_Check_UART_Data(
volatile struct mstp_port_struct_t *mstp_port) // port specific data
void RS485_Check_UART_Data(volatile struct mstp_port_struct_t *mstp_port) // port specific data
{
COMData com_data = 0; /* byte from COM driver */
unsigned timeout = 10; // milliseconds to wait for a character
Duration ticks; /* duration to wait for data */
COMData com_data = 0; /* byte from COM driver */
unsigned timeout = 10; // milliseconds to wait for a character
Duration ticks; /* duration to wait for data */
if (mstp_port->ReceiveError)
{
// wait for state machine to clear this
}
// wait for state machine to read from the DataRegister
else if (!mstp_port->DataAvailable)
{
// check for data
ticks = MilliSecsToTicks(timeout);
if (!ticks)
ticks = 1;
if (RTKGetTimed(ReceiveBuffer[RS485_Port],&com_data,ticks))
{
// if error,
if (com_data & (COM_OVERRUN << 8))
mstp_port->ReceiveError = true;
else if (com_data & (COM_FRAME << 8))
mstp_port->ReceiveError = true;
else
{
mstp_port->DataRegister = com_data & 0x00FF;
mstp_port->DataAvailable = true;
}
if (mstp_port->ReceiveError) {
// wait for state machine to clear this
}
// wait for state machine to read from the DataRegister
else if (!mstp_port->DataAvailable) {
// check for data
ticks = MilliSecsToTicks(timeout);
if (!ticks)
ticks = 1;
if (RTKGetTimed(ReceiveBuffer[RS485_Port], &com_data, ticks)) {
// if error,
if (com_data & (COM_OVERRUN << 8))
mstp_port->ReceiveError = true;
else if (com_data & (COM_FRAME << 8))
mstp_port->ReceiveError = true;
else {
mstp_port->DataRegister = com_data & 0x00FF;
mstp_port->DataAvailable = true;
}
}
}
}
}
void RS485_Process_Tx_Message(void)
{
// nothing to do
}
+13 -13
View File
@@ -4,25 +4,25 @@
// C99 Boolean types for compilers without C99 support
#ifndef __cplusplus
typedef int _Bool;
#ifndef bool
#define bool _Bool
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#define __bool_true_false_are_defined 1
typedef int _Bool;
#ifndef bool
#define bool _Bool
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#define __bool_true_false_are_defined 1
#endif
#ifndef FALSE
#define FALSE 0
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#define TRUE 1
#endif
#endif
+7 -7
View File
@@ -6,14 +6,14 @@
#include <stddef.h>
typedef unsigned char uint8_t; // 1 byte 0 to 255
typedef signed char int8_t; // 1 byte -127 to 127
typedef unsigned short uint16_t; // 2 bytes 0 to 65535
typedef signed short int16_t; // 2 bytes -32767 to 32767
typedef unsigned char uint8_t; // 1 byte 0 to 255
typedef signed char int8_t; // 1 byte -127 to 127
typedef unsigned short uint16_t; // 2 bytes 0 to 65535
typedef signed short int16_t; // 2 bytes -32767 to 32767
//typedef unsigned short long uint24_t; // 3 bytes 0 to 16777215
typedef unsigned long uint32_t; // 4 bytes 0 to 4294967295
typedef signed long int32_t; // 4 bytes -2147483647 to 2147483647
typedef unsigned long uint32_t; // 4 bytes 0 to 4294967295
typedef signed long int32_t; // 4 bytes -2147483647 to 2147483647
// typedef signed long long int64_t;
// typedef unsigned long long uint64_t;
#endif // STDINT_H
#endif // STDINT_H
+74 -81
View File
@@ -37,8 +37,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 "bacdcode.h"
#include "bip.h"
#include "net.h"
@@ -46,60 +46,64 @@
/* To fill a need, we invent the gethostaddr() function. */
static long gethostaddr(void)
{
struct hostent *host_ent;
char host_name[255];
struct hostent *host_ent;
char host_name[255];
if (gethostname(host_name, sizeof(host_name)) != 0)
return -1;
#ifdef BIP_DEBUG
printf("host name: %s\n",host_name);
#endif
if ((host_ent = gethostbyname(host_name)) == NULL)
return -1;
if (gethostname(host_name, sizeof(host_name)) != 0)
return -1;
#ifdef BIP_DEBUG
printf("host name: %s\n", host_name);
#endif
if ((host_ent = gethostbyname(host_name)) == NULL)
return -1;
return *(long *)host_ent->h_addr;
return *(long *) host_ent->h_addr;
}
static void set_broadcast_address(uint32_t net_address)
{
long broadcast_address = 0;
long mask = 0;
long broadcast_address = 0;
long mask = 0;
/* Note: sometimes INADDR_BROADCAST does not let me get
/* Note: sometimes INADDR_BROADCAST does not let me get
any unicast messages. Not sure why... */
#if USE_INADDR
(void)net_address;
bip_set_broadcast_addr(INADDR_BROADCAST);
#else
if (IN_CLASSA(ntohl(net_address)))
broadcast_address = (ntohl(net_address) & ~IN_CLASSA_HOST) | IN_CLASSA_HOST;
else if (IN_CLASSB(ntohl(net_address)))
broadcast_address = (ntohl(net_address) & ~IN_CLASSB_HOST) | IN_CLASSB_HOST;
else if (IN_CLASSC(ntohl(net_address)))
broadcast_address = (ntohl(net_address) & ~IN_CLASSC_HOST) | IN_CLASSC_HOST;
else if (IN_CLASSD(ntohl(net_address)))
broadcast_address = (ntohl(net_address) & ~IN_CLASSD_HOST) | IN_CLASSD_HOST;
else
broadcast_address = INADDR_BROADCAST;
bip_set_broadcast_addr(htonl(broadcast_address));
#endif
#if USE_INADDR
(void) net_address;
bip_set_broadcast_addr(INADDR_BROADCAST);
#else
if (IN_CLASSA(ntohl(net_address)))
broadcast_address =
(ntohl(net_address) & ~IN_CLASSA_HOST) | IN_CLASSA_HOST;
else if (IN_CLASSB(ntohl(net_address)))
broadcast_address =
(ntohl(net_address) & ~IN_CLASSB_HOST) | IN_CLASSB_HOST;
else if (IN_CLASSC(ntohl(net_address)))
broadcast_address =
(ntohl(net_address) & ~IN_CLASSC_HOST) | IN_CLASSC_HOST;
else if (IN_CLASSD(ntohl(net_address)))
broadcast_address =
(ntohl(net_address) & ~IN_CLASSD_HOST) | IN_CLASSD_HOST;
else
broadcast_address = INADDR_BROADCAST;
bip_set_broadcast_addr(htonl(broadcast_address));
#endif
}
static void cleanup(void)
{
WSACleanup();
WSACleanup();
}
void bip_set_interface(char *ifname)
{
(void)ifname;
/* dummy function */
(void) ifname;
/* dummy function */
}
bool bip_init(void)
{
int rv = 0; // return from socket lib calls
struct sockaddr_in sin = {-1};
int rv = 0; // return from socket lib calls
struct sockaddr_in sin = { -1 };
int value = 1;
int sock_fd = -1;
int Result;
@@ -109,63 +113,55 @@ bool bip_init(void)
Result = WSAStartup((1 << 8) | 1, &wd);
//Result = WSAStartup(MAKEWORD(2,2), &wd);
if (Result != 0)
{
Code = WSAGetLastError();
printf("TCP/IP stack initialization failed, error code: %i\n",
Code);
exit(1);
if (Result != 0) {
Code = WSAGetLastError();
printf("TCP/IP stack initialization failed, error code: %i\n",
Code);
exit(1);
}
atexit(cleanup);
address.s_addr = gethostaddr();
if (address.s_addr == (unsigned)-1)
{
Code = WSAGetLastError();
printf("Get host address failed, error code: %i\n",
Code);
exit(1);
if (address.s_addr == (unsigned) -1) {
Code = WSAGetLastError();
printf("Get host address failed, error code: %i\n", Code);
exit(1);
}
#ifdef BIP_DEBUG
printf("host address: %s\n",inet_ntoa(address));
#endif
#ifdef BIP_DEBUG
printf("host address: %s\n", inet_ntoa(address));
#endif
bip_set_addr(address.s_addr);
set_broadcast_address(address.s_addr);
/* 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)
{
fprintf(stderr,"bip: failed to allocate a socket.\n");
return false;
if (sock_fd < 0) {
fprintf(stderr, "bip: failed to allocate a socket.\n");
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)
{
fprintf(stderr,"bip: failed to set REUSEADDR socket option.\n");
close(sock_fd);
bip_set_socket(-1);
return false;
(char *) &value, sizeof(value));
if (rv < 0) {
fprintf(stderr, "bip: failed to set REUSEADDR socket option.\n");
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)
{
fprintf(stderr,"bip: failed to set BROADCAST socket option.\n");
close(sock_fd);
bip_set_socket(-1);
return false;
(char *) &value, sizeof(value));
if (rv < 0) {
fprintf(stderr, "bip: failed to set BROADCAST socket option.\n");
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;
#if USE_INADDR
#if USE_INADDR
/* by setting sin.sin_addr.s_addr to INADDR_ANY,
I am telling the IP stack to automatically fill
in the IP address of the machine the process
@@ -182,20 +178,18 @@ bool bip_init(void)
Note: sometimes INADDR_ANY does not let me get
any unicast messages. Not sure why... */
sin.sin_addr.s_addr = htonl(INADDR_ANY);
#else
#else
/* or we could use the specific adapter address
note: already in network byte order */
sin.sin_addr.s_addr = address.s_addr;
#endif
#endif
sin.sin_port = htons(bip_get_port());
memset(&(sin.sin_zero), '\0', sizeof(sin.sin_zero));
rv = bind(sock_fd,
(const struct sockaddr*)&sin, sizeof(struct sockaddr));
if (rv < 0)
{
fprintf(stderr,"bip: failed to bind to %s port %hd\n",
inet_ntoa(sin.sin_addr),
bip_get_port());
(const struct sockaddr *) &sin, sizeof(struct sockaddr));
if (rv < 0) {
fprintf(stderr, "bip: failed to bind to %s port %hd\n",
inet_ntoa(sin.sin_addr), bip_get_port());
close(sock_fd);
bip_set_socket(-1);
return false;
@@ -203,4 +197,3 @@ bool bip_init(void)
return true;
}
+174 -217
View File
@@ -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 "iam.h"
#include "address.h"
#include "config.h"
@@ -43,262 +43,219 @@
#include "txbuf.h"
// buffer used for receive
static uint8_t Rx_Buf[MAX_MPDU] = {0};
static uint8_t Rx_Buf[MAX_MPDU] = { 0 };
/* send a whois to see who is on the network */
static bool Who_Is_Request = true;
static void Read_Properties(void)
{
uint32_t device_id = 0;
bool status = false;
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
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_CONFORMANCE_CLASS,
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
};
uint32_t device_id = 0;
bool status = false;
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
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_CONFORMANCE_CLASS,
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
};
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
OBJECT_DEVICE,
device_id,
object_props[property],
BACNET_ARRAY_ALL);
if (status)
property++;
}
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
OBJECT_DEVICE,
device_id, object_props[property], BACNET_ARRAY_ALL);
if (status)
property++;
}
} else
next_device = true;
if (next_device) {
next_device = false;
index++;
if (index >= MAX_ADDRESS_CACHE)
index = 0;
property = 0;
}
}
else
next_device = true;
if (next_device)
{
next_device = false;
index++;
if (index >= MAX_ADDRESS_CACHE)
index = 0;
property = 0;
}
}
return;
return;
}
static void LocalIAmHandler(
uint8_t *service_request,
uint16_t service_len,
BACNET_ADDRESS *src)
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;
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");
(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;
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,
handler_who_is);
apdu_set_unconfirmed_handler(
SERVICE_UNCONFIRMED_I_AM,
LocalIAmHandler);
// we need to handle who-is to support dynamic device binding
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS,
handler_who_is);
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(
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_WRITE_PROPERTY,
handler_write_property);
// handle the data coming back from confirmed requests
apdu_set_confirmed_ack_handler(
SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property_ack);
// 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);
// 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_WRITE_PROPERTY,
handler_write_property);
// handle the data coming back from confirmed requests
apdu_set_confirmed_ack_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property_ack);
}
static void print_address(
char *name,
BACNET_ADDRESS *dest) // destination address
static void print_address(char *name, BACNET_ADDRESS * dest) // destination address
{
int i = 0; // counter
int i = 0; // counter
if (dest)
{
printf("%s: ",name);
for (i = 0; i < dest->mac_len; i++)
{
printf("%02X",dest->mac[i]);
if (dest) {
printf("%s: ", name);
for (i = 0; i < dest->mac_len; i++) {
printf("%02X", dest->mac[i]);
}
printf("\n");
}
printf("\n");
}
}
static void print_address_cache(void)
{
int i,j;
BACNET_ADDRESS address;
uint32_t device_id = 0;
unsigned max_apdu = 0;
int i, j;
BACNET_ADDRESS address;
uint32_t device_id = 0;
unsigned max_apdu = 0;
fprintf(stderr,"Device\tMAC\tMaxAPDU\tNet\n");
for (i = 0; i < MAX_ADDRESS_CACHE; i++)
{
if (address_get_by_index(i,&device_id, &max_apdu, &address))
{
fprintf(stderr,"%u\t",device_id);
for (j = 0; j < address.mac_len; j++)
{
fprintf(stderr,"%02X",address.mac[j]);
}
fprintf(stderr,"\t");
fprintf(stderr,"%hu\t",max_apdu);
fprintf(stderr,"%hu\n",address.net);
fprintf(stderr, "Device\tMAC\tMaxAPDU\tNet\n");
for (i = 0; i < MAX_ADDRESS_CACHE; i++) {
if (address_get_by_index(i, &device_id, &max_apdu, &address)) {
fprintf(stderr, "%u\t", device_id);
for (j = 0; j < address.mac_len; j++) {
fprintf(stderr, "%02X", address.mac[j]);
}
fprintf(stderr, "\t");
fprintf(stderr, "%hu\t", max_apdu);
fprintf(stderr, "%hu\n", address.net);
}
}
}
}
int main(int argc, char *argv[])
{
BACNET_ADDRESS src = {0}; // address where message came from
uint16_t pdu_len = 0;
unsigned timeout = 100; // milliseconds
BACNET_ADDRESS my_address, broadcast_address;
BACNET_ADDRESS src = { 0 }; // address where message came from
uint16_t pdu_len = 0;
unsigned timeout = 100; // milliseconds
BACNET_ADDRESS my_address, broadcast_address;
(void)argc;
(void)argv;
Device_Set_Object_Instance_Number(124);
Init_Service_Handlers();
// init the data link layer
/* configure standard BACnet/IP port */
bip_set_port(0xBAC0);
if (!bip_init())
return 1;
(void) argc;
(void) argv;
Device_Set_Object_Instance_Number(124);
Init_Service_Handlers();
// init the data link layer
/* configure standard BACnet/IP port */
bip_set_port(0xBAC0);
if (!bip_init())
return 1;
datalink_get_broadcast_address(&broadcast_address);
print_address("Broadcast",&broadcast_address);
datalink_get_my_address(&my_address);
print_address("Address",&my_address);
datalink_get_broadcast_address(&broadcast_address);
print_address("Broadcast", &broadcast_address);
datalink_get_my_address(&my_address);
print_address("Address", &my_address);
printf("BACnet stack running...\n");
// loop forever
for (;;)
{
// input
printf("BACnet stack running...\n");
// loop forever
for (;;) {
// input
// returns 0 bytes on timeout
pdu_len = bip_receive(
&src,
&Rx_Buf[0],
MAX_MPDU,
timeout);
// returns 0 bytes on timeout
pdu_len = bip_receive(&src, &Rx_Buf[0], MAX_MPDU, timeout);
// process
// process
if (pdu_len)
{
npdu_handler(
&src,
&Rx_Buf[0],
pdu_len);
}
if (I_Am_Request)
{
I_Am_Request = false;
iam_send(&Handler_Transmit_Buffer[0]);
} else if (Who_Is_Request)
{
Who_Is_Request = false;
Send_WhoIs(-1,-1);
}
else
{
Read_Properties();
if (pdu_len) {
npdu_handler(&src, &Rx_Buf[0], pdu_len);
}
if (I_Am_Request) {
I_Am_Request = false;
iam_send(&Handler_Transmit_Buffer[0]);
} else if (Who_Is_Request) {
Who_Is_Request = false;
Send_WhoIs(-1, -1);
} else {
Read_Properties();
}
// output
// blink LEDs, Turn on or off outputs, etc
/* wait for ESC from keyboard before quitting */
if (kbhit() && (getch() == 0x1B))
break;
}
// output
print_address_cache();
// blink LEDs, Turn on or off outputs, etc
/* wait for ESC from keyboard before quitting */
if (kbhit() && (getch() == 0x1B))
break;
}
print_address_cache();
return 0;
return 0;
}
+13 -13
View File
@@ -4,25 +4,25 @@
// C99 Boolean types for compilers without C99 support
#ifndef __cplusplus
typedef int _Bool;
#ifndef bool
#define bool _Bool
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#define __bool_true_false_are_defined 1
typedef int _Bool;
#ifndef bool
#define bool _Bool
#endif
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#define __bool_true_false_are_defined 1
#endif
#ifndef FALSE
#define FALSE 0
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#define TRUE 1
#endif
#endif
+7 -7
View File
@@ -6,14 +6,14 @@
#include <stddef.h>
typedef unsigned char uint8_t; // 1 byte 0 to 255
typedef signed char int8_t; // 1 byte -127 to 127
typedef unsigned short uint16_t; // 2 bytes 0 to 65535
typedef signed short int16_t; // 2 bytes -32767 to 32767
typedef unsigned char uint8_t; // 1 byte 0 to 255
typedef signed char int8_t; // 1 byte -127 to 127
typedef unsigned short uint16_t; // 2 bytes 0 to 65535
typedef signed short int16_t; // 2 bytes -32767 to 32767
//typedef unsigned short long uint24_t; // 3 bytes 0 to 16777215
typedef unsigned long uint32_t; // 4 bytes 0 to 4294967295
typedef signed long int32_t; // 4 bytes -2147483647 to 2147483647
typedef unsigned long uint32_t; // 4 bytes 0 to 4294967295
typedef signed long int32_t; // 4 bytes -2147483647 to 2147483647
// typedef signed long long int64_t;
// typedef unsigned long long uint64_t;
#endif // STDINT_H
#endif // STDINT_H