From nobody@FreeBSD.org  Tue Aug 14 18:37:04 2007
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 4A8C516A418
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 14 Aug 2007 18:37:04 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 347DE13C48E
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 14 Aug 2007 18:37:04 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.1/8.14.1) with ESMTP id l7EIb4uH057547
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 14 Aug 2007 18:37:04 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.1/8.14.1/Submit) id l7EIb4Mb057544;
	Tue, 14 Aug 2007 18:37:04 GMT
	(envelope-from nobody)
Message-Id: <200708141837.l7EIb4Mb057544@www.freebsd.org>
Date: Tue, 14 Aug 2007 18:37:04 GMT
From: Heiko Wundram <wundram@beenic.net>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Python 2.5.1 doesn't offer HCI socket support through the socket module
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         115523
>Category:       ports
>Synopsis:       lang/Python 2.5.1 doesn't offer HCI socket support through the socket module
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    perky
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Aug 14 18:40:01 GMT 2007
>Closed-Date:    Fri May 01 14:27:49 UTC 2009
>Last-Modified:  Fri May 01 14:27:49 UTC 2009
>Originator:     Heiko Wundram
>Release:        6-STABLE
>Organization:
>Environment:
FreeBSD phoenix.modelnine.org 6.2-STABLE FreeBSD 6.2-STABLE #0: Mon Jul 30 17:24:08 CEST 2007     modelnine@phoenix.modelnine.org:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
Currently, the Python 2.5 port doesn't contain support for opening and managing HCI raw sockets.

Implementation for this is simplistic to add to the socket module itself, but as the patch is very FreeBSD-centric (I wouldn't know how to implement the same with BlueZ, basically), and as I've had differing experiences with people from the Python community wrt. patches, I thought about posting the patch here, only, for inclusion as patch file for a Python build.

The patch should not break anything in the standard Python build.
>How-To-Repeat:
No problem, really.
>Fix:
After applying the patch, the socket family sockaddr_hci is known to the socket module (which allows bind/connect through sockaddr_hci, specifying the interface name as a single valued tuple), and BTPROTO_HCI is exported as a constant (among with some other constants which are required for normal operation).

For example:
x = socket.socket(socket.AF_BLUETOOTH,socket.SOCK_RAW,socket.BTPROTO_HCI)
x.setsockopt(socket.SOL_HCI_RAW,socket.SO_HCI_RAW_FILTER,"\xff"*12)
x.send(<some HCI command>)
print repr(x.recv(512))

Patch attached with submission follows:

diff -ur Python-2.5.1/Modules/socketmodule.c Python-2.5.1-new/Modules/socketmodule.c
--- Modules/socketmodule.c	2007-03-31 20:56:11.000000000 +0200
+++ Modules/socketmodule.c	2007-08-14 17:26:32.000000000 +0200
@@ -362,10 +362,12 @@
 #if defined(__FreeBSD__)
 #define BTPROTO_L2CAP BLUETOOTH_PROTO_L2CAP
 #define BTPROTO_RFCOMM BLUETOOTH_PROTO_RFCOMM
+#define BTPROTO_HCI BLUETOOTH_PROTO_HCI
 #define sockaddr_l2 sockaddr_l2cap
 #define sockaddr_rc sockaddr_rfcomm
 #define _BT_L2_MEMB(sa, memb) ((sa)->l2cap_##memb)
 #define _BT_RC_MEMB(sa, memb) ((sa)->rfcomm_##memb)
+#define _BT_HCI_MEMB(sa, memb) ((sa)->hci_##memb)
 #elif defined(__NetBSD__)
 #define sockaddr_l2 sockaddr_bt
 #define sockaddr_rc sockaddr_bt
@@ -1119,7 +1121,17 @@
 			return ret;
 		}
 
-#if !defined(__FreeBSD__)
+#if defined(__FreeBSD__)
+
+		case BTPROTO_HCI:
+		{
+			struct sockaddr_hci *a = (struct sockaddr_hci *)addr;
+			PyObject *ret = NULL;
+			ret = Py_BuildValue("s", _BT_HCI_MEMB(a, node));
+			return ret;
+		}
+#else
+
 		case BTPROTO_SCO:
 		{
 			struct sockaddr_sco *a = (struct sockaddr_sco *) addr;
@@ -1347,7 +1359,27 @@
 			*len_ret = sizeof *addr;
 			return 1;
 		}
-#if !defined(__FreeBSD__)
+#if defined(__FreeBSD__)
+		case BTPROTO_HCI:
+		{
+			struct sockaddr_hci *addr;
+			char *straddr;
+
+			addr = (struct sockaddr_hci *)addr_ret;
+			_BT_HCI_MEMB(addr, len) = sizeof *addr;
+			_BT_HCI_MEMB(addr, family) = AF_BLUETOOTH;
+			if (!PyArg_ParseTuple(args, "s", &straddr)) {
+				PyErr_SetString(socket_error, "getsockaddrarg: "
+						"wrong format");
+				return 0;
+			}
+			strncpy(_BT_HCI_MEMB(addr, node), straddr,
+				sizeof(_BT_HCI_MEMB(addr, node)));
+
+			*len_ret = sizeof *addr;
+			return 1;
+		}
+#else
 		case BTPROTO_SCO:
 		{
 			struct sockaddr_sco *addr;
@@ -1485,7 +1517,11 @@
 		case BTPROTO_RFCOMM:
 			*len_ret = sizeof (struct sockaddr_rc);
 			return 1;
-#if !defined(__FreeBSD__)
+#if defined(__FreeBSD__)
+		case BTPROTO_HCI:
+			*len_ret = sizeof (struct sockaddr_hci);
+			return 1;
+#else
 		case BTPROTO_SCO:
 			*len_ret = sizeof (struct sockaddr_sco);
 			return 1;
@@ -4417,7 +4453,9 @@
 #ifdef USE_BLUETOOTH
 	PyModule_AddIntConstant(m, "AF_BLUETOOTH", AF_BLUETOOTH);
 	PyModule_AddIntConstant(m, "BTPROTO_L2CAP", BTPROTO_L2CAP);
-#if !defined(__FreeBSD__)
+#if defined(__FreeBSD__)
+	PyModule_AddIntConstant(m, "BTPROTO_HCI", BTPROTO_HCI);
+#else
 	PyModule_AddIntConstant(m, "BTPROTO_SCO", BTPROTO_SCO);
 #endif
 	PyModule_AddIntConstant(m, "BTPROTO_RFCOMM", BTPROTO_RFCOMM);
@@ -4461,6 +4499,9 @@
 #ifdef SO_EXCLUSIVEADDRUSE
 	PyModule_AddIntConstant(m, "SO_EXCLUSIVEADDRUSE", SO_EXCLUSIVEADDRUSE);
 #endif
+#ifdef  SO_HCI_RAW_FILTER
+	PyModule_AddIntConstant(m, "SO_HCI_RAW_FILTER", SO_HCI_RAW_FILTER);
+#endif
 
 #ifdef	SO_KEEPALIVE
 	PyModule_AddIntConstant(m, "SO_KEEPALIVE", SO_KEEPALIVE);
@@ -4565,6 +4606,9 @@
 #ifdef	SOL_ATALK
 	PyModule_AddIntConstant(m, "SOL_ATALK", SOL_ATALK);
 #endif
+#ifdef  SOL_HCI_RAW
+	PyModule_AddIntConstant(m, "SOL_HCI_RAW", SOL_HCI_RAW);
+#endif
 #ifdef	SOL_NETROM
 	PyModule_AddIntConstant(m, "SOL_NETROM", SOL_NETROM);
 #endif


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-ports-bugs->python 
Responsible-Changed-By: edwin 
Responsible-Changed-When: Wed Aug 15 04:35:13 UTC 2007 
Responsible-Changed-Why:  
Over to maintainer 

http://www.freebsd.org/cgi/query-pr.cgi?pr=115523 
Responsible-Changed-From-To: python->perky 
Responsible-Changed-By: perky 
Responsible-Changed-When: Wed Aug 15 07:56:53 GMT 2007 
Responsible-Changed-Why:  
I'll handle this. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=115523 
State-Changed-From-To: open->closed 
State-Changed-By: miwi 
State-Changed-When: Fri May 1 14:27:48 UTC 2009 
State-Changed-Why:  
this should be fixed long time ago. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=115523 
>Unformatted:
