Skip to content

Add Timestamp for CAN Frames #1

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 3 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
23 changes: 1 addition & 22 deletions interface_linux.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package socketcan

import (
"fmt"
"unsafe"

"golang.org/x/sys/unix"
)

Expand All @@ -12,24 +9,6 @@ func getIfIndex(itf Interface, ifName string) (int, error) {
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
fd := itf.SocketFD()
copy(ifReq.Name[:], ifNameRaw)
_, _, errno := unix.Syscall(unix.SYS_IOCTL,
uintptr(fd),
unix.SIOCGIFINDEX,
uintptr(unsafe.Pointer(&ifReq)))
if errno != 0 {
return 0, fmt.Errorf("ioctl: %v", errno)
}

return ifReq.Index, nil
return IoctlGetIfIndex(fd, ifNameRaw)
}
51 changes: 51 additions & 0 deletions ioctl_linux.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/**
* Special ioctl commands for supporting the unix interface
* to SocketCAN interface.
*
*/

package socketcan

import (
"fmt"
"syscall"
"unsafe"

"golang.org/x/sys/unix"
)

// Unfortunately - this is not made public in the "unix" library so,
// making ioctl requests is hard. I've manually recreated it here.
func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) {
_, _, e1 := syscall.Syscall(unix.SYS_IOCTL, uintptr(fd), uintptr(req), uintptr(arg))
if e1 != 0 {
err = error(e1)
}
return
}

func IoctlGetIfIndex(fd int, ifNameRaw []byte) (int, error) {
type ifreq struct {
Name [unix.IFNAMSIZ]byte
Index int
}
var ifReq ifreq

if len(ifNameRaw) > unix.IFNAMSIZ {
return -1, fmt.Errorf("Maximum ifname length is %d characters", unix.IFNAMSIZ)
}

copy(ifReq.Name[:], ifNameRaw)
err := ioctlPtr(fd, unix.SIOCGIFINDEX, unsafe.Pointer(&ifReq));
if err != nil {
return -1, err
}

return ifReq.Index, nil
}

func IoctlGetTimeval(fd int) (*syscall.Timeval, error) {
var value syscall.Timeval
err := ioctlPtr(fd, syscall.SIOCGSTAMP, unsafe.Pointer(&value));
return &value, err
}
1 change: 1 addition & 0 deletions raw_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ type RawInterface interface {
Send(CanFrame) error
Receive() (CanFrame, error)
Close() error
GetTimestamp() (int64, error)
}
15 changes: 15 additions & 0 deletions raw_interface_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,21 @@ func (itf *rawInterface) Receive() (CanFrame, error) {
return f, nil
}

/** Request the timestamp for the last read CAN frame.
* This method must be called immediately after the last
* frame was read.
* @return The timestamp is in CLOCK_MONOTONIC domain in
* nanoseconds.
*/
func (itf *rawInterface) GetTimestamp() (int64, error) {
timeVal, err := IoctlGetTimeval(itf.fd)
if err != nil {
return -1, err
}

return timeVal.Nano(), nil
}

func IsClosedInterfaceError(err error) bool {
errno, ok := err.(syscall.Errno)
if ok == false {
Expand Down
4 changes: 4 additions & 0 deletions raw_interface_stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ func (itf *rawInterfaceStub) Receive() (CanFrame, error) {
return f, nil
}

func (itf *rawInterface) GetTimestamp() (int64, error) {
return 0, nil;
}

func IsClosedInterfaceError(err error) bool {
return false
}