Got the ARCNET datalink layer working
This commit is contained in:
@@ -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 <stdint.h>
|
||||
#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) &&
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user