#! /bin/sh -e # DP: socketcan interface for python dir= if [ $# -eq 3 -a "$2" = '-d' ]; then pdir="-d $3" dir="$3/" elif [ $# -ne 1 ]; then echo >&2 "usage: `basename $0`: -patch|-unpatch [-d ]" exit 1 fi case "$1" in -patch) patch $pdir -f --no-backup-if-mismatch -p0 < $0 ;; -unpatch) patch $pdir -f --no-backup-if-mismatch -R -p0 < $0 ;; *) echo >&2 "usage: `basename $0`: -patch|-unpatch [-d ]" exit 1 esac exit 0 # append the patch here and adjust the -p? flag in the patch calls. --- configure.in 2010-03-09 22:47:28.000000000 +0100 +++ configure.in 2010-09-05 21:43:30.000000000 +0200 @@ -1341,6 +1341,13 @@ AC_CHECK_HEADERS(linux/netlink.h,,,[ #endif ]) +# On Linux, can.h and can/raw.h require sys/socket.h +AC_CHECK_HEADERS(linux/can.h linux/can/raw.h,,,[ +#ifdef HAVE_SYS_SOCKET_H +#include +#endif +]) + # checks for typedefs was_it_defined=no AC_MSG_CHECKING(for clock_t in time.h) --- Modules/socketmodule.c 2010-02-04 21:26:34.000000000 +0100 +++ Modules/socketmodule.c 2010-09-05 21:58:47.000000000 +0200 @@ -1151,6 +1151,25 @@ makesockaddr(int sockfd, struct sockaddr } #endif +#ifdef HAVE_LINUX_CAN_H + case AF_CAN: + { + struct sockaddr_can *a = (struct sockaddr_can *)addr; + char *ifname = ""; + struct ifreq ifr; + /* need to look up interface name give index */ + if (a->can_ifindex) { + ifr.ifr_ifindex = a->can_ifindex; + if (ioctl(sockfd, SIOCGIFNAME, &ifr) == 0) + ifname = ifr.ifr_name; + } + + return Py_BuildValue("sh", + ifname, + a->can_family); + } +#endif + /* More cases here... */ default: @@ -1486,6 +1505,43 @@ getsockaddrarg(PySocketSockObject *s, Py } #endif +#ifdef HAVE_LINUX_CAN_H + case AF_CAN: + switch (s->sock_proto) { + case CAN_RAW: + { + struct sockaddr_can* addr; + char *interfaceName; + struct ifreq ifr; + addr = (struct sockaddr_can *)addr_ret; + + if (!PyArg_ParseTuple(args, "s", &interfaceName)) + return 0; + + if (!strcmp(interfaceName, "any")) { + ifr.ifr_ifindex = 0; + } else { + strncpy(ifr.ifr_name, interfaceName, + sizeof(ifr.ifr_name)); + ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; + if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { + s->errorhandler(); + return 0; + } + } + + addr->can_family = AF_CAN; + addr->can_ifindex = ifr.ifr_ifindex; + + *len_ret = sizeof(*addr); + return 1; + } + default: + PyErr_SetString(socket_error, "getsockaddrarg: unsupported CAN protocol"); + return 0; + } +#endif + /* More cases here... */ default: @@ -1579,6 +1635,14 @@ getsockaddrlen(PySocketSockObject *s, so } #endif +#ifdef HAVE_LINUX_CAN_H + case AF_CAN: + { + *len_ret = sizeof (struct sockaddr_can); + return 1; + } +#endif + /* More cases here... */ default: @@ -4584,6 +4648,14 @@ init_socket(void) PyModule_AddStringConstant(m, "BDADDR_ANY", "00:00:00:00:00:00"); PyModule_AddStringConstant(m, "BDADDR_LOCAL", "00:00:00:FF:FF:FF"); #endif +#ifdef AF_CAN + /* Controller Area Network */ + PyModule_AddIntConstant(m, "AF_CAN", AF_CAN); +#endif +#ifdef PF_CAN + /* Controller Area Network */ + PyModule_AddIntConstant(m, "PF_CAN", PF_CAN); +#endif #ifdef HAVE_NETPACKET_PACKET_H PyModule_AddIntConstant(m, "AF_PACKET", AF_PACKET); @@ -4785,6 +4857,28 @@ init_socket(void) #else PyModule_AddIntConstant(m, "SOL_UDP", 17); #endif +#ifdef SOL_CAN_BASE + PyModule_AddIntConstant(m, "SOL_CAN_BASE", SOL_CAN_BASE); +#endif +#ifdef SOL_CAN_RAW + PyModule_AddIntConstant(m, "SOL_CAN_RAW", SOL_CAN_RAW); + PyModule_AddIntConstant(m, "CAN_RAW", CAN_RAW); +#endif +#ifdef HAVE_LINUX_CAN_H + PyModule_AddIntConstant(m, "CAN_EFF_FLAG", CAN_EFF_FLAG); + PyModule_AddIntConstant(m, "CAN_RTR_FLAG", CAN_RTR_FLAG); + PyModule_AddIntConstant(m, "CAN_ERR_FLAG", CAN_ERR_FLAG); + + PyModule_AddIntConstant(m, "CAN_SFF_MASK", CAN_SFF_MASK); + PyModule_AddIntConstant(m, "CAN_EFF_MASK", CAN_EFF_MASK); + PyModule_AddIntConstant(m, "CAN_ERR_MASK", CAN_ERR_MASK); +#endif +#ifdef HAVE_LINUX_CAN_RAW_H + PyModule_AddIntConstant(m, "CAN_RAW_FILTER", CAN_RAW_FILTER); + PyModule_AddIntConstant(m, "CAN_RAW_ERR_FILTER", CAN_RAW_ERR_FILTER); + PyModule_AddIntConstant(m, "CAN_RAW_LOOPBACK", CAN_RAW_LOOPBACK); + PyModule_AddIntConstant(m, "CAN_RAW_RECV_OWN_MSGS", CAN_RAW_RECV_OWN_MSGS); +#endif #ifdef IPPROTO_IP PyModule_AddIntConstant(m, "IPPROTO_IP", IPPROTO_IP); #else --- Modules/socketmodule.h 2008-06-14 10:36:07.000000000 +0200 +++ Modules/socketmodule.h 2010-09-05 21:51:10.000000000 +0200 @@ -69,6 +69,20 @@ typedef int socklen_t; # include #endif +#ifdef HAVE_LINUX_CAN_H +#include +#ifndef PF_CAN +# define PF_CAN 29 +#endif +#ifndef AF_CAN +# define AF_CAN PF_CAN +#endif +#endif + +#ifdef HAVE_LINUX_CAN_RAW_H +#include +#endif + #ifndef Py__SOCKET_H #define Py__SOCKET_H #ifdef __cplusplus @@ -114,6 +128,9 @@ typedef union sock_addr { #ifdef HAVE_NETPACKET_PACKET_H struct sockaddr_ll ll; #endif +#ifdef HAVE_LINUX_CAN_H + struct sockaddr_can* can; +#endif } sock_addr_t; /* The object holding a socket. It holds some extra information,