Patch #929192: Improvements to bluetooth support.

Added setbdaddr and makebdaddr.
Extended makesockaddr to understand Bluetooth addresses.
Changed getsockaddr to expect the Bluetooth addresses as a string,
not a six element tuple.
Reformatted some of the Bluetooth code to be more consistent with PEP 7.
This commit is contained in:
Martin v. Löwis 2004-06-03 09:24:42 +00:00
parent eac324b90b
commit 558d9bf528
1 changed files with 172 additions and 81 deletions

View File

@ -858,6 +858,51 @@ makeipaddr(struct sockaddr *addr, int addrlen)
}
#ifdef USE_BLUETOOTH
/* Convert a string representation of a Bluetooth address into a numeric
address. Returns the length (6), or raises an exception and returns -1 if
an error occurred. */
static int
setbdaddr(char *name, bdaddr_t *bdaddr)
{
unsigned int b0, b1, b2, b3, b4, b5;
char ch;
int n;
n = sscanf(name, "%X:%X:%X:%X:%X:%X%c",
&b5, &b4, &b3, &b2, &b1, &b0, &ch);
if (n == 6 && (b0 | b1 | b2 | b3 | b4 | b5) < 256) {
bdaddr->b[0] = b0;
bdaddr->b[1] = b1;
bdaddr->b[2] = b2;
bdaddr->b[3] = b3;
bdaddr->b[4] = b4;
bdaddr->b[5] = b5;
return 6;
} else {
PyErr_SetString(socket_error, "bad bluetooth address");
return -1;
}
}
/* Create a string representation of the Bluetooth address. This is always a
string of the form 'XX:XX:XX:XX:XX:XX' where XX is a two digit hexadecimal
value (zero padded if necessary). */
static PyObject *
makebdaddr(bdaddr_t *bdaddr)
{
char buf[(6 * 2) + 5 + 1];
sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
bdaddr->b[5], bdaddr->b[4], bdaddr->b[3],
bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]);
return PyString_FromString(buf);
}
#endif
/* Create an object representing the given socket address,
suitable for passing it back to bind(), connect() etc.
The family field of the sockaddr structure is inspected
@ -865,7 +910,7 @@ makeipaddr(struct sockaddr *addr, int addrlen)
/*ARGSUSED*/
static PyObject *
makesockaddr(int sockfd, struct sockaddr *addr, int addrlen)
makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto)
{
if (addrlen == 0) {
/* No address -- may be recvfrom() from known socket */
@ -920,6 +965,49 @@ makesockaddr(int sockfd, struct sockaddr *addr, int addrlen)
}
#endif
#ifdef USE_BLUETOOTH
case AF_BLUETOOTH:
switch (proto) {
case BTPROTO_L2CAP:
{
struct sockaddr_l2 *a = (struct sockaddr_l2 *) addr;
PyObject *addrobj = makebdaddr(&_BT_L2_MEMB(a, bdaddr));
PyObject *ret = NULL;
if (addrobj) {
ret = Py_BuildValue("Oi",
addrobj,
_BT_L2_MEMB(a, psm));
Py_DECREF(addrobj);
}
return ret;
}
case BTPROTO_RFCOMM:
{
struct sockaddr_rc *a = (struct sockaddr_rc *) addr;
PyObject *addrobj = makebdaddr(&_BT_RC_MEMB(a, bdaddr));
PyObject *ret = NULL;
if (addrobj) {
ret = Py_BuildValue("Oi",
addrobj,
_BT_RC_MEMB(a, channel));
Py_DECREF(addrobj);
}
return ret;
}
#if !defined(__FreeBSD__)
case BTPROTO_SCO:
{
struct sockaddr_sco *a = (struct sockaddr_sco *) addr;
return makebdaddr(&_BT_SCO_MEMB(a, bdaddr));
}
#endif
}
#endif
#ifdef HAVE_NETPACKET_PACKET_H
case AF_PACKET:
{
@ -1054,63 +1142,69 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#ifdef USE_BLUETOOTH
case AF_BLUETOOTH:
{
switch( s->sock_proto )
switch (s->sock_proto) {
case BTPROTO_L2CAP:
{
case BTPROTO_L2CAP:
{
struct sockaddr_l2* addr = (struct sockaddr_l2*)_BT_SOCKADDR_MEMB(s, l2);
bdaddr_t* bdaddr = &_BT_L2_MEMB(addr, bdaddr);
struct sockaddr_l2 *addr = (struct sockaddr_l2 *) _BT_SOCKADDR_MEMB(s, l2);
char *straddr;
_BT_L2_MEMB(addr, family) = AF_BLUETOOTH;
if( !PyArg_ParseTuple(args, "(iiiiii)i", &bdaddr->b[0], &bdaddr->b[1], &bdaddr->b[2], &bdaddr->b[3], &bdaddr->b[4], &bdaddr->b[5], &_BT_L2_MEMB(addr, psm)) )
{
PyErr_SetString(socket_error, "getsockaddrarg: wrong format");
return 0;
}
*addr_ret = (struct sockaddr *) addr;
*len_ret = sizeof *addr;
return 1;
}
case BTPROTO_RFCOMM:
{
struct sockaddr_rc* addr = (struct sockaddr_rc*)_BT_SOCKADDR_MEMB(s, rc);
bdaddr_t* bdaddr = &_BT_RC_MEMB(addr, bdaddr);
_BT_RC_MEMB(addr, family) = AF_BLUETOOTH;
if( !PyArg_ParseTuple(args, "(iiiiii)i", &bdaddr->b[0], &bdaddr->b[1], &bdaddr->b[2], &bdaddr->b[3], &bdaddr->b[4], &bdaddr->b[5], &_BT_RC_MEMB(addr, channel)) )
{
PyErr_SetString(socket_error, "getsockaddrarg: wrong format");
return 0;
}
*addr_ret = (struct sockaddr *) addr;
*len_ret = sizeof *addr;
return 1;
}
#if !defined(__FreeBSD__)
case BTPROTO_SCO:
{
struct sockaddr_sco* addr = (struct sockaddr_sco*)_BT_SOCKADDR_MEMB(s, sco);
bdaddr_t* bdaddr = &_BT_SCO_MEMB(addr, bdaddr);
_BT_SCO_MEMB(addr, family) = AF_BLUETOOTH;
if( !PyArg_ParseTuple(args, "iiiiii", &bdaddr->b[0], &bdaddr->b[1], &bdaddr->b[2], &bdaddr->b[3], &bdaddr->b[4], &bdaddr->b[5]) )
{
PyErr_SetString(socket_error, "getsockaddrarg: wrong format");
return 0;
}
*addr_ret = (struct sockaddr *) addr;
*len_ret = sizeof *addr;
return 1;
}
#endif
default:
{
PyErr_SetString(socket_error, "getsockaddrarg: unknown Bluetooth protocol");
_BT_L2_MEMB(addr, family) = AF_BLUETOOTH;
if (!PyArg_ParseTuple(args, "si", &straddr,
&_BT_L2_MEMB(addr, psm))) {
PyErr_SetString(socket_error, "getsockaddrarg: "
"wrong format");
return 0;
}
if (setbdaddr(straddr, &_BT_L2_MEMB(addr, bdaddr)) < 0)
return 0;
*addr_ret = (struct sockaddr *) addr;
*len_ret = sizeof *addr;
return 1;
}
case BTPROTO_RFCOMM:
{
struct sockaddr_rc *addr = (struct sockaddr_rc *) _BT_SOCKADDR_MEMB(s, rc);
char *straddr;
_BT_RC_MEMB(addr, family) = AF_BLUETOOTH;
if (!PyArg_ParseTuple(args, "si", &straddr,
&_BT_RC_MEMB(addr, channel))) {
PyErr_SetString(socket_error, "getsockaddrarg: "
"wrong format");
return 0;
}
if (setbdaddr(straddr, &_BT_RC_MEMB(addr, bdaddr)) < 0)
return 0;
*addr_ret = (struct sockaddr *) addr;
*len_ret = sizeof *addr;
return 1;
}
#if !defined(__FreeBSD__)
case BTPROTO_SCO:
{
struct sockaddr_sco *addr = (struct sockaddr_sco *) _BT_SOCKADDR_MEMB(s, sco);
char *straddr;
_BT_SCO_MEMB(addr, family) = AF_BLUETOOTH;
straddr = PyString_AsString(args);
if (straddr == NULL) {
PyErr_SetString(socket_error, "getsockaddrarg: "
"wrong format");
return 0;
}
if (setbdaddr(straddr, &_BT_SCO_MEMB(addr, bdaddr)) < 0)
return 0;
*addr_ret = (struct sockaddr *) addr;
*len_ret = sizeof *addr;
return 1;
}
#endif
default:
PyErr_SetString(socket_error, "getsockaddrarg: unknown Bluetooth protocol");
return 0;
}
}
#endif
@ -1193,28 +1287,23 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
{
switch(s->sock_proto)
{
case BTPROTO_L2CAP:
{
*len_ret = sizeof (struct sockaddr_l2);
return 1;
}
case BTPROTO_RFCOMM:
{
*len_ret = sizeof (struct sockaddr_rc);
return 1;
}
case BTPROTO_L2CAP:
*len_ret = sizeof (struct sockaddr_l2);
return 1;
case BTPROTO_RFCOMM:
*len_ret = sizeof (struct sockaddr_rc);
return 1;
#if !defined(__FreeBSD__)
case BTPROTO_SCO:
{
*len_ret = sizeof (struct sockaddr_sco);
return 1;
}
case BTPROTO_SCO:
*len_ret = sizeof (struct sockaddr_sco);
return 1;
#endif
default:
{
PyErr_SetString(socket_error, "getsockaddrlen: unknown BT protocol");
return 0;
}
default:
PyErr_SetString(socket_error, "getsockaddrlen: "
"unknown BT protocol");
return 0;
}
}
#endif
@ -1291,7 +1380,7 @@ sock_accept(PySocketSockObject *s)
goto finally;
}
addr = makesockaddr(s->sock_fd, (struct sockaddr *)addrbuf,
addrlen);
addrlen, s->sock_proto);
if (addr == NULL)
goto finally;
@ -1754,7 +1843,8 @@ sock_getsockname(PySocketSockObject *s)
Py_END_ALLOW_THREADS
if (res < 0)
return s->errorhandler();
return makesockaddr(s->sock_fd, (struct sockaddr *) addrbuf, addrlen);
return makesockaddr(s->sock_fd, (struct sockaddr *) addrbuf, addrlen,
s->sock_proto);
}
PyDoc_STRVAR(getsockname_doc,
@ -1782,7 +1872,8 @@ sock_getpeername(PySocketSockObject *s)
Py_END_ALLOW_THREADS
if (res < 0)
return s->errorhandler();
return makesockaddr(s->sock_fd, (struct sockaddr *) addrbuf, addrlen);
return makesockaddr(s->sock_fd, (struct sockaddr *) addrbuf, addrlen,
s->sock_proto);
}
PyDoc_STRVAR(getpeername_doc,
@ -2037,7 +2128,7 @@ sock_recvfrom(PySocketSockObject *s, PyObject *args)
return NULL;
if (!(addr = makesockaddr(s->sock_fd, (struct sockaddr *)addrbuf,
addrlen)))
addrlen, s->sock_proto)))
goto finally;
ret = PyTuple_Pack(2, buf, addr);
@ -3259,7 +3350,7 @@ socket_getaddrinfo(PyObject *self, PyObject *args)
goto err;
for (res = res0; res; res = res->ai_next) {
PyObject *addr =
makesockaddr(-1, res->ai_addr, res->ai_addrlen);
makesockaddr(-1, res->ai_addr, res->ai_addrlen, protocol);
if (addr == NULL)
goto err;
single = Py_BuildValue("iiisO", res->ai_family,
@ -3717,8 +3808,8 @@ init_socket(void)
PyModule_AddIntConstant(m, "BTPROTO_SCO", BTPROTO_SCO);
#endif
PyModule_AddIntConstant(m, "BTPROTO_RFCOMM", BTPROTO_RFCOMM);
PyModule_AddObject(m, "BDADDR_ANY", Py_BuildValue( "iiiiii", 0,0,0,0,0,0 ) );
PyModule_AddObject(m, "BDADDR_LOCAL", Py_BuildValue( "iiiiii", 0,0,0,0xff,0xff,0xff ) );
PyModule_AddObject(m, "BDADDR_ANY", Py_BuildValue("s", "00:00:00:00:00:00"));
PyModule_AddObject(m, "BDADDR_LOCAL", Py_BuildValue("s", "00:00:00:FF:FF:FF"));
#endif
#ifdef HAVE_NETPACKET_PACKET_H