diff options
author | Pier-Yves Lessard <py.lessard@gmail.com> | 2017-08-28 08:32:44 (GMT) |
---|---|---|
committer | Christian Heimes <christian@python.org> | 2017-08-28 08:32:44 (GMT) |
commit | a30f6d45ac3e72761b96a8df0527182029eaee24 (patch) | |
tree | 78979f1ea774a03b5f895f4a661a829a247f3a83 /Modules | |
parent | ed94a8b2851914bcda3a77b28b25517b8baa91e6 (diff) | |
download | cpython-a30f6d45ac3e72761b96a8df0527182029eaee24.zip cpython-a30f6d45ac3e72761b96a8df0527182029eaee24.tar.gz cpython-a30f6d45ac3e72761b96a8df0527182029eaee24.tar.bz2 |
bpo-30987 - Support for ISO-TP protocol in SocketCAN (#2956)
* Added support for CAN_ISOTP protocol
* Added unit tests for CAN ISOTP
* Updated documentation for ISO-TP protocol
* Removed trailing whitespace in documentation
* Added blurb NEWS.d file
* updated Misc/ACKS
* Fixed broken unit test that was using isotp const outside of skippable section
* Removed dependecy over third party project
* Added implementation for getsockname + unit tests
* Missing newline at end of ACKS file
* Accidentally inserted a type in ACKS file
* Followed tiran changes review #1 recommendations
* Added spaces after comma
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/socketmodule.c | 75 |
1 files changed, 70 insertions, 5 deletions
diff --git a/Modules/socketmodule.c b/Modules/socketmodule.c index bf8d19f..beadecf 100644 --- a/Modules/socketmodule.c +++ b/Modules/socketmodule.c @@ -1373,9 +1373,22 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto) ifname = ifr.ifr_name; } - return Py_BuildValue("O&h", PyUnicode_DecodeFSDefault, - ifname, - a->can_family); + switch (proto) { +#ifdef CAN_ISOTP + case CAN_ISOTP: + { + return Py_BuildValue("O&kk", PyUnicode_DecodeFSDefault, + ifname, + a->can_addr.tp.rx_id, + a->can_addr.tp.tx_id); + } +#endif + default: + { + return Py_BuildValue("O&", PyUnicode_DecodeFSDefault, + ifname); + } + } } #endif @@ -1869,7 +1882,9 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, } #endif -#if defined(AF_CAN) && defined(CAN_RAW) && defined(CAN_BCM) +#ifdef AF_CAN + +#if defined(CAN_RAW) && defined(CAN_BCM) case AF_CAN: switch (s->sock_proto) { case CAN_RAW: @@ -1880,7 +1895,6 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, PyObject *interfaceName; struct ifreq ifr; Py_ssize_t len; - addr = (struct sockaddr_can *)addr_ret; if (!PyArg_ParseTuple(args, "O&", PyUnicode_FSConverter, @@ -1913,6 +1927,54 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args, Py_DECREF(interfaceName); return 1; } +#endif + +#ifdef CAN_ISOTP + case CAN_ISOTP: + { + struct sockaddr_can *addr; + PyObject *interfaceName; + struct ifreq ifr; + Py_ssize_t len; + unsigned long int rx_id, tx_id; + + addr = (struct sockaddr_can *)addr_ret; + + if (!PyArg_ParseTuple(args, "O&kk", PyUnicode_FSConverter, + &interfaceName, + &rx_id, + &tx_id)) + return 0; + + len = PyBytes_GET_SIZE(interfaceName); + + if (len == 0) { + ifr.ifr_ifindex = 0; + } else if ((size_t)len < sizeof(ifr.ifr_name)) { + strncpy(ifr.ifr_name, PyBytes_AS_STRING(interfaceName), sizeof(ifr.ifr_name)); + ifr.ifr_name[(sizeof(ifr.ifr_name))-1] = '\0'; + if (ioctl(s->sock_fd, SIOCGIFINDEX, &ifr) < 0) { + s->errorhandler(); + Py_DECREF(interfaceName); + return 0; + } + } else { + PyErr_SetString(PyExc_OSError, + "AF_CAN interface name too long"); + Py_DECREF(interfaceName); + return 0; + } + + addr->can_family = AF_CAN; + addr->can_ifindex = ifr.ifr_ifindex; + addr->can_addr.tp.rx_id = rx_id; + addr->can_addr.tp.tx_id = tx_id; + + *len_ret = sizeof(*addr); + Py_DECREF(interfaceName); + return 1; + } +#endif default: PyErr_SetString(PyExc_OSError, "getsockaddrarg: unsupported CAN protocol"); @@ -6995,6 +7057,9 @@ PyInit__socket(void) PyModule_AddIntMacro(m, CAN_SFF_MASK); PyModule_AddIntMacro(m, CAN_EFF_MASK); PyModule_AddIntMacro(m, CAN_ERR_MASK); +#ifdef CAN_ISOTP + PyModule_AddIntMacro(m, CAN_ISOTP); +#endif #endif #ifdef HAVE_LINUX_CAN_RAW_H PyModule_AddIntMacro(m, CAN_RAW_FILTER); |