mirror of
https://github.com/python/cpython.git
synced 2025-07-16 07:45:20 +00:00
bpo-40291: Add support for CAN_J1939 sockets (GH-19538)
Add support for CAN_J1939 sockets that wrap SAE J1939 protocol functionality provided by Linux 5.4+ kernels.
This commit is contained in:
parent
fd33cdbd05
commit
360371f79c
8 changed files with 197 additions and 5 deletions
|
@ -1556,6 +1556,16 @@ makesockaddr(SOCKET_T sockfd, struct sockaddr *addr, size_t addrlen, int proto)
|
|||
a->can_addr.tp.tx_id);
|
||||
}
|
||||
#endif /* CAN_ISOTP */
|
||||
#ifdef CAN_J1939
|
||||
case CAN_J1939:
|
||||
{
|
||||
return Py_BuildValue("O&KkB", PyUnicode_DecodeFSDefault,
|
||||
ifname,
|
||||
a->can_addr.j1939.name,
|
||||
a->can_addr.j1939.pgn,
|
||||
a->can_addr.j1939.addr);
|
||||
}
|
||||
#endif /* CAN_J1939 */
|
||||
default:
|
||||
{
|
||||
return Py_BuildValue("(O&)", PyUnicode_DecodeFSDefault,
|
||||
|
@ -2237,6 +2247,55 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
|
|||
return 1;
|
||||
}
|
||||
#endif /* CAN_ISOTP */
|
||||
#ifdef CAN_J1939
|
||||
case CAN_J1939:
|
||||
{
|
||||
PyObject *interfaceName;
|
||||
struct ifreq ifr;
|
||||
Py_ssize_t len;
|
||||
uint64_t j1939_name;
|
||||
uint32_t j1939_pgn;
|
||||
uint8_t j1939_addr;
|
||||
|
||||
struct sockaddr_can *addr = &addrbuf->can;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "O&KkB", PyUnicode_FSConverter,
|
||||
&interfaceName,
|
||||
&j1939_name,
|
||||
&j1939_pgn,
|
||||
&j1939_addr))
|
||||
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.j1939.name = j1939_name;
|
||||
addr->can_addr.j1939.pgn = j1939_pgn;
|
||||
addr->can_addr.j1939.addr = j1939_addr;
|
||||
|
||||
*len_ret = sizeof(*addr);
|
||||
Py_DECREF(interfaceName);
|
||||
return 1;
|
||||
}
|
||||
#endif /* CAN_J1939 */
|
||||
default:
|
||||
PyErr_Format(PyExc_OSError,
|
||||
"%s(): unsupported CAN protocol", caller);
|
||||
|
@ -7687,6 +7746,9 @@ PyInit__socket(void)
|
|||
#ifdef CAN_ISOTP
|
||||
PyModule_AddIntMacro(m, CAN_ISOTP);
|
||||
#endif
|
||||
#ifdef CAN_J1939
|
||||
PyModule_AddIntMacro(m, CAN_J1939);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_LINUX_CAN_RAW_H
|
||||
PyModule_AddIntMacro(m, CAN_RAW_FILTER);
|
||||
|
@ -7734,6 +7796,37 @@ PyInit__socket(void)
|
|||
PyModule_AddIntConstant(m, "CAN_BCM_CAN_FD_FRAME", CAN_FD_FRAME);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef HAVE_LINUX_CAN_J1939_H
|
||||
PyModule_AddIntMacro(m, J1939_MAX_UNICAST_ADDR);
|
||||
PyModule_AddIntMacro(m, J1939_IDLE_ADDR);
|
||||
PyModule_AddIntMacro(m, J1939_NO_ADDR);
|
||||
PyModule_AddIntMacro(m, J1939_NO_NAME);
|
||||
PyModule_AddIntMacro(m, J1939_PGN_REQUEST);
|
||||
PyModule_AddIntMacro(m, J1939_PGN_ADDRESS_CLAIMED);
|
||||
PyModule_AddIntMacro(m, J1939_PGN_ADDRESS_COMMANDED);
|
||||
PyModule_AddIntMacro(m, J1939_PGN_PDU1_MAX);
|
||||
PyModule_AddIntMacro(m, J1939_PGN_MAX);
|
||||
PyModule_AddIntMacro(m, J1939_NO_PGN);
|
||||
|
||||
/* J1939 socket options */
|
||||
PyModule_AddIntMacro(m, SO_J1939_FILTER);
|
||||
PyModule_AddIntMacro(m, SO_J1939_PROMISC);
|
||||
PyModule_AddIntMacro(m, SO_J1939_SEND_PRIO);
|
||||
PyModule_AddIntMacro(m, SO_J1939_ERRQUEUE);
|
||||
|
||||
PyModule_AddIntMacro(m, SCM_J1939_DEST_ADDR);
|
||||
PyModule_AddIntMacro(m, SCM_J1939_DEST_NAME);
|
||||
PyModule_AddIntMacro(m, SCM_J1939_PRIO);
|
||||
PyModule_AddIntMacro(m, SCM_J1939_ERRQUEUE);
|
||||
|
||||
PyModule_AddIntMacro(m, J1939_NLA_PAD);
|
||||
PyModule_AddIntMacro(m, J1939_NLA_BYTES_ACKED);
|
||||
|
||||
PyModule_AddIntMacro(m, J1939_EE_INFO_NONE);
|
||||
PyModule_AddIntMacro(m, J1939_EE_INFO_TX_ABORT);
|
||||
|
||||
PyModule_AddIntMacro(m, J1939_FILTER_MAX);
|
||||
#endif
|
||||
#ifdef SOL_RDS
|
||||
PyModule_AddIntMacro(m, SOL_RDS);
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue