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

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, /* Create an object representing the given socket address,
suitable for passing it back to bind(), connect() etc. suitable for passing it back to bind(), connect() etc.
The family field of the sockaddr structure is inspected The family field of the sockaddr structure is inspected
@ -865,7 +910,7 @@ makeipaddr(struct sockaddr *addr, int addrlen)
/*ARGSUSED*/ /*ARGSUSED*/
static PyObject * static PyObject *
makesockaddr(int sockfd, struct sockaddr *addr, int addrlen) makesockaddr(int sockfd, struct sockaddr *addr, int addrlen, int proto)
{ {
if (addrlen == 0) { if (addrlen == 0) {
/* No address -- may be recvfrom() from known socket */ /* No address -- may be recvfrom() from known socket */
@ -920,6 +965,49 @@ makesockaddr(int sockfd, struct sockaddr *addr, int addrlen)
} }
#endif #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 #ifdef HAVE_NETPACKET_PACKET_H
case AF_PACKET: case AF_PACKET:
{ {
@ -1054,63 +1142,69 @@ getsockaddrarg(PySocketSockObject *s, PyObject *args,
#ifdef USE_BLUETOOTH #ifdef USE_BLUETOOTH
case AF_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);
{ char *straddr;
struct sockaddr_l2* addr = (struct sockaddr_l2*)_BT_SOCKADDR_MEMB(s, l2);
bdaddr_t* bdaddr = &_BT_L2_MEMB(addr, bdaddr);
_BT_L2_MEMB(addr, family) = AF_BLUETOOTH; _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)) ) if (!PyArg_ParseTuple(args, "si", &straddr,
{ &_BT_L2_MEMB(addr, psm))) {
PyErr_SetString(socket_error, "getsockaddrarg: wrong format"); PyErr_SetString(socket_error, "getsockaddrarg: "
return 0; "wrong format");
}
*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");
return 0; 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 #endif
@ -1193,28 +1287,23 @@ getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret)
{ {
switch(s->sock_proto) switch(s->sock_proto)
{ {
case BTPROTO_L2CAP:
{ case BTPROTO_L2CAP:
*len_ret = sizeof (struct sockaddr_l2); *len_ret = sizeof (struct sockaddr_l2);
return 1; return 1;
} case BTPROTO_RFCOMM:
case BTPROTO_RFCOMM: *len_ret = sizeof (struct sockaddr_rc);
{ return 1;
*len_ret = sizeof (struct sockaddr_rc);
return 1;
}
#if !defined(__FreeBSD__) #if !defined(__FreeBSD__)
case BTPROTO_SCO: case BTPROTO_SCO:
{ *len_ret = sizeof (struct sockaddr_sco);
*len_ret = sizeof (struct sockaddr_sco); return 1;
return 1;
}
#endif #endif
default: default:
{ PyErr_SetString(socket_error, "getsockaddrlen: "
PyErr_SetString(socket_error, "getsockaddrlen: unknown BT protocol"); "unknown BT protocol");
return 0; return 0;
}
} }
} }
#endif #endif
@ -1291,7 +1380,7 @@ sock_accept(PySocketSockObject *s)
goto finally; goto finally;
} }
addr = makesockaddr(s->sock_fd, (struct sockaddr *)addrbuf, addr = makesockaddr(s->sock_fd, (struct sockaddr *)addrbuf,
addrlen); addrlen, s->sock_proto);
if (addr == NULL) if (addr == NULL)
goto finally; goto finally;
@ -1754,7 +1843,8 @@ sock_getsockname(PySocketSockObject *s)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (res < 0) if (res < 0)
return s->errorhandler(); 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, PyDoc_STRVAR(getsockname_doc,
@ -1782,7 +1872,8 @@ sock_getpeername(PySocketSockObject *s)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
if (res < 0) if (res < 0)
return s->errorhandler(); 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, PyDoc_STRVAR(getpeername_doc,
@ -2037,7 +2128,7 @@ sock_recvfrom(PySocketSockObject *s, PyObject *args)
return NULL; return NULL;
if (!(addr = makesockaddr(s->sock_fd, (struct sockaddr *)addrbuf, if (!(addr = makesockaddr(s->sock_fd, (struct sockaddr *)addrbuf,
addrlen))) addrlen, s->sock_proto)))
goto finally; goto finally;
ret = PyTuple_Pack(2, buf, addr); ret = PyTuple_Pack(2, buf, addr);
@ -3259,7 +3350,7 @@ socket_getaddrinfo(PyObject *self, PyObject *args)
goto err; goto err;
for (res = res0; res; res = res->ai_next) { for (res = res0; res; res = res->ai_next) {
PyObject *addr = PyObject *addr =
makesockaddr(-1, res->ai_addr, res->ai_addrlen); makesockaddr(-1, res->ai_addr, res->ai_addrlen, protocol);
if (addr == NULL) if (addr == NULL)
goto err; goto err;
single = Py_BuildValue("iiisO", res->ai_family, single = Py_BuildValue("iiisO", res->ai_family,
@ -3717,8 +3808,8 @@ init_socket(void)
PyModule_AddIntConstant(m, "BTPROTO_SCO", BTPROTO_SCO); PyModule_AddIntConstant(m, "BTPROTO_SCO", BTPROTO_SCO);
#endif #endif
PyModule_AddIntConstant(m, "BTPROTO_RFCOMM", BTPROTO_RFCOMM); 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_ANY", Py_BuildValue("s", "00:00:00:00:00:00"));
PyModule_AddObject(m, "BDADDR_LOCAL", Py_BuildValue( "iiiiii", 0,0,0,0xff,0xff,0xff ) ); PyModule_AddObject(m, "BDADDR_LOCAL", Py_BuildValue("s", "00:00:00:FF:FF:FF"));
#endif #endif
#ifdef HAVE_NETPACKET_PACKET_H #ifdef HAVE_NETPACKET_PACKET_H