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 <stdint.h>
|
||||||
#include "bacdef.h"
|
#include "bacdef.h"
|
||||||
#include "arcnet.h"
|
#include "arcnet.h"
|
||||||
@@ -12,6 +46,39 @@ static struct sockaddr ARCNET_Socket_Address;
|
|||||||
// Broadcast address
|
// Broadcast address
|
||||||
#define ARCNET_BROADCAST 0
|
#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)
|
bool arcnet_valid(void)
|
||||||
{
|
{
|
||||||
return (ARCNET_Sock_FD >= 0);
|
return (ARCNET_Sock_FD >= 0);
|
||||||
@@ -31,7 +98,16 @@ static int arcnet_bind(char *interface_name)
|
|||||||
int sock_fd = -1; // return value
|
int sock_fd = -1; // return value
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int rv; // return value - error value from df or ioctl call
|
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);
|
fprintf(stderr,"arcnet: opening \"%s\"\n",interface_name);
|
||||||
// note: on some systems you may have to add or enable in
|
// note: on some systems you may have to add or enable in
|
||||||
// modules.conf (or in modutils/alias on Debian with update-modules)
|
// 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);
|
rv = ioctl(sock_fd, SIOCGIFHWADDR, &ifr);
|
||||||
if (rv != -1) /* worked okay */
|
if (rv != -1) /* worked okay */
|
||||||
ARCNET_MAC_Address = ifr.ifr_hwaddr.sa_data[0];
|
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);
|
atexit(arcnet_cleanup);
|
||||||
|
|
||||||
@@ -236,15 +323,18 @@ uint16_t arcnet_receive(
|
|||||||
if (received_bytes == 0)
|
if (received_bytes == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
printf("arcnet: received %u bytes from %02Xh (proto==%02Xh)\n",
|
/* printf("arcnet: received %u bytes (offset=%02Xh %02Xh) "
|
||||||
received_bytes, 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) {
|
if (pkt->hard.source == ARCNET_MAC_Address) {
|
||||||
fprintf(stderr,"arcnet: self sent packet?\n");
|
fprintf(stderr,"arcnet: self sent packet?\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (pkt->soft.raw[0] != 0xCD) {
|
if (pkt->soft.raw[0] != 0xCD) {
|
||||||
fprintf(stderr,"arcnet: Non-BACnet packet.\n");
|
/* fprintf(stderr,"arcnet: Non-BACnet packet.\n"); */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((pkt->hard.dest != ARCNET_MAC_Address) &&
|
if ((pkt->hard.dest != ARCNET_MAC_Address) &&
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
// used for testing, but kind of noisy on the network
|
// used for testing, but kind of noisy on the network
|
||||||
// Read_Properties();
|
Read_Properties();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user