From f0f3c9ab64e2ed729522b66c24d7374ecb1f6586 Mon Sep 17 00:00:00 2001 From: skarg Date: Wed, 7 Sep 2005 13:01:54 +0000 Subject: [PATCH] Got the ARCNET datalink layer working --- bacnet-stack/ports/linux/arcnet.c | 100 ++++++++++++++++++++++++++++-- bacnet-stack/ports/linux/main.c | 2 +- 2 files changed, 96 insertions(+), 6 deletions(-) diff --git a/bacnet-stack/ports/linux/arcnet.c b/bacnet-stack/ports/linux/arcnet.c index 0da69b52..ab8991e1 100644 --- a/bacnet-stack/ports/linux/arcnet.c +++ b/bacnet-stack/ports/linux/arcnet.c @@ -1,3 +1,37 @@ +/*####COPYRIGHTBEGIN#### + ------------------------------------------- + Copyright (C) 2005 Steve Karg + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + The Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA. + + As a special exception, if other files instantiate templates or + use macros or inline functions from this file, or you compile + this file and link it with other works to produce a work based + on this file, this file does not by itself cause the resulting + work to be covered by the GNU General Public License. However + the source code for this file must still be made available in + accordance with section (3) of the GNU General Public License. + + This exception does not invalidate any other reasons why a work + based on this file might be covered by the GNU General Public + License. + ------------------------------------------- +####COPYRIGHTEND####*/ + #include #include "bacdef.h" #include "arcnet.h" @@ -12,6 +46,39 @@ static struct sockaddr ARCNET_Socket_Address; // Broadcast address #define ARCNET_BROADCAST 0 +/* +Hints: + +When using a PCI20-485D ARCNET card from Contemporary Controls, +you might need to know about the following settings: + +Assuming a 20MHz clock on the COM20020 chip: + +clockp Clock Prescaler DataRate +------ --------------- -------- +0 8 2.5 Mbps +1 16 1.25 Mbps +2 32 625 Kbps +3 64 312.5 Kbps +4 128 156.25Kbps + +1. Install the arcnet driver and arcnet raw mode driver: +# modprobe com20020_pci clockp=4 +# modprobe arc_rawmode + +2. Use ifconfig to bring up the interface +# ifconfig arc0 up + +3. The hardware address (MAC address) is set using the dipswitch + on the back of the card. 0 is broadcast, so don't use 0. + +4. The backplane mode on the PCI20-485D card is done in hardware, + so the driver does not need to do backplane mode. If you + use another type of PCI20 card, you could pass in backplane=1 or + backplane=0 as an option to the modprobe of com20020_pci. + +*/ + bool arcnet_valid(void) { return (ARCNET_Sock_FD >= 0); @@ -31,7 +98,16 @@ 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; + /* 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) @@ -88,7 +164,18 @@ static int arcnet_bind(char *interface_name) rv = ioctl(sock_fd, SIOCGIFHWADDR, &ifr); if (rv != -1) /* worked okay */ ARCNET_MAC_Address = ifr.ifr_hwaddr.sa_data[0]; - fprintf(stderr,"arcnet: MAC=%02Xh\n",ARCNET_MAC_Address); + // 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); atexit(arcnet_cleanup); @@ -236,15 +323,18 @@ uint16_t arcnet_receive( if (received_bytes == 0) return 0; - printf("arcnet: received %u bytes from %02Xh (proto==%02Xh)\n", - received_bytes, pkt->hard.source, pkt->soft.raw[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]); + */ + if (pkt->hard.source == ARCNET_MAC_Address) { fprintf(stderr,"arcnet: self sent packet?\n"); return 0; } if (pkt->soft.raw[0] != 0xCD) { - fprintf(stderr,"arcnet: Non-BACnet packet.\n"); + /* fprintf(stderr,"arcnet: Non-BACnet packet.\n"); */ return 0; } if ((pkt->hard.dest != ARCNET_MAC_Address) && diff --git a/bacnet-stack/ports/linux/main.c b/bacnet-stack/ports/linux/main.c index a6141e3b..232188b0 100644 --- a/bacnet-stack/ports/linux/main.c +++ b/bacnet-stack/ports/linux/main.c @@ -284,7 +284,7 @@ int main(int argc, char *argv[]) { case 1: // used for testing, but kind of noisy on the network - // Read_Properties(); + Read_Properties(); break; case 2: break;