Skip to content

add extended flag into ID #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# golang-socketcan

fork from https://github.com/atuleu/golang-socketcan
10 changes: 0 additions & 10 deletions constant.go

This file was deleted.

6 changes: 4 additions & 2 deletions frame.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ type CanFrame struct {

func (f CanFrame) putID(buf []byte) {
if f.Extended == true {
f.ID = f.ID & CAN_EFF_MASK
f.ID &= CAN_EFF_MASK
f.ID |= CAN_EFF_FLAG
} else {
f.ID = f.ID & CAN_SFF_MASK
f.ID &= CAN_SFF_MASK
}

if f.RTR {
f.ID |= CAN_RTR_FLAG
}
Expand Down
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module socketcan

go 1.18

require golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e // indirect
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e h1:NHvCuwuS43lGnYhten69ZWqi2QOj/CiDNcKbVqwVoew=
golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
21 changes: 0 additions & 21 deletions interface.go

This file was deleted.

35 changes: 0 additions & 35 deletions interface_linux.go

This file was deleted.

7 changes: 0 additions & 7 deletions raw_interface.go

This file was deleted.

120 changes: 100 additions & 20 deletions raw_interface_linux.go
Original file line number Diff line number Diff line change
@@ -1,44 +1,123 @@
package socketcan

import (
"syscall"
/*
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <stdint.h>
#include <ctype.h>
#include <errno.h>
#include <libgen.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/epoll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/can/raw.h>

#define CAN_FILTER_PASS 0x01 //过滤方式-通过
#define CAN_FILTER_REJECT 0x02 //过滤方式-拒绝

int rcvFiltersSet(int canfd, const uint canId, const uint filterType)
{
if(canfd <= 0) //canfd就不用解释了…
return -1;

if(0 == canId){
setsockopt(canfd, SOL_CAN_RAW, CAN_RAW_FILTER, NULL, 0); //不需要接收任何报文
return 0;
}

struct can_filter rfilter;

if(filterType & CAN_FILTER_PASS){
rfilter.can_id = canId;
} else {
rfilter.can_id = canId | CAN_INV_FILTER;
}
if(canId &0x80000000) {
rfilter.can_mask = 0x1fffffff;
} else {
rfilter.can_mask = 0x7ff;
}

if(filterType & CAN_FILTER_REJECT){
int join_filter = 1;
setsockopt(canfd, SOL_CAN_RAW, CAN_RAW_JOIN_FILTERS, &join_filter, sizeof(join_filter));
}
setsockopt(canfd, SOL_CAN_RAW, CAN_RAW_FILTER, &rfilter, sizeof(rfilter));
return 0;
}
*/
import "C"

import (
"errors"
"golang.org/x/sys/unix"
)

type rawInterface struct {
type RawInterface struct {
fd int
name string
}

func (itf *rawInterface) SocketFD() int {
return itf.fd
func (itf *RawInterface) getIfIndex(ifName string) (int, error) {
ifNameRaw, err := unix.ByteSliceFromString(ifName)
if err != nil {
return 0, err
}
if len(ifNameRaw) > unix.IFNAMSIZ {
return 0, fmt.Errorf("Maximum ifname length is %d characters", unix.IFNAMSIZ)
}

type ifreq struct {
Name [unix.IFNAMSIZ]byte
Index int
}
var ifReq ifreq
copy(ifReq.Name[:], ifNameRaw)
_, _, errno := unix.Syscall(unix.SYS_IOCTL,
uintptr(itf.fd),
unix.SIOCGIFINDEX,
uintptr(unsafe.Pointer(&ifReq)))
if errno != 0 {
return 0, fmt.Errorf("ioctl: %v", errno)
}

return ifReq.Index, nil
}

func NewRawInterface(ifName string) (RawInterface, error) {
res := &rawInterface{name: ifName}
func NewCanItf(ifName string) (RawInterface, error) {
itf := RawInterface{name: ifName}
var err error
res.fd, err = unix.Socket(unix.AF_CAN, unix.SOCK_RAW, unix.CAN_RAW)
itf.fd, err = unix.Socket(unix.AF_CAN, unix.SOCK_RAW, unix.CAN_RAW)
if err != nil {
return nil, err
}

ifIndex, err := getIfIndex(res, ifName)
ifIndex, err := getIfIndex(itf, ifName)
if err != nil {
return res, err
return itf, err
}

addr := &unix.SockaddrCAN{Ifindex: ifIndex}
err = unix.Bind(res.fd, addr)
err = unix.Bind(itf.fd, addr)

return res, err
return itf, err
}

func (itf *rawInterface) Close() error {
func (itf *RawInterface) Close() error {
return unix.Close(itf.fd)
}

func (itf *rawInterface) Send(f CanFrame) error {
func (itf *RawInterface) Send(f CanFrame) error {
frameBytes := make([]byte, 16)
f.putID(frameBytes)
frameBytes[4] = f.Dlc
Expand All @@ -47,7 +126,7 @@ func (itf *rawInterface) Send(f CanFrame) error {
return err
}

func (itf *rawInterface) Receive() (CanFrame, error) {
func (itf *RawInterface) Receive() (CanFrame, error) {
f := CanFrame{Data: make([]byte, 8)}
frameBytes := make([]byte, 16)
_, err := unix.Read(itf.fd, frameBytes)
Expand All @@ -62,10 +141,11 @@ func (itf *rawInterface) Receive() (CanFrame, error) {
return f, nil
}

func IsClosedInterfaceError(err error) bool {
errno, ok := err.(syscall.Errno)
if ok == false {
return false
func (itf *RawInterface) AddfilterPass(canid_pass uint) error {
succ := C.rcvFiltersSet(C.int(itf.fd), C.uint(canid_pass), C.CAN_FILTER_PASS)
if succ == 0 {
return nil
}
return errno == syscall.EBADF || errno == syscall.ENETDOWN || errno == syscall.ENODEV

return errors.New("can filter failed")
}
33 changes: 0 additions & 33 deletions raw_interface_stub.go

This file was deleted.