pax_global_header00006660000000000000000000000064133461125370014517gustar00rootroot0000000000000052 comment=857c1b3fadbd7e86ebb7072efbfd084cf7a4c198 pybluez-0.22+really0.22/000077500000000000000000000000001334611253700147225ustar00rootroot00000000000000pybluez-0.22+really0.22/CHANGELOG000066400000000000000000000236421334611253700161430ustar00rootroot00000000000000PyBluez CHANGELOG file this file contains a list of changes through the different versions of PyBluez. changes from 0.21 to 0.22(August 05, 2015) ------------------------- GNU/Linux: Features: - experimental support for Bluetooth Low Energy, based on pygattlib implementation Bugs: - l2cap options issue #88 - When cancelling device discovery, DeviceDiscoverer does not call inquiry_complete() #85 - No way to select device id for device discovery #77 - _get_available_port() should try to bind() with a supplied address instead of "" #45 Windows: Bugs: - No adapter detected - WP8.1 #72 - Non-blocking sockets and blocking sockets with a timeout do not work correctly when using WinSock backend #40 - Need to setsockopt in Windows #10 changes from 0.20 to 0.21(Apr 05, 2015) ------------------------- GNU/Linux: Bugs: - No way to select device id for device discovery #77 - RSSI info not passed on by DeviceDiscoverer #74 - Warnings during compilation on linux #73 - python3 UnicodeDecodeError in DeviceDiscoverer find_devices #67 Windows: Bugs: - Problem with iqnuiring unicode names on windows8.1 with python3.4 #76 - warnings during build for windows (ms visual studio 2010 express) #60 changes from 0.19 to 0.20(Jan 13, 2014) ------------------------- GNU/Linux/Windows: Python 3 is now supported. Python 3.3 uses Visual C++ 2010 Express Edition for build on windows. changes from 0.18 to 0.19 ------------------------- Added option to return the class of device in discover_devices() (Lukas Hetzenecker) GNU/Linux: Added setl2capsecurity() method to BluetoothSocket Fixed get_l2cap_options(), set_l2cap_options(), set_l2cap_mtu() Added abovementioned functions as socket methods Added BT_SECURITY_*, L2CAP_MODE_* constants Added support for the "Extended Inquiry Response" event in the asynchronous DeviceDiscoverer (Lukas Hetzenecker) Fixed problems with kernel 3.x windows: Allow threads during the initialization of the inquiry in widcomm (Lukas Hetzenecker) changes from 0.17 to 0.18 (Nov 25, 2009) ---------------------------------------- windows: support Visual C++ 2008 Express Edition for Python 2.6 (this should add support for Windows Vista and Windows 7) (Lukas Hetzenecker) include widcomm/util.h in source distribution changes from 0.16 to 0.17 (Oct 15, 2009) ---------------------------------------- GNU/Linux: bugfix for linux 2.6.30+ zero out struct sockaddr DeviceDiscoverer may specify bluetooth device_id (roelhuybrechts) DeviceDiscoverer do not override duration parameter (roelhuybrechts) changes from 0.15 to 0.16 (Feb 5, 2009) --------------------------------------- fix variable naming in example/simple/inquiry.py (M. Harris Bhatti) windows: only import msbt if widcomm fails fix memory error in MSBT stack widcomm comment out debugging statements GNU/Linux: fix examples to import bluetooth._bluetooth changes from 0.14 to 0.15 (Jan 21, 2008) ---------------------------------------- GNU/Linux: don't hardcode duration in discover_devices() to 8 (Gustavo Chain) win32: search for wbtapi.dll before trying to import widcomm changes from 0.13 to 0.14 (Nov 12, 2007) ---------------------------------------- GNU/Linux: fix device class parsing bug in inquiry-with-rssi (Pepe Aracil) changes from 0.12 to 0.13 (August 30, 2007) ------------------------------------------- GNU/Linux: Oops, stupid bug introduced from last bugfix changes from 0.11 to 0.12 (August 29, 2007) ------------------------------------------- GNU/Linux: fixed _checkaddr bug (reported by Giovanni) changes from 0.10 to 0.11 (August 25, 2007) ------------------------------------------- win32: fixed bug preventing MSBT stack from loading when Widcomm not present changes from 0.9.2 to 0.10 (August 10, 2007) -------------------------------------------- win32: better searching for Platform SDK path (Ren� M�ller) proper Py_{BEGIN,END}_ALLOW_THREADS (Ren� M�ller) added experimental Broadcom/Widcomm support. All the basics should be supported: RFCOMM sockets L2CAP sockets Device Discovery, Name Lookup SDP search on remote devices SDP advertisement (RFCOMM, L2CAP) Widcomm stack notes: 1. BluetoothSocket.accept () always returns 0 for the port, as the RFCOMM channel/L2CAP PSM of the client device is not exposed by the Widcomm API 2. Not all fields of advertise_service are supported. The following parameters are currently not supported: description, protocols 3. The following methods of BluetoothSocket are not supported: gettimeout, dup, makefile, settimeout 4. The following parameters to discover_devices are not supported: duration, flush_cache (cache always flushes) 5. The timeout parameter of lookup_name is not supported 6. Once a listening socket has accepted a connection, it is not put back into listening mode. The original listening socket essentially becomes useless. 7. SDP search/browse operations on the local host are not yet supported GNU/Linux: fix segfault on trying to SDP advertise when sdpd not running (reported by Eric Butler) changes from 0.9.1 to 0.9.2 (Dec 29, 2006) ------------------------------------------ GNU/Linux: fixed endian-ness error in L2CAP psm field. only affects big-endian machines. changes from 0.9 to 0.9.1 (Sep 14, 2006) ---------------------------------------- GNU/Linux: fixed missing #include that prevents PyBluez from compiling with newer version of BlueZ (reported by Priyank Gosalia) changes from 0.8 to 0.9 (Sep 9, 2006) ---------------------------------------- added protocols optional parameter to advertise_service (bluez: Bea Lam) refactor: merged bluez/bluetooth.py and msbt/bluetooth.py GNU/Linux: added _bluetooth.hci_devid (Mikael Lindqvist) added _bluetooth.SCO_OPTIONS constant added Py_{BEGIN,END}_ALLOW_THREADS guards around sdp_connect (spotted by Rostislav Belov) win32: send() now returns the number of bytes sent (spotted by Keith O'Hara) sdp search no longer raises an exception when no records are found and no other error occurred. changes from 0.7.1 to 0.8 (July 31, 2006) ---------------------------------------- win32: added settimeout, gettimeout, setblocking methods (David Conolly) GNU/Linux: fixed DeviceDiscoverer device class byte swap bug (spotted by Bea Lam) changes from 0.7 to 0.7.1 (May 13, 2006) --------------------------------------- win32: discover_devices() no longer raises an IOError when no devices are detected lookup_name() sort of works (consistently on some machines, not at all on others) advertise_service() fully supported changes from 0.6.1 to 0.7 (May 5, 2006) --------------------------------------- - fixed some docstring errors - added lookup_names parameter to discover_devices() If set to True, discover_devices() returns a list of (address, name) pairs. If set to False (default), returns a list of addresses - added constant PORT_ANY. bind to port PORT_ANY for dynamic port assignment. get_available_port() is now deprecated. - added support for Microsoft Windows Bluetooth API. This comes standard on Windows XP SP1, and Windows Vista. The following features are supported: RFCOMM sockets (bind, listen, connect, accept, send, recv, close, getsockname, fileno) discover_devices() find_service() advertise_service() - with limitations. See code for details The following features are not yet supported in Windows XP: DeviceDiscoverer class lookup_name() changes from 0.6 to 0.6.1 (Feb 24, 2006) ---------------------------------------- fixed UUID parsing again (byte swap error) added parsing of 32-bit reserved UUIDs fixed rfcomm-client and rfcomm-server examples to use the same UUID addded service-id to find_service result changes from 0.5 to 0.6 (Feb 18, 2006) -------------------------------------- fixed examples/basic/l2-mtu.py [sock -> client_sock] fixed hci_send_req [keywords bug] fixed UUID parsing (Cezar S Espinola) changes from 0.4 to 0.5 (Dec 16, 2005) -------------------------------------- added service-classes and profiles keys to find_service result added service class list and profile list support to advertise_service (Elvis Pf zenreuter) fixed do_search response_list (Richard Moore) BluetoothError now inherits from IOError (Elvis Pf�tzenreuter) added CHANGELOG added COPYING changes from 0.3 to 0.4 (Nov 9, 2005) ------------------------------------- fixed DeviceDiscoverer name request parsing (Alastair Tre) fixed set_l2cap_mtu bluetooth module error (simo salminen) changes from 0.2 to 0.3 (Sep 20, 2005) -------------------------------------- fixed invalid free() in bt_hci_inquiry (ted wright) fixed endian error for RFCOMM sockets (Ted Wright) no longer using SDP_RECORD_PERSIST changes from 0.1 to 0.2 (Apr 4, 2005) ------------------------------------- Support for SDP service advertisement and searching added. Support for easy asynchronous device discovery added (DeviceDiscoverer). fixed hci_send_req. added a bunch of constants for ioctl on hci sockets renamed most things from bluez* to bt* or bluetooth* changed module name from bluez to _bluetooth changed bluezsocket to btsocket New API is incompatible with 0.1. version 0.1 (Dec 16, 2004) -------------------------- Support for HCI, L2CAP, and RFCOMM sockets. No support for OBEX or SDP. pybluez-0.22+really0.22/COPYING000066400000000000000000000431051334611253700157600ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. pybluez-0.22+really0.22/MANIFEST.in000066400000000000000000000007241334611253700164630ustar00rootroot00000000000000include CHANGELOG include COPYING include README include setup.py recursive-include bluetooth *.py recursive-include bluez *.c recursive-include bluez *.h recursive-include msbt *.c recursive-include widcomm *.cpp recursive-include widcomm *.hpp recursive-include widcomm *.h recursive-include osx *.c recursive-include osx *.h recursive-include port3 *.h recursive-include examples *.py recursive-exclude * *.pyc recursive-exclude * *.o recursive-exclude * *.opp pybluez-0.22+really0.22/README000066400000000000000000000043141334611253700156040ustar00rootroot00000000000000PyBluez Python extension module allowing access to system Bluetooth resources. https://github.com/karulis/pybluez BUILD REQUIREMENTS: GNU/Linux: - Python 2.3 or more recent version - Python distutils (standard in most Python distros, separate package python-dev in Debian) - BlueZ libraries and header files Windows: - Microsoft Windows XP SP1 or Windows Vista/7/8/8.1 - Visual C++ 2010 Express for build for Python 3.3 or newer - Visual C++ 2008 Express for build for Python 3.2 or older - In order to build 64-bit debug and release executables, Visual Studio 2008/2010 Standard Edition is required - Widcomm BTW development kit 5.0 or later (Optional) - Python 2.3 or more recent version INSTALLATION: from a command shell: # python setup.py install EXAMPLES: GNU/Linux and Windows XP: # examples/simple/inquiry.py - Detecting nearby Bluetooth devices # examples/simple/sdp-browse.py - Browsing SDP services on a Bluetooth device # examples/simple/rfcomm-server.py - establishing an RFCOMM connection. # examples/simple/rfcomm-client.py - establishing an RFCOMM connection. GNU/Linux only: # exmaples/simple/l2capserver.py # exmaples/simple/l2capclient.py # examples/simple/asynchronous-inquiry.py # examples/bluezchat (requires PyGTK) # examples/advanced/inquiry-with-rssi.py # examples/l2-unreliable-server.py # examples/l2-unreliable-client.py CONTACT: Please use the mailing list at http://groups.google.com/group/pybluez/ LICENSE: PyBluez is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. PyBluez is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PyBluez; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA pybluez-0.22+really0.22/README.rst000066400000000000000000000120621334611253700164120ustar00rootroot00000000000000================== PyBluez ================== Python extension module allowing access to system Bluetooth resources. https://github.com/karulis/pybluez **EXAMPLES:** .. code-block:: python # simple inquiry example import bluetooth nearby_devices = bluetooth.discover_devices(lookup_names=True) print("found %d devices" % len(nearby_devices)) for addr, name in nearby_devices: print(" %s - %s" % (addr, name)) .. code-block:: python # bluetooth low energy scan from bluetooth.ble import DiscoveryService service = DiscoveryService() devices = service.discover(2) for address, name in devices.items(): print("name: {}, address: {}".format(name, address)) *GNU/Linux and Windows XP examples:* - `examples/simple/inquiry.py`_ - Detecting nearby Bluetooth devices - `examples/simple/sdp-browse.py`_ - Browsing SDP services on a Bluetooth device. - `examples/simple/rfcomm-server.py`_ - establishing an RFCOMM connection. - `examples/simple/rfcomm-client.py`_ - establishing an RFCOMM connection. *GNU/Linux only examples:* - `examples/simple/l2capserver.py`_ - `examples/simple/l2capclient.py`_ - `examples/simple/asynchronous-inquiry.py`_ - `examples/bluezchat`_ - `examples/advanced/inquiry-with-rssi.py`_ - `examples/advanced/l2-unreliable-server.py`_ - `examples/advanced/l2-unreliable-client.py`_ *GNU/Linux experimental BLE support:* - `examples/ble/scan.py`_ - `examples/ble/beacon.py`_ - `examples/ble/beacon_scan.py`_ - `examples/ble/read_name.py`_ **CONTACT:** Please use the mailing list at http://groups.google.com/group/pybluez/ **INSTALLATION:** Use pip(there are also binaries for Windows platform on PyPi): pip install pybluez For experimental Bluetooth Low Energy support(only for Linux platform - for additional dependencies please take look at: `ble-dependencies`_): pip install pybluez[ble] For source installation: python setup.py install for Bluetooth Low Energy support: pip install -e .[ble] **BUILD REQUIREMENTS:** *GNU/Linux:* - Python 2.3 or more recent version - Python distutils (standard in most Python distros, separate package python-dev in Debian) - BlueZ libraries and header files *Windows:* - Microsoft Windows XP SP1 or Windows Vista/7/8/8.1 - Visual C++ 2010 Express for build for Python 3.3 or newer - Visual C++ 2008 Express for build for Python 3.2 or older - In order to build 64-bit debug and release executables, Visual Studio 2008/2010 Standard Edition is required - Widcomm BTW development kit 5.0 or later (Optional) - Python 2.3 or more recent version **LICENSE:** PyBluez is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. PyBluez is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with PyBluez; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA .. _examples/simple/inquiry.py: https://github.com/karulis/pybluez/blob/master/examples/simple/inquiry.py .. _examples/simple/sdp-browse.py: https://github.com/karulis/pybluez/blob/master/examples/simple/sdp-browse.py .. _examples/simple/rfcomm-server.py: https://github.com/karulis/pybluez/blob/master/examples/simple/rfcomm-server.py .. _examples/simple/rfcomm-client.py: https://github.com/karulis/pybluez/blob/master/examples/simple/rfcomm-client.py .. _examples/simple/l2capserver.py: https://github.com/karulis/pybluez/blob/master/examples/simple/l2capserver.py .. _examples/simple/l2capclient.py: https://github.com/karulis/pybluez/blob/master/examples/simple/l2capclient.py .. _examples/simple/asynchronous-inquiry.py: https://github.com/karulis/pybluez/blob/master/examples/simple/asynchronous-inquiry.py .. _examples/bluezchat: https://github.com/karulis/pybluez/blob/master/examples/bluezchat .. _examples/advanced/inquiry-with-rssi.py: https://github.com/karulis/pybluez/blob/master/examples/advanced/inquiry-with-rssi.py .. _examples/advanced/l2-unreliable-server.py: https://github.com/karulis/pybluez/blob/master/examples/advanced/l2-unreliable-server.py .. _examples/advanced/l2-unreliable-client.py: https://github.com/karulis/pybluez/blob/master/examples/advanced/l2-unreliable-client.py .. _examples/ble/scan.py: https://github.com/karulis/pybluez/blob/master/examples/ble/scan.py .. _examples/ble/beacon.py: https://github.com/karulis/pybluez/blob/master/examples/ble/beacon.py .. _examples/ble/beacon_scan.py: https://github.com/karulis/pybluez/blob/master/examples/ble/beacon_scan.py .. _examples/ble/read_name.py: https://github.com/karulis/pybluez/blob/master/examples/ble/read_name.py .. _ble-dependencies: https://bitbucket.org/OscarAcena/pygattlib/src/45e04060881a20189412681f52d55ff5add9f388/DEPENDS?at=defaultpybluez-0.22+really0.22/bluetooth/000077500000000000000000000000001334611253700167275ustar00rootroot00000000000000pybluez-0.22+really0.22/bluetooth/__init__.py000066400000000000000000000135471334611253700210520ustar00rootroot00000000000000import sys import os if sys.version < '3': from .btcommon import * else: from bluetooth.btcommon import * __version__ = 0.22 def _dbg(*args): return sys.stderr.write(*args) sys.stderr.write("\n") if sys.platform == "win32": _dbg("trying widcomm") have_widcomm = False dll = "wbtapi.dll" sysroot = os.getenv ("SystemRoot") if os.path.exists (dll) or \ os.path.exists (os.path.join (sysroot, "system32", dll)) or \ os.path.exists (os.path.join (sysroot, dll)): try: from . import widcomm if widcomm.inquirer.is_device_ready (): # if the Widcomm stack is active and a Bluetooth device on that # stack is detected, then use the Widcomm stack from .widcomm import * have_widcomm = True except ImportError: pass if not have_widcomm: # otherwise, fall back to the Microsoft stack _dbg("Widcomm not ready. falling back to MS stack") if sys.version < '3': from .msbt import * else: from bluetooth.msbt import * elif sys.platform.startswith("linux"): if sys.version < '3': from .bluez import * else: from bluetooth.bluez import * elif sys.platform == "darwin": from .osx import * else: raise Exception("This platform (%s) is currently not supported by pybluez." % sys.platform) discover_devices.__doc__ = \ """ performs a bluetooth device discovery using the first available bluetooth resource. if lookup_names is False, returns a list of bluetooth addresses. if lookup_names is True, returns a list of (address, name) tuples lookup_names=False if set to True, then discover_devices also attempts to lookup the display name of each detected device. if lookup_class is True, the class of the device is added to the tuple """ lookup_name.__doc__ = \ """ Tries to determine the friendly name (human readable) of the device with the specified bluetooth address. Returns the name on success, and None on failure. """ advertise_service.__doc__ = \ """ Advertises a service with the local SDP server. sock must be a bound, listening socket. name should be the name of the service, and service_id (if specified) should be a string of the form "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", where each 'X' is a hexadecimal digit. service_classes is a list of service classes whose this service belongs to. Each class service is a 16-bit UUID in the form "XXXX", where each 'X' is a hexadecimal digit, or a 128-bit UUID in the form "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX". There are some constants for standard services, e.g. SERIAL_PORT_CLASS that equals to "1101". Some class constants: SERIAL_PORT_CLASS LAN_ACCESS_CLASS DIALUP_NET_CLASS HEADSET_CLASS CORDLESS_TELEPHONY_CLASS AUDIO_SOURCE_CLASS AUDIO_SINK_CLASS PANU_CLASS NAP_CLASS GN_CLASS profiles is a list of service profiles that thie service fulfills. Each profile is a tuple with ( uuid, version). Most standard profiles use standard classes as UUIDs. PyBluez offers a list of standard profiles, for example SERIAL_PORT_PROFILE. All standard profiles have the same name as the classes, except that _CLASS suffix is replaced by _PROFILE. provider is a text string specifying the provider of the service description is a text string describing the service A note on working with Symbian smartphones: bt_discover in Python for Series 60 will only detect service records with service class SERIAL_PORT_CLASS and profile SERIAL_PORT_PROFILE """ stop_advertising.__doc__ = \ """ Instructs the local SDP server to stop advertising the service associated with sock. You should typically call this right before you close sock. """ find_service.__doc__ = \ """ find_service (name = None, uuid = None, address = None) Searches for SDP services that match the specified criteria and returns the search results. If no criteria are specified, then returns a list of all nearby services detected. If more than one is specified, then the search results will match all the criteria specified. If uuid is specified, it must be either a 16-bit UUID in the form "XXXX", where each 'X' is a hexadecimal digit, or as a 128-bit UUID in the form "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX". A special case of address is "localhost", which will search for services on the local machine. The search results will be a list of dictionaries. Each dictionary represents a search match and will have the following key/value pairs: host - the bluetooth address of the device advertising the service name - the name of the service being advertised description - a description of the service being advertised provider - the name of the person/organization providing the service protocol - either 'RFCOMM', 'L2CAP', None if the protocol was not specified, or 'UNKNOWN' if the protocol was specified but unrecognized port - the L2CAP PSM # if the protocol is 'L2CAP', the RFCOMM channel # if the protocol is 'RFCOMM', or None if it wasn't specified service-classes - a list of service class IDs (UUID strings). possibly empty profiles - a list of profiles - (UUID, version) pairs - the service claims to support. possibly empty. service-id - the Service ID of the service. None if it wasn't set See the Bluetooth spec for the difference between Service ID and Service Class ID List """ pybluez-0.22+really0.22/bluetooth/ble.py000066400000000000000000000000271334611253700200420ustar00rootroot00000000000000from gattlib import * pybluez-0.22+really0.22/bluetooth/bluez.py000066400000000000000000000554121334611253700204310ustar00rootroot00000000000000import sys import struct if sys.version < '3': from .btcommon import * import _bluetooth as _bt get_byte = ord else: from bluetooth.btcommon import * import bluetooth._bluetooth as _bt get_byte = int import array import fcntl _constants = [ 'HCI', 'RFCOMM', 'L2CAP', 'SCO', 'SOL_L2CAP', 'SOL_RFCOMM',\ 'L2CAP_OPTIONS' ] for _c in _constants: command_ = "{C} = _bt.{C1}".format(C=_c, C1=_c) exec(command_) del _constants # ============== SDP service registration and unregistration ============ def discover_devices (duration=8, flush_cache=True, lookup_names=False, lookup_class=False, device_id=-1): if device_id == -1: device_id = _bt.hci_get_route() sock = _gethcisock (device_id) try: results = _bt.hci_inquiry (sock, duration=duration, flush_cache=True, lookup_class=lookup_class, device_id=device_id) except _bt.error: sock.close () raise BluetoothError ("error communicating with local " "bluetooth adapter") if lookup_names: pairs = [] for item in results: if lookup_class: addr, dev_class = item else: addr = item timeoutms = int (10 * 1000) try: name = _bt.hci_read_remote_name (sock, addr, timeoutms) except _bt.error: # name lookup failed. either a timeout, or I/O error continue pairs.append ((addr, name, dev_class) if lookup_class else (addr, name)) sock.close () return pairs else: sock.close () return results def lookup_name (address, timeout=10): if not is_valid_address (address): raise BluetoothError ("%s is not a valid Bluetooth address" % address) sock = _gethcisock () timeoutms = int (timeout * 1000) try: name = _bt.hci_read_remote_name (sock, address, timeoutms) except _bt.error: # name lookup failed. either a timeout, or I/O error name = None sock.close () return name def set_packet_timeout (address, timeout): """ Adjusts the ACL flush timeout for the ACL connection to the specified device. This means that all L2CAP and RFCOMM data being sent to that device will be dropped if not acknowledged in timeout milliseconds (maximum 1280). A timeout of 0 means to never drop packets. Since this affects all Bluetooth connections to that device, and not just those initiated by this process or PyBluez, a call to this method requires superuser privileges. You must have an active connection to the specified device before invoking this method """ n = round (timeout / 0.625) write_flush_timeout (address, n) def get_l2cap_options (sock): """get_l2cap_options (sock, mtu) Gets L2CAP options for the specified L2CAP socket. Options are: omtu, imtu, flush_to, mode, fcs, max_tx, txwin_size. """ # TODO this should be in the C module, because it depends # directly on struct l2cap_options layout. s = sock.getsockopt (SOL_L2CAP, L2CAP_OPTIONS, 12) options = list( struct.unpack ("HHHBBBH", s)) return options def set_l2cap_options (sock, options): """set_l2cap_options (sock, options) Sets L2CAP options for the specified L2CAP socket. The option list must be in the same format supplied by get_l2cap_options(). """ # TODO this should be in the C module, because it depends # directly on struct l2cap_options layout. s = struct.pack ("HHHBBBH", *options) sock.setsockopt (SOL_L2CAP, L2CAP_OPTIONS, s) def set_l2cap_mtu (sock, mtu): """set_l2cap_mtu (sock, mtu) Adjusts the MTU for the specified L2CAP socket. This method needs to be invoked on both sides of the connection for it to work! The default mtu that all L2CAP connections start with is 672 bytes. mtu must be between 48 and 65535, inclusive. """ options = get_l2cap_options (sock) options[0] = options[1] = mtu set_l2cap_options (sock, options) def _get_available_port (protocol, addr=""): """ deprecated. bind to PORT_ANY instead. """ if protocol == RFCOMM: for channel in range (1,31): s = BluetoothSocket (RFCOMM) try: s.bind ( (addr, channel)) s.close () return channel except: s.close () elif protocol == L2CAP: for psm in range (0x1001,0x8000,2): s = BluetoothSocket (L2CAP) try: s.bind ( (addr, psm)) s.close () return psm except: s.close () else: raise ValueError ("protocol must either RFCOMM or L2CAP") class BluetoothSocket: __doc__ = _bt.btsocket.__doc__ def __init__ (self, proto = RFCOMM, _sock=None): if _sock is None: _sock = _bt.btsocket (proto) self._sock = _sock self._proto = proto def dup (self): """dup () -> socket object Return a new socket object connected to the same system resource.""" return BluetoothSocket (proto=self._proto, _sock=self._sock) def accept (self): try: client, addr = self._sock.accept () except _bt.error as e: raise BluetoothError (str (e)) newsock = BluetoothSocket (self._proto, client) return (newsock, addr) accept.__doc__ = _bt.btsocket.accept.__doc__ def bind (self, addrport): if self._proto == RFCOMM or self._proto == L2CAP: addr, port = addrport if port == 0: addrport = (addr, _get_available_port (self._proto, addr)) return self._sock.bind (addrport) def get_l2cap_options(self): """get_l2cap_options (sock, mtu) Gets L2CAP options for the specified L2CAP socket. Options are: omtu, imtu, flush_to, mode, fcs, max_tx, txwin_size. """ return get_l2cap_options(self) def set_l2cap_options(self, options): """set_l2cap_options (sock, options) Sets L2CAP options for the specified L2CAP socket. The option list must be in the same format supplied by get_l2cap_options(). """ return set_l2cap_options(self, options) def set_l2cap_mtu(self, mtu): """set_l2cap_mtu (sock, mtu) Adjusts the MTU for the specified L2CAP socket. This method needs to be invoked on both sides of the connection for it to work! The default mtu that all L2CAP connections start with is 672 bytes. mtu must be between 48 and 65535, inclusive. """ return set_l2cap_mtu(self, mtu) # import methods from the wraapped socket object _s = ("""def %s (self, *args, **kwargs): try: return self._sock.%s (*args, **kwargs) except _bt.error as e: raise BluetoothError (str (e)) %s.__doc__ = _bt.btsocket.%s.__doc__\n""") for _m in ( 'connect', 'connect_ex', 'close', 'fileno', 'getpeername', 'getsockname', 'gettimeout', 'getsockopt', 'listen', 'makefile', 'recv', 'recvfrom', 'sendall', 'send', 'sendto', 'setblocking', 'setsockopt', 'settimeout', 'shutdown', 'setl2capsecurity'): exec( _s % (_m, _m, _m, _m)) del _m, _s def advertise_service (sock, name, service_id = "", service_classes = [], \ profiles = [], provider = "", description = "", protocols = []): if service_id != "" and not is_valid_uuid (service_id): raise ValueError ("invalid UUID specified for service_id") for uuid in service_classes: if not is_valid_uuid (uuid): raise ValueError ("invalid UUID specified in service_classes") for uuid, version in profiles: if not is_valid_uuid (uuid) or version < 0 or version > 0xFFFF: raise ValueError ("Invalid Profile Descriptor") for uuid in protocols: if not is_valid_uuid (uuid): raise ValueError ("invalid UUID specified in protocols") try: _bt.sdp_advertise_service (sock._sock, name, service_id, \ service_classes, profiles, provider, description, \ protocols) except _bt.error as e: raise BluetoothError (str (e)) def stop_advertising (sock): try: _bt.sdp_stop_advertising (sock._sock) except _bt.error as e: raise BluetoothError (str (e)) def find_service (name = None, uuid = None, address = None): if not address: devices = discover_devices () else: devices = [ address ] results = [] if uuid is not None and not is_valid_uuid (uuid): raise ValueError ("invalid UUID") try: for addr in devices: try: s = _bt.SDPSession () s.connect (addr) matches = [] if uuid is not None: matches = s.search (uuid) else: matches = s.browse () except _bt.error: continue if name is not None: matches = [s for s in matches if s.get ("name", "") == name] for m in matches: m["host"] = addr results.extend (matches) except _bt.error as e: raise BluetoothError (str (e)) return results # ================ BlueZ internal methods ================ def _gethcisock (device_id = -1): try: sock = _bt.hci_open_dev (device_id) except: raise BluetoothError ("error accessing bluetooth device") return sock def get_acl_conn_handle (hci_sock, addr): hci_fd = hci_sock.fileno () reqstr = struct.pack ("6sB17s", _bt.str2ba (addr), _bt.ACL_LINK, b"\0" * 17) request = array.array ("b", reqstr) try: fcntl.ioctl (hci_fd, _bt.HCIGETCONNINFO, request, 1) except IOError: raise BluetoothError ("There is no ACL connection to %s" % addr) # XXX should this be "<8xH14x"? handle = struct.unpack ("8xH14x", request.tostring ())[0] return handle def write_flush_timeout (addr, timeout): hci_sock = _bt.hci_open_dev () # get the ACL connection handle to the remote device handle = get_acl_conn_handle (hci_sock, addr) # XXX should this be " 127: return byte_ - 256 else: return byte_ class DeviceDiscoverer: """ Skeleton class for finer control of the device discovery process. To implement asynchronous device discovery (e.g. if you want to do something *as soon as* a device is discovered), subclass DeviceDiscoverer and override device_discovered () and inquiry_complete () """ def __init__ (self, device_id=-1): """ __init__ (device_id=-1) device_id - The ID of the Bluetooth adapter that will be used for discovery. """ self.sock = None self.is_inquiring = False self.lookup_names = False self.device_id = device_id self.names_to_find = {} self.names_found = {} def find_devices (self, lookup_names=True, duration=8, flush_cache=True): """ find_devices (lookup_names=True, service_name=None, duration=8, flush_cache=True) Call this method to initiate the device discovery process lookup_names - set to True if you want to lookup the user-friendly names for each device found. service_name - set to the name of a service you're looking for. only devices with a service of this name will be returned in device_discovered () NOT YET IMPLEMENTED ADVANCED PARAMETERS: (don't change these unless you know what you're doing) duration - the number of 1.2 second units to spend searching for bluetooth devices. If lookup_names is True, then the inquiry process can take a lot longer. flush_cache - return devices discovered in previous inquiries """ if self.is_inquiring: raise BluetoothError ("Already inquiring!") self.lookup_names = lookup_names self.sock = _gethcisock (self.device_id) flt = _bt.hci_filter_new () _bt.hci_filter_all_events (flt) _bt.hci_filter_set_ptype (flt, _bt.HCI_EVENT_PKT) try: self.sock.setsockopt (_bt.SOL_HCI, _bt.HCI_FILTER, flt) except: raise BluetoothError ("problem with local bluetooth device.") # send the inquiry command max_responses = 255 cmd_pkt = struct.pack ("BBBBB", 0x33, 0x8b, 0x9e, \ duration, max_responses) self.pre_inquiry () try: _bt.hci_send_cmd (self.sock, _bt.OGF_LINK_CTL, \ _bt.OCF_INQUIRY, cmd_pkt) except: raise BluetoothError ("problem with local bluetooth device.") self.is_inquiring = True self.names_to_find = {} self.names_found = {} def cancel_inquiry (self): """ Call this method to cancel an inquiry in process. inquiry_complete will still be called. """ self.names_to_find = {} if self.is_inquiring: try: _bt.hci_send_cmd (self.sock, _bt.OGF_LINK_CTL, \ _bt.OCF_INQUIRY_CANCEL) except: self.sock.close () self.sock = None raise BluetoothError ("error canceling inquiry") self.is_inquiring = False def process_inquiry (self): """ Repeatedly calls process_event () until the device inquiry has completed. """ while self.is_inquiring or len (self.names_to_find) > 0: self.process_event () def process_event (self): """ Waits for one event to happen, and proceses it. The event will be either a device discovery, or an inquiry completion. """ self._process_hci_event () def _process_hci_event (self): if self.sock is None: return # voodoo magic!!! pkt = self.sock.recv (258) ptype, event, plen = struct.unpack ("BBB", pkt[:3]) pkt = pkt[3:] if event == _bt.EVT_INQUIRY_RESULT: nrsp = get_byte(pkt[0]) for i in range (nrsp): addr = _bt.ba2str (pkt[1+6*i:1+6*i+6]) psrm = pkt[ 1+6*nrsp+i ] pspm = pkt[ 1+7*nrsp+i ] devclass_raw = struct.unpack ("BBB", pkt[1+9*nrsp+3*i:1+9*nrsp+3*i+3]) devclass = (devclass_raw[2] << 16) | \ (devclass_raw[1] << 8) | \ devclass_raw[0] clockoff = pkt[1+12*nrsp+2*i:1+12*nrsp+2*i+2] self._device_discovered (addr, devclass, psrm, pspm, clockoff, None, None) elif event == _bt.EVT_INQUIRY_RESULT_WITH_RSSI: nrsp = get_byte(pkt[0]) for i in range (nrsp): addr = _bt.ba2str (pkt[1+6*i:1+6*i+6]) psrm = pkt[ 1+6*nrsp+i ] pspm = pkt[ 1+7*nrsp+i ] # devclass_raw = pkt[1+8*nrsp+3*i:1+8*nrsp+3*i+3] # devclass = struct.unpack ("I", "%s\0" % devclass_raw)[0] devclass_raw = struct.unpack ("BBB", pkt[1+8*nrsp+3*i:1+8*nrsp+3*i+3]) devclass = (devclass_raw[2] << 16) | \ (devclass_raw[1] << 8) | \ devclass_raw[0] clockoff = pkt[1+11*nrsp+2*i:1+11*nrsp+2*i+2] rssi = byte_to_signed_int(get_byte(pkt[1+13*nrsp+i])) self._device_discovered (addr, devclass, psrm, pspm, clockoff, rssi, None) elif _bt.HAVE_EVT_EXTENDED_INQUIRY_RESULT and event == _bt.EVT_EXTENDED_INQUIRY_RESULT: nrsp = get_byte(pkt[0]) for i in range (nrsp): addr = _bt.ba2str (pkt[1+6*i:1+6*i+6]) psrm = pkt[ 1+6*nrsp+i ] pspm = pkt[ 1+7*nrsp+i ] devclass_raw = struct.unpack ("BBB", pkt[1+8*nrsp+3*i:1+8*nrsp+3*i+3]) devclass = (devclass_raw[2] << 16) | \ (devclass_raw[1] << 8) | \ devclass_raw[0] clockoff = pkt[1+11*nrsp+2*i:1+11*nrsp+2*i+2] rssi = byte_to_signed_int(get_byte(pkt[1+13*nrsp+i])) data_len = _bt.EXTENDED_INQUIRY_INFO_SIZE - _bt.INQUIRY_INFO_WITH_RSSI_SIZE data = pkt[1+14*nrsp+i:1+14*nrsp+i+data_len] name = None pos = 0 while(pos <= len(data)): struct_len = get_byte(data[pos]) if struct_len == 0: break eir_type = get_byte(data[pos+1]) if eir_type == 0x09: # Complete local name name = data[pos+2:pos+struct_len+1] pos += struct_len + 2 self._device_discovered (addr, devclass, psrm, pspm, clockoff, rssi, name) elif event == _bt.EVT_INQUIRY_COMPLETE or event == _bt.EVT_CMD_COMPLETE: self.is_inquiring = False if len (self.names_to_find) == 0: # print "inquiry complete (evt_inquiry_complete)" self.sock.close () self._inquiry_complete () else: self._send_next_name_req () elif event == _bt.EVT_CMD_STATUS: # XXX shold this be " 0 address = list(self.names_to_find.keys ())[0] device_class, rssi, psrm, pspm, clockoff = self.names_to_find[address] bdaddr = _bt.str2ba (address) #TODO not supported in python3 cmd_pkt = "%s%s\0%s" % (bdaddr, psrm, clockoff) try: _bt.hci_send_cmd (self.sock, _bt.OGF_LINK_CTL, \ _bt.OCF_REMOTE_NAME_REQ, cmd_pkt) except Exception as e: raise BluetoothError ("error request name of %s - %s" % (address, str (e))) def fileno (self): if not self.sock: return None return self.sock.fileno () def pre_inquiry (self): """ Called just after find_devices is invoked, but just before the inquiry is started. This method exists to be overriden """ def device_discovered (self, address, device_class, rssi, name): """ Called when a bluetooth device is discovered. address is the bluetooth address of the device device_class is the Class of Device, as specified in [1] passed in as a 3-byte string name is the user-friendly name of the device if lookup_names was set when the inquiry was started. otherwise None This method exists to be overriden. [1] https://www.bluetooth.org/foundry/assignnumb/document/baseband """ if name: print(("found: %s - %s (class 0x%X, rssi %s)" % \ (address, name, device_class, rssi))) else: print(("found: %s (class 0x%X)" % (address, device_class))) print(("found: %s (class 0x%X, rssi %s)" % \ (address, device_class, rssi))) def _inquiry_complete (self): """ Called when an inquiry started by find_devices has completed. """ self.sock.close () self.sock = None self.inquiry_complete() def inquiry_complete (self): """ Called when an inquiry started by find_devices has completed. """ print("inquiry complete") pybluez-0.22+really0.22/bluetooth/btcommon.py000066400000000000000000000320371334611253700211240ustar00rootroot00000000000000import sys import struct import binascii L2CAP=0 RFCOMM=3 PORT_ANY=0 # Service Class IDs SDP_SERVER_CLASS = "1000" BROWSE_GRP_DESC_CLASS = "1001" PUBLIC_BROWSE_GROUP = "1002" SERIAL_PORT_CLASS = "1101" LAN_ACCESS_CLASS = "1102" DIALUP_NET_CLASS = "1103" IRMC_SYNC_CLASS = "1104" OBEX_OBJPUSH_CLASS = "1105" OBEX_FILETRANS_CLASS = "1106" IRMC_SYNC_CMD_CLASS = "1107" HEADSET_CLASS = "1108" CORDLESS_TELEPHONY_CLASS = "1109" AUDIO_SOURCE_CLASS = "110a" AUDIO_SINK_CLASS = "110b" AV_REMOTE_TARGET_CLASS = "110c" ADVANCED_AUDIO_CLASS = "110d" AV_REMOTE_CLASS = "110e" VIDEO_CONF_CLASS = "110f" INTERCOM_CLASS = "1110" FAX_CLASS = "1111" HEADSET_AGW_CLASS = "1112" WAP_CLASS = "1113" WAP_CLIENT_CLASS = "1114" PANU_CLASS = "1115" NAP_CLASS = "1116" GN_CLASS = "1117" DIRECT_PRINTING_CLASS = "1118" REFERENCE_PRINTING_CLASS = "1119" IMAGING_CLASS = "111a" IMAGING_RESPONDER_CLASS = "111b" IMAGING_ARCHIVE_CLASS = "111c" IMAGING_REFOBJS_CLASS = "111d" HANDSFREE_CLASS = "111e" HANDSFREE_AGW_CLASS = "111f" DIRECT_PRT_REFOBJS_CLASS = "1120" REFLECTED_UI_CLASS = "1121" BASIC_PRINTING_CLASS = "1122" PRINTING_STATUS_CLASS = "1123" HID_CLASS = "1124" HCR_CLASS = "1125" HCR_PRINT_CLASS = "1126" HCR_SCAN_CLASS = "1127" CIP_CLASS = "1128" VIDEO_CONF_GW_CLASS = "1129" UDI_MT_CLASS = "112a" UDI_TA_CLASS = "112b" AV_CLASS = "112c" SAP_CLASS = "112d" PNP_INFO_CLASS = "1200" GENERIC_NETWORKING_CLASS = "1201" GENERIC_FILETRANS_CLASS = "1202" GENERIC_AUDIO_CLASS = "1203" GENERIC_TELEPHONY_CLASS = "1204" UPNP_CLASS = "1205" UPNP_IP_CLASS = "1206" UPNP_PAN_CLASS = "1300" UPNP_LAP_CLASS = "1301" UPNP_L2CAP_CLASS = "1302" VIDEO_SOURCE_CLASS = "1303" VIDEO_SINK_CLASS = "1304" # Bluetooth Profile Descriptors SDP_SERVER_PROFILE = ( SDP_SERVER_CLASS, 0x0100) BROWSE_GRP_DESC_PROFILE = ( BROWSE_GRP_DESC_CLASS, 0x0100) SERIAL_PORT_PROFILE = ( SERIAL_PORT_CLASS, 0x0100) LAN_ACCESS_PROFILE = ( LAN_ACCESS_CLASS, 0x0100) DIALUP_NET_PROFILE = ( DIALUP_NET_CLASS, 0x0100) IRMC_SYNC_PROFILE = ( IRMC_SYNC_CLASS, 0x0100) OBEX_OBJPUSH_PROFILE = ( OBEX_OBJPUSH_CLASS, 0x0100) OBEX_FILETRANS_PROFILE = ( OBEX_FILETRANS_CLASS, 0x0100) IRMC_SYNC_CMD_PROFILE = ( IRMC_SYNC_CMD_CLASS, 0x0100) HEADSET_PROFILE = ( HEADSET_CLASS, 0x0100) CORDLESS_TELEPHONY_PROFILE = ( CORDLESS_TELEPHONY_CLASS, 0x0100) AUDIO_SOURCE_PROFILE = ( AUDIO_SOURCE_CLASS, 0x0100) AUDIO_SINK_PROFILE = ( AUDIO_SINK_CLASS, 0x0100) AV_REMOTE_TARGET_PROFILE = ( AV_REMOTE_TARGET_CLASS, 0x0100) ADVANCED_AUDIO_PROFILE = ( ADVANCED_AUDIO_CLASS, 0x0100) AV_REMOTE_PROFILE = ( AV_REMOTE_CLASS, 0x0100) VIDEO_CONF_PROFILE = ( VIDEO_CONF_CLASS, 0x0100) INTERCOM_PROFILE = ( INTERCOM_CLASS, 0x0100) FAX_PROFILE = ( FAX_CLASS, 0x0100) HEADSET_AGW_PROFILE = ( HEADSET_AGW_CLASS, 0x0100) WAP_PROFILE = ( WAP_CLASS, 0x0100) WAP_CLIENT_PROFILE = ( WAP_CLIENT_CLASS, 0x0100) PANU_PROFILE = ( PANU_CLASS, 0x0100) NAP_PROFILE = ( NAP_CLASS, 0x0100) GN_PROFILE = ( GN_CLASS, 0x0100) DIRECT_PRINTING_PROFILE = ( DIRECT_PRINTING_CLASS, 0x0100) REFERENCE_PRINTING_PROFILE = ( REFERENCE_PRINTING_CLASS, 0x0100) IMAGING_PROFILE = ( IMAGING_CLASS, 0x0100) IMAGING_RESPONDER_PROFILE = ( IMAGING_RESPONDER_CLASS, 0x0100) IMAGING_ARCHIVE_PROFILE = ( IMAGING_ARCHIVE_CLASS, 0x0100) IMAGING_REFOBJS_PROFILE = ( IMAGING_REFOBJS_CLASS, 0x0100) HANDSFREE_PROFILE = ( HANDSFREE_CLASS, 0x0100) HANDSFREE_AGW_PROFILE = ( HANDSFREE_AGW_CLASS, 0x0100) DIRECT_PRT_REFOBJS_PROFILE = ( DIRECT_PRT_REFOBJS_CLASS, 0x0100) REFLECTED_UI_PROFILE = ( REFLECTED_UI_CLASS, 0x0100) BASIC_PRINTING_PROFILE = ( BASIC_PRINTING_CLASS, 0x0100) PRINTING_STATUS_PROFILE = ( PRINTING_STATUS_CLASS, 0x0100) HID_PROFILE = ( HID_CLASS, 0x0100) HCR_PROFILE = ( HCR_SCAN_CLASS, 0x0100) HCR_PRINT_PROFILE = ( HCR_PRINT_CLASS, 0x0100) HCR_SCAN_PROFILE = ( HCR_SCAN_CLASS, 0x0100) CIP_PROFILE = ( CIP_CLASS, 0x0100) VIDEO_CONF_GW_PROFILE = ( VIDEO_CONF_GW_CLASS, 0x0100) UDI_MT_PROFILE = ( UDI_MT_CLASS, 0x0100) UDI_TA_PROFILE = ( UDI_TA_CLASS, 0x0100) AV_PROFILE = ( AV_CLASS, 0x0100) SAP_PROFILE = ( SAP_CLASS, 0x0100) PNP_INFO_PROFILE = ( PNP_INFO_CLASS, 0x0100) GENERIC_NETWORKING_PROFILE = ( GENERIC_NETWORKING_CLASS, 0x0100) GENERIC_FILETRANS_PROFILE = ( GENERIC_FILETRANS_CLASS, 0x0100) GENERIC_AUDIO_PROFILE = ( GENERIC_AUDIO_CLASS, 0x0100) GENERIC_TELEPHONY_PROFILE = ( GENERIC_TELEPHONY_CLASS, 0x0100) UPNP_PROFILE = ( UPNP_CLASS, 0x0100) UPNP_IP_PROFILE = ( UPNP_IP_CLASS, 0x0100) UPNP_PAN_PROFILE = ( UPNP_PAN_CLASS, 0x0100) UPNP_LAP_PROFILE = ( UPNP_LAP_CLASS, 0x0100) UPNP_L2CAP_PROFILE = ( UPNP_L2CAP_CLASS, 0x0100) VIDEO_SOURCE_PROFILE = ( VIDEO_SOURCE_CLASS, 0x0100) VIDEO_SINK_PROFILE = ( VIDEO_SINK_CLASS, 0x0100) # Universal Service Attribute IDs SERVICE_RECORD_HANDLE_ATTRID = 0x0000 SERVICE_CLASS_ID_LIST_ATTRID = 0x0001 SERVICE_RECORD_STATE_ATTRID = 0x0002 SERVICE_ID_ATTRID = 0x0003 PROTOCOL_DESCRIPTOR_LIST_ATTRID = 0x0004 BROWSE_GROUP_LIST_ATTRID = 0x0005 LANGUAGE_BASE_ATTRID_LIST_ATTRID = 0x0006 SERVICE_INFO_TIME_TO_LIVE_ATTRID = 0x0007 SERVICE_AVAILABILITY_ATTRID = 0x0008 BLUETOOTH_PROFILE_DESCRIPTOR_LIST_ATTRID = 0x0009 DOCUMENTATION_URL_ATTRID = 0x000a CLIENT_EXECUTABLE_URL_ATTRID = 0x000b ICON_URL_ATTRID = 0x000c SERVICE_NAME_ATTRID = 0x0100 SERVICE_DESCRIPTION_ATTRID = 0x0101 PROVIDER_NAME_ATTRID = 0x0102 # Protocol UUIDs SDP_UUID = "0001" UDP_UUID = "0002" RFCOMM_UUID = "0003" TCP_UUID = "0004" TCS_BIN_UUID = "0005" TCS_AT_UUID = "0006" OBEX_UUID = "0008" IP_UUID = "0009" FTP_UUID = "000a" HTTP_UUID = "000c" WSP_UUID = "000e" BNEP_UUID = "000f" UPNP_UUID = "0010" HIDP_UUID = "0011" HCRP_CTRL_UUID = "0012" HCRP_DATA_UUID = "0014" HCRP_NOTE_UUID = "0016" AVCTP_UUID = "0017" AVDTP_UUID = "0019" CMTP_UUID = "001b" UDI_UUID = "001d" L2CAP_UUID = "0100" class BluetoothError (IOError): pass def is_valid_address (s): """ returns True if address is a valid Bluetooth address valid address are always strings of the form XX:XX:XX:XX:XX:XX where X is a hexadecimal character. For example, 01:23:45:67:89:AB is a valid address, but IN:VA:LI:DA:DD:RE is not """ try: pairs = s.split (":") if len (pairs) != 6: return False for b in pairs: int (b, 16) except: return False return True def is_valid_uuid (uuid): """ is_valid_uuid (uuid) -> bool returns True if uuid is a valid 128-bit UUID. valid UUIDs are always strings taking one of the following forms: XXXX XXXXXXXX XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX where each X is a hexadecimal digit (case insensitive) """ try: if len (uuid) == 4: if int (uuid, 16) < 0: return False elif len (uuid) == 8: if int (uuid, 16) < 0: return False elif len (uuid) == 36: pieces = uuid.split ("-") if len (pieces) != 5 or \ len (pieces[0]) != 8 or \ len (pieces[1]) != 4 or \ len (pieces[2]) != 4 or \ len (pieces[3]) != 4 or \ len (pieces[4]) != 12: return False [ int (p, 16) for p in pieces ] else: return False except ValueError: return False except TypeError: return False return True def to_full_uuid (uuid): """ converts a short 16-bit or 32-bit reserved UUID to a full 128-bit Bluetooth UUID. """ if not is_valid_uuid (uuid): raise ValueError ("invalid UUID") if len (uuid) == 4: return "0000%s-0000-1000-8000-00805F9B34FB" % uuid elif len (uuid) == 8: return "%s-0000-1000-8000-00805F9B34FB" % uuid else: return uuid # =============== parsing and constructing raw SDP records ============ def sdp_parse_size_desc (data): dts = struct.unpack ("B", data[0:1])[0] dtype, dsizedesc = dts >> 3, dts & 0x7 dstart = 1 if dtype == 0: dsize = 0 elif dsizedesc == 0: dsize = 1 elif dsizedesc == 1: dsize = 2 elif dsizedesc == 2: dsize = 4 elif dsizedesc == 3: dsize = 8 elif dsizedesc == 4: dsize = 16 elif dsizedesc == 5: dsize = struct.unpack ("B", data[1:2])[0] dstart += 1 elif dsizedesc == 6: dsize = struct.unpack ("!H", data[1:3])[0] dstart += 2 elif dsizedesc == 7: dsize == struct.unpack ("!I", data[1:5])[0] dstart += 4 if dtype > 8: raise ValueError ("Invalid TypeSizeDescriptor byte %s %d, %d" \ % (binascii.hexlify (data[0:1]), dtype, dsizedesc)) return dtype, dsize, dstart def sdp_parse_uuid (data, size): if size == 2: return binascii.hexlify (data) elif size == 4: return binascii.hexlify (data) elif size == 16: return "%08X-%04X-%04X-%04X-%04X%08X" % struct.unpack ("!IHHHHI", data) else: return ValueError ("invalid UUID size") def sdp_parse_int (data, size, signed): fmts = { 1 : "!b" , 2 : "!h" , 4 : "!i" , 8 : "!q" , 16 : "!qq" } fmt = fmts[size] if not signed: fmt = fmt.upper () if fmt in [ "!qq", "!QQ" ]: upp, low = struct.unpack ("!QQ", data) result = ( upp << 64) | low if signed: result=- ((~ (result-1))&0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) return result else: return struct.unpack (fmt, data)[0] def sdp_parse_data_elementSequence (data): result = [] pos = 0 datalen = len (data) while pos < datalen: rtype, rval, consumed = sdp_parse_data_element (data[pos:]) pos += consumed result.append ( (rtype, rval)) return result def sdp_parse_data_element (data): dtype, dsize, dstart = sdp_parse_size_desc (data) elem = data[dstart:dstart+dsize] if dtype == 0: rtype, rval = "Nil", None elif dtype == 1: rtype, rval = "UInt%d"% (dsize*8), sdp_parse_int (elem, dsize, False) elif dtype == 2: rtype, rval = "SInt%d"% (dsize*8), sdp_parse_int (elem, dsize, True) elif dtype == 3: rtype, rval = "UUID", sdp_parse_uuid (elem, dsize) elif dtype == 4: rtype, rval = "String", elem elif dtype == 5: rtype, rval = "Bool", (struct.unpack ("B", elem)[0] != 0) elif dtype == 6: rtype, rval = "ElemSeq", sdp_parse_data_elementSequence (elem) elif dtype == 7: rtype, rval = "AltElemSeq", sdp_parse_data_elementSequence (elem) elif dtype == 8: rtype, rval = "URL", elem return rtype, rval, dstart+dsize def sdp_parse_raw_record (data): dtype, dsize, dstart = sdp_parse_size_desc (data) assert dtype == 6 pos = dstart datalen = len (data) record = {} while pos < datalen: type, attrid, consumed = sdp_parse_data_element (data[pos:]) assert type == "UInt16" pos += consumed type, attrval, consumed = sdp_parse_data_element (data[pos:]) pos += consumed record[attrid] = attrval return record def sdp_make_data_element (type, value): def maketsd (tdesc, sdesc): return struct.pack ("B", (tdesc << 3) | sdesc) def maketsdl (tdesc, size): if size < (1<<8): return struct.pack ("!BB", tdesc << 3 | 5, size) elif size < (1<<16): return struct.pack ("!BH", tdesc << 3 | 6, size) else: return struct.pack ("!BI", tdesc << 3 | 7, size) easyinttypes = { "UInt8" : (1, 0, "!B"), "UInt16" : (1, 1, "!H"), "UInt32" : (1, 2, "!I"), "UInt64" : (1, 3, "!Q"), "SInt8" : (2, 0, "!b"), "SInt16" : (2, 1, "!h"), "SInt32" : (2, 2, "!i"), "SInt64" : (2, 3, "!q"), } if type == "Nil": return maketsd (0, 0) elif type in easyinttypes: tdesc, sdesc, fmt = easyinttypes[type] return maketsd (tdesc, sdesc) + struct.pack (fmt, value) elif type == "UInt128": ts = maketsd (1, 4) upper = ts >> 64 lower = (ts & 0xFFFFFFFFFFFFFFFF) return ts + struct.pack ("!QQ", upper, lower) elif type == "SInt128": ts = maketsd (2, 4) # FIXME raise NotImplementedException ("128-bit signed int NYI!") elif type == "UUID": if len (value) == 4: return maketsd (3, 1) + binascii.unhexlify (value) elif len (value) == 8: return maketsd (3, 2) + binascii.unhexlify (value) elif len (value) == 36: return maketsd (3, 4) + binascii.unhexlify (value.replace ("-","")) elif type == "String": return maketsdl (4, len (value)) + str.encode(value) elif type == "Bool": return maketsd (5,0) + (value and "\x01" or "\x00") elif type == "ElemSeq": packedseq = bytes() for subtype, subval in value: nextelem = sdp_make_data_element (subtype, subval) packedseq = packedseq + nextelem return maketsdl (6, len (packedseq)) + packedseq elif type == "AltElemSeq": packedseq = bytes() for subtype, subval in value: packedseq = packedseq + sdp_make_data_element (subtype, subval) return maketsdl (7, len (packedseq)) + packedseq elif type == "URL": return maketsdl (8, len (value)) + value else: raise ValueError ("invalid type %s" % type) pybluez-0.22+really0.22/bluetooth/msbt.py000066400000000000000000000214121334611253700202460ustar00rootroot00000000000000from bluetooth import * import bluetooth._msbt as bt bt.initwinsock () # ============== SDP service registration and unregistration ============ def discover_devices (duration=8, flush_cache=True, lookup_names=False, lookup_class=False, device_id=-1): #this is order of items in C-code btAddresIndex = 0 namesIndex = 1 classIndex = 2 devices = bt.discover_devices(duration=duration, flush_cache=flush_cache) ret = list() for device in devices: item = [device[btAddresIndex],] if lookup_names: item.append(device[namesIndex]) if lookup_class: item.append(device[classIndex]) if len(item) == 1: # in case of address-only we return string not tuple ret.append(item[0]) else: ret.append(tuple(i for i in item)) return ret def lookup_name (address, timeout=10): if not is_valid_address (address): raise ValueError ("Invalid Bluetooth address") return bt.lookup_name (address) class BluetoothSocket: def __init__ (self, proto = RFCOMM, sockfd = None): if proto not in [ RFCOMM ]: raise ValueError ("invalid protocol") if sockfd: self._sockfd = sockfd else: self._sockfd = bt.socket (bt.SOCK_STREAM, bt.BTHPROTO_RFCOMM) self._proto = proto # used by advertise_service and stop_advertising self._sdp_handle = None self._raw_sdp_record = None # used to track if in blocking or non-blocking mode (FIONBIO appears # write only) self._blocking = True self._timeout = False def bind (self, addrport): if self._proto == RFCOMM: addr, port = addrport if port == 0: port = bt.BT_PORT_ANY bt.bind (self._sockfd, addr, port) def listen (self, backlog): bt.listen (self._sockfd, backlog) def accept (self): clientfd, addr, port = bt.accept (self._sockfd) client = BluetoothSocket (self._proto, sockfd=clientfd) return client, (addr, port) def connect (self, addrport): addr, port = addrport bt.connect (self._sockfd, addr, port) def send (self, data): return bt.send (self._sockfd, data) def recv (self, numbytes): return bt.recv (self._sockfd, numbytes) def close (self): return bt.close (self._sockfd) def getsockname (self): return bt.getsockname (self._sockfd) def setblocking (self, blocking): bt.setblocking (self._sockfd, blocking) self._blocking = blocking def settimeout (self, timeout): if timeout < 0: raise ValueError ("invalid timeout") if timeout == 0: self.setblocking (False) else: self.setblocking (True) bt.settimeout (self._sockfd, timeout) self._timeout = timeout def gettimeout (self): if self._blocking and not self._timeout: return None return bt.gettimeout (self._sockfd) def fileno (self): return self._sockfd def dup (self): return BluetoothSocket (self._proto, sockfd=bt.dup (self._sockfd)) def makefile (self): # TODO raise Exception("Not yet implemented") def advertise_service (sock, name, service_id = "", service_classes = [], \ profiles = [], provider = "", description = "", protocols = []): if service_id != "" and not is_valid_uuid (service_id): raise ValueError ("invalid UUID specified for service_id") for uuid in service_classes: if not is_valid_uuid (uuid): raise ValueError ("invalid UUID specified in service_classes") for uuid, version in profiles: if not is_valid_uuid (uuid) or version < 0 or version > 0xFFFF: raise ValueError ("Invalid Profile Descriptor") for uuid in protocols: if not is_valid_uuid (uuid): raise ValueError ("invalid UUID specified in protocols") if sock._raw_sdp_record is not None: raise IOError ("service already advertised") avpairs = [] # service UUID if len (service_id) > 0: avpairs.append (("UInt16", SERVICE_ID_ATTRID)) avpairs.append (("UUID", service_id)) # service class list if len (service_classes) > 0: seq = [ ("UUID", svc_class) for svc_class in service_classes ] avpairs.append (("UInt16", SERVICE_CLASS_ID_LIST_ATTRID)) avpairs.append (("ElemSeq", seq)) # set protocol and port information assert sock._proto == RFCOMM addr, port = sock.getsockname () avpairs.append (("UInt16", PROTOCOL_DESCRIPTOR_LIST_ATTRID)) l2cap_pd = ("ElemSeq", (("UUID", L2CAP_UUID),)) rfcomm_pd = ("ElemSeq", (("UUID", RFCOMM_UUID), ("UInt8", port))) proto_list = [ l2cap_pd, rfcomm_pd ] for proto_uuid in protocols: proto_list.append (("ElemSeq", (("UUID", proto_uuid),))) avpairs.append (("ElemSeq", proto_list)) # make the service publicly browseable avpairs.append (("UInt16", BROWSE_GROUP_LIST_ATTRID)) avpairs.append (("ElemSeq", (("UUID", PUBLIC_BROWSE_GROUP),))) # profile descriptor list if len (profiles) > 0: seq = [ ("ElemSeq", (("UUID",uuid), ("UInt16",version))) \ for uuid, version in profiles ] avpairs.append (("UInt16", BLUETOOTH_PROFILE_DESCRIPTOR_LIST_ATTRID)) avpairs.append (("ElemSeq", seq)) # service name avpairs.append (("UInt16", SERVICE_NAME_ATTRID)) avpairs.append (("String", name)) # service description if len (description) > 0: avpairs.append (("UInt16", SERVICE_DESCRIPTION_ATTRID)) avpairs.append (("String", description)) # service provider if len (provider) > 0: avpairs.append (("UInt16", PROVIDER_NAME_ATTRID)) avpairs.append (("String", provider)) sock._raw_sdp_record = sdp_make_data_element ("ElemSeq", avpairs) # pr = sdp_parse_raw_record (sock._raw_sdp_record) # for attrid, val in pr.items (): # print "%5s: %s" % (attrid, val) # print binascii.hexlify (sock._raw_sdp_record) # print repr (sock._raw_sdp_record) sock._sdp_handle = bt.set_service_raw (sock._raw_sdp_record, True) def stop_advertising (sock): if sock._raw_sdp_record is None: raise IOError ("service isn't advertised, " \ "but trying to un-advertise") bt.set_service_raw (sock._raw_sdp_record, False, sock._sdp_handle) sock._raw_sdp_record = None sock._sdp_handle = None def find_service (name = None, uuid = None, address = None): if address is not None: addresses = [ address ] else: addresses = discover_devices (lookup_names = False) results = [] for addr in addresses: uuidstr = uuid or PUBLIC_BROWSE_GROUP if not is_valid_uuid (uuidstr): raise ValueError ("invalid UUID") uuidstr = to_full_uuid (uuidstr) dresults = bt.find_service (addr, uuidstr) for dict in dresults: raw = dict["rawrecord"] record = sdp_parse_raw_record (raw) if SERVICE_CLASS_ID_LIST_ATTRID in record: svc_class_id_list = [ t[1] for t in \ record[SERVICE_CLASS_ID_LIST_ATTRID] ] dict["service-classes"] = svc_class_id_list else: dict["services-classes"] = [] if BLUETOOTH_PROFILE_DESCRIPTOR_LIST_ATTRID in record: pdl = [] for profile_desc in \ record[BLUETOOTH_PROFILE_DESCRIPTOR_LIST_ATTRID]: uuidpair, versionpair = profile_desc[1] pdl.append ((uuidpair[1], versionpair[1])) dict["profiles"] = pdl else: dict["profiles"] = [] dict["provider"] = record.get (PROVIDER_NAME_ATTRID, None) dict["service-id"] = record.get (SERVICE_ID_ATTRID, None) # XXX the C version is buggy (retrieves an extra byte or two), # so get the service name here even though it may have already # been set dict["name"] = record.get (SERVICE_NAME_ATTRID, None) dict["handle"] = record.get (SERVICE_RECORD_HANDLE_ATTRID, None) # if LANGUAGE_BASE_ATTRID_LIST_ATTRID in record: # for triple in record[LANGUAGE_BASE_ATTRID_LIST_ATTRID]: # code_ISO639, encoding, base_offset = triple # # if SERVICE_DESCRIPTION_ATTRID in record: # service_description = record[SERVICE_DESCRIPTION_ATTRID] if name is None: results.extend (dresults) else: results.extend ([ d for d in dresults if d["name"] == name ]) return results # =============== DeviceDiscoverer ================== class DeviceDiscoverer: def __init__ (self): raise NotImplementedError pybluez-0.22+really0.22/bluetooth/osx.py000066400000000000000000000000631334611253700201110ustar00rootroot00000000000000from .btcommon import * raise NotImplementedError pybluez-0.22+really0.22/bluetooth/widcomm.py000066400000000000000000000715711334611253700207530ustar00rootroot00000000000000from .btcommon import * import socket import struct import threading import os import _widcomm DEFAULT_MTU = 672 def dbg (*args): return sys.stdout.write (*args) sys.stdout.write ("\n") def BD_ADDR_to_str (bda): return "%02X:%02X:%02X:%02X:%02X:%02X" % \ (ord(bda[0]), ord(bda[1]), ord(bda[2]), ord(bda[3]), ord(bda[4]), ord(bda[5])) def str_to_BD_ADDR (s): digits = [ int (c, 16) for c in s.split(":") ] return struct.pack ("6B", *digits) class WCInquirer: DEVST_DOWN = 0 DEVST_UP = 1 DEVST_ERROR = 2 DEVST_UNLOADED = 3 DEVST_RELOADED = 4 def __init__ (self): self._wcinq = _widcomm._WCInquirer () port = self._wcinq.get_sockport () self.readsock = socket.socket (socket.AF_INET, socket.SOCK_STREAM) self.readsock.connect (("127.0.0.1", port)) self._wcinq.accept_client () self.recently_discovered = [] self.inquiry_in_progress = False self.sdp_query_in_progress = False def fileno (): return self.readsock.fileno () def start_inquiry (self): self.recently_discovered = [] self.inquiry_in_progress = self._wcinq.start_inquiry () def read_msg (self): intsize = struct.calcsize ("=i") msg_type = struct.unpack ("=i", self.readsock.recv (intsize))[0] if msg_type == _widcomm.INQ_DEVICE_RESPONDED: fmt = "=6s3s248si" data = self.readsock.recv (struct.calcsize (fmt)) bda, devclass, bdname, connected = struct.unpack (fmt, data) bdaddr = BD_ADDR_to_str (bda) bdname = bdname.strip ("\0") self.recently_discovered.append ((bdaddr, devclass, bdname, connected)) elif msg_type == _widcomm.INQ_INQUIRY_COMPLETE: fmt = "=ih" data = self.readsock.recv (struct.calcsize (fmt)) success, num_responses = struct.unpack (fmt, data) self.inquiry_in_progress = False elif msg_type == _widcomm.INQ_DISCOVERY_COMPLETE: self.sdp_query_in_progress = False elif msg_type == _widcomm.INQ_STACK_STATUS_CHANGE: fmt = "=i" data = self.readsock.recv (struct.calcsize (fmt)) new_status = struct.unpack (fmt, data)[0] def start_discovery (self, addr, uuid = None): bd_addr = str_to_BD_ADDR (addr) if uuid is not None: self.sdp_query_in_progress = \ self._wcinq.start_discovery (bd_addr, to_full_uuid (uuid)) else: self.sdp_query_in_progress = \ self._wcinq.start_discovery (bd_addr) self.sdp_query_in_progress = True def read_discovery_records (self, addr, uuid = None): if not is_valid_address (addr): raise ValueError ("invalid Bluetooth address") bd_addr = str_to_BD_ADDR (addr) if uuid is not None: dbg ("read_discovery_records (%s, %s)" % (addr, uuid)) return self._wcinq.read_discovery_records (bd_addr, to_full_uuid (uuid)) else: return self._wcinq.read_discovery_records (bd_addr) def is_device_ready (self): return self._wcinq.is_device_ready () def get_local_device_address (self): return self._wcinq.get_local_device_address () inquirer = WCInquirer () def discover_devices (duration=8, flush_cache=True, lookup_names=False, lookup_class=False): inquirer.start_inquiry () while inquirer.inquiry_in_progress: inquirer.read_msg () discovered = inquirer.recently_discovered[:] if not lookup_names and not lookup_class: return [ tup[0] for tup in discovered ] if lookup_names and not lookup_class: result = [] for bdaddr, devClass, bdName, bConnected in discovered: if bdName: result.append ((bdaddr, bdName)) else: result.append ((bdAddr, None)) return result if not lookup_names and lookup_class: result = [] for bdaddr, devClass, bdName, bConnected in discovered: hex = "%02X%02X%02X" % (ord(devClass[0]), ord(devClass[1]), ord(devClass[2])) devClass = int(hex, 16) result.append ((bdAddr, devClass)) return result if lookup_names and lookup_class: result = [] for bdaddr, devClass, bdName, bConnected in discovered: hex = "%02X%02X%02X" % (ord(devClass[0]), ord(devClass[1]), ord(devClass[2])) devClass = int(hex, 16) if bdName: result.append ((bdaddr, bdName, devClass)) else: result.append ((bdAddr, None, devClass)) return result def lookup_name (address, timeout=10): discover_devices () for bdaddr, devClass, bdName, bConnected in inquirer.recently_discovered: if bdaddr == address: return bdName def advertise_service (sock, name, service_id = "", service_classes = [], \ profiles = [], provider = "", description = "", protocols = []): sock._advertise_service (name, service_id, service_classes, profiles, provider, description, protocols) def stop_advertising (sock): sock._stop_advertising () def find_service (name = None, uuid = None, address = None): if address: if address == "localhost": raise NotImplementedError if not is_valid_address (address): raise ValueError ("invalid Bluetooth address") addresses = [ address ] else: addresses = discover_devices () if uuid and not is_valid_uuid (uuid): raise ValueError ("invalid uuid ", uuid) results = [] for addr in addresses: inquirer.start_discovery (addr, uuid) while inquirer.sdp_query_in_progress: inquirer.read_msg () results.extend (inquirer.read_discovery_records (addr, uuid)) return results def _port_return_code_to_str (code): k = { _widcomm.RFCOMM_SUCCESS : "Success", _widcomm.RFCOMM_ALREADY_OPENED : "Port already opened", _widcomm.RFCOMM_NOT_OPENED : "Connection not open", _widcomm.RFCOMM_HANDLE_ERROR: "This error should never occur " \ "(HANDLE_ERROR) and is a stack bug", _widcomm.RFCOMM_LINE_ERR: "Line error", _widcomm.RFCOMM_START_FAILED: "Connection attempt failed", _widcomm.RFCOMM_PAR_NEG_FAILED: "Parameter negotion (MTU) failed", _widcomm.RFCOMM_PORT_NEG_FAILED: "Port negotiation failed", _widcomm.RFCOMM_PEER_CONNECTION_FAILED: "Connection ended by remote "\ "side", _widcomm.RFCOMM_PEER_TIMEOUT: "Timeout by remote side", _widcomm.RFCOMM_INVALID_PARAMETER: "Invalid parameter", _widcomm.RFCOMM_UNKNOWN_ERROR: "Unknown error" } if code in k: return k[code] else: return "Invalid RFCOMM error code %s" % str (code) def _port_ev_code_to_str (code): d = { _widcomm.PORT_EV_RXFLAG : "Received certain character", _widcomm.PORT_EV_TXEMPTY : "Transmit Queue Empty", _widcomm.PORT_EV_CTS : "CTS changed state", _widcomm.PORT_EV_DSR : "DSR changed state", _widcomm.PORT_EV_RLSD : "RLSD changed state", _widcomm.PORT_EV_BREAK : "BREAK received", _widcomm.PORT_EV_ERR : "Line status error occurred", _widcomm.PORT_EV_RING : "Ring signal detected", _widcomm.PORT_EV_CTSS : "CTS state", _widcomm.PORT_EV_DSRS : "DSR state", _widcomm.PORT_EV_RLSDS : "RLSD state", _widcomm.PORT_EV_OVERRUN : "Receiver buffer overrun", _widcomm.PORT_EV_TXCHAR : "Any character transmitted", _widcomm.PORT_EV_CONNECTED : "RFCOMM connection established", _widcomm.PORT_EV_CONNECT_ERR : "Was not able to establish " \ "connection or disconnected", _widcomm.PORT_EV_FC : "Flow control enabled flag changed by remote", _widcomm.PORT_EV_FCS : "Flow control status true = enabled" } result = [] for k, v in list(d.items ()): if code & k: result.append (v) if len (result) == 0: return "Invalid event code %d" % code else: return "\n".join (result) def _sdp_checkraise (code): if code == _widcomm.SDP_OK: return elif code == _widcomm.SDP_COULD_NOT_ADD_RECORD: raise BluetoothError ("Could not add SDP record") elif code == _widcomm.SDP_INVALID_RECORD: raise BluetoothError ("Invalid SDP record") elif code == _widcomm.SDP_INVALID_PARAMETERS: raise BluetoothError ("SDP: invalid parameters") raise RuntimeError ("unknown SDP status code %s" % code) class BluetoothSocket: def __init__ (self, proto = RFCOMM, _sockdata = None): if not proto in [ RFCOMM, L2CAP ]: raise ValueError ("invalid protocol") self.proto = proto if proto == RFCOMM: self.bind = self.rfcomm_bind self.listen = self.rfcomm_listen self.accept = self.rfcomm_accept self.connect = self.rfcomm_connect self.send = self.rfcomm_send self.recv = self.rfcomm_recv self.close = self.rfcomm_close self.getsockname = self.rfcomm_getsockname self.setblocking = self.rfcomm_setblocking self.settimeout = self.rfcomm_settimeout self.gettimeout = self.rfcomm_gettimeout self.dup = self.rfcomm_dup self.makefile = self.rfcomm_makefile self.fileno = self.rfcomm_fileno self.__make_cobjects = self.__rfcomm_make_cobjects self._advertise_service = self.__rfcomm_advertise_service if _sockdata: self._wc, self._if, self.readsock = _sockdata else: self.__make_cobjects () self.connected = self._wc.is_connected () elif proto == L2CAP: dbg ("creating l2cap socket") self.bind = self.l2cap_bind self.listen = self.l2cap_listen self.accept = self.l2cap_accept self.connect = self.l2cap_connect self.send = self.l2cap_send self.recv = self.l2cap_recv self.close = self.l2cap_close self.getsockname = self.l2cap_getsockname self.setblocking = self.l2cap_setblocking self.settimeout = self.l2cap_settimeout self.gettimeout = self.l2cap_gettimeout self.dup = self.l2cap_dup self.makefile = self.l2cap_makefile self.fileno = self.l2cap_fileno self.__make_cobjects = self.__l2cap_make_cobjects self._advertise_service = self.__l2cap_advertise_service if _sockdata: self._wc, self._if, self.readsock = _sockdata self.connected = True else: self.__make_cobjects () self.connected = False else: raise NotImplementedError () self.nonblocking = False self.connecting = False self.listening = False self.bound = False self.received_data = [] self.last_event_code = None self.port = 0 self._sdpservice = None def _stop_advertising (self): if not self._sdpservice: raise BluetoothError ("not advertising any services") self._sdpservice = None def __rfcomm_make_cobjects (self): self._wc = _widcomm._WCRfCommPort () self._if = _widcomm._WCRfCommIf () self.readsock = socket.socket (socket.AF_INET, socket.SOCK_STREAM) self.readsock.connect (("127.0.0.1", self._wc.get_sockport ())) self._wc.accept_client () def rfcomm_read_msg (self): intsize = struct.calcsize ("=i") msg_type_data = self.readsock.recv (intsize) msg_type = struct.unpack ("=i", msg_type_data)[0] if msg_type == _widcomm.RFCOMM_DATA_RECEIVED: datalen_fmt = "=i" datalen_data = self.readsock.recv (struct.calcsize (datalen_fmt)) datalen = struct.unpack (datalen_fmt, datalen_data)[0] self.received_data.append (self.readsock.recv (datalen)) elif msg_type == _widcomm.RFCOMM_EVENT_RECEIVED: fmt = "=I" data = self.readsock.recv (struct.calcsize (fmt)) code = struct.unpack (fmt, data)[0] dbg ("event %X received" % code) if code & _widcomm.PORT_EV_CONNECTED: self.connecting = False self.listening = False self.connected = True if code & _widcomm.PORT_EV_CONNECT_ERR: self.connecting = False self.listening = False self.connected = False raise BluetoothError ("Connection failed") if code & _widcomm.PORT_EV_RXFLAG: dbg ("Rx flag") if code & _widcomm.PORT_EV_TXEMPTY: dbg ("Tx queue empty") if code & _widcomm.PORT_EV_CTS: dbg ("CTS changed state") if code & _widcomm.PORT_EV_DSR: dbg ("DSR changed state") if code & _widcomm.PORT_EV_RLSD: dbg ("RLSD changed state") if code & _widcomm.PORT_EV_BREAK: dbg ("BREAK received") if code & _widcomm.PORT_EV_ERR: dbg ("Line status error") if code & _widcomm.PORT_EV_RING: dbg ("Ring") if code & _widcomm.PORT_EV_CTSS: dbg ("CTS state") if code & _widcomm.PORT_EV_DSRS: dbg ("DSR state") if code & _widcomm.PORT_EV_RLSDS: dbg ("RLSD state") if code & _widcomm.PORT_EV_OVERRUN: dbg ("Receive buffer overrun") if code & _widcomm.PORT_EV_TXCHAR: dbg ("Data transmitted") if code & _widcomm.PORT_EV_FC: dbg ("Flow control changed by remote") if code & _widcomm.PORT_EV_FCS: dbg ("Flow control status true = enabled") self.last_event_code = code def rfcomm_bind (self, addrport): addr, port = addrport if len (addr): raise ValueError ("Widcomm stack can't bind to " \ "user-specified adapter") result = self._if.assign_scn_value (RFCOMM_UUID, port) if not result: raise BluetoothError ("unable to bind to port") self.bound = True self.port = self._if.get_scn () def rfcomm_listen (self, backlog): if self.connected: raise BluetoothError ("already connected") if self.listening: raise BluetoothError ("already listening/connecting") if backlog != 1: raise ValueError ("Widcomm stack requires backlog == 1") port = self._if.get_scn () self._if.set_security_level ("", _widcomm.BTM_SEC_NONE, True) if not port: raise BluetoothError ("not bound to a port") result = self._wc.open_server (port, DEFAULT_MTU) if result != _widcomm.RFCOMM_SUCCESS: raise BluetoothError (_port_return_code_to_str (result)) self.listening = True def rfcomm_accept (self): if self.connected: raise BluetoothError ("already connected") while self.listening and not self.connected: dbg ("waiting for connection") self.rfcomm_read_msg () if self.connected: port = self._if.get_scn () client_bdaddr = BD_ADDR_to_str (self._wc.is_connected ()) # XXX widcomm API doesn't provide a way to determine the RFCOMM # channel number of the client client_port = 0 # create a new socket object and give it ownership of the # wrapped C++ objects, since those are the ones actually connected _sockdata = self._wc, self._if, self.readsock clientsock = BluetoothSocket (RFCOMM, _sockdata) # now create new C++ objects self.__rfcomm_make_cobjects () # self.bind (("", port)) # self.listen (1) return clientsock, (client_bdaddr, client_port) def rfcomm_connect (self, addrport): addr, port = addrport dbg ("connecting to %s port %d" % (addr, port)) if not is_valid_address (addr): raise ValueError ("invalid address %s" % addr) self._if.assign_scn_value (RFCOMM_UUID, port) self._if.set_security_level ("", _widcomm.BTM_SEC_NONE, False) result = self._wc.open_client (port, str_to_BD_ADDR (addr), DEFAULT_MTU) if result != _widcomm.RFCOMM_SUCCESS: raise BluetoothError (_port_return_code_to_str (result)) self.connecting = True while self.connecting: self.rfcomm_read_msg () if not self._wc.is_connected (): raise BluetoothError ("connection failed") def rfcomm_send (self, data): dbg ("sending: [%s]" % data) status, written = self._wc.write (data) if status == _widcomm.RFCOMM_SUCCESS: dbg ("sent okay") return written else: raise BluetoothError (_port_return_code_to_str (status)) def rfcomm_recv (self, numbytes): if self.nonblocking and not self.received_data: # XXX are we supposed to raise an exception, or just return None? return None while not self.received_data and self._wc.is_connected (): self.rfcomm_read_msg () if self.received_data: data = self.received_data.pop (0) if len(data) > numbytes: self.received_data.insert (0, data[numbytes:]) return data[:numbytes] else: return data def rfcomm_close (self): self._wc.close () self._wc = None self.bound = False self.connecting = False self.listening = False self.connected = False # return bt.close (self._sockfd) def rfcomm_getsockname (self): if not self.bound: raise BluetoothError ("Socket not bound") addr = inquirer.get_local_device_address () port = self._if.get_scn () return addr, port def rfcomm_setblocking (self, blocking): self.nonblocking = not blocking self.readsock.setblocking (blocking) def rfcomm_settimeout (self, timeout): raise NotImplementedError pass # if timeout < 0: raise ValueError ("invalid timeout") # # if timeout == 0: # self.setblocking (False) # else: # self.setblocking (True) # # XXX this doesn't look correct # timeout = 0 # winsock timeout still needs to be set 0 # # s = bt.settimeout (self._sockfd, timeout) # self._timeout = timeout def rfcomm_gettimeout (self): raise NotImplementedError # if self._blocking and not self._timeout: return None # return bt.gettimeout (self._sockfd) def rfcomm_fileno (self): return self.readsock.fileno () def rfcomm_dup (self): raise NotImplementedError def rfcomm_makefile (self): raise NotImplementedError def __rfcomm_advertise_service (self, name, service_id, service_classes, profiles, provider, description, protocols): if self._sdpservice is not None: raise BluetoothError ("Service already advertised") if not self.listening: raise BluetoothError ("Socket must be listening before advertised") if protocols: raise NotImplementedError ("extra protocols not yet supported in Widcomm stack") self._sdpservice = _widcomm._WCSdpService () if service_classes: service_classes = [ to_full_uuid (s) for s in service_classes ] _sdp_checkraise (self._sdpservice.add_service_class_id_list ( \ service_classes)) # self._if.set_security_level (name, _widcomm.BTM_SEC_NONE, True) _sdp_checkraise (self._sdpservice.add_rfcomm_protocol_descriptor ( \ self.port)) if profiles: for uuid, version in profiles: uuid = to_full_uuid (uuid) _sdp_checkraise (self._sdpservice.add_profile_descriptor_list (\ uuid, version)) _sdp_checkraise (self._sdpservice.add_service_name (name)) _sdp_checkraise (self._sdpservice.make_public_browseable ()) def __l2cap_make_cobjects (self): dbg ("__l2cap_make_cobjects") self._wc = _widcomm._WCL2CapConn () self._if = _widcomm._WCL2CapIf () self.readsock = socket.socket (socket.AF_INET, socket.SOCK_STREAM) self.readsock.connect (("127.0.0.1", self._wc.get_sockport ())) self._wc.accept_client () def l2cap_read_msg (self): intsize = struct.calcsize ("=i") msg_type_data = self.readsock.recv (intsize) msg_type = struct.unpack ("=i", msg_type_data)[0] if msg_type == _widcomm.L2CAP_DATA_RECEIVED: datalen_fmt = "=i" datalen_data = self.readsock.recv (struct.calcsize (datalen_fmt)) datalen = struct.unpack (datalen_fmt, datalen_data)[0] self.received_data.append (self.readsock.recv (datalen)) elif msg_type == _widcomm.L2CAP_INCOMING_CONNECTION: result = self._wc.accept () if not result: raise BluetoothError ("accept() failed") elif msg_type == _widcomm.L2CAP_REMOTE_DISCONNECTED: dbg ("L2CAP_REMOTE_DISCONNECTED") self.connecting = False self.listening = False self.connected = False elif msg_type == _widcomm.L2CAP_CONNECTED: self.connecting = False self.listening = False self.connected = True # elif msg_type == _widcomm.PORT_EV_CONNECT_ERR: # self.connecting = False # self.listening = False # raise BluetoothError ("Connection failed") def l2cap_bind (self, addrport): dbg ("l2cap_bind %s" % str(addrport)) addr, port = addrport if len (addr): raise ValueError ("Widcomm stack can't bind to " \ "user-specified adapter") result = self._if.assign_psm_value (L2CAP_UUID, port) if not result: raise BluetoothError ("unable to bind to port") self.bound = True self.port = self._if.get_psm () result = self._if.register () if not result: raise BluetoothError ("register() failed") def l2cap_listen (self, backlog): dbg ("l2cap_listen %s" % backlog) if self.connected: raise BluetoothError ("already connected") if self.listening: raise BluetoothError ("already listening/connecting") if backlog != 1: raise ValueError ("Widcomm stack requires backlog == 1") port = self._if.get_psm () self._if.set_security_level ("", _widcomm.BTM_SEC_NONE, True) if not port: raise BluetoothError ("not bound to a port") result = self._wc.listen (self._if) if not result: raise BluetoothError ("listen() failed. don't know why") self.listening = True def l2cap_accept (self): dbg ("l2cap_accept") if self.connected: raise BluetoothError ("already connected") while self.listening and not self.connected: dbg ("waiting for connection") self.l2cap_read_msg () if self.connected: port = self._if.get_psm () client_bdaddr = BD_ADDR_to_str (self._wc.remote_bd_addr ()) # XXX widcomm API doesn't provide a way to determine the L2CAP # PSM of the client client_port = 0 # create a new socket object and give it ownership of the # wrapped C++ objects, since those are the ones actually connected _sockdata = self._wc, self._if, self.readsock clientsock = BluetoothSocket (L2CAP, _sockdata) # now create new C++ objects self.__l2cap_make_cobjects () # self.bind (("", port)) # self.listen (1) return clientsock, (client_bdaddr, client_port) def l2cap_connect (self, addrport): addr, port = addrport dbg ("connecting to %s port %d" % (addr, port)) if not is_valid_address (addr): raise ValueError ("invalid address %s" % addr) if not self._if.assign_psm_value (L2CAP_UUID, port): raise BluetoothError ("Failed to assign PSM %d" % port) if not self._if.set_security_level ("", _widcomm.BTM_SEC_NONE, False): raise BluetoothError ("Failed to set security level") if not self._if.register (): raise BluetoothError ("Failed to register PSM") self.connecting = True if not self._wc.connect (self._if, str_to_BD_ADDR (addr)): raise BluetoothError ("Connect failed") while self.connecting: self.l2cap_read_msg () if not self.connected: raise BluetoothError ("connection failed") def l2cap_send (self, data): dbg ("sending: [%s]" % data) status, written = self._wc.write (data) if status: dbg ("sent okay") return written else: raise BluetoothError (_port_return_code_to_str (status)) def l2cap_recv (self, numbytes): if self.nonblocking and not self.received_data: # XXX are we supposed to raise an exception, or just return None? return None while not self.received_data and self.connected: self.l2cap_read_msg () if self.received_data: data = self.received_data.pop (0) if len(data) > numbytes: self.received_data.insert (0, data[numbytes:]) return data[:numbytes] else: return data def l2cap_close (self): self._wc.disconnect () self._if.deregister () self._wc = None self.bound = False self.connecting = False self.listening = False self.connected = False # return bt.close (self._sockfd) def l2cap_getsockname (self): if not self.bound: raise BluetoothError ("Socket not bound") addr = inquirer.get_local_device_address () port = self._if.get_psm () return addr, port def l2cap_setblocking (self, blocking): self.nonblocking = not blocking self.readsock.setblocking (blocking) def l2cap_settimeout (self, timeout): raise NotImplementedError # if timeout < 0: raise ValueError ("invalid timeout") # # if timeout == 0: # self.setblocking (False) # else: # self.setblocking (True) # # XXX this doesn't look correct # timeout = 0 # winsock timeout still needs to be set 0 # # s = bt.settimeout (self._sockfd, timeout) # self._timeout = timeout def l2cap_gettimeout (self): raise NotImplementedError # if self._blocking and not self._timeout: return None # return bt.gettimeout (self._sockfd) def l2cap_fileno (self): return self.readsock.fileno () def l2cap_dup (self): raise NotImplementedError # return BluetoothSocket (self._proto, sockfd=bt.dup (self._sockfd)) def l2cap_makefile (self): raise NotImplementedError def __l2cap_advertise_service (self, name, service_id, service_classes, profiles, provider, description, protocols): if self._sdpservice is not None: raise BluetoothError ("Service already advertised") if not self.listening: raise BluetoothError ("Socket must be listening before advertised") if protocols: raise NotImplementedError ("extra protocols not yet supported in Widcomm stack") self._sdpservice = _widcomm._WCSdpService () if service_classes: service_classes = [ to_full_uuid (s) for s in service_classes ] _sdp_checkraise (self._sdpservice.add_service_class_id_list ( \ service_classes)) _sdp_checkraise (self._sdpservice.add_l2cap_protocol_descriptor ( \ self.port)) if profiles: for uuid, version in profiles: uuid = to_full_uuid (uuid) _sdp_checkraise (self._sdpservice.add_profile_descriptor_list (\ uuid, version)) _sdp_checkraise (self._sdpservice.add_service_name (name)) _sdp_checkraise (self._sdpservice.make_public_browseable ()) class DeviceDiscoverer: def __init__ (self): raise NotImplementedError pybluez-0.22+really0.22/bluez/000077500000000000000000000000001334611253700160435ustar00rootroot00000000000000pybluez-0.22+really0.22/bluez/btmodule.c000066400000000000000000002703511334611253700200320ustar00rootroot00000000000000/* This module provides an interface to bluetooth. A great deal of the code is taken from the pyaffix project. - there are three kinds of bluetooth addresses used here HCI address is a single int specifying the device id L2CAP address is a pair (host, port) RFCOMM address is a pair (host, channel) SCO address is just a host the host part of the address is always a string of the form "XX:XX:XX:XX:XX" Local naming conventions: - names starting with sock_ are socket object methods - names starting with bt_ are module-level functions */ #include "btmodule.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "btsdp.h" /* Socket object documentation */ PyDoc_STRVAR(sock_doc, "BluetoothSocket(proto=RFCOMM) -> bluetooth socket object\n\ \n\ Open a socket of the given protocol. proto must be one of\n\ HCI, L2CAP, RFCOMM, or SCO. SCO sockets have\n\ not been tested at all yet.\n\ \n\ A BluetoothSocket object represents one endpoint of a bluetooth connection.\n\ \n\ Methods of BluetoothSocket objects (keyword arguments not allowed):\n\ \n\ accept() -- accept a connection, returning new socket and client address\n\ bind(addr) -- bind the socket to a local address\n\ close() -- close the socket\n\ connect(addr) -- connect the socket to a remote address\n\ connect_ex(addr) -- connect, return an error code instead of an exception\n\ dup() -- return a new socket object identical to the current one\n\ fileno() -- return underlying file descriptor\n\ getpeername() -- return remote address\n\ getsockname() -- return local address\n\ getsockopt(level, optname[, buflen]) -- get socket options\n\ gettimeout() -- return timeout or None\n\ listen(n) -- start listening for incoming connections\n\ makefile([mode, [bufsize]]) -- return a file object for the socket\n\ recv(buflen[, flags]) -- receive data\n\ recvfrom(buflen[, flags]) -- receive data and sender's address\n\ sendall(data[, flags]) -- send all data\n\ send(data[, flags]) -- send data, may not send all of it\n\ sendto(data[, flags], addr) -- send data to a given address\n\ setblocking(0 | 1) -- set or clear the blocking I/O flag\n\ setsockopt(level, optname, value) -- set socket options\n\ settimeout(None | float) -- set or clear the timeout\n\ shutdown(how) -- shut down traffic in one or both directions"); /* Global variable holding the exception type for errors detected by this module (but not argument type or memory errors, etc.). */ PyObject *bluetooth_error; static PyObject *socket_timeout; /* A forward reference to the socket type object. The sock_type variable contains pointers to various functions, some of which call new_sockobject(), which uses sock_type, so there has to be a circular reference. */ PyTypeObject sock_type; /* Convenience function to raise an error according to errno and return a NULL pointer from a function. */ PyObject * set_error(void) { return PyErr_SetFromErrno(bluetooth_error); } /* Function to perform the setting of socket blocking mode internally. block = (1 | 0). */ static int internal_setblocking(PySocketSockObject *s, int block) { int delay_flag; Py_BEGIN_ALLOW_THREADS delay_flag = fcntl(s->sock_fd, F_GETFL, 0); if (block) delay_flag &= (~O_NONBLOCK); else delay_flag |= O_NONBLOCK; fcntl(s->sock_fd, F_SETFL, delay_flag); Py_END_ALLOW_THREADS /* Since these don't return anything */ return 1; } /* Do a select() on the socket, if necessary (sock_timeout > 0). The argument writing indicates the direction. This does not raise an exception; we'll let our caller do that after they've reacquired the interpreter lock. Returns 1 on timeout, 0 otherwise. */ static int internal_select(PySocketSockObject *s, int writing) { fd_set fds; struct timeval tv; int n; /* Nothing to do unless we're in timeout mode (not non-blocking) */ if (s->sock_timeout <= 0.0) return 0; /* Guard against closed socket */ if (s->sock_fd < 0) return 0; /* Construct the arguments to select */ tv.tv_sec = (int)s->sock_timeout; tv.tv_usec = (int)((s->sock_timeout - tv.tv_sec) * 1e6); FD_ZERO(&fds); FD_SET(s->sock_fd, &fds); /* See if the socket is ready */ if (writing) n = select(s->sock_fd+1, NULL, &fds, NULL, &tv); else n = select(s->sock_fd+1, &fds, NULL, NULL, &tv); if (n == 0) return 1; return 0; } /* Initialize a new socket object. */ static double defaulttimeout = -1.0; /* Default timeout for new sockets */ static void init_sockobject(PySocketSockObject *s, int fd, int family, int type, int proto) { s->sock_fd = fd; s->sock_family = family; s->sock_type = type; s->sock_proto = proto; s->sock_timeout = defaulttimeout; s->errorhandler = &set_error; if (defaulttimeout >= 0.0) internal_setblocking(s, 0); } /* Create a new socket object. This just creates the object and initializes it. If the creation fails, return NULL and set an exception (implicit in NEWOBJ()). */ static PySocketSockObject * new_sockobject(int fd, int family, int type, int proto) { PySocketSockObject *s; s = (PySocketSockObject *) PyType_GenericNew(&sock_type, NULL, NULL); if (s != NULL) init_sockobject(s, fd, family, type, proto); return s; } /* 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 to determine what kind of address it really is. */ /*ARGSUSED*/ static PyObject * makesockaddr(PySocketSockObject *s, struct sockaddr *addr, int addrlen) { if (addrlen == 0) { /* No address -- may be recvfrom() from known socket */ Py_INCREF(Py_None); return Py_None; } else { char ba_name[18]; switch(s->sock_proto) { case BTPROTO_HCI: { return Py_BuildValue("H", ((struct sockaddr_hci*)(addr))->hci_dev ); } case BTPROTO_L2CAP: { struct sockaddr_l2 *a = (struct sockaddr_l2*)addr; ba2str( &a->l2_bdaddr, ba_name ); return Py_BuildValue("sH", ba_name, btohs(a->l2_psm) ); } case BTPROTO_RFCOMM: { struct sockaddr_rc *a = (struct sockaddr_rc*)addr; ba2str( &a->rc_bdaddr, ba_name ); return Py_BuildValue("sB", ba_name, a->rc_channel ); } case BTPROTO_SCO: { struct sockaddr_sco *a = (struct sockaddr_sco*)addr; ba2str( &a->sco_bdaddr, ba_name ); return Py_BuildValue("s", ba_name); } default: PyErr_SetString(bluetooth_error, "getsockaddrarg: unknown Bluetooth protocol"); return 0; } } } /* Parse a socket address argument according to the socket object's address family. Return 1 if the address was in the proper format, 0 of not. The address is returned through addr_ret, its length through len_ret. */ static int getsockaddrarg(PySocketSockObject *s, PyObject *args, struct sockaddr *addr_ret, int *len_ret) { memset(addr_ret, 0, sizeof(struct sockaddr)); addr_ret->sa_family = AF_BLUETOOTH; switch( s->sock_proto ) { case BTPROTO_HCI: { struct sockaddr_hci *addr = (struct sockaddr_hci*) addr_ret; if ( !PyArg_ParseTuple(args, "H", &addr->hci_dev) ) { return 0; } *len_ret = sizeof(struct sockaddr_hci); return 1; } case BTPROTO_L2CAP: { struct sockaddr_l2* addr = (struct sockaddr_l2*) addr_ret; char *ba_name = 0; if ( !PyArg_ParseTuple(args, "sH", &ba_name, &addr->l2_psm) ) { return 0; } str2ba( ba_name, &addr->l2_bdaddr ); // check for a valid PSM if( ! ( 0x1 & addr->l2_psm ) ) { PyErr_SetString( PyExc_ValueError, "Invalid PSM"); return 0; } addr->l2_psm = htobs(addr->l2_psm); *len_ret = sizeof *addr; return 1; } case BTPROTO_RFCOMM: { struct sockaddr_rc *addr = (struct sockaddr_rc*) addr_ret; char *ba_name = 0; if( !PyArg_ParseTuple(args, "sB", &ba_name, &addr->rc_channel) ) { return 0; } str2ba( ba_name, &addr->rc_bdaddr ); *len_ret = sizeof *addr; return 1; } case BTPROTO_SCO: { struct sockaddr_sco *addr = (struct sockaddr_sco*) addr_ret; char *ba_name = 0; if( !PyArg_ParseTuple(args, "s", &ba_name) ) { return 0; } str2ba( ba_name, &addr->sco_bdaddr); *len_ret = sizeof *addr; return 1; } default: { PyErr_SetString(bluetooth_error, "getsockaddrarg: unknown Bluetooth protocol"); return 0; } } } /* Get the address length according to the socket object's address family. Return 1 if the family is known, 0 otherwise. The length is returned through len_ret. */ int 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_SCO: *len_ret = sizeof (struct sockaddr_sco); return 1; case BTPROTO_HCI: *len_ret = sizeof (struct sockaddr_hci); return 1; default: PyErr_SetString(bluetooth_error, "getsockaddrlen: unknown bluetooth protocol"); return 0; } } int str2uuid( const char *uuid_str, uuid_t *uuid ) { uint32_t uuid_int[4]; char *endptr; if( strlen( uuid_str ) == 36 ) { // Parse uuid128 standard format: 12345678-9012-3456-7890-123456789012 char buf[9] = { 0 }; if( uuid_str[8] != '-' && uuid_str[13] != '-' && uuid_str[18] != '-' && uuid_str[23] != '-' ) { return 0; } // first 8-bytes strncpy(buf, uuid_str, 8); uuid_int[0] = htonl( strtoul( buf, &endptr, 16 ) ); if( endptr != buf + 8 ) return 0; // second 8-bytes strncpy(buf, uuid_str+9, 4); strncpy(buf+4, uuid_str+14, 4); uuid_int[1] = htonl( strtoul( buf, &endptr, 16 ) ); if( endptr != buf + 8 ) return 0; // third 8-bytes strncpy(buf, uuid_str+19, 4); strncpy(buf+4, uuid_str+24, 4); uuid_int[2] = htonl( strtoul( buf, &endptr, 16 ) ); if( endptr != buf + 8 ) return 0; // fourth 8-bytes strncpy(buf, uuid_str+28, 8); uuid_int[3] = htonl( strtoul( buf, &endptr, 16 ) ); if( endptr != buf + 8 ) return 0; if( uuid != NULL ) sdp_uuid128_create( uuid, uuid_int ); } else if ( strlen( uuid_str ) == 8 ) { // 32-bit reserved UUID uint32_t i = strtoul( uuid_str, &endptr, 16 ); if( endptr != uuid_str + 8 ) return 0; if( uuid != NULL ) sdp_uuid32_create( uuid, i ); } else if( strlen( uuid_str ) == 4 ) { // 16-bit reserved UUID int i = strtol( uuid_str, &endptr, 16 ); if( endptr != uuid_str + 4 ) return 0; if( uuid != NULL ) sdp_uuid16_create( uuid, i ); } else { return 0; } return 1; } int pyunicode2uuid( PyObject *item, uuid_t *uuid ) { #if PY_MAJOR_VERSION >= 3 PyObject* ascii = PyUnicode_AsASCIIString( item ); int ret = str2uuid( PyBytes_AsString( ascii ), uuid ); Py_XDECREF( ascii ); return ret; #else return str2uuid( PyString_AsString( item ), NULL ); #endif } void uuid2str( const uuid_t *uuid, char *dest ) { if( uuid->type == SDP_UUID16 ) { sprintf(dest, "%04X", uuid->value.uuid16 ); } else if( uuid->type == SDP_UUID32 ) { sprintf(dest, "%08X", uuid->value.uuid32 ); } else if( uuid->type == SDP_UUID128 ) { uint32_t *data = (uint32_t*)(&uuid->value.uuid128); sprintf(dest, "%08X-%04X-%04X-%04X-%04X%08X", ntohl(data[0]), ntohl(data[1])>>16, (ntohl(data[1])<<16)>>16, ntohl(data[2])>>16, (ntohl(data[2])<<16)>>16, ntohl(data[3])); } } // =================== socket methods ==================== // /* s.accept() method */ static PyObject * sock_accept(PySocketSockObject *s) { char addrbuf[256]; int newfd; socklen_t addrlen; PyObject *sock = NULL; PyObject *addr = NULL; PyObject *res = NULL; int timeout; if (!getsockaddrlen(s, &addrlen)) return NULL; memset(addrbuf, 0, addrlen); newfd = -1; Py_BEGIN_ALLOW_THREADS timeout = internal_select(s, 0); if (!timeout) newfd = accept(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen); Py_END_ALLOW_THREADS if (timeout) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } if (newfd < 0) return s->errorhandler(); /* Create the new object with unspecified family, to avoid calls to bind() etc. on it. */ sock = (PyObject *) new_sockobject(newfd, s->sock_family, s->sock_type, s->sock_proto); if (sock == NULL) { close(newfd); goto finally; } addr = makesockaddr(s, (struct sockaddr *)addrbuf, addrlen); if (addr == NULL) goto finally; res = Py_BuildValue("OO", sock, addr); finally: Py_XDECREF(sock); Py_XDECREF(addr); return res; } PyDoc_STRVAR(accept_doc, "accept() -> (socket object, address info)\n\ \n\ Wait for an incoming connection. Return a new socket representing the\n\ connection, and the address of the client. For L2CAP sockets, the address\n\ is a (host, psm) tuple. For RFCOMM sockets, the address is a (host, channel)\n\ tuple. For SCO sockets, the address is just a host."); /* s.setblocking(flag) method. Argument: False -- non-blocking mode; same as settimeout(0) True -- blocking mode; same as settimeout(None) */ static PyObject * sock_setblocking(PySocketSockObject *s, PyObject *arg) { int block; block = PyInt_AsLong(arg); if (block == -1 && PyErr_Occurred()) return NULL; s->sock_timeout = block ? -1.0 : 0.0; internal_setblocking(s, block); Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(setblocking_doc, "setblocking(flag)\n\ \n\ Set the socket to blocking (flag is true) or non-blocking (false).\n\ setblocking(True) is equivalent to settimeout(None);\n\ setblocking(False) is equivalent to settimeout(0.0)."); /* s.settimeout(timeout) method. Argument: None -- no timeout, blocking mode; same as setblocking(True) 0.0 -- non-blocking mode; same as setblocking(False) > 0 -- timeout mode; operations time out after timeout seconds < 0 -- illegal; raises an exception */ static PyObject * sock_settimeout(PySocketSockObject *s, PyObject *arg) { double timeout; if (arg == Py_None) timeout = -1.0; else { timeout = PyFloat_AsDouble(arg); if (timeout < 0.0) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_ValueError, "Timeout value out of range"); return NULL; } } s->sock_timeout = timeout; internal_setblocking(s, timeout < 0.0); Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(settimeout_doc, "settimeout(timeout)\n\ \n\ Set a timeout on socket operations. 'timeout' can be a float,\n\ giving in seconds, or None. Setting a timeout of None disables\n\ the timeout feature and is equivalent to setblocking(1).\n\ Setting a timeout of zero is the same as setblocking(0)."); /* s.gettimeout() method. Returns the timeout associated with a socket. */ static PyObject * sock_gettimeout(PySocketSockObject *s) { if (s->sock_timeout < 0.0) { Py_INCREF(Py_None); return Py_None; } else return PyFloat_FromDouble(s->sock_timeout); } PyDoc_STRVAR(gettimeout_doc, "gettimeout() -> timeout\n\ \n\ Returns the timeout in floating seconds associated with socket \n\ operations. A timeout of None indicates that timeouts on socket \n\ operations are disabled."); /* s.setsockopt() method. With an integer third argument, sets an integer option. With a string third argument, sets an option from a buffer; use optional built-in module 'struct' to encode the string. */ static PyObject * sock_setsockopt(PySocketSockObject *s, PyObject *args) { int level; int optname; int res; void *buf; int buflen; int flag; if (PyArg_ParseTuple(args, "iii:setsockopt", &level, &optname, &flag)) { buf = (void *) &flag; buflen = sizeof flag; } else { PyErr_Clear(); if (!PyArg_ParseTuple(args, "iis#:setsockopt", &level, &optname, &buf, &buflen)) { return NULL; } } res = setsockopt(s->sock_fd, level, optname, buf, buflen); if (res < 0) return s->errorhandler(); Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(setsockopt_doc, "setsockopt(level, option, value)\n\ \n\ Set a socket option. See the Unix manual for level and option.\n\ The value argument can either be an integer or a string."); /* s.getsockopt() method. With two arguments, retrieves an integer option. With a third integer argument, retrieves a string buffer of that size; use optional built-in module 'struct' to decode the string. */ static PyObject * sock_getsockopt(PySocketSockObject *s, PyObject *args) { int level; int optname; int res; socklen_t buflen = 0; if (!PyArg_ParseTuple(args, "ii|i:getsockopt", &level, &optname, &buflen)) return NULL; if (buflen == 0) { int flag = 0; socklen_t flagsize = sizeof flag; res = getsockopt(s->sock_fd, level, optname, (void *)&flag, &flagsize); if (res < 0) return s->errorhandler(); return PyInt_FromLong(flag); } else if (buflen <= 0 || buflen > 1024) { PyErr_SetString(bluetooth_error, "getsockopt buflen out of range"); return NULL; } else { PyObject *buf = PyString_FromStringAndSize((char *)NULL, buflen); if (buf == NULL) return NULL; res = getsockopt(s->sock_fd, level, optname, (void *)PyString_AS_STRING(buf), &buflen); if (res < 0) { Py_DECREF(buf); return s->errorhandler(); } _PyString_Resize(&buf, buflen); return buf; } return NULL; } PyDoc_STRVAR(getsockopt_doc, "getsockopt(level, option[, buffersize]) -> value\n\ \n\ Get a socket option. See the Unix manual for level and option.\n\ If a nonzero buffersize argument is given, the return value is a\n\ string of that length; otherwise it is an integer."); static PyObject * sock_setl2capsecurity(PySocketSockObject *s, PyObject *args) { int level; struct bt_security sec; if (! PyArg_ParseTuple(args, "i:setsockopt", &level)) return NULL; memset(&sec, 0, sizeof(sec)); sec.level = level; if (setsockopt(s->sock_fd, SOL_BLUETOOTH, BT_SECURITY, &sec, sizeof(sec)) == 0) { Py_INCREF(Py_None); return Py_None; } if (errno != ENOPROTOOPT) return s->errorhandler(); int lm_map[] = { 0, L2CAP_LM_AUTH, L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT, L2CAP_LM_AUTH | L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE, }, opt = lm_map[level]; if (setsockopt(s->sock_fd, SOL_L2CAP, L2CAP_LM, &opt, sizeof(opt)) < 0) return s->errorhandler(); Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(setl2capsecurity_doc, "setl2capsecurity(BT_SECURITY_*) -> value\n\ \n\ Sets socket security. Levels are BT_SECURITY_SDP, LOW, MEDIUM\n\ and HIGH."); /* s.bind(sockaddr) method */ static PyObject * sock_bind(PySocketSockObject *s, PyObject *addro) { struct sockaddr addr = { 0 }; int addrlen; int res; if (!getsockaddrarg(s, addro, &addr, &addrlen)) return NULL; Py_BEGIN_ALLOW_THREADS res = bind(s->sock_fd, &addr, addrlen); Py_END_ALLOW_THREADS if (res < 0) return s->errorhandler(); Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(bind_doc, "bind(address)\n\ \n\ Bind the socket to a local address. address must always be a tuple.\n\ HCI sockets: ( device number, )\n\ device number should be 0, 1, 2, etc.\n\ L2CAP sockets: ( host, psm )\n\ host should be an address e.g. \"01:23:45:67:89:ab\"\n\ psm should be an unsigned integer\n\ RFCOMM sockets: ( host, channel )\n\ SCO sockets: ( host )\n\ "); /* s.close() method. Set the file descriptor to -1 so operations tried subsequently will surely fail. */ static PyObject * sock_close(PySocketSockObject *s) { int fd; if ((fd = s->sock_fd) != -1) { s->sock_fd = -1; Py_BEGIN_ALLOW_THREADS (void) close(fd); Py_END_ALLOW_THREADS } if( s->sdp_session ) { sdp_close( s->sdp_session ); s->sdp_record_handle = 0; s->sdp_session = NULL; } Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(close_doc, "close()\n\ \n\ Close the socket. It cannot be used after this call."); static int internal_connect(PySocketSockObject *s, struct sockaddr *addr, int addrlen, int *timeoutp) { int res, timeout; timeout = 0; res = connect(s->sock_fd, addr, addrlen); if (s->sock_timeout > 0.0) { if (res < 0 && errno == EINPROGRESS) { timeout = internal_select(s, 1); res = connect(s->sock_fd, addr, addrlen); if (res < 0 && errno == EISCONN) res = 0; } } if (res < 0) res = errno; *timeoutp = timeout; return res; } /* s.connect(sockaddr) method */ static PyObject * sock_connect(PySocketSockObject *s, PyObject *addro) { struct sockaddr addr = { 0 }; int addrlen; int res; int timeout; if (!getsockaddrarg(s, addro, &addr, &addrlen)) return NULL; Py_BEGIN_ALLOW_THREADS res = internal_connect(s, &addr, addrlen, &timeout); Py_END_ALLOW_THREADS if (timeout) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } if (res != 0) return s->errorhandler(); Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(connect_doc, "connect(address)\n\ \n\ Connect the socket to a remote address. For L2CAP sockets, the address is a \n\ (host,psm) tuple. For RFCOMM sockets, the address is a (host,channel) tuple.\n\ For SCO sockets, the address is just the host."); /* s.connect_ex(sockaddr) method */ static PyObject * sock_connect_ex(PySocketSockObject *s, PyObject *addro) { struct sockaddr addr = { 0 }; int addrlen; int res; int timeout; if (!getsockaddrarg(s, addro, &addr, &addrlen)) return NULL; Py_BEGIN_ALLOW_THREADS res = internal_connect(s, &addr, addrlen, &timeout); Py_END_ALLOW_THREADS return PyInt_FromLong((long) res); } PyDoc_STRVAR(connect_ex_doc, "connect_ex(address) -> errno\n\ \n\ This is like connect(address), but returns an error code (the errno value)\n\ instead of raising an exception when an error occurs."); /* s.fileno() method */ static PyObject * sock_fileno(PySocketSockObject *s) { return PyInt_FromLong((long) s->sock_fd); } PyDoc_STRVAR(fileno_doc, "fileno() -> integer\n\ \n\ Return the integer file descriptor of the socket."); #ifndef NO_DUP /* s.dup() method */ static PyObject * sock_dup(PySocketSockObject *s) { int newfd; PyObject *sock; newfd = dup(s->sock_fd); if (newfd < 0) return s->errorhandler(); sock = (PyObject *) new_sockobject(newfd, s->sock_family, s->sock_type, s->sock_proto); if (sock == NULL) close(newfd); return sock; } PyDoc_STRVAR(dup_doc, "dup() -> socket object\n\ \n\ Return a new socket object connected to the same system resource."); #endif /* s.getsockname() method */ static PyObject * sock_getsockname(PySocketSockObject *s) { char addrbuf[256]; int res; socklen_t addrlen; if (!getsockaddrlen(s, &addrlen)) return NULL; memset(addrbuf, 0, addrlen); Py_BEGIN_ALLOW_THREADS res = getsockname(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen); Py_END_ALLOW_THREADS if (res < 0) return s->errorhandler(); return makesockaddr(s, (struct sockaddr *) addrbuf, addrlen); } PyDoc_STRVAR(getsockname_doc, "getsockname() -> address info\n\ \n\ Return the address of the local endpoint."); /* s.getpeername() method */ static PyObject * sock_getpeername(PySocketSockObject *s) { char addrbuf[256]; int res; socklen_t addrlen; if (!getsockaddrlen(s, &addrlen)) return NULL; memset(addrbuf, 0, addrlen); Py_BEGIN_ALLOW_THREADS res = getpeername(s->sock_fd, (struct sockaddr *) addrbuf, &addrlen); Py_END_ALLOW_THREADS if (res < 0) return s->errorhandler(); return makesockaddr(s, (struct sockaddr *) addrbuf, addrlen); } PyDoc_STRVAR(getpeername_doc, "getpeername() -> address info\n\ \n\ Return the address of the remote endpoint. For HCI sockets, the address is a\n\ device number (0, 1, 2, etc). For L2CAP sockets, the address is a \n\ (host,psm) tuple. For RFCOMM sockets, the address is a (host,channel) tuple.\n\ For SCO sockets, the address is just the host."); /* s.listen(n) method */ static PyObject * sock_listen(PySocketSockObject *s, PyObject *arg) { int backlog; int res; backlog = PyInt_AsLong(arg); if (backlog == -1 && PyErr_Occurred()) return NULL; Py_BEGIN_ALLOW_THREADS if (backlog < 1) backlog = 1; res = listen(s->sock_fd, backlog); Py_END_ALLOW_THREADS if (res < 0) return s->errorhandler(); Py_INCREF(Py_None); s->is_listening_socket = 1; return Py_None; } PyDoc_STRVAR(listen_doc, "listen(backlog)\n\ \n\ Enable a server to accept connections. The backlog argument must be at\n\ least 1; it specifies the number of unaccepted connection that the system\n\ will allow before refusing new connections."); #ifndef NO_DUP /* s.makefile(mode) method. Create a new open file object referring to a dupped version of the socket's file descriptor. (The dup() call is necessary so that the open file and socket objects may be closed independent of each other.) The mode argument specifies 'r' or 'w' passed to fdopen(). */ static PyObject * sock_makefile(PySocketSockObject *s, PyObject *args) { extern int fclose(FILE *); char *mode = "r"; int bufsize = -1; int fd; FILE *fp; PyObject *f; if (!PyArg_ParseTuple(args, "|si:makefile", &mode, &bufsize)) return NULL; if ((fd = dup(s->sock_fd)) < 0 || (fp = fdopen(fd, mode)) == NULL) { if (fd >= 0) close(fd); return s->errorhandler(); } #if PY_MAJOR_VERSION >= 3 f = PyFile_FromFd(fd, "", mode, bufsize, NULL, NULL, NULL, 1); #else f = PyFile_FromFile(fp, "", mode, fclose); if (f != NULL) PyFile_SetBufSize(f, bufsize); #endif return f; } PyDoc_STRVAR(makefile_doc, "makefile([mode[, buffersize]]) -> file object\n\ \n\ Return a regular file object corresponding to the socket.\n\ The mode and buffersize arguments are as for the built-in open() function."); #endif /* NO_DUP */ /* s.recv(nbytes [,flags]) method */ static PyObject * sock_recv(PySocketSockObject *s, PyObject *args) { int len, n = 0, flags = 0, timeout; PyObject *buf; if (!PyArg_ParseTuple(args, "i|i:recv", &len, &flags)) return NULL; if (len < 0) { PyErr_SetString(PyExc_ValueError, "negative buffersize in recv"); return NULL; } buf = PyString_FromStringAndSize((char *) 0, len); if (buf == NULL) return NULL; Py_BEGIN_ALLOW_THREADS timeout = internal_select(s, 0); if (!timeout) n = recv(s->sock_fd, PyString_AS_STRING(buf), len, flags); Py_END_ALLOW_THREADS if (timeout) { Py_DECREF(buf); PyErr_SetString(socket_timeout, "timed out"); return NULL; } if (n < 0) { Py_DECREF(buf); return s->errorhandler(); } if (n != len) _PyString_Resize(&buf, n); return buf; } PyDoc_STRVAR(recv_doc, "recv(buffersize[, flags]) -> data\n\ \n\ Receive up to buffersize bytes from the socket. For the optional flags\n\ argument, see the Unix manual. When no data is available, block until\n\ at least one byte is available or until the remote end is closed. When\n\ the remote end is closed and all data is read, return the empty string."); /* s.recvfrom(nbytes [,flags]) method */ static PyObject * sock_recvfrom(PySocketSockObject *s, PyObject *args) { char addrbuf[256]; PyObject *buf = NULL; PyObject *addr = NULL; PyObject *ret = NULL; int len, n = 0, flags = 0, timeout; socklen_t addrlen; if (!PyArg_ParseTuple(args, "i|i:recvfrom", &len, &flags)) return NULL; if (!getsockaddrlen(s, &addrlen)) return NULL; buf = PyString_FromStringAndSize((char *) 0, len); if (buf == NULL) return NULL; Py_BEGIN_ALLOW_THREADS memset(addrbuf, 0, addrlen); timeout = internal_select(s, 0); if (!timeout) n = recvfrom(s->sock_fd, PyString_AS_STRING(buf), len, flags, (void *)addrbuf, &addrlen ); Py_END_ALLOW_THREADS if (timeout) { Py_DECREF(buf); PyErr_SetString(socket_timeout, "timed out"); return NULL; } if (n < 0) { Py_DECREF(buf); return s->errorhandler(); } if (n != len && _PyString_Resize(&buf, n) < 0) return NULL; if (!(addr = makesockaddr(s, (struct sockaddr *)addrbuf, addrlen))) goto finally; ret = Py_BuildValue("OO", buf, addr); finally: Py_XDECREF(addr); Py_XDECREF(buf); return ret; } PyDoc_STRVAR(recvfrom_doc, "recvfrom(buffersize[, flags]) -> (data, address info)\n\ \n\ Like recv(buffersize, flags) but also return the sender's address info."); /* s.send(data [,flags]) method */ static PyObject * sock_send(PySocketSockObject *s, PyObject *args) { char *buf; int len, n = 0, flags = 0, timeout; if (!PyArg_ParseTuple(args, "s#|i:send", &buf, &len, &flags)) return NULL; Py_BEGIN_ALLOW_THREADS timeout = internal_select(s, 1); if (!timeout) n = send(s->sock_fd, buf, len, flags); Py_END_ALLOW_THREADS if (timeout) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } if (n < 0) return s->errorhandler(); return PyInt_FromLong((long)n); } PyDoc_STRVAR(send_doc, "send(data[, flags]) -> count\n\ \n\ Send a data string to the socket. For the optional flags\n\ argument, see the Unix manual. Return the number of bytes\n\ sent; this may be less than len(data) if the network is busy."); /* s.sendall(data [,flags]) method */ static PyObject * sock_sendall(PySocketSockObject *s, PyObject *args) { char *buf; int len, n = 0, flags = 0, timeout; if (!PyArg_ParseTuple(args, "s#|i:sendall", &buf, &len, &flags)) return NULL; Py_BEGIN_ALLOW_THREADS do { timeout = internal_select(s, 1); if (timeout) break; n = send(s->sock_fd, buf, len, flags); if (n < 0) break; buf += n; len -= n; } while (len > 0); Py_END_ALLOW_THREADS if (timeout) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } if (n < 0) return s->errorhandler(); Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(sendall_doc, "sendall(data[, flags])\n\ \n\ Send a data string to the socket. For the optional flags\n\ argument, see the Unix manual. This calls send() repeatedly\n\ until all data is sent. If an error occurs, it's impossible\n\ to tell how much data has been sent."); /* s.sendto(data, [flags,] sockaddr) method */ static PyObject * sock_sendto(PySocketSockObject *s, PyObject *args) { PyObject *addro; char *buf; struct sockaddr addr = { 0 }; int addrlen, len, n = 0, flags, timeout; flags = 0; if (!PyArg_ParseTuple(args, "s#O:sendto", &buf, &len, &addro)) { PyErr_Clear(); if (!PyArg_ParseTuple(args, "s#iO:sendto", &buf, &len, &flags, &addro)) return NULL; } if (!getsockaddrarg(s, addro, &addr, &addrlen)) return NULL; Py_BEGIN_ALLOW_THREADS timeout = internal_select(s, 1); if (!timeout) n = sendto(s->sock_fd, buf, len, flags, &addr, addrlen); Py_END_ALLOW_THREADS if (timeout) { PyErr_SetString(socket_timeout, "timed out"); return NULL; } if (n < 0) return s->errorhandler(); return PyInt_FromLong((long)n); } PyDoc_STRVAR(sendto_doc, "sendto(data[, flags], address) -> count\n\ \n\ Like send(data, flags) but allows specifying the destination address.\n\ For IP sockets, the address is a pair (hostaddr, port)."); /* s.shutdown(how) method */ static PyObject * sock_shutdown(PySocketSockObject *s, PyObject *arg) { int how; int res; how = PyInt_AsLong(arg); if (how == -1 && PyErr_Occurred()) return NULL; Py_BEGIN_ALLOW_THREADS res = shutdown(s->sock_fd, how); Py_END_ALLOW_THREADS if (res < 0) return s->errorhandler(); Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(shutdown_doc, "shutdown(flag)\n\ \n\ Shut down the reading side of the socket (flag == 0), the writing side\n\ of the socket (flag == 1), or both ends (flag == 2)."); /* s.getsockid() method */ static PyObject * sock_getsockid(PySocketSockObject *s, PyObject *arg) { int dd; dd = s->sock_fd; return Py_BuildValue("i", dd); } /* List of methods for socket objects */ static PyMethodDef sock_methods[] = { {"accept", (PyCFunction)sock_accept, METH_NOARGS, accept_doc}, {"bind", (PyCFunction)sock_bind, METH_O, bind_doc}, {"close", (PyCFunction)sock_close, METH_NOARGS, close_doc}, {"connect", (PyCFunction)sock_connect, METH_O, connect_doc}, {"connect_ex", (PyCFunction)sock_connect_ex, METH_O, connect_ex_doc}, #ifndef NO_DUP {"dup", (PyCFunction)sock_dup, METH_NOARGS, dup_doc}, #endif {"fileno", (PyCFunction)sock_fileno, METH_NOARGS, fileno_doc}, {"getpeername", (PyCFunction)sock_getpeername, METH_NOARGS, getpeername_doc}, {"getsockid", (PyCFunction)sock_getsockid, METH_NOARGS, "Gets socket id."}, {"getsockname", (PyCFunction)sock_getsockname, METH_NOARGS, getsockname_doc}, {"getsockopt", (PyCFunction)sock_getsockopt, METH_VARARGS, getsockopt_doc}, {"listen", (PyCFunction)sock_listen, METH_O, listen_doc}, #ifndef NO_DUP {"makefile", (PyCFunction)sock_makefile, METH_VARARGS, makefile_doc}, #endif {"recv", (PyCFunction)sock_recv, METH_VARARGS, recv_doc}, {"recvfrom", (PyCFunction)sock_recvfrom, METH_VARARGS, recvfrom_doc}, {"send", (PyCFunction)sock_send, METH_VARARGS, send_doc}, {"sendall", (PyCFunction)sock_sendall, METH_VARARGS, sendall_doc}, {"sendto", (PyCFunction)sock_sendto, METH_VARARGS, sendto_doc}, {"setblocking", (PyCFunction)sock_setblocking, METH_O, setblocking_doc}, {"settimeout", (PyCFunction)sock_settimeout, METH_O, settimeout_doc}, {"gettimeout", (PyCFunction)sock_gettimeout, METH_NOARGS, gettimeout_doc}, {"setsockopt", (PyCFunction)sock_setsockopt, METH_VARARGS, setsockopt_doc}, {"setl2capsecurity", (PyCFunction)sock_setl2capsecurity, METH_VARARGS, setl2capsecurity_doc}, {"shutdown", (PyCFunction)sock_shutdown, METH_O, shutdown_doc}, {NULL, NULL} /* sentinel */ }; /* Deallocate a socket object in response to the last Py_DECREF(). First close the file description. */ static void sock_dealloc(PySocketSockObject *s) { // close the OS file descriptor if (s->sock_fd != -1) { Py_BEGIN_ALLOW_THREADS close(s->sock_fd); Py_END_ALLOW_THREADS } if( s->sdp_session ) { sdp_close( s->sdp_session ); s->sdp_record_handle = 0; s->sdp_session = NULL; } Py_TYPE(s)->tp_free((PyObject *)s); } static PyObject * sock_repr(PySocketSockObject *s) { char buf[512]; #if SIZEOF_SOCKET_T > SIZEOF_LONG if (s->sock_fd > LONG_MAX) { /* this can occur on Win64, and actually there is a special ugly printf formatter for decimal pointer length integer printing, only bother if necessary*/ PyErr_SetString(PyExc_OverflowError, "no printf formatter to display " "the socket descriptor in decimal"); return NULL; } #endif PyOS_snprintf( buf, sizeof(buf), "", (long)s->sock_fd, s->sock_family, s->sock_type, s->sock_proto); return PyString_FromString(buf); } /* Create a new, uninitialized socket object. */ static PyObject * sock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *new; new = type->tp_alloc(type, 0); if (new != NULL) { ((PySocketSockObject *)new)->sock_fd = -1; ((PySocketSockObject *)new)->sock_timeout = -1.0; ((PySocketSockObject *)new)->errorhandler = &set_error; } return new; } /* Initialize a new socket object. */ /*ARGSUSED*/ static int sock_initobj(PyObject *self, PyObject *args, PyObject *kwds) { PySocketSockObject *s = (PySocketSockObject *)self; int fd; int family = AF_BLUETOOTH, type = SOCK_STREAM, proto = BTPROTO_RFCOMM; static char *keywords[] = {"proto", 0}; if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:socket", keywords, &proto)) return -1; switch(proto) { case BTPROTO_HCI: type = SOCK_RAW; break; case BTPROTO_L2CAP: type = SOCK_SEQPACKET; break; case BTPROTO_RFCOMM: type = SOCK_STREAM; break; case BTPROTO_SCO: type = SOCK_SEQPACKET; break; } Py_BEGIN_ALLOW_THREADS fd = socket(family, type, proto); Py_END_ALLOW_THREADS if (fd < 0) { set_error(); return -1; } init_sockobject(s, fd, family, type, proto); /* From now on, ignore SIGPIPE and let the error checking do the work. */ #ifdef SIGPIPE (void) signal(SIGPIPE, SIG_IGN); #endif return 0; } /* Type object for socket objects. */ PyTypeObject sock_type = { #if PY_MAJOR_VERSION < 3 PyObject_HEAD_INIT(0) /* Must fill in type value later */ 0, /* ob_size */ #else PyVarObject_HEAD_INIT(NULL, 0) /* Must fill in type value later */ #endif "_bluetooth.btsocket", /* tp_name */ sizeof(PySocketSockObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)sock_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)sock_repr,/* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ sock_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ sock_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ sock_initobj, /* tp_init */ PyType_GenericAlloc,/* tp_alloc */ sock_new, /* tp_new */ PyObject_Del, /* tp_free */ }; #ifndef NO_DUP /* Create a socket object from a numeric file description. Useful e.g. if stdin is a socket. Additional arguments as for socket(). */ /*ARGSUSED*/ static PyObject * bt_fromfd(PyObject *self, PyObject *args) { PySocketSockObject *s; int fd; int family, type, proto = 0; if (!PyArg_ParseTuple(args, "iii|i:fromfd", &fd, &family, &type, &proto)) return NULL; /* Dup the fd so it and the socket can be closed independently */ fd = dup(fd); if (fd < 0) return set_error(); s = new_sockobject(fd, family, type, proto); /* From now on, ignore SIGPIPE and let the error checking do the work. */ #ifdef SIGPIPE (void) signal(SIGPIPE, SIG_IGN); #endif return (PyObject *) s; } PyDoc_STRVAR(bt_fromfd_doc, "fromfd(fd, family, type[, proto]) -> socket object\n\ \n\ Create a socket object from the given file descriptor.\n\ The remaining arguments are the same as for socket()."); #endif /* NO_DUP */ static PyObject * bt_btohs(PyObject *self, PyObject *args) { int x1, x2; if (!PyArg_ParseTuple(args, "i:btohs", &x1)) { return NULL; } x2 = (int)btohs((short)x1); return PyInt_FromLong(x2); } PyDoc_STRVAR(bt_btohs_doc, "btohs(integer) -> integer\n\ \n\ Convert a 16-bit integer from bluetooth to host byte order."); static PyObject * bt_btohl(PyObject *self, PyObject *args) { unsigned long x; PyObject *arg; if (!PyArg_ParseTuple(args, "O:btohl", &arg)) { return NULL; } if (PyInt_Check(arg)) { x = PyInt_AS_LONG(arg); if (x == (unsigned long) -1 && PyErr_Occurred()) return NULL; } else if (PyLong_Check(arg)) { x = PyLong_AsUnsignedLong(arg); if (x == (unsigned long) -1 && PyErr_Occurred()) return NULL; #if SIZEOF_LONG > 4 { unsigned long y; /* only want the trailing 32 bits */ y = x & 0xFFFFFFFFUL; if (y ^ x) return PyErr_Format(PyExc_OverflowError, "long int larger than 32 bits"); x = y; } #endif } else return PyErr_Format(PyExc_TypeError, "expected int/long, %s found", arg->ob_type->tp_name); if (x == (unsigned long) -1 && PyErr_Occurred()) return NULL; return PyInt_FromLong(btohl(x)); } PyDoc_STRVAR(bt_btohl_doc, "btohl(integer) -> integer\n\ \n\ Convert a 32-bit integer from bluetooth to host byte order."); static PyObject * bt_htobs(PyObject *self, PyObject *args) { unsigned long x1, x2; if (!PyArg_ParseTuple(args, "i:htobs", &x1)) { return NULL; } x2 = (int)htobs((short)x1); return PyInt_FromLong(x2); } PyDoc_STRVAR(bt_htobs_doc, "htobs(integer) -> integer\n\ \n\ Convert a 16-bit integer from host to bluetooth byte order."); static PyObject * bt_htobl(PyObject *self, PyObject *args) { unsigned long x; PyObject *arg; if (!PyArg_ParseTuple(args, "O:htobl", &arg)) { return NULL; } if (PyInt_Check(arg)) { x = PyInt_AS_LONG(arg); if (x == (unsigned long) -1 && PyErr_Occurred()) return NULL; } else if (PyLong_Check(arg)) { x = PyLong_AsUnsignedLong(arg); if (x == (unsigned long) -1 && PyErr_Occurred()) return NULL; #if SIZEOF_LONG > 4 { unsigned long y; /* only want the trailing 32 bits */ y = x & 0xFFFFFFFFUL; if (y ^ x) return PyErr_Format(PyExc_OverflowError, "long int larger than 32 bits"); x = y; } #endif } else return PyErr_Format(PyExc_TypeError, "expected int/long, %s found", arg->ob_type->tp_name); return PyInt_FromLong(htobl(x)); } //static PyObject * //bt_get_available_port_number( PyObject *self, PyObject *arg ) //{ // int protocol = -1; // int s; // // protocol = PyInt_AsLong(arg); // // if (protocol == -1 && PyErr_Occurred()) // return NULL; // // switch(protocol) { // case BTPROTO_RFCOMM: // { // struct sockaddr_rc sockaddr = { 0 }; // int s, psm; // s = socket( AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM ); // // sockaddr.rc_family = AF_BLUETOOTH; // bacppy( &sockaddr.rc_bdaddr, BDADDR_ANY // } // break; // case BTPROTO_L2CAP: // { // loc_addr.l2_family = AF_BLUETOOTH; // bacpy( &loc_addr.l2_bdaddr, BDADDR_ANY ); // loc_addr.l2_psm = htobs(0x1001); // // } // break; // default: // { // PyErr_SetString( PyExc_ValueError, // "protocol must be either RFCOMM or L2CAP" ); // return 0; // } // break; // } // Py_INCREF( Py_None ); // return Py_None; //} PyDoc_STRVAR(bt_htobl_doc, "htobl(integer) -> integer\n\ \n\ Convert a 32-bit integer from host to bluetooth byte order."); /* Python API to getting and setting the default timeout value. */ static PyObject * bt_getdefaulttimeout(PyObject *self) { if (defaulttimeout < 0.0) { Py_INCREF(Py_None); return Py_None; } else return PyFloat_FromDouble(defaulttimeout); } PyDoc_STRVAR(bt_getdefaulttimeout_doc, "getdefaulttimeout() -> timeout\n\ \n\ Returns the default timeout in floating seconds for new socket objects.\n\ A value of None indicates that new socket objects have no timeout.\n\ When the socket module is first imported, the default is None."); static PyObject * bt_setdefaulttimeout(PyObject *self, PyObject *arg) { double timeout; if (arg == Py_None) timeout = -1.0; else { timeout = PyFloat_AsDouble(arg); if (timeout < 0.0) { if (!PyErr_Occurred()) PyErr_SetString(PyExc_ValueError, "Timeout value out of range"); return NULL; } } defaulttimeout = timeout; Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(bt_setdefaulttimeout_doc, "setdefaulttimeout(timeout)\n\ \n\ Set the default timeout in floating seconds for new socket objects.\n\ A value of None indicates that new socket objects have no timeout.\n\ When the socket module is first imported, the default is None."); /* * ---------------------------------------------------------------------- * HCI Section (Calvin) * * This section provides the socket methods for calling HCI commands. * These commands may be called statically, and implementation is * independent from the rest of the module (except for bt_methods[]). * * ---------------------------------------------------------------------- * */ /* * params: (int) device number * effect: opens and binds a new HCI socket * return: a PySocketSockObject, or NULL on failure */ static PyObject * bt_hci_open_dev(PyObject *self, PyObject *args) { int dev = -1, fd; PySocketSockObject *s = NULL; if ( !PyArg_ParseTuple(args, "|i", &dev) ) { return NULL; } // if the device was not specified, just use the first available bt device if (dev < 0) { dev = hci_get_route(NULL); } if (dev < 0) { PyErr_SetString(bluetooth_error, "no available bluetoot devices"); return 0; } Py_BEGIN_ALLOW_THREADS fd = hci_open_dev(dev); Py_END_ALLOW_THREADS s = (PySocketSockObject *)PyType_GenericNew(&sock_type, NULL, NULL); if (s != NULL) init_sockobject(s, fd, AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI); return (PyObject*)s; } PyDoc_STRVAR(bt_hci_open_dev_doc, "hci_open_dev"); /* * params: (int) device number * effect: closes an HCI socket */ static PyObject * bt_hci_close_dev(PyObject *self, PyObject *args) { int dev, err; if ( !PyArg_ParseTuple(args, "i", &dev) ) { return NULL; } Py_BEGIN_ALLOW_THREADS err = hci_close_dev(dev); Py_END_ALLOW_THREADS if( err < 0 ) return set_error(); Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(bt_hci_close_dev_doc, "hci_close_dev(dev_id)\n\ \n\ closes the specified device id. Note: device id is NOT a btoscket.\n\ You can also use btsocket.close() to close a specific socket."); /* * params: (int) socket fd, (uint_16) ogf control bits * (uint_16) ocf control bits, (struct) command params * effect: executes command described by the OGF and OCF bits * (see bluetooth/hci.h) * return: (int) 0 on success, -1 on failure */ static PyObject * bt_hci_send_cmd(PyObject *self, PyObject *args) { PySocketSockObject *socko = NULL; int err, plen = 0; uint16_t ogf, ocf; char *param = NULL; int dd = 0; if ( !PyArg_ParseTuple(args, "OHH|s#", &socko, &ogf, &ocf, ¶m, &plen)) { return NULL; } dd = socko->sock_fd; Py_BEGIN_ALLOW_THREADS err = hci_send_cmd(dd, ogf, ocf, plen, (void*)param); Py_END_ALLOW_THREADS if( err ) return socko->errorhandler(); return Py_BuildValue("i", err); } PyDoc_STRVAR(bt_hci_send_cmd_doc, "hci_send_command(sock, ogf, ocf, params)\n\ \n\ Transmits the specified HCI command to the socket.\n\ sock - the btoscket object to use\n\ ogf, pcf - see bluetooth specification\n\ params - packed command parameters (use the struct module to do this)"); static PyObject * bt_hci_send_req(PyObject *self, PyObject *args, PyObject *kwds) { PySocketSockObject *socko = NULL; int err; int to=0; char rparam[256]; struct hci_request req = { 0 }; int dd = 0; static char *keywords[] = { "sock", "ogf", "ocf", "event", "rlen", "params", "timeout", 0 }; if( !PyArg_ParseTupleAndKeywords(args, kwds, "OHHii|s#i", keywords, &socko, &req.ogf, &req.ocf, &req.event, &req.rlen, &req.cparam, &req.clen, &to) ) return 0; req.rparam = rparam; dd = socko->sock_fd; Py_BEGIN_ALLOW_THREADS err = hci_send_req( dd, &req, to ); Py_END_ALLOW_THREADS if( err< 0 ) return socko->errorhandler(); return PyString_FromStringAndSize(rparam, req.rlen); } PyDoc_STRVAR(bt_hci_send_req_doc, "hci_send_req(sock, ogf, ocf, event, rlen, params=None, timeout=0)\n\ \n\ Transmits a HCI cmomand to the socket and waits for the specified event.\n\ sock - the btsocket object\n\ ogf, ocf - see bluetooth specification\n\ event - the event to wait for. Probably one of EVT_*\n\ rlen - the size of the returned packet to expect. This must be\n\ specified since bt won't know how much data to expect\n\ otherwise\n\ params - the command parameters\n\ timeout - timeout, in milliseconds"); static PyObject* bt_hci_inquiry(PyObject *self, PyObject *args, PyObject *kwds) { int i, err; int dev_id = 0; int length = 8; int flush = 1; int flags = 0; int lookup_class = 0; char ba_name[19]; inquiry_info *info = NULL; PySocketSockObject *socko = NULL; struct hci_inquiry_req *ir; char buf[sizeof(*ir) + sizeof(inquiry_info) * 250]; PyObject *rtn_list = (PyObject *)NULL; static char *keywords[] = {"sock", "duration", "flush_cache", "lookup_class", "device_id", 0}; if( !PyArg_ParseTupleAndKeywords(args, kwds, "O|iiii", keywords, &socko, &length, &flush, &lookup_class, &dev_id) ) { return 0; } flags |= (flush)?IREQ_CACHE_FLUSH:0; ir = (struct hci_inquiry_req*)buf; ir->dev_id = dev_id; ir->num_rsp = 250; ir->length = length; ir->flags = flags; ir->lap[0] = 0x33; ir->lap[1] = 0x8b; ir->lap[2] = 0x9e; Py_BEGIN_ALLOW_THREADS err = ioctl(socko->sock_fd, HCIINQUIRY, (unsigned long) buf); Py_END_ALLOW_THREADS if( err < 0 ) return socko->errorhandler(); info = (inquiry_info*)(buf + sizeof(*ir)); if( (rtn_list = PyList_New(0)) == NULL ) return 0; memset( ba_name, 0, sizeof(ba_name) ); // fill in the list with the discovered bluetooth addresses for(i=0;inum_rsp;i++) { PyObject * addr_entry = (PyObject *)NULL; int err; ba2str( &(info+i)->bdaddr, ba_name ); addr_entry = PyString_FromString( ba_name ); if (lookup_class) { PyObject *item_tuple = PyTuple_New(2); int dev_class = (info+i)->dev_class[2] << 16 | (info+i)->dev_class[1] << 8 | (info+i)->dev_class[0]; PyObject *class_entry = PyInt_FromLong( dev_class ); err = PyTuple_SetItem( item_tuple, 0, addr_entry ); if (err) { Py_XDECREF( item_tuple ); Py_XDECREF( rtn_list ); return NULL; } err = PyTuple_SetItem( item_tuple, 1, class_entry ); if (err) { Py_XDECREF( item_tuple ); Py_XDECREF( rtn_list ); return NULL; } err = PyList_Append( rtn_list, item_tuple ); Py_DECREF( item_tuple ); if (err) { Py_XDECREF( rtn_list ); return NULL; } } else { err = PyList_Append( rtn_list, addr_entry ); Py_DECREF( addr_entry ); if (err) { Py_XDECREF( rtn_list ); return NULL; } } } return rtn_list; } PyDoc_STRVAR(bt_hci_inquiry_doc, "hci_inquiry(dev_id=0, duration=8, flush_cache=True\n\ \n\ Performs a device inquiry using the specified device (usually 0 or 1).\n\ The inquiry will last 1.28 * duration seconds. If flush_cache is True, then\n\ previously discovered devices will not be returned in the inquiry.)"); static PyObject* bt_hci_read_remote_name(PyObject *self, PyObject *args, PyObject *kwds) { char *addr = NULL; bdaddr_t ba; int timeout = 5192; static char name[249]; PySocketSockObject *socko = NULL; int err = 0; static char *keywords[] = {"dd", "bdaddr", "timeout", 0}; if( !PyArg_ParseTupleAndKeywords(args, kwds, "Os|i", keywords, &socko, &addr, &timeout) ) { return 0; } str2ba( addr, &ba ); memset( name, 0, sizeof(name) ); Py_BEGIN_ALLOW_THREADS err = hci_read_remote_name( socko->sock_fd, &ba, sizeof(name)-1, name, timeout ); Py_END_ALLOW_THREADS if( err < 0) return PyErr_SetFromErrno(bluetooth_error); return PyString_FromString( name ); } PyDoc_STRVAR(bt_hci_read_remote_name_doc, "hci_read_remote_name(sock, bdaddr, timeout=5192)\n\ \n\ Performs a remote name request to the specified bluetooth device.\n\ sock - the HCI socket object to use\n\ bdaddr - the bluetooth address of the remote device\n\ timeout - maximum amount of time, in milliseconds, to wait\n\ \n\ Returns the name of the device, or raises an error on failure"); // lot of repetitive code... yay macros!! #define DECL_HCI_FILTER_OP_1(name, docstring) \ static PyObject * bt_hci_filter_ ## name (PyObject *self, PyObject *args )\ { \ char *param; \ int len, arg; \ if( !PyArg_ParseTuple(args,"s#i", ¶m, &len, &arg) ) \ return 0; \ if( len != sizeof(struct hci_filter) ) { \ PyErr_SetString(PyExc_ValueError, "bad filter"); \ return 0; \ } \ hci_filter_ ## name ( arg, (struct hci_filter*)param ); \ return PyString_FromStringAndSize(param, len); \ } \ PyDoc_STRVAR(bt_hci_filter_ ## name ## _doc, docstring); DECL_HCI_FILTER_OP_1(set_ptype, "set ptype!") DECL_HCI_FILTER_OP_1(clear_ptype, "clear ptype!") DECL_HCI_FILTER_OP_1(test_ptype, "test ptype!") DECL_HCI_FILTER_OP_1(set_event, "set event!") DECL_HCI_FILTER_OP_1(clear_event, "clear event!") DECL_HCI_FILTER_OP_1(test_event, "test event!") DECL_HCI_FILTER_OP_1(set_opcode, "set opcode!") DECL_HCI_FILTER_OP_1(test_opcode, "test opcode!") #undef DECL_HCI_FILTER_OP_1 #define DECL_HCI_FILTER_OP_2(name, docstring) \ static PyObject * bt_hci_filter_ ## name (PyObject *self, PyObject *args )\ { \ char *param; \ int len; \ if( !PyArg_ParseTuple(args,"s#", ¶m, &len) ) \ return 0; \ if( len != sizeof(struct hci_filter) ) { \ PyErr_SetString(PyExc_ValueError, "bad filter"); \ return 0; \ } \ hci_filter_ ## name ( (struct hci_filter*)param ); \ return PyString_FromStringAndSize(param, len); \ } \ PyDoc_STRVAR(bt_hci_filter_ ## name ## _doc, docstring); DECL_HCI_FILTER_OP_2(all_events, "all events!"); DECL_HCI_FILTER_OP_2(clear, "clear filter"); DECL_HCI_FILTER_OP_2(all_ptypes, "all packet types!"); DECL_HCI_FILTER_OP_2(clear_opcode, "clear opcode!") #undef DECL_HCI_FILTER_OP_2 static PyObject * bt_cmd_opcode_pack(PyObject *self, PyObject *args ) { uint16_t opcode, ogf, ocf; if (!PyArg_ParseTuple(args, "HH", &ogf, &ocf )) return 0; opcode = cmd_opcode_pack(ogf, ocf); return Py_BuildValue("H", opcode); } PyDoc_STRVAR(bt_cmd_opcode_pack_doc, "cmd_opcode_pack(ogf, ocf)\n\ \n\ packs an OCF and an OGF value together to form a opcode"); static PyObject * bt_cmd_opcode_ogf(PyObject *self, PyObject *args ) { uint16_t opcode; if (!PyArg_ParseTuple(args, "H", &opcode)) return 0; return Py_BuildValue("H", cmd_opcode_ogf(opcode)); } PyDoc_STRVAR(bt_cmd_opcode_ogf_doc, "cmd_opcode_ogf(opcode)\n\ \n\ Convenience function to extract and return the OGF value from an opcode"); static PyObject * bt_cmd_opcode_ocf(PyObject *self, PyObject *args ) { uint16_t opcode; if (!PyArg_ParseTuple(args, "H", &opcode)) return 0; return Py_BuildValue("H", cmd_opcode_ocf(opcode)); } PyDoc_STRVAR(bt_cmd_opcode_ocf_doc, "cmd_opcode_ocf(opcode)\n\ \n\ Convenience function to extract and return the OCF value from an opcode"); static PyObject * bt_ba2str(PyObject *self, PyObject *args) { char *data=NULL; int len=0; char ba_str[19] = {0}; if (!PyArg_ParseTuple(args, "s#", &data, &len)) return 0; ba2str((bdaddr_t*)data, ba_str); return PyString_FromString( ba_str ); // return Py_BuildValue("s#", ba_str, 18); } PyDoc_STRVAR(bt_ba2str_doc, "ba2str(data)\n\ \n\ Converts a packed bluetooth address to a human readable string"); static PyObject * bt_str2ba(PyObject *self, PyObject *args) { char *ba_str=NULL; bdaddr_t ba; if (!PyArg_ParseTuple(args, "s", &ba_str)) return 0; str2ba( ba_str, &ba ); return Py_BuildValue(BYTES_FORMAT_CHR, (char*)(&ba), sizeof(ba)); } PyDoc_STRVAR(bt_str2ba_doc, "str2ba(string)\n\ \n\ Converts a bluetooth address string into a packed bluetooth address. The\n\ string should be of the form \"XX:XX:XX:XX:XX:XX\""); /* * params: (string) device address * effect: - * return: Device id */ static PyObject * bt_hci_devid(PyObject *self, PyObject *args) { char *devaddr=NULL; int devid; if ( !PyArg_ParseTuple(args, "|s", &devaddr) ) { return NULL; } if (devaddr) devid=hci_devid(devaddr); else devid=hci_get_route(NULL); return Py_BuildValue("i",devid); } PyDoc_STRVAR( bt_hci_role_doc, "hci_devid(address)\n\ \n\ get the device id for the local device with specified address.\n\ "); /* * params: (string) device address * effect: - * return: Device id */ static PyObject * bt_hci_role(PyObject *self, PyObject *args) { int devid; int fd; int role; if ( !PyArg_ParseTuple(args, "ii", &fd, &devid) ) return NULL; struct hci_dev_info di = {dev_id: devid}; if (ioctl(fd, HCIGETDEVINFO, (void *) &di)) return NULL; role = di.link_mode == HCI_LM_MASTER; return Py_BuildValue("i", role); } PyDoc_STRVAR( bt_hci_devid_doc, "hci_role(hci_fd, dev_id)\n\ \n\ get the role (master or slave) of the device id.\n\ "); /* * params: (string) device address * effect: - * return: Device id */ static PyObject * bt_hci_read_clock(PyObject *self, PyObject *args) { int fd; int handle; int which; int timeout; uint32_t btclock; uint16_t accuracy; int res; if ( !PyArg_ParseTuple(args, "iiii", &fd, &handle, &which, &timeout) ) return NULL; res = hci_read_clock(fd, handle, which, &btclock, &accuracy, timeout); if (res) { Py_INCREF(Py_None); return Py_None; } return Py_BuildValue("(ii)", btclock, accuracy); } PyDoc_STRVAR( bt_hci_read_clock_doc, "hci_read_clock(hci_fd, acl_handle, which_clock, timeout_ms)\n\ \n\ Get the Bluetooth Clock (native or piconet).\n\ "); /* * params: (string) device address * effect: - * return: Device id */ static PyObject * bt_hci_get_route(PyObject *self, PyObject *args) { int dev_id = 0; char *addr = NULL; bdaddr_t ba; if ( !PyArg_ParseTuple(args, "|s", &addr) ) { return NULL; } if(addr && strlen(addr)) { str2ba( addr, &ba ); dev_id = hci_get_route(&ba); } else { dev_id = hci_get_route(NULL); } if (dev_id < 0) { return PyErr_SetFromErrno(PyExc_OSError); } return PyInt_FromLong(dev_id); } PyDoc_STRVAR( bt_hci_get_route_doc, "hci_get_route(address)\n\ \n\ get the device id through which remote specified addr can be reached.\n\ "); /* * params: (string) device address * effect: - * return: Device id */ static PyObject * bt_hci_acl_conn_handle(PyObject *self, PyObject *args) { int fd; char *devaddr=NULL; bdaddr_t binaddr; struct hci_conn_info_req *cr; char buf[sizeof(struct hci_conn_info_req) + sizeof(struct hci_conn_info)]; int handle = -1; if ( !PyArg_ParseTuple(args, "is", &fd, &devaddr) ) return NULL; if (devaddr) str2ba(devaddr, &binaddr); else str2ba("00:00:00:00:00:00", &binaddr); cr = (struct hci_conn_info_req*) &buf; bacpy(&cr->bdaddr, &binaddr); cr->type = ACL_LINK; if (ioctl(fd, HCIGETCONNINFO, (unsigned long) cr) == 0) handle = htobs(cr->conn_info->handle); return Py_BuildValue("i", handle); } PyDoc_STRVAR( bt_hci_acl_conn_handle_doc, "hci_acl_conn_handle(hci_fd, address)\n\ \n\ get the ACL connection handle for the given remote device addr.\n\ "); static PyObject * bt_hci_filter_new(PyObject *self, PyObject *args) { struct hci_filter flt; int len = sizeof(flt); hci_filter_clear( &flt ); return Py_BuildValue("s#", (char*)&flt, len); } PyDoc_STRVAR(bt_hci_filter_new_doc, "hci_filter_new()\n\ \n\ Returns a new HCI filter suitable for operating on with the hci_filter_*\n\ methods, and for passing to getsockopt and setsockopt. The filter is\n\ initially cleared"); /* * ------------------- * End of HCI section * ------------------- */ /* ========= SDP specific bluetooth module methods ========== */ PyObject * bt_sdp_advertise_service( PyObject *self, PyObject *args ) { PySocketSockObject *socko = NULL; char *name = NULL, *service_id_str = NULL, *provider = NULL, *description = NULL; PyObject *service_classes, *profiles, *protocols; int namelen = 0, provlen = 0, desclen = 0; uuid_t svc_uuid = { 0 }; int i; char addrbuf[256] = { 0 }; int res; socklen_t addrlen; struct sockaddr *sockaddr; uuid_t root_uuid, l2cap_uuid, rfcomm_uuid; sdp_list_t *l2cap_list = 0, *rfcomm_list = 0, *root_list = 0, *proto_list = 0, *profile_list = 0, *svc_class_list = 0, *access_proto_list = 0; sdp_data_t *channel = 0, *psm = 0; sdp_record_t record; sdp_session_t *session = 0; int err = 0; if (!PyArg_ParseTuple(args, "O!s#sOOs#s#O", &sock_type, &socko, &name, &namelen, &service_id_str, &service_classes, &profiles, &provider, &provlen, &description, &desclen, &protocols)) { return 0; } if( provlen == 0 ) provider = NULL; if( desclen == 0 ) description = NULL; if( socko->sdp_record_handle != 0 ) { PyErr_SetString(bluetooth_error, "SDP service record already registered with this socket!"); return 0; } if( namelen == 0 ) { PyErr_SetString(bluetooth_error, "must specify name!"); return 0; } // convert the service ID string into a uuid_t if it was specified if( strlen(service_id_str) && ! str2uuid( service_id_str, &svc_uuid ) ) { PyErr_SetString(PyExc_ValueError, "invalid service ID"); return NULL; } // service_classes must be a list / sequence if (! PySequence_Check(service_classes)) { PyErr_SetString(PyExc_ValueError, "service_classes must be a sequence"); return 0; } // make sure each item in the list is a valid UUID for(i = 0; i < PySequence_Length(service_classes); ++i) { PyObject *item = PySequence_GetItem(service_classes, i); if( ! pyunicode2uuid( item, NULL ) ) { PyErr_SetString(PyExc_ValueError, "service_classes must be a list of " "strings, each either of the form XXXX or " "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); return 0; } } // profiles must be a list / sequence if (! PySequence_Check(profiles)) { PyErr_SetString(PyExc_ValueError, "profiles must be a sequence"); return 0; } // make sure each item in the list is a valid ( uuid, version ) pair for(i = 0; i < PySequence_Length(profiles); ++i) { char *profile_uuid_str = NULL; uint16_t version; PyObject *tuple = PySequence_GetItem(profiles, i); if ( ( ! PySequence_Check(tuple) ) || ( ! PyArg_ParseTuple(tuple, "sH", &profile_uuid_str, &version)) || ( ! str2uuid( profile_uuid_str, NULL ) ) ) { PyErr_SetString(PyExc_ValueError, "Each profile must be a ('uuid', version) tuple"); return 0; } } // protocols must be a list / sequence if (! PySequence_Check(protocols)) { PyErr_SetString(PyExc_ValueError, "protocols must be a sequence"); return 0; } // make sure each item in the list is a valid UUID for(i = 0; i < PySequence_Length(protocols); ++i) { PyObject *item = PySequence_GetItem(protocols, i); if( ! pyunicode2uuid( item, NULL ) ) { PyErr_SetString(PyExc_ValueError, "protocols must be a list of " "strings, each either of the form XXXX or " "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); return 0; } } // verify that the socket is bound and listening if( ! socko->is_listening_socket ) { PyErr_SetString(bluetooth_error, "must have already called socket.listen()"); return 0; } // get the socket information if (!getsockaddrlen(socko, &addrlen)) { PyErr_SetString(bluetooth_error, "error getting socket information"); return 0; } Py_BEGIN_ALLOW_THREADS res = getsockname(socko->sock_fd, (struct sockaddr *) addrbuf, &addrlen); Py_END_ALLOW_THREADS if (res < 0) { PyErr_SetString(bluetooth_error, "error getting socket information"); return 0; } sockaddr = (struct sockaddr *)addrbuf; // can only deal with L2CAP and RFCOMM sockets if( socko->sock_proto != BTPROTO_L2CAP && socko->sock_proto != BTPROTO_RFCOMM ) { PyErr_SetString(bluetooth_error, "Sorry, can only advertise L2CAP and RFCOMM sockets for now"); return 0; } // abort if this socket is already advertising a service if( socko->sdp_record_handle != 0 && socko->sdp_session != NULL ) { PyErr_SetString(bluetooth_error, "This socket is already being used to advertise a service!\n" "Use stop_advertising first!\n"); return 0; } // okay, now construct the SDP service record. memset( &record, 0, sizeof(sdp_record_t) ); record.handle = 0xffffffff; // make the service record publicly browsable sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); root_list = sdp_list_append(0, &root_uuid); sdp_set_browse_groups( &record, root_list ); // set l2cap information (this will always go in) sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); l2cap_list = sdp_list_append( 0, &l2cap_uuid ); proto_list = sdp_list_append( 0, l2cap_list ); if( socko->sock_proto == BTPROTO_RFCOMM ) { // register the RFCOMM channel for RFCOMM sockets uint8_t rfcomm_channel = ((struct sockaddr_rc*)sockaddr)->rc_channel; sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID); channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel); rfcomm_list = sdp_list_append( 0, &rfcomm_uuid ); sdp_list_append( rfcomm_list, channel ); sdp_list_append( proto_list, rfcomm_list ); } else { // register the PSM for L2CAP sockets unsigned short l2cap_psm = ((struct sockaddr_l2*)sockaddr)->l2_psm; psm = sdp_data_alloc(SDP_UINT16, &l2cap_psm); sdp_list_append(l2cap_list, psm); } // add additional protocols, if any sdp_list_t *extra_protos_array[PySequence_Length(protocols)]; if (PySequence_Length(protocols) > 0) { for(i = 0; i < PySequence_Length(protocols); i++) { uuid_t *proto_uuid = (uuid_t*) malloc( sizeof( uuid_t ) ); PyObject *item = PySequence_GetItem(protocols, i); pyunicode2uuid( item, proto_uuid ); sdp_list_t *new_list; new_list = sdp_list_append( 0, proto_uuid ); proto_list = sdp_list_append( proto_list, new_list ); // keep track, to free the list later extra_protos_array[i] = new_list; } } access_proto_list = sdp_list_append( 0, proto_list ); sdp_set_access_protos( &record, access_proto_list ); // add service classes, if any for(i = 0; i < PySequence_Length(service_classes); i++) { uuid_t *svc_class_uuid = (uuid_t*) malloc( sizeof( uuid_t ) ); PyObject *item = PySequence_GetItem(service_classes, i); pyunicode2uuid( item, svc_class_uuid ); svc_class_list = sdp_list_append(svc_class_list, svc_class_uuid); } sdp_set_service_classes(&record, svc_class_list); // add profiles, if any for(i = 0; i < PySequence_Length(profiles); i++) { char *profile_uuid_str; sdp_profile_desc_t *profile_desc = (sdp_profile_desc_t*)malloc(sizeof(sdp_profile_desc_t)); PyObject *tuple = PySequence_GetItem(profiles, i); PyArg_ParseTuple(tuple, "sH", &profile_uuid_str, &profile_desc->version); str2uuid( profile_uuid_str, &profile_desc->uuid ); profile_list = sdp_list_append( profile_list, profile_desc ); } sdp_set_profile_descs(&record, profile_list); // set the name, provider and description sdp_set_info_attr( &record, name, provider, description ); // set the general service ID, if needed if( strlen(service_id_str) ) sdp_set_service_id( &record, svc_uuid ); // connect to the local SDP server, register the service record, and // disconnect Py_BEGIN_ALLOW_THREADS session = sdp_connect( BDADDR_ANY, BDADDR_LOCAL, 0 ); Py_END_ALLOW_THREADS if (!session) { PyErr_SetFromErrno (bluetooth_error); return 0; } socko->sdp_session = session; Py_BEGIN_ALLOW_THREADS err = sdp_record_register(session, &record, 0); Py_END_ALLOW_THREADS // cleanup if( psm ) sdp_data_free( psm ); if( channel ) sdp_data_free( channel ); sdp_list_free( l2cap_list, 0 ); sdp_list_free( rfcomm_list, 0 ); for(i = 0; i < PySequence_Length(protocols); i++) { sdp_list_free( extra_protos_array[i], free ); } sdp_list_free( root_list, 0 ); sdp_list_free( access_proto_list, 0 ); sdp_list_free( svc_class_list, free ); sdp_list_free( profile_list, free ); if( err ) { PyErr_SetFromErrno(bluetooth_error); return 0; } socko->sdp_record_handle = record.handle; Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR( bt_sdp_advertise_service_doc, "sdp_advertise_service( socket, name )\n\ \n\ Registers a service with the local SDP server.\n\ \n\ socket must be a bound, listening socket - you must have already\n\ called socket.listen(). Only L2CAP and RFCOMM sockets are supported.\n\ \n\ name is the name that you want to appear in the SDP record\n\ \n\ Registered services will be automatically unregistered when the socket is\n\ closed.\ "); PyObject * bt_sdp_stop_advertising( PyObject *self, PyObject *args ) { PySocketSockObject *socko = NULL; if ( !PyArg_ParseTuple(args, "O!", &sock_type, &socko ) ) { return 0; } // verify that we got a real socket object if( ! socko || (Py_TYPE(socko) != &sock_type) ) { // TODO change this to a more accurate exception type PyErr_SetString(bluetooth_error, "must pass in _bluetooth.socket object"); return 0; } if( socko->sdp_session != NULL ) { Py_BEGIN_ALLOW_THREADS sdp_close( socko->sdp_session ); Py_END_ALLOW_THREADS socko->sdp_session = NULL; socko->sdp_record_handle = 0; } else { PyErr_SetString( bluetooth_error, "not currently advertising!"); } Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR( bt_sdp_stop_advertising_doc, "sdp_stop_advertising( socket )\n\ \n\ stop advertising services associated with this socket\n\ "); /* List of functions exported by this module. */ #define DECL_BT_METHOD(name, argtype) \ { #name, (PyCFunction)bt_ ##name, argtype, bt_ ## name ## _doc } static PyMethodDef bt_methods[] = { DECL_BT_METHOD( hci_devid, METH_VARARGS ), DECL_BT_METHOD( hci_get_route, METH_VARARGS ), DECL_BT_METHOD( hci_role, METH_VARARGS ), DECL_BT_METHOD( hci_read_clock, METH_VARARGS ), DECL_BT_METHOD( hci_acl_conn_handle, METH_VARARGS ), DECL_BT_METHOD( hci_open_dev, METH_VARARGS ), DECL_BT_METHOD( hci_close_dev, METH_VARARGS ), DECL_BT_METHOD( hci_send_cmd, METH_VARARGS ), DECL_BT_METHOD( hci_send_req, METH_VARARGS | METH_KEYWORDS ), DECL_BT_METHOD( hci_inquiry, METH_VARARGS | METH_KEYWORDS ), DECL_BT_METHOD( hci_read_remote_name, METH_VARARGS | METH_KEYWORDS ), DECL_BT_METHOD( hci_filter_new, METH_VARARGS ), DECL_BT_METHOD( hci_filter_clear, METH_VARARGS ), DECL_BT_METHOD( hci_filter_all_events, METH_VARARGS ), DECL_BT_METHOD( hci_filter_all_ptypes, METH_VARARGS ), DECL_BT_METHOD( hci_filter_clear_opcode, METH_VARARGS ), DECL_BT_METHOD( hci_filter_set_ptype, METH_VARARGS ), DECL_BT_METHOD( hci_filter_clear_ptype, METH_VARARGS ), DECL_BT_METHOD( hci_filter_test_ptype, METH_VARARGS ), DECL_BT_METHOD( hci_filter_set_event, METH_VARARGS ), DECL_BT_METHOD( hci_filter_clear_event, METH_VARARGS ), DECL_BT_METHOD( hci_filter_test_event, METH_VARARGS ), DECL_BT_METHOD( hci_filter_set_opcode, METH_VARARGS ), DECL_BT_METHOD( hci_filter_test_opcode, METH_VARARGS ), DECL_BT_METHOD( cmd_opcode_pack, METH_VARARGS ), DECL_BT_METHOD( cmd_opcode_ogf, METH_VARARGS ), DECL_BT_METHOD( cmd_opcode_ocf, METH_VARARGS ), DECL_BT_METHOD( ba2str, METH_VARARGS ), DECL_BT_METHOD( str2ba, METH_VARARGS ), #ifndef NO_DUP DECL_BT_METHOD( fromfd, METH_VARARGS ), #endif DECL_BT_METHOD( btohs, METH_VARARGS ), DECL_BT_METHOD( btohl, METH_VARARGS ), DECL_BT_METHOD( htobs, METH_VARARGS ), DECL_BT_METHOD( htobl, METH_VARARGS ), DECL_BT_METHOD( getdefaulttimeout, METH_NOARGS ), DECL_BT_METHOD( setdefaulttimeout, METH_O ), DECL_BT_METHOD( sdp_advertise_service, METH_VARARGS ), DECL_BT_METHOD( sdp_stop_advertising, METH_VARARGS ), // DECL_BT_METHOD( advertise_service, METH_VARARGS | METH_KEYWORDS ), {NULL, NULL} /* Sentinel */ }; #undef DECL_BT_METHOD /* Initialize the bt module. */ PyDoc_STRVAR(socket_doc, "Implementation module for bluetooth operations.\n\ \n\ See the bluetooth module for documentation."); #if PY_MAJOR_VERSION < 3 PyMODINIT_FUNC init_bluetooth(void) { Py_TYPE(&sock_type) = &PyType_Type; Py_TYPE(&sdp_session_type) = &PyType_Type; // Initialization steps for _bluetooth. PyObject *m = Py_InitModule3("_bluetooth", bt_methods, socket_doc); bluetooth_error = PyErr_NewException("_bluetooth.error", NULL, NULL); if (bluetooth_error == NULL) return; Py_INCREF(bluetooth_error); PyModule_AddObject(m, "error", bluetooth_error); socket_timeout = PyErr_NewException("_bluetooth.timeout", bluetooth_error, NULL); if (socket_timeout == NULL) return; Py_INCREF(socket_timeout); PyModule_AddObject(m, "timeout", socket_timeout); Py_INCREF((PyObject *)&sock_type); if (PyModule_AddObject(m, "btsocket", (PyObject *)&sock_type) != 0) return; Py_INCREF((PyObject *)&sdp_session_type); if (PyModule_AddObject(m, "SDPSession", (PyObject *)&sdp_session_type) != 0) return; #else PyMODINIT_FUNC PyInit__bluetooth(void) { Py_TYPE(&sock_type) = &PyType_Type; Py_TYPE(&sdp_session_type) = &PyType_Type; // Initialization steps for _bluetooth. static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_bluetooth", socket_doc, -1, bt_methods, NULL, NULL, NULL, NULL }; PyObject *m = PyModule_Create(&moduledef); bluetooth_error = PyErr_NewException("_bluetooth.error", NULL, NULL); if (bluetooth_error == NULL) return NULL; Py_INCREF(bluetooth_error); PyModule_AddObject(m, "error", bluetooth_error); socket_timeout = PyErr_NewException("_bluetooth.timeout", bluetooth_error, NULL); if (socket_timeout == NULL) return NULL; Py_INCREF(socket_timeout); PyModule_AddObject(m, "timeout", socket_timeout); Py_INCREF((PyObject *)&sock_type); if (PyModule_AddObject(m, "btsocket", (PyObject *)&sock_type) != 0) return NULL; Py_INCREF((PyObject *)&sdp_session_type); if (PyModule_AddObject(m, "SDPSession", (PyObject *)&sdp_session_type) != 0) return NULL; #endif // because we're lazy... #define ADD_INT_CONST(m, a) PyModule_AddIntConstant(m, #a, a) // Global variables that can be accessible from Python. // ADD_INT_CONST(m, PF_BLUETOOTH); // ADD_INT_CONST(m, AF_BLUETOOTH); ADD_INT_CONST(m, SOL_HCI); ADD_INT_CONST(m, HCI_DATA_DIR); ADD_INT_CONST(m, HCI_TIME_STAMP); ADD_INT_CONST(m, HCI_FILTER); ADD_INT_CONST(m, HCI_MAX_EVENT_SIZE); ADD_INT_CONST(m, HCI_EVENT_HDR_SIZE); PyModule_AddIntConstant(m, "HCI", BTPROTO_HCI); PyModule_AddIntConstant(m, "L2CAP", BTPROTO_L2CAP); PyModule_AddIntConstant(m, "RFCOMM", BTPROTO_RFCOMM); PyModule_AddIntConstant(m, "SCO", BTPROTO_SCO); // /* Socket types */ // ADD_INT_CONST(m, SOCK_STREAM); // ADD_INT_CONST(m, SOCK_DGRAM); // ADD_INT_CONST(m, SOCK_RAW); // ADD_INT_CONST(m, SOCK_SEQPACKET); /* HCI Constants */ /* HCI OGF values */ #ifdef OGF_LINK_CTL ADD_INT_CONST(m, OGF_LINK_CTL); #endif #ifdef OGF_LINK_POLICY ADD_INT_CONST(m, OGF_LINK_POLICY); #endif #ifdef OGF_HOST_CTL ADD_INT_CONST(m, OGF_HOST_CTL); #endif #ifdef OGF_INFO_PARAM ADD_INT_CONST(m, OGF_INFO_PARAM); #endif #ifdef OGF_STATUS_PARAM ADD_INT_CONST(m, OGF_STATUS_PARAM); #endif #ifdef OGF_TESTING_CMD ADD_INT_CONST(m, OGF_TESTING_CMD); #endif #ifdef OGF_VENDOR_CMD ADD_INT_CONST(m, OGF_VENDOR_CMD); #endif /* HCI OCF values */ #ifdef OCF_INQUIRY ADD_INT_CONST(m, OCF_INQUIRY); #endif #ifdef OCF_INQUIRY_CANCEL ADD_INT_CONST(m, OCF_INQUIRY_CANCEL); #endif #ifdef OCF_PERIODIC_INQUIRY ADD_INT_CONST(m, OCF_PERIODIC_INQUIRY); #endif #ifdef OCF_EXIT_PERIODIC_INQUIRY ADD_INT_CONST(m, OCF_EXIT_PERIODIC_INQUIRY); #endif #ifdef OCF_CREATE_CONN ADD_INT_CONST(m, OCF_CREATE_CONN); #endif #ifdef OCF_DISCONNECT ADD_INT_CONST(m, OCF_DISCONNECT); #endif #ifdef OCF_ADD_SCO ADD_INT_CONST(m, OCF_ADD_SCO); #endif #ifdef OCF_ACCEPT_CONN_REQ ADD_INT_CONST(m, OCF_ACCEPT_CONN_REQ); #endif #ifdef OCF_REJECT_CONN_REQ ADD_INT_CONST(m, OCF_REJECT_CONN_REQ); #endif #ifdef OCF_LINK_KEY_REPLY ADD_INT_CONST(m, OCF_LINK_KEY_REPLY); #endif #ifdef OCF_LINK_KEY_NEG_REPLY ADD_INT_CONST(m, OCF_LINK_KEY_NEG_REPLY); #endif #ifdef OCF_PIN_CODE_REPLY ADD_INT_CONST(m, OCF_PIN_CODE_REPLY); #endif #ifdef OCF_PIN_CODE_NEG_REPLY ADD_INT_CONST(m, OCF_PIN_CODE_NEG_REPLY); #endif #ifdef OCF_SET_CONN_PTYPE ADD_INT_CONST(m, OCF_SET_CONN_PTYPE); #endif #ifdef OCF_AUTH_REQUESTED ADD_INT_CONST(m, OCF_AUTH_REQUESTED); #endif #ifdef OCF_SET_CONN_ENCRYPT ADD_INT_CONST(m, OCF_SET_CONN_ENCRYPT); #endif #ifdef OCF_REMOTE_NAME_REQ ADD_INT_CONST(m, OCF_REMOTE_NAME_REQ); #endif #ifdef OCF_READ_REMOTE_FEATURES ADD_INT_CONST(m, OCF_READ_REMOTE_FEATURES); #endif #ifdef OCF_READ_REMOTE_VERSION ADD_INT_CONST(m, OCF_READ_REMOTE_VERSION); #endif #ifdef OCF_READ_CLOCK_OFFSET ADD_INT_CONST(m, OCF_READ_CLOCK_OFFSET); #endif #ifdef OCF_READ_CLOCK_OFFSET ADD_INT_CONST(m, OCF_READ_CLOCK); #endif #ifdef OCF_HOLD_MODE ADD_INT_CONST(m, OCF_HOLD_MODE); #endif #ifdef OCF_SNIFF_MODE ADD_INT_CONST(m, OCF_SNIFF_MODE); #endif #ifdef OCF_EXIT_SNIFF_MODE ADD_INT_CONST(m, OCF_EXIT_SNIFF_MODE); #endif #ifdef OCF_PARK_MODE ADD_INT_CONST(m, OCF_PARK_MODE); #endif #ifdef OCF_EXIT_PARK_MODE ADD_INT_CONST(m, OCF_EXIT_PARK_MODE); #endif #ifdef OCF_QOS_SETUP ADD_INT_CONST(m, OCF_QOS_SETUP); #endif #ifdef OCF_ROLE_DISCOVERY ADD_INT_CONST(m, OCF_ROLE_DISCOVERY); #endif #ifdef OCF_SWITCH_ROLE ADD_INT_CONST(m, OCF_SWITCH_ROLE); #endif #ifdef OCF_READ_LINK_POLICY ADD_INT_CONST(m, OCF_READ_LINK_POLICY); #endif #ifdef OCF_WRITE_LINK_POLICY ADD_INT_CONST(m, OCF_WRITE_LINK_POLICY); #endif #ifdef OCF_RESET ADD_INT_CONST(m, OCF_RESET); #endif #ifdef OCF_SET_EVENT_FLT ADD_INT_CONST(m, OCF_SET_EVENT_FLT); #endif #ifdef OCF_CHANGE_LOCAL_NAME ADD_INT_CONST(m, OCF_CHANGE_LOCAL_NAME); #endif #ifdef OCF_READ_LOCAL_NAME ADD_INT_CONST(m, OCF_READ_LOCAL_NAME); #endif #ifdef OCF_WRITE_CA_TIMEOUT ADD_INT_CONST(m, OCF_WRITE_CA_TIMEOUT); #endif #ifdef OCF_WRITE_PG_TIMEOUT ADD_INT_CONST(m, OCF_WRITE_PG_TIMEOUT); #endif #ifdef OCF_READ_PAGE_TIMEOUT ADD_INT_CONST(m, OCF_READ_PAGE_TIMEOUT); #endif #ifdef OCF_WRITE_PAGE_TIMEOUT ADD_INT_CONST(m, OCF_WRITE_PAGE_TIMEOUT); #endif #ifdef OCF_WRITE_SCAN_ENABLE ADD_INT_CONST(m, OCF_WRITE_SCAN_ENABLE); #endif #ifdef OCF_READ_PAGE_ACTIVITY ADD_INT_CONST(m, OCF_READ_PAGE_ACTIVITY); #endif #ifdef OCF_WRITE_PAGE_ACTIVITY ADD_INT_CONST(m, OCF_WRITE_PAGE_ACTIVITY); #endif #ifdef OCF_READ_INQ_ACTIVITY ADD_INT_CONST(m, OCF_READ_INQ_ACTIVITY); #endif #ifdef OCF_WRITE_INQ_ACTIVITY ADD_INT_CONST(m, OCF_WRITE_INQ_ACTIVITY); #endif #ifdef OCF_READ_AUTH_ENABLE ADD_INT_CONST(m, OCF_READ_AUTH_ENABLE); #endif #ifdef OCF_WRITE_AUTH_ENABLE ADD_INT_CONST(m, OCF_WRITE_AUTH_ENABLE); #endif #ifdef OCF_READ_ENCRYPT_MODE ADD_INT_CONST(m, OCF_READ_ENCRYPT_MODE); #endif #ifdef OCF_WRITE_ENCRYPT_MODE ADD_INT_CONST(m, OCF_WRITE_ENCRYPT_MODE); #endif #ifdef OCF_READ_CLASS_OF_DEV ADD_INT_CONST(m, OCF_READ_CLASS_OF_DEV); #endif #ifdef OCF_WRITE_CLASS_OF_DEV ADD_INT_CONST(m, OCF_WRITE_CLASS_OF_DEV); #endif #ifdef OCF_READ_VOICE_SETTING ADD_INT_CONST(m, OCF_READ_VOICE_SETTING); #endif #ifdef OCF_WRITE_VOICE_SETTING ADD_INT_CONST(m, OCF_WRITE_VOICE_SETTING); #endif #ifdef OCF_READ_TRANSMIT_POWER_LEVEL ADD_INT_CONST(m, OCF_READ_TRANSMIT_POWER_LEVEL); #endif #ifdef OCF_HOST_BUFFER_SIZE ADD_INT_CONST(m, OCF_HOST_BUFFER_SIZE); #endif #ifdef OCF_READ_LINK_SUPERVISION_TIMEOUT ADD_INT_CONST(m, OCF_READ_LINK_SUPERVISION_TIMEOUT); #endif #ifdef OCF_WRITE_LINK_SUPERVISION_TIMEOUT ADD_INT_CONST(m, OCF_WRITE_LINK_SUPERVISION_TIMEOUT); #endif #ifdef OCF_READ_CURRENT_IAC_LAP ADD_INT_CONST(m, OCF_READ_CURRENT_IAC_LAP); #endif #ifdef OCF_WRITE_CURRENT_IAC_LAP ADD_INT_CONST(m, OCF_WRITE_CURRENT_IAC_LAP); #endif #ifdef OCF_READ_INQUIRY_MODE ADD_INT_CONST(m, OCF_READ_INQUIRY_MODE); #endif #ifdef OCF_WRITE_INQUIRY_MODE ADD_INT_CONST(m, OCF_WRITE_INQUIRY_MODE); #endif #ifdef OCF_READ_AFH_MODE ADD_INT_CONST(m, OCF_READ_AFH_MODE); #endif #ifdef OCF_WRITE_AFH_MODE ADD_INT_CONST(m, OCF_WRITE_AFH_MODE); #endif #ifdef OCF_READ_LOCAL_VERSION ADD_INT_CONST(m, OCF_READ_LOCAL_VERSION); #endif #ifdef OCF_READ_LOCAL_FEATURES ADD_INT_CONST(m, OCF_READ_LOCAL_FEATURES); #endif #ifdef OCF_READ_BUFFER_SIZE ADD_INT_CONST(m, OCF_READ_BUFFER_SIZE); #endif #ifdef OCF_READ_BD_ADDR ADD_INT_CONST(m, OCF_READ_BD_ADDR); #endif #ifdef OCF_READ_FAILED_CONTACT_COUNTER ADD_INT_CONST(m, OCF_READ_FAILED_CONTACT_COUNTER); #endif #ifdef OCF_RESET_FAILED_CONTACT_COUNTER ADD_INT_CONST(m, OCF_RESET_FAILED_CONTACT_COUNTER); #endif #ifdef OCF_GET_LINK_QUALITY ADD_INT_CONST(m, OCF_GET_LINK_QUALITY); #endif #ifdef OCF_READ_RSSI ADD_INT_CONST(m, OCF_READ_RSSI); #endif #ifdef OCF_READ_AFH_MAP ADD_INT_CONST(m, OCF_READ_AFH_MAP); #endif /* HCI events */ #ifdef EVT_INQUIRY_COMPLETE ADD_INT_CONST(m, EVT_INQUIRY_COMPLETE); #endif #ifdef EVT_INQUIRY_RESULT ADD_INT_CONST(m, EVT_INQUIRY_RESULT); #endif #ifdef EVT_CONN_COMPLETE ADD_INT_CONST(m, EVT_CONN_COMPLETE); #endif #ifdef EVT_CONN_COMPLETE_SIZE ADD_INT_CONST(m, EVT_CONN_COMPLETE_SIZE); #endif #ifdef EVT_CONN_REQUEST ADD_INT_CONST(m, EVT_CONN_REQUEST); #endif #ifdef EVT_CONN_REQUEST_SIZE ADD_INT_CONST(m, EVT_CONN_REQUEST_SIZE); #endif #ifdef EVT_DISCONN_COMPLETE ADD_INT_CONST(m, EVT_DISCONN_COMPLETE); #endif #ifdef EVT_DISCONN_COMPLETE_SIZE ADD_INT_CONST(m, EVT_DISCONN_COMPLETE_SIZE); #endif #ifdef EVT_AUTH_COMPLETE ADD_INT_CONST(m, EVT_AUTH_COMPLETE); #endif #ifdef EVT_AUTH_COMPLETE_SIZE ADD_INT_CONST(m, EVT_AUTH_COMPLETE_SIZE); #endif #ifdef EVT_REMOTE_NAME_REQ_COMPLETE ADD_INT_CONST(m, EVT_REMOTE_NAME_REQ_COMPLETE); #endif #ifdef EVT_REMOTE_NAME_REQ_COMPLETE_SIZE ADD_INT_CONST(m, EVT_REMOTE_NAME_REQ_COMPLETE_SIZE); #endif #ifdef EVT_ENCRYPT_CHANGE ADD_INT_CONST(m, EVT_ENCRYPT_CHANGE); #endif #ifdef EVT_ENCRYPT_CHANGE_SIZE ADD_INT_CONST(m, EVT_ENCRYPT_CHANGE_SIZE); #endif #ifdef EVT_READ_REMOTE_FEATURES_COMPLETE ADD_INT_CONST(m, EVT_READ_REMOTE_FEATURES_COMPLETE); #endif #ifdef EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE ADD_INT_CONST(m, EVT_READ_REMOTE_FEATURES_COMPLETE_SIZE); #endif #ifdef EVT_READ_REMOTE_VERSION_COMPLETE ADD_INT_CONST(m, EVT_READ_REMOTE_VERSION_COMPLETE); #endif #ifdef EVT_READ_REMOTE_VERSION_COMPLETE_SIZE ADD_INT_CONST(m, EVT_READ_REMOTE_VERSION_COMPLETE_SIZE); #endif #ifdef EVT_QOS_SETUP_COMPLETE ADD_INT_CONST(m, EVT_QOS_SETUP_COMPLETE); #endif #ifdef EVT_QOS_SETUP_COMPLETE_SIZE ADD_INT_CONST(m, EVT_QOS_SETUP_COMPLETE_SIZE); #endif #ifdef EVT_CMD_COMPLETE ADD_INT_CONST(m, EVT_CMD_COMPLETE); #endif #ifdef EVT_CMD_COMPLETE_SIZE ADD_INT_CONST(m, EVT_CMD_COMPLETE_SIZE); #endif #ifdef EVT_CMD_STATUS ADD_INT_CONST(m, EVT_CMD_STATUS); #endif #ifdef EVT_CMD_STATUS_SIZE ADD_INT_CONST(m, EVT_CMD_STATUS_SIZE); #endif #ifdef EVT_ROLE_CHANGE ADD_INT_CONST(m, EVT_ROLE_CHANGE); #endif #ifdef EVT_ROLE_CHANGE_SIZE ADD_INT_CONST(m, EVT_ROLE_CHANGE_SIZE); #endif #ifdef EVT_NUM_COMP_PKTS ADD_INT_CONST(m, EVT_NUM_COMP_PKTS); #endif #ifdef EVT_NUM_COMP_PKTS_SIZE ADD_INT_CONST(m, EVT_NUM_COMP_PKTS_SIZE); #endif #ifdef EVT_MODE_CHANGE ADD_INT_CONST(m, EVT_MODE_CHANGE); #endif #ifdef EVT_MODE_CHANGE_SIZE ADD_INT_CONST(m, EVT_MODE_CHANGE_SIZE); #endif #ifdef EVT_PIN_CODE_REQ ADD_INT_CONST(m, EVT_PIN_CODE_REQ); #endif #ifdef EVT_PIN_CODE_REQ_SIZE ADD_INT_CONST(m, EVT_PIN_CODE_REQ_SIZE); #endif #ifdef EVT_LINK_KEY_REQ ADD_INT_CONST(m, EVT_LINK_KEY_REQ); #endif #ifdef EVT_LINK_KEY_REQ_SIZE ADD_INT_CONST(m, EVT_LINK_KEY_REQ_SIZE); #endif #ifdef EVT_LINK_KEY_NOTIFY ADD_INT_CONST(m, EVT_LINK_KEY_NOTIFY); #endif #ifdef EVT_LINK_KEY_NOTIFY_SIZE ADD_INT_CONST(m, EVT_LINK_KEY_NOTIFY_SIZE); #endif #ifdef EVT_READ_CLOCK_OFFSET_COMPLETE ADD_INT_CONST(m, EVT_READ_CLOCK_OFFSET_COMPLETE); #endif #ifdef EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE ADD_INT_CONST(m, EVT_READ_CLOCK_OFFSET_COMPLETE_SIZE); #endif #ifdef EVT_CONN_PTYPE_CHANGED ADD_INT_CONST(m, EVT_CONN_PTYPE_CHANGED); #endif #ifdef EVT_CONN_PTYPE_CHANGED_SIZE ADD_INT_CONST(m, EVT_CONN_PTYPE_CHANGED_SIZE); #endif #ifdef EVT_QOS_VIOLATION ADD_INT_CONST(m, EVT_QOS_VIOLATION); #endif #ifdef EVT_QOS_VIOLATION_SIZE ADD_INT_CONST(m, EVT_QOS_VIOLATION_SIZE); #endif #ifdef EVT_INQUIRY_RESULT_WITH_RSSI ADD_INT_CONST(m, EVT_INQUIRY_RESULT_WITH_RSSI); #endif #ifdef EVT_EXTENDED_INQUIRY_RESULT ADD_INT_CONST(m, EVT_EXTENDED_INQUIRY_RESULT); PyModule_AddIntConstant(m, "HAVE_EVT_EXTENDED_INQUIRY_RESULT", 1); #else PyModule_AddIntConstant(m, "HAVE_EVT_EXTENDED_INQUIRY_RESULT", 0); #endif #ifdef EVT_TESTING ADD_INT_CONST(m, EVT_TESTING); #endif #ifdef EVT_VENDOR ADD_INT_CONST(m, EVT_VENDOR); #endif #ifdef EVT_STACK_INTERNAL ADD_INT_CONST(m, EVT_STACK_INTERNAL); #endif #ifdef EVT_STACK_INTERNAL_SIZE ADD_INT_CONST(m, EVT_STACK_INTERNAL_SIZE); #endif #ifdef EVT_SI_DEVICE ADD_INT_CONST(m, EVT_SI_DEVICE); #endif #ifdef EVT_SI_DEVICE_SIZE ADD_INT_CONST(m, EVT_SI_DEVICE_SIZE); #endif #ifdef EVT_SI_SECURITY ADD_INT_CONST(m, EVT_SI_SECURITY); #endif /* HCI packet types */ #ifdef HCI_COMMAND_PKT ADD_INT_CONST(m, HCI_COMMAND_PKT); #endif #ifdef HCI_ACLDATA_PKT ADD_INT_CONST(m, HCI_ACLDATA_PKT); #endif #ifdef HCI_SCODATA_PKT ADD_INT_CONST(m, HCI_SCODATA_PKT); #endif #ifdef HCI_EVENT_PKT ADD_INT_CONST(m, HCI_EVENT_PKT); #endif #ifdef HCI_UNKNOWN_PKT ADD_INT_CONST(m, HCI_UNKNOWN_PKT); #endif /* socket options */ #ifdef SO_DEBUG ADD_INT_CONST(m, SO_DEBUG); #endif #ifdef SO_ACCEPTCONN ADD_INT_CONST(m, SO_ACCEPTCONN); #endif #ifdef SO_REUSEADDR ADD_INT_CONST(m, SO_REUSEADDR); #endif #ifdef SO_KEEPALIVE ADD_INT_CONST(m, SO_KEEPALIVE); #endif #ifdef SO_DONTROUTE ADD_INT_CONST(m, SO_DONTROUTE); #endif #ifdef SO_BROADCAST ADD_INT_CONST(m, SO_BROADCAST); #endif #ifdef SO_USELOOPBACK ADD_INT_CONST(m, SO_USELOOPBACK); #endif #ifdef SO_LINGER ADD_INT_CONST(m, SO_LINGER); #endif #ifdef SO_OOBINLINE ADD_INT_CONST(m, SO_OOBINLINE); #endif #ifdef SO_REUSEPORT ADD_INT_CONST(m, SO_REUSEPORT); #endif #ifdef SO_SNDBUF ADD_INT_CONST(m, SO_SNDBUF); #endif #ifdef SO_RCVBUF ADD_INT_CONST(m, SO_RCVBUF); #endif #ifdef SO_SNDLOWAT ADD_INT_CONST(m, SO_SNDLOWAT); #endif #ifdef SO_RCVLOWAT ADD_INT_CONST(m, SO_RCVLOWAT); #endif #ifdef SO_SNDTIMEO ADD_INT_CONST(m, SO_SNDTIMEO); #endif #ifdef SO_RCVTIMEO ADD_INT_CONST(m, SO_RCVTIMEO); #endif #ifdef SO_ERROR ADD_INT_CONST(m, SO_ERROR); #endif #ifdef SO_TYPE ADD_INT_CONST(m, SO_TYPE); #endif /* Maximum number of connections for "listen" */ #ifdef SOMAXCONN ADD_INT_CONST(m, SOMAXCONN); #else ADD_INT_CONST(m, SOMAXCONN); #endif /* Flags for send, recv */ #ifdef MSG_OOB ADD_INT_CONST(m, MSG_OOB); #endif #ifdef MSG_PEEK ADD_INT_CONST(m, MSG_PEEK); #endif #ifdef MSG_DONTROUTE ADD_INT_CONST(m, MSG_DONTROUTE); #endif #ifdef MSG_DONTWAIT ADD_INT_CONST(m, MSG_DONTWAIT); #endif #ifdef MSG_EOR ADD_INT_CONST(m, MSG_EOR); #endif #ifdef MSG_TRUNC ADD_INT_CONST(m, MSG_TRUNC); #endif #ifdef MSG_CTRUNC ADD_INT_CONST(m, MSG_CTRUNC); #endif #ifdef MSG_WAITALL ADD_INT_CONST(m, MSG_WAITALL); #endif #ifdef MSG_BTAG ADD_INT_CONST(m, MSG_BTAG); #endif #ifdef MSG_ETAG ADD_INT_CONST(m, MSG_ETAG); #endif /* Size of inquiry info */ #ifdef INQUIRY_INFO_WITH_RSSI_SIZE ADD_INT_CONST(m, INQUIRY_INFO_WITH_RSSI_SIZE); #endif #ifdef EXTENDED_INQUIRY_INFO_SIZE ADD_INT_CONST(m, EXTENDED_INQUIRY_INFO_SIZE); #endif /* Protocol level and numbers, usable for [gs]etsockopt */ ADD_INT_CONST(m, SOL_SOCKET); ADD_INT_CONST(m, SOL_L2CAP); ADD_INT_CONST(m, SOL_RFCOMM); ADD_INT_CONST(m, SOL_SCO); ADD_INT_CONST(m, SCO_OPTIONS); ADD_INT_CONST(m, L2CAP_OPTIONS); /* ioctl */ ADD_INT_CONST(m, HCIDEVUP); ADD_INT_CONST(m, HCIDEVDOWN); ADD_INT_CONST(m, HCIDEVRESET); ADD_INT_CONST(m, HCIDEVRESTAT); ADD_INT_CONST(m, HCIGETDEVLIST); ADD_INT_CONST(m, HCIGETDEVINFO); ADD_INT_CONST(m, HCIGETCONNLIST); ADD_INT_CONST(m, HCIGETCONNINFO); ADD_INT_CONST(m, HCISETRAW); ADD_INT_CONST(m, HCISETSCAN); ADD_INT_CONST(m, HCISETAUTH); ADD_INT_CONST(m, HCISETENCRYPT); ADD_INT_CONST(m, HCISETPTYPE); ADD_INT_CONST(m, HCISETLINKPOL); ADD_INT_CONST(m, HCISETLINKMODE); ADD_INT_CONST(m, HCISETACLMTU); ADD_INT_CONST(m, HCISETSCOMTU); ADD_INT_CONST(m, HCIINQUIRY); ADD_INT_CONST(m, ACL_LINK); ADD_INT_CONST(m, SCO_LINK); /* RFCOMM */ ADD_INT_CONST(m, RFCOMM_LM); ADD_INT_CONST(m, RFCOMM_LM_MASTER); ADD_INT_CONST(m, RFCOMM_LM_AUTH ); ADD_INT_CONST(m, RFCOMM_LM_ENCRYPT); ADD_INT_CONST(m, RFCOMM_LM_TRUSTED); ADD_INT_CONST(m, RFCOMM_LM_RELIABLE); ADD_INT_CONST(m, RFCOMM_LM_SECURE); /* L2CAP */ ADD_INT_CONST(m, L2CAP_LM); ADD_INT_CONST(m, L2CAP_LM_MASTER); ADD_INT_CONST(m, L2CAP_LM_AUTH); ADD_INT_CONST(m, L2CAP_LM_ENCRYPT); ADD_INT_CONST(m, L2CAP_LM_TRUSTED); ADD_INT_CONST(m, L2CAP_LM_RELIABLE); ADD_INT_CONST(m, L2CAP_LM_SECURE); ADD_INT_CONST(m, L2CAP_COMMAND_REJ); ADD_INT_CONST(m, L2CAP_CONN_REQ ); ADD_INT_CONST(m, L2CAP_CONN_RSP ); ADD_INT_CONST(m, L2CAP_CONF_REQ ); ADD_INT_CONST(m, L2CAP_CONF_RSP ); ADD_INT_CONST(m, L2CAP_DISCONN_REQ); ADD_INT_CONST(m, L2CAP_DISCONN_RSP); ADD_INT_CONST(m, L2CAP_ECHO_REQ ); ADD_INT_CONST(m, L2CAP_ECHO_RSP ); ADD_INT_CONST(m, L2CAP_INFO_REQ ); ADD_INT_CONST(m, L2CAP_INFO_RSP ); ADD_INT_CONST(m, L2CAP_MODE_BASIC); ADD_INT_CONST(m, L2CAP_MODE_RETRANS); ADD_INT_CONST(m, L2CAP_MODE_FLOWCTL); ADD_INT_CONST(m, L2CAP_MODE_ERTM); ADD_INT_CONST(m, L2CAP_MODE_STREAMING); ADD_INT_CONST(m, BT_SECURITY); ADD_INT_CONST(m, BT_SECURITY_SDP); ADD_INT_CONST(m, BT_SECURITY_LOW); ADD_INT_CONST(m, BT_SECURITY_MEDIUM); ADD_INT_CONST(m, BT_SECURITY_HIGH); #ifdef BT_DEFER_SETUP ADD_INT_CONST(m, BT_DEFER_SETUP); #endif ADD_INT_CONST(m, SOL_BLUETOOTH); #undef ADD_INT_CONST #if PY_MAJOR_VERSION >= 3 return m; #endif } /* * Affix socket module * Socket module for python based in the original socket module for python * This code is a copy from socket.c source code from python2.2 with * updates/modifications to support affix socket interface * * AAA FFFFFFF FFFFFFF IIIIIII X X * A A F F I X X * A A F F I X X * AAAAAAA FFFF FFFF I X X * A A F F I X X * A A F F IIIIIII X X * * Any modifications of this sourcecode must keep this information !!!!! * * by Carlos Chinea * (C) Nokia Research Center, 2004 */ pybluez-0.22+really0.22/bluez/btmodule.h000066400000000000000000000023621334611253700200320ustar00rootroot00000000000000#ifndef __btmodule_h__ #define __btmodule_h__ #include "Python.h" #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* The object holding a socket. It holds some extra information, like the address family, which is used to decode socket address arguments properly. */ typedef struct { PyObject_HEAD int sock_fd; /* Socket file descriptor */ int sock_family; /* Address family, always AF_BLUETOOTH */ int sock_type; /* Socket type, e.g., SOCK_STREAM */ int sock_proto; /* Protocol type, e.g., BTPROTO_L2CAP */ PyObject *(*errorhandler)(void); /* Error handler; checks errno, returns NULL and sets a Python exception */ double sock_timeout; /* Operation timeout in seconds; 0.0 means non-blocking */ int is_listening_socket; // XXX this is a hack to make // sdp_advertise_service easier uint32_t sdp_record_handle; // if it's a listening socket and advertised // via SDP, this is the SDP handle sdp_session_t *sdp_session; } PySocketSockObject; #ifdef __cplusplus } #endif extern PyObject *bluetooth_error; #endif // __btmodule_h__ pybluez-0.22+really0.22/bluez/btsdp.c000066400000000000000000000340441334611253700173300ustar00rootroot00000000000000#include "Python.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "btmodule.h" #include "btsdp.h" extern PyTypeObject sock_type; extern int getsockaddrlen(PySocketSockObject *s, socklen_t *len_ret); extern PyObject *set_error(void); extern int str2uuid( const char *uuid_str, uuid_t *uuid ); extern void uuid2str( const uuid_t *uuid, char *dest ); // =================== utility functions ===================== static void dict_set_str_pyobj(PyObject *dict, const char *key, PyObject *valobj) { PyObject *keyobj; keyobj = PyString_FromString( key ); PyDict_SetItem( dict, keyobj, valobj ); Py_DECREF( keyobj ); } static void dict_set_strings(PyObject *dict, const char *key, const char *val) { PyObject *keyobj, *valobj; keyobj = PyString_FromString( key ); valobj = PyString_FromString( val ); PyDict_SetItem( dict, keyobj, valobj ); Py_DECREF( keyobj ); Py_DECREF( valobj ); } static void dict_set_str_long(PyObject *dict, const char *key, long val) { PyObject *keyobj, *valobj; keyobj = PyString_FromString( key ); valobj = PyInt_FromLong(val); PyDict_SetItem( dict, keyobj, valobj ); Py_DECREF( keyobj ); Py_DECREF( valobj ); } PyDoc_STRVAR(sess_doc, "SDPSession()\n\ \n\ TODO\n\ "); /* * utility function to perform an SDP search on a connected session. Builds * and returns a python list of dictionaries. Each dictionary represents a * service record match */ static PyObject * do_search( sdp_session_t *sess, uuid_t *uuid ) { sdp_list_t *response_list = NULL, *attrid_list, *search_list, *r; uint32_t range = 0x0000ffff; char buf[1024] = { 0 }; int err = 0; PyObject *result = 0; PyObject *rtn_list = PyList_New(0); if( ! rtn_list ) return 0; search_list = sdp_list_append( 0, uuid ); attrid_list = sdp_list_append( 0, &range ); // perform the search Py_BEGIN_ALLOW_THREADS err = sdp_service_search_attr_req( sess, search_list, \ SDP_ATTR_REQ_RANGE, attrid_list, &response_list); Py_END_ALLOW_THREADS if( err ) { PyErr_SetFromErrno( bluetooth_error ); result = 0; goto cleanup; } // parse the results (ewww....) // go through each of the service records for (r = response_list; r; r = r->next ) { PyObject *dict = PyDict_New(); sdp_record_t *rec = (sdp_record_t*) r->data; sdp_list_t *proto_list = NULL, *svc_class_list = NULL, *profile_list = NULL; PyObject *py_class_list = NULL, *py_profile_list = NULL; uuid_t service_id = { 0 }; if( ! dict ) return 0; // initialize service class list py_class_list = PyList_New(0); if( ! py_class_list ) return 0; dict_set_str_pyobj( dict, "service-classes", py_class_list ); Py_DECREF( py_class_list ); // initialize profile list py_profile_list = PyList_New(0); if( ! py_profile_list ) return 0; dict_set_str_pyobj( dict, "profiles", py_profile_list ); Py_DECREF( py_profile_list ); // set service name if( ! sdp_get_service_name( rec, buf, sizeof(buf) ) ) { dict_set_strings( dict, "name", buf ); memset(buf, 0, sizeof( buf ) ); } else { dict_set_str_pyobj( dict, "name", Py_None ); } // set service description if( ! sdp_get_service_desc( rec, buf, sizeof(buf) ) ) { dict_set_strings( dict, "description", buf ); memset(buf, 0, sizeof( buf ) ); } else { dict_set_str_pyobj( dict, "description", Py_None ); } // set service provider name if( ! sdp_get_provider_name( rec, buf, sizeof(buf) ) ) { dict_set_strings( dict, "provider", buf ); memset(buf, 0, sizeof( buf ) ); } else { dict_set_str_pyobj( dict, "provider", Py_None ); } // set service id if( ! sdp_get_service_id( rec, &service_id ) ) { uuid2str( &service_id, buf ); dict_set_strings( dict, "service-id", buf ); memset(buf, 0, sizeof( buf ) ); } else { dict_set_str_pyobj( dict, "service-id", Py_None ); } // get a list of the protocol sequences if( sdp_get_access_protos( rec, &proto_list ) == 0 ) { sdp_list_t *p = proto_list; int port; if( ( port = sdp_get_proto_port( p, RFCOMM_UUID ) ) != 0 ) { dict_set_strings( dict, "protocol", "RFCOMM" ); dict_set_str_long( dict, "port", port ); } else if ( (port = sdp_get_proto_port( p, L2CAP_UUID ) ) != 0 ) { dict_set_strings( dict, "protocol", "L2CAP" ); dict_set_str_long( dict, "port", port ); } else { dict_set_strings( dict, "protocol", "UNKNOWN" ); dict_set_str_pyobj( dict, "port", Py_None ); } // sdp_get_access_protos allocates data on the heap for the // protocol list, so we need to free the results... for( ; p ; p = p->next ) { sdp_list_free( (sdp_list_t*)p->data, 0 ); } sdp_list_free( proto_list, 0 ); } else { dict_set_str_pyobj( dict, "protocol", Py_None ); dict_set_str_pyobj( dict, "port", Py_None ); } // get a list of the service classes if( sdp_get_service_classes( rec, &svc_class_list ) == 0 ) { sdp_list_t *iter; for( iter = svc_class_list; iter != NULL; iter = iter->next ) { PyObject *pystr; char uuid_str[40] = { 0 }; uuid2str( (uuid_t*)iter->data, uuid_str ); pystr = PyString_FromString( uuid_str ); PyList_Append( py_class_list, pystr ); Py_DECREF( pystr ); } sdp_list_free( svc_class_list, free ); } // get a list of the profiles if( sdp_get_profile_descs( rec, &profile_list ) == 0 ) { sdp_list_t *iter; for( iter = profile_list; iter != NULL; iter = iter->next ) { PyObject *tuple, *py_uuid, *py_version; sdp_profile_desc_t *desc = (sdp_profile_desc_t*)iter->data; char uuid_str[40] = { 0 }; uuid2str( &desc->uuid, uuid_str ); py_uuid = PyString_FromString( uuid_str ); py_version = PyInt_FromLong( desc->version ); tuple = PyTuple_New( 2 ); PyList_Append( py_profile_list, tuple ); Py_DECREF( tuple ); PyTuple_SetItem( tuple, 0, py_uuid ); PyTuple_SetItem( tuple, 1, py_version ); // Py_DECREF( py_uuid ); // Py_DECREF( py_version ); } sdp_list_free( profile_list, free ); } PyList_Append( rtn_list, dict ); Py_DECREF( dict ); sdp_record_free( rec ); } result = rtn_list; cleanup: sdp_list_free( response_list, 0 ); sdp_list_free( search_list, 0 ); sdp_list_free( attrid_list, 0 ); return result; } // ==================== SDPSession methods =========================== // connect static PyObject * sess_connect(PySDPSessionObject *s, PyObject *args, PyObject *kwds) { bdaddr_t src; bdaddr_t dst; char *dst_buf = "localhost"; uint32_t flags = SDP_RETRY_IF_BUSY; static char *keywords[] = {"target", 0}; bacpy( &src, BDADDR_ANY ); bacpy( &dst, BDADDR_LOCAL ); if( s->session != NULL ) { sdp_close( s->session ); } if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s", keywords, &dst_buf)) return NULL; if( strncmp( dst_buf, "localhost", 18 ) != 0 ) { str2ba( dst_buf, &dst ); } else { // XXX } Py_BEGIN_ALLOW_THREADS s->session = sdp_connect( &src, &dst, flags ); Py_END_ALLOW_THREADS if( s->session == NULL ) return PyErr_SetFromErrno( bluetooth_error ); Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(sess_connect_doc, "connect( dest = \"localhost\" )\n\ \n\ Connects the SDP session to the SDP server specified by dest. If the\n\ session was already connected, it's closed first.\n\ \n\ dest specifies the bluetooth address of the server to connect to. Special\n\ case is \"localhost\"\n\ \n\ raises _bluetooth.error if something goes wrong\n\ "); // close static PyObject * sess_close(PySDPSessionObject *s) { if( s->session != NULL ) { Py_BEGIN_ALLOW_THREADS sdp_close( s->session ); Py_END_ALLOW_THREADS s->session = NULL; } Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(sess_close_doc, "close()\n\ \n\ closes the connection with the SDP server. No effect if a session is not open.\n\ "); // fileno static PyObject * sess_fileno(PySDPSessionObject *s) { return PyInt_FromLong((long) s->session->sock); } PyDoc_STRVAR(sess_fileno_doc, "fileno() -> integer\n\ \n\ Return the integer file descriptor of the socket.\n\ You can use this for direct communication with the SDP server.\n\ "); // search static PyObject * sess_search(PySDPSessionObject *s, PyObject *args, PyObject *kwds) { char *uuid_str = 0; uuid_t uuid = { 0 }; PyObject *result = 0; if (!PyArg_ParseTuple(args, "s", &uuid_str)) return NULL; // convert the UUID string into a uuid_t if( ! str2uuid( uuid_str, &uuid ) ) { PyErr_SetString(PyExc_ValueError, "invalid UUID!"); return NULL; } // make sure the SDP session is open if( ! s->session ) { PyErr_SetString( bluetooth_error, "SDP session is not active!" ); return 0; } // perform the search result = do_search( s->session, &uuid ); return result; } PyDoc_STRVAR(sess_search_doc, "search( UUID )\n\ \n\ Searches for a service record with the specified UUID. If no match is found,\n\ returns None. Otherwise, returns a dictionary\n\ \n\ UUID must be in the form \"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX\", \n\ where each X is a hexadecimal digit.\n\ "); // browse static PyObject * sess_browse(PySDPSessionObject *s) { uuid_t uuid = { 0 }; PyObject *result = 0; // convert the UUID string into a uuid_t sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP); // make sure the SDP session is open if( ! s->session ) { PyErr_SetString( bluetooth_error, "SDP session is not active!" ); return 0; } // perform the search result = do_search( s->session, &uuid ); return result; } PyDoc_STRVAR(sess_browse_doc, "browse()\n\ \n\ Browses all services advertised by connected SDP session\n\ "); static PyMethodDef sess_methods[] = { { "search", (PyCFunction) sess_search, METH_VARARGS, sess_search_doc }, { "browse", (PyCFunction) sess_browse, METH_NOARGS, sess_browse_doc }, { "fileno", (PyCFunction)sess_fileno, METH_NOARGS, sess_fileno_doc }, { "connect", (PyCFunction) sess_connect, METH_VARARGS | METH_KEYWORDS, sess_connect_doc }, { "close", (PyCFunction)sess_close, METH_NOARGS, sess_close_doc }, {NULL, NULL} }; /* =============== object maintenance =============== */ /* Deallocate a socket object in response to the last Py_DECREF(). First close the file description. */ static void sess_dealloc(PySDPSessionObject *s) { if(s->session != NULL) { sdp_close( s->session ); s->session = NULL; } Py_TYPE(s)->tp_free((PyObject *)s); } static PyObject * sess_repr(PySDPSessionObject *s) { char buf[512]; if (s->session != NULL) { PyOS_snprintf( buf, sizeof(buf), ""); } else { PyOS_snprintf( buf, sizeof(buf), ""); } return PyString_FromString(buf); } /* Create a new, uninitialized socket object. */ static PyObject * sess_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *newsess; newsess = type->tp_alloc(type, 0); if (newsess != NULL) { ((PySDPSessionObject *)newsess)->session = NULL; } return newsess; } /* Initialize a new socket object. */ /*ARGSUSED*/ static int sess_initobj(PyObject *self, PyObject *args, PyObject *kwds) { PySDPSessionObject *s = (PySDPSessionObject *)self; s->errorhandler = &set_error; /* From now on, ignore SIGPIPE and let the error checking do the work. */ #ifdef SIGPIPE (void) signal(SIGPIPE, SIG_IGN); #endif return 0; } /* Type object for socket objects. */ PyTypeObject sdp_session_type = { #if PY_MAJOR_VERSION < 3 PyObject_HEAD_INIT(0) /* Must fill in type value later */ 0, /* ob_size */ #else PyVarObject_HEAD_INIT(NULL, 0) /* Must fill in type value later */ #endif "_bluetooth.SDPSession", /* tp_name */ sizeof(PySDPSessionObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)sess_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)sess_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ sess_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ sess_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ sess_initobj, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ sess_new, /* tp_new */ PyObject_Del, /* tp_free */ }; pybluez-0.22+really0.22/bluez/btsdp.h000066400000000000000000000005651334611253700173360ustar00rootroot00000000000000#ifndef __pybluez_sdp_h__ #define __pybluez_sdp_h__ #include #include typedef struct { PyObject_HEAD sdp_session_t *session; PyObject *(*errorhandler)(void); /* Error handler; checks errno, returns NULL and sets a Python exception */ } PySDPSessionObject; extern PyTypeObject sdp_session_type; #endif pybluez-0.22+really0.22/docs/000077500000000000000000000000001334611253700156525ustar00rootroot00000000000000pybluez-0.22+really0.22/docs/epydoc.css000066400000000000000000000104561334611253700176550ustar00rootroot00000000000000 /* Body color */ body { background: #ffffff; color: #000000; } /* Tables */ table.summary, table.details, table.index { background: #e8f0f8; color: #000000; } tr.summary, tr.details, tr.index { background: #70b0f0; color: #000000; text-align: left; font-size: 120%; } tr.group { background: #c0e0f8; color: #000000; text-align: left; font-size: 120%; font-style: italic; } /* Documentation page titles */ h2.module { margin-top: 0.2em; } h2.class { margin-top: 0.2em; } /* Headings */ h1.heading { font-size: +140%; font-style: italic; font-weight: bold; } h2.heading { font-size: +125%; font-style: italic; font-weight: bold; } h3.heading { font-size: +110%; font-style: italic; font-weight: normal; } /* Base tree */ pre.base-tree { font-size: 80%; margin: 0; } /* Details Sections */ table.func-details { background: #e8f0f8; color: #000000; border: 2px groove #c0d0d0; padding: 0 1em 0 1em; margin: 0.4em 0 0 0; } h3.func-detail { background: transparent; color: #000000; margin: 0 0 1em 0; } table.var-details { background: #e8f0f8; color: #000000; border: 2px groove #c0d0d0; padding: 0 1em 0 1em; margin: 0.4em 0 0 0; } h3.var-details { background: transparent; color: #000000; margin: 0 0 1em 0; } /* Function signatures */ .sig { background: transparent; color: #000000; font-weight: bold; } .sig-name { background: transparent; color: #006080; } .sig-arg, .sig-kwarg, .sig-vararg { background: transparent; color: #008060; } .sig-default { background: transparent; color: #602000; } .summary-sig { background: transparent; color: #000000; } .summary-sig-name { background: transparent; color: #204080; } .summary-sig-arg, .summary-sig-kwarg, .summary-sig-vararg { background: transparent; color: #008060; } /* Doctest blocks */ .py-src { background: transparent; color: #000000; } .py-prompt { background: transparent; color: #005050; font-weight: bold;} .py-string { background: transparent; color: #006030; } .py-comment { background: transparent; color: #003060; } .py-keyword { background: transparent; color: #600000; } .py-output { background: transparent; color: #404040; } pre.doctestblock { background: #f4faff; color: #000000; padding: .5em; margin: 1em; border: 1px solid #708890; } table pre.doctestblock { background: #dce4ec; color: #000000; padding: .5em; margin: 1em; border: 1px solid #708890; } /* Variable values */ pre.variable { background: #dce4ec; color: #000000; padding: .5em; margin: 0; border: 1px solid #708890; } .variable-linewrap { background: transparent; color: #604000; } .variable-ellipsis { background: transparent; color: #604000; } .variable-quote { background: transparent; color: #604000; } .re { background: transparent; color: #000000; } .re-char { background: transparent; color: #006030; } .re-op { background: transparent; color: #600000; } .re-group { background: transparent; color: #003060; } .re-ref { background: transparent; color: #404040; } /* Navigation bar */ table.navbar { background: #a0c0ff; color: #0000ff; border: 2px groove #c0d0d0; } th.navbar { background: #a0c0ff; color: #0000ff; } th.navselect { background: #70b0ff; color: #000000; } .nomargin { margin: 0; } /* Links */ a:link { background: transparent; color: #0000ff; } a:visited { background: transparent; color: #204080; } a.navbar:link { background: transparent; color: #0000ff; text-decoration: none; } a.navbar:visited { background: transparent; color: #204080; text-decoration: none; } /* Lists */ ul { margin-top: 0; } pybluez-0.22+really0.22/docs/index.html000066400000000000000000000006061334611253700176510ustar00rootroot00000000000000 API Documentation pybluez-0.22+really0.22/docs/private/000077500000000000000000000000001334611253700173245ustar00rootroot00000000000000pybluez-0.22+really0.22/docs/private/bluetooth-module.html000066400000000000000000003670121334611253700235130ustar00rootroot00000000000000 bluetooth
Module bluetooth
[show private | hide private]
[frames | no frames]

Module bluetooth

PyBluez - Bluetooth extension module
Classes
BluetoothSocket BluetoothSocket
DeviceDiscoverer DeviceDiscoverer

Exceptions
BluetoothError  

Function Summary
  advertise_service(sock, name, service_id, service_classes, profiles, provider, description)
Advertises a service with the local SDP server.
  discover_devices(duration, flush_cache, lookup_names)
discover_devices( duration=8, flush_cache=True, lookup_names=False ) -> results availability: GNU/Linux, Windows XP performs a bluetooth device discovery using the first available bluetooth resource.
  find_service(name, uuid, address)
find_service( name = None, uuid = None, address = None ) Searches for SDP services that match the specified criteria and returns the search results.
  get_available_port(protocol)
deprecated.
  is_valid_address(address)
is_valid_address(address) -> bool availability: GNU/Linux, Windows XP returns True if address is a valid bluetooth address valid address are always strings of the form XX:XX:XX:XX:XX:XX where X is a hexadecimal character.
  is_valid_uuid(uuid)
is_valid_uuid(uuid) -> bool availability: GNU/Linux, Windows XP returns True if uuid is a valid UUID.
  lookup_name(address, timeout)
lookup_name( address, timeout=10 ) -> name
  set_l2cap_mtu(sock, mtu)
set_l2cap_mtu( sock, mtu )
  set_packet_timeout(address, timeout)
set_packet_timeout( address, timeout )
  stop_advertising(sock)
Instructs the local SDP server to stop advertising the service associated with sock.

Variable Summary
str ADVANCED_AUDIO_CLASS = '110d'
tuple ADVANCED_AUDIO_PROFILE = ('110d', 256)
str AUDIO_SINK_CLASS = '110b'
tuple AUDIO_SINK_PROFILE = ('110b', 256)
str AUDIO_SOURCE_CLASS = '110a'
tuple AUDIO_SOURCE_PROFILE = ('110a', 256)
str AV_CLASS = '112c'
tuple AV_PROFILE = ('112c', 256)
str AV_REMOTE_CLASS = '110e'
tuple AV_REMOTE_PROFILE = ('110e', 256)
str AV_REMOTE_TARGET_CLASS = '110c'
tuple AV_REMOTE_TARGET_PROFILE = ('110c', 256)
str BASIC_PRINTING_CLASS = '1122'
tuple BASIC_PRINTING_PROFILE = ('1122', 256)
str BROWSE_GRP_DESC_CLASS = '1001'
tuple BROWSE_GRP_DESC_PROFILE = ('1001', 256)
str CIP_CLASS = '1128'
tuple CIP_PROFILE = ('1128', 256)
str CORDLESS_TELEPHONY_CLASS = '1109'
tuple CORDLESS_TELEPHONY_PROFILE = ('1109', 256)
str DIALUP_NET_CLASS = '1103'
tuple DIALUP_NET_PROFILE = ('1103', 256)
str DIRECT_PRINTING_CLASS = '1118'
tuple DIRECT_PRINTING_PROFILE = ('1118', 256)
str DIRECT_PRT_REFOBJS_CLASS = '1120'
tuple DIRECT_PRT_REFOBJS_PROFILE = ('1120', 256)
str FAX_CLASS = '1111'
tuple FAX_PROFILE = ('1111', 256)
str GENERIC_AUDIO_CLASS = '1203'
tuple GENERIC_AUDIO_PROFILE = ('1203', 256)
str GENERIC_FILETRANS_CLASS = '1202'
tuple GENERIC_FILETRANS_PROFILE = ('1202', 256)
str GENERIC_NETWORKING_CLASS = '1201'
tuple GENERIC_NETWORKING_PROFILE = ('1201', 256)
str GENERIC_TELEPHONY_CLASS = '1204'
tuple GENERIC_TELEPHONY_PROFILE = ('1204', 256)
str GN_CLASS = '1117'
tuple GN_PROFILE = ('1117', 256)
str HANDSFREE_AGW_CLASS = '111f'
tuple HANDSFREE_AGW_PROFILE = ('111f', 256)
str HANDSFREE_CLASS = '111e'
tuple HANDSFREE_PROFILE = ('111e', 256)
str HCR_CLASS = '1125'
str HCR_PRINT_CLASS = '1126'
tuple HCR_PRINT_PROFILE = ('1126', 256)
tuple HCR_PROFILE = ('1127', 256)
str HCR_SCAN_CLASS = '1127'
tuple HCR_SCAN_PROFILE = ('1127', 256)
str HEADSET_AGW_CLASS = '1112'
tuple HEADSET_AGW_PROFILE = ('1112', 256)
str HEADSET_CLASS = '1108'
tuple HEADSET_PROFILE = ('1108', 256)
str HID_CLASS = '1124'
tuple HID_PROFILE = ('1124', 256)
str IMAGING_ARCHIVE_CLASS = '111c'
tuple IMAGING_ARCHIVE_PROFILE = ('111c', 256)
str IMAGING_CLASS = '111a'
tuple IMAGING_PROFILE = ('111a', 256)
str IMAGING_REFOBJS_CLASS = '111d'
tuple IMAGING_REFOBJS_PROFILE = ('111d', 256)
str IMAGING_RESPONDER_CLASS = '111b'
tuple IMAGING_RESPONDER_PROFILE = ('111b', 256)
str INTERCOM_CLASS = '1110'
tuple INTERCOM_PROFILE = ('1110', 256)
str IRMC_SYNC_CLASS = '1104'
str IRMC_SYNC_CMD_CLASS = '1107'
tuple IRMC_SYNC_CMD_PROFILE = ('1107', 256)
tuple IRMC_SYNC_PROFILE = ('1104', 256)
int L2CAP = 3                                                                     
str LAN_ACCESS_CLASS = '1102'
tuple LAN_ACCESS_PROFILE = ('1102', 256)
str NAP_CLASS = '1116'
tuple NAP_PROFILE = ('1116', 256)
str OBEX_FILETRANS_CLASS = '1106'
tuple OBEX_FILETRANS_PROFILE = ('1106', 256)
str OBEX_OBJPUSH_CLASS = '1105'
tuple OBEX_OBJPUSH_PROFILE = ('1105', 256)
str PANU_CLASS = '1115'
tuple PANU_PROFILE = ('1115', 256)
str PNP_INFO_CLASS = '1200'
tuple PNP_INFO_PROFILE = ('1200', 256)
int PORT_ANY = 0                                                                     
str PRINTING_STATUS_CLASS = '1123'
tuple PRINTING_STATUS_PROFILE = ('1123', 256)
str PUBLIC_BROWSE_GROUP = '1002'
str REFERENCE_PRINTING_CLASS = '1119'
tuple REFERENCE_PRINTING_PROFILE = ('1119', 256)
str REFLECTED_UI_CLASS = '1121'
tuple REFLECTED_UI_PROFILE = ('1121', 256)
int RFCOMM = 0                                                                     
str SAP_CLASS = '112d'
tuple SAP_PROFILE = ('112d', 256)
str SDP_SERVER_CLASS = '1000'
tuple SDP_SERVER_PROFILE = ('1000', 256)
str SERIAL_PORT_CLASS = '1101'
tuple SERIAL_PORT_PROFILE = ('1101', 256)
str UDI_MT_CLASS = '112a'
tuple UDI_MT_PROFILE = ('112a', 256)
str UDI_TA_CLASS = '112b'
tuple UDI_TA_PROFILE = ('112b', 256)
str UPNP_CLASS = '1205'
str UPNP_IP_CLASS = '1206'
tuple UPNP_IP_PROFILE = ('1206', 256)
str UPNP_L2CAP_CLASS = '1302'
tuple UPNP_L2CAP_PROFILE = ('1302', 256)
str UPNP_LAP_CLASS = '1301'
tuple UPNP_LAP_PROFILE = ('1301', 256)
str UPNP_PAN_CLASS = '1300'
tuple UPNP_PAN_PROFILE = ('1300', 256)
tuple UPNP_PROFILE = ('1205', 256)
str VIDEO_CONF_CLASS = '110f'
str VIDEO_CONF_GW_CLASS = '1129'
tuple VIDEO_CONF_GW_PROFILE = ('1129', 256)
tuple VIDEO_CONF_PROFILE = ('110f', 256)
str VIDEO_SINK_CLASS = '1304'
tuple VIDEO_SINK_PROFILE = ('1304', 256)
str VIDEO_SOURCE_CLASS = '1303'
tuple VIDEO_SOURCE_PROFILE = ('1303', 256)
str WAP_CLASS = '1113'
str WAP_CLIENT_CLASS = '1114'
tuple WAP_CLIENT_PROFILE = ('1114', 256)
tuple WAP_PROFILE = ('1113', 256)

Function Details

advertise_service(sock, name, service_id='', service_classes=[], profiles=[], provider='', description='')

Advertises a service with the local SDP server.  sock must be a bound,
listening socket.  name should be the name of the service, and service_id 
(if specified) should be a string of the form 
"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", where each 'X' is a hexadecimal digit.

service_classes is a list of service classes whose this service belongs to.
Each class service is a 16-bit UUID in the form "XXXX", where each 'X' is a
hexadecimal digit, or a 128-bit UUID in the form
"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX". There are some constants for
standard services, e.g. SERIAL_PORT_CLASS that equals to "1101". Some class
constants:

SERIAL_PORT_CLASS        LAN_ACCESS_CLASS         DIALUP_NET_CLASS 
HEADSET_CLASS            CORDLESS_TELEPHONY_CLASS AUDIO_SOURCE_CLASS
AUDIO_SINK_CLASS         PANU_CLASS               NAP_CLASS
GN_CLASS

profiles is a list of service profiles that thie service fulfills. Each
profile is a tuple with ( uuid, version ). Most standard profiles use
standard classes as UUIDs. PyBluez offers a list of standard profiles,
for example SERIAL_PORT_PROFILE. All standard profiles have the same
name as the classes, except that _CLASS suffix is replaced by _PROFILE.

provider is a text string specifying the provider of the service

description is a text string describing the service

A note on working with Symbian smartphones:
    bt_discover in Python for Series 60 will only detect service records
    with service class SERIAL_PORT_CLASS and profile SERIAL_PORT_PROFILE

discover_devices(duration=8, flush_cache=True, lookup_names=False)

discover_devices( duration=8, flush_cache=True, lookup_names=False ) -> results

availability: GNU/Linux, Windows XP

performs a bluetooth device discovery using the first available bluetooth
resource.

if lookup_names is False, returns a list of bluetooth addresses.
if lookup_names is True, returns a list of (address, name) tuples

duration=8 
    how long, in units of 1.28 seconds, to search for devices.  To find as
    many devices as possible, you should set this to at least 8.  
    This parameter only works with GNU/Linux systems
flush_cache=True 
    if set to False, then discover_devices may return devices found during
    previous discoveries.
lookup_names=False
    if set to True, then discover_devices also attempts to lookup the
    display name of each detected device.

find_service(name=None, uuid=None, address=None)

find_service( name = None, uuid = None, address = None )

Searches for SDP services that match the specified criteria and returns
the search results.  If no criteria are specified, then returns a list of
all nearby services detected.  If more than one is specified, then
the search results will match all the criteria specified.  If uuid is
specified, it must be either a 16-bit UUID in the form "XXXX", where each
'X' is a hexadecimal digit, or as a 128-bit UUID in the form
"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX".  A special case of address is
"localhost", which will search for services on the local machine.

The search results will be a list of dictionaries.  Each dictionary
represents a search match and will have the following key/value pairs:

  host          - the bluetooth address of the device advertising the
                  service
  name          - the name of the service being advertised
  description   - a description of the service being advertised
  provider      - the name of the person/organization providing the service
  protocol      - either 'RFCOMM', 'L2CAP', None if the protocol was not
                  specified, or 'UNKNOWN' if the protocol was specified but
                  unrecognized
  port          - the L2CAP PSM # if the protocol is 'L2CAP', the RFCOMM
                  channel # if the protocol is 'RFCOMM', or None if it
                  wasn't specified
  service-classes - a list of service class IDs (UUID strings).  possibly
                    empty
  profiles        - a list of profiles - (UUID, version) pairs - the
                    service claims to support.  possibly empty.
  service-id      - the Service ID of the service.  None if it wasn't set
                    See the Bluetooth spec for the difference between
                    Service ID and Service Class ID List

get_available_port(protocol)

deprecated. bind to port zero instead.

is_valid_address(address)

is_valid_address(address) -> bool

availability: GNU/Linux, Windows XP

returns True if address is a valid bluetooth address

valid address are always strings of the form XX:XX:XX:XX:XX:XX
where X is a hexadecimal character.  For example,
    01:23:45:67:89:AB is a valid address, but
    IN:VA:LI:DA:DD:RE is not

is_valid_uuid(uuid)

is_valid_uuid(uuid) -> bool

availability: GNU/Linux, Windows XP

returns True if uuid is a valid UUID.

valid UUIDs are always strings taking one of the following forms:
    XXXX
    XXXXXXXX
    XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
where each X is a hexadecimal digit (case insensitive)

lookup_name(address, timeout=10)

lookup_name( address, timeout=10 ) -> name

availability: GNU/Linux

Tries to determine the friendly name (human readable) of the device with the specified bluetooth address. Returns the name on success, and None on failure.

timeout=10 how many seconds to search before giving up.

set_l2cap_mtu(sock, mtu)

set_l2cap_mtu( sock, mtu )

availability: GNU/Linux

Adjusts the MTU for the specified L2CAP socket. This method needs to be invoked on both sides of the connection for it to work! The default mtu that all L2CAP connections start with is 672 bytes.

mtu must be between 48 and 65535, inclusive.

set_packet_timeout(address, timeout)

set_packet_timeout( address, timeout )

Availability: GNU/Linux

Adjusts the ACL flush timeout for the ACL connection to the specified device. This means that all L2CAP and RFCOMM data being sent to that device will be dropped if not acknowledged in timeout milliseconds (maximum 1280). A timeout of 0 means to never drop packets.

Since this affects all Bluetooth connections to that device, and not just those initiated by this process or PyBluez, a call to this method requires superuser privileges.

You must have an active connection to the specified device before invoking this method

stop_advertising(sock)

Instructs the local SDP server to stop advertising the service associated with sock. You should typically call this right before you close sock.

Variable Details

ADVANCED_AUDIO_CLASS

Type:
str
Value:
'110d'                                                                 

ADVANCED_AUDIO_PROFILE

Type:
tuple
Value:
('110d', 256)                                                          

AUDIO_SINK_CLASS

Type:
str
Value:
'110b'                                                                 

AUDIO_SINK_PROFILE

Type:
tuple
Value:
('110b', 256)                                                          

AUDIO_SOURCE_CLASS

Type:
str
Value:
'110a'                                                                 

AUDIO_SOURCE_PROFILE

Type:
tuple
Value:
('110a', 256)                                                          

AV_CLASS

Type:
str
Value:
'112c'                                                                 

AV_PROFILE

Type:
tuple
Value:
('112c', 256)                                                          

AV_REMOTE_CLASS

Type:
str
Value:
'110e'                                                                 

AV_REMOTE_PROFILE

Type:
tuple
Value:
('110e', 256)                                                          

AV_REMOTE_TARGET_CLASS

Type:
str
Value:
'110c'                                                                 

AV_REMOTE_TARGET_PROFILE

Type:
tuple
Value:
('110c', 256)                                                          

BASIC_PRINTING_CLASS

Type:
str
Value:
'1122'                                                                 

BASIC_PRINTING_PROFILE

Type:
tuple
Value:
('1122', 256)                                                          

BROWSE_GRP_DESC_CLASS

Type:
str
Value:
'1001'                                                                 

BROWSE_GRP_DESC_PROFILE

Type:
tuple
Value:
('1001', 256)                                                          

CIP_CLASS

Type:
str
Value:
'1128'                                                                 

CIP_PROFILE

Type:
tuple
Value:
('1128', 256)                                                          

CORDLESS_TELEPHONY_CLASS

Type:
str
Value:
'1109'                                                                 

CORDLESS_TELEPHONY_PROFILE

Type:
tuple
Value:
('1109', 256)                                                          

DIALUP_NET_CLASS

Type:
str
Value:
'1103'                                                                 

DIALUP_NET_PROFILE

Type:
tuple
Value:
('1103', 256)                                                          

DIRECT_PRINTING_CLASS

Type:
str
Value:
'1118'                                                                 

DIRECT_PRINTING_PROFILE

Type:
tuple
Value:
('1118', 256)                                                          

DIRECT_PRT_REFOBJS_CLASS

Type:
str
Value:
'1120'                                                                 

DIRECT_PRT_REFOBJS_PROFILE

Type:
tuple
Value:
('1120', 256)                                                          

FAX_CLASS

Type:
str
Value:
'1111'                                                                 

FAX_PROFILE

Type:
tuple
Value:
('1111', 256)                                                          

GENERIC_AUDIO_CLASS

Type:
str
Value:
'1203'                                                                 

GENERIC_AUDIO_PROFILE

Type:
tuple
Value:
('1203', 256)                                                          

GENERIC_FILETRANS_CLASS

Type:
str
Value:
'1202'                                                                 

GENERIC_FILETRANS_PROFILE

Type:
tuple
Value:
('1202', 256)                                                          

GENERIC_NETWORKING_CLASS

Type:
str
Value:
'1201'                                                                 

GENERIC_NETWORKING_PROFILE

Type:
tuple
Value:
('1201', 256)                                                          

GENERIC_TELEPHONY_CLASS

Type:
str
Value:
'1204'                                                                 

GENERIC_TELEPHONY_PROFILE

Type:
tuple
Value:
('1204', 256)                                                          

GN_CLASS

Type:
str
Value:
'1117'                                                                 

GN_PROFILE

Type:
tuple
Value:
('1117', 256)                                                          

HANDSFREE_AGW_CLASS

Type:
str
Value:
'111f'                                                                 

HANDSFREE_AGW_PROFILE

Type:
tuple
Value:
('111f', 256)                                                          

HANDSFREE_CLASS

Type:
str
Value:
'111e'                                                                 

HANDSFREE_PROFILE

Type:
tuple
Value:
('111e', 256)                                                          

HCR_CLASS

Type:
str
Value:
'1125'                                                                 

HCR_PRINT_CLASS

Type:
str
Value:
'1126'                                                                 

HCR_PRINT_PROFILE

Type:
tuple
Value:
('1126', 256)                                                          

HCR_PROFILE

Type:
tuple
Value:
('1127', 256)                                                          

HCR_SCAN_CLASS

Type:
str
Value:
'1127'                                                                 

HCR_SCAN_PROFILE

Type:
tuple
Value:
('1127', 256)                                                          

HEADSET_AGW_CLASS

Type:
str
Value:
'1112'                                                                 

HEADSET_AGW_PROFILE

Type:
tuple
Value:
('1112', 256)                                                          

HEADSET_CLASS

Type:
str
Value:
'1108'                                                                 

HEADSET_PROFILE

Type:
tuple
Value:
('1108', 256)                                                          

HID_CLASS

Type:
str
Value:
'1124'                                                                 

HID_PROFILE

Type:
tuple
Value:
('1124', 256)                                                          

IMAGING_ARCHIVE_CLASS

Type:
str
Value:
'111c'                                                                 

IMAGING_ARCHIVE_PROFILE

Type:
tuple
Value:
('111c', 256)                                                          

IMAGING_CLASS

Type:
str
Value:
'111a'                                                                 

IMAGING_PROFILE

Type:
tuple
Value:
('111a', 256)                                                          

IMAGING_REFOBJS_CLASS

Type:
str
Value:
'111d'                                                                 

IMAGING_REFOBJS_PROFILE

Type:
tuple
Value:
('111d', 256)                                                          

IMAGING_RESPONDER_CLASS

Type:
str
Value:
'111b'                                                                 

IMAGING_RESPONDER_PROFILE

Type:
tuple
Value:
('111b', 256)                                                          

INTERCOM_CLASS

Type:
str
Value:
'1110'                                                                 

INTERCOM_PROFILE

Type:
tuple
Value:
('1110', 256)                                                          

IRMC_SYNC_CLASS

Type:
str
Value:
'1104'                                                                 

IRMC_SYNC_CMD_CLASS

Type:
str
Value:
'1107'                                                                 

IRMC_SYNC_CMD_PROFILE

Type:
tuple
Value:
('1107', 256)                                                          

IRMC_SYNC_PROFILE

Type:
tuple
Value:
('1104', 256)                                                          

L2CAP

Type:
int
Value:
3                                                                     

LAN_ACCESS_CLASS

Type:
str
Value:
'1102'                                                                 

LAN_ACCESS_PROFILE

Type:
tuple
Value:
('1102', 256)                                                          

NAP_CLASS

Type:
str
Value:
'1116'                                                                 

NAP_PROFILE

Type:
tuple
Value:
('1116', 256)                                                          

OBEX_FILETRANS_CLASS

Type:
str
Value:
'1106'                                                                 

OBEX_FILETRANS_PROFILE

Type:
tuple
Value:
('1106', 256)                                                          

OBEX_OBJPUSH_CLASS

Type:
str
Value:
'1105'                                                                 

OBEX_OBJPUSH_PROFILE

Type:
tuple
Value:
('1105', 256)                                                          

PANU_CLASS

Type:
str
Value:
'1115'                                                                 

PANU_PROFILE

Type:
tuple
Value:
('1115', 256)                                                          

PNP_INFO_CLASS

Type:
str
Value:
'1200'                                                                 

PNP_INFO_PROFILE

Type:
tuple
Value:
('1200', 256)                                                          

PORT_ANY

Type:
int
Value:
0                                                                     

PRINTING_STATUS_CLASS

Type:
str
Value:
'1123'                                                                 

PRINTING_STATUS_PROFILE

Type:
tuple
Value:
('1123', 256)                                                          

PUBLIC_BROWSE_GROUP

Type:
str
Value:
'1002'                                                                 

REFERENCE_PRINTING_CLASS

Type:
str
Value:
'1119'                                                                 

REFERENCE_PRINTING_PROFILE

Type:
tuple
Value:
('1119', 256)                                                          

REFLECTED_UI_CLASS

Type:
str
Value:
'1121'                                                                 

REFLECTED_UI_PROFILE

Type:
tuple
Value:
('1121', 256)                                                          

RFCOMM

Type:
int
Value:
0                                                                     

SAP_CLASS

Type:
str
Value:
'112d'                                                                 

SAP_PROFILE

Type:
tuple
Value:
('112d', 256)                                                          

SDP_SERVER_CLASS

Type:
str
Value:
'1000'                                                                 

SDP_SERVER_PROFILE

Type:
tuple
Value:
('1000', 256)                                                          

SERIAL_PORT_CLASS

Type:
str
Value:
'1101'                                                                 

SERIAL_PORT_PROFILE

Type:
tuple
Value:
('1101', 256)                                                          

UDI_MT_CLASS

Type:
str
Value:
'112a'                                                                 

UDI_MT_PROFILE

Type:
tuple
Value:
('112a', 256)                                                          

UDI_TA_CLASS

Type:
str
Value:
'112b'                                                                 

UDI_TA_PROFILE

Type:
tuple
Value:
('112b', 256)                                                          

UPNP_CLASS

Type:
str
Value:
'1205'                                                                 

UPNP_IP_CLASS

Type:
str
Value:
'1206'                                                                 

UPNP_IP_PROFILE

Type:
tuple
Value:
('1206', 256)                                                          

UPNP_L2CAP_CLASS

Type:
str
Value:
'1302'                                                                 

UPNP_L2CAP_PROFILE

Type:
tuple
Value:
('1302', 256)                                                          

UPNP_LAP_CLASS

Type:
str
Value:
'1301'                                                                 

UPNP_LAP_PROFILE

Type:
tuple
Value:
('1301', 256)                                                          

UPNP_PAN_CLASS

Type:
str
Value:
'1300'                                                                 

UPNP_PAN_PROFILE

Type:
tuple
Value:
('1300', 256)                                                          

UPNP_PROFILE

Type:
tuple
Value:
('1205', 256)                                                          

VIDEO_CONF_CLASS

Type:
str
Value:
'110f'                                                                 

VIDEO_CONF_GW_CLASS

Type:
str
Value:
'1129'                                                                 

VIDEO_CONF_GW_PROFILE

Type:
tuple
Value:
('1129', 256)                                                          

VIDEO_CONF_PROFILE

Type:
tuple
Value:
('110f', 256)                                                          

VIDEO_SINK_CLASS

Type:
str
Value:
'1304'                                                                 

VIDEO_SINK_PROFILE

Type:
tuple
Value:
('1304', 256)                                                          

VIDEO_SOURCE_CLASS

Type:
str
Value:
'1303'                                                                 

VIDEO_SOURCE_PROFILE

Type:
tuple
Value:
('1303', 256)                                                          

WAP_CLASS

Type:
str
Value:
'1113'                                                                 

WAP_CLIENT_CLASS

Type:
str
Value:
'1114'                                                                 

WAP_CLIENT_PROFILE

Type:
tuple
Value:
('1114', 256)                                                          

WAP_PROFILE

Type:
tuple
Value:
('1113', 256)                                                          

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/private/bluetooth.BluetoothError-class.html000066400000000000000000000114261334611253700263040ustar00rootroot00000000000000 bluetooth.BluetoothError
Module bluetooth :: Class BluetoothError
[show private | hide private]
[frames | no frames]

Class BluetoothError

Exception --+            
            |            
StandardError --+        
                |        
 EnvironmentError --+    
                    |    
              IOError --+
                        |
                       BluetoothError


Method Summary
    Inherited from EnvironmentError
  __init__(...)
  __str__(...)
    Inherited from Exception
  __getitem__(...)

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/private/bluetooth.BluetoothSocket-class.html000066400000000000000000000542071334611253700264470ustar00rootroot00000000000000 bluetooth.BluetoothSocket
Module bluetooth :: Class BluetoothSocket
[show private | hide private]
[frames | no frames]

Class BluetoothSocket


BluetoothSocket

availability: GNU/Linux, Windows XP
Method Summary
  __init__(self, proto, _sock)
Create a new Bluetooth socket that uses the specified transport protocol.
  accept(self)
accept() -> (BluetoothSocket, addrport)
  bind(self, addrport)
bind(addrport) availability: GNU/Linux, Windows XP Bind the socket to a local adapter and port.
  close(self)
close()
  connect(self, addrport)
connect(addrport)
  dup(self)
dup() -> socket object
  fileno(self)
fileno() -> integer
  getpeername(self)
getpeername() -> address info
  getsockname(self)
getsockname() -> address info
  getsockopt(self, level, option, buffersize)
getsockopt(level, option[, buffersize]) -> value
  gettimouet(self, timeout)
gettimeout() -> timeout
  listen(self, backlog)
listen(backlog)
  makefile(self)
makefile([mode[, buffersize]]) -> file object
  recv(self, buffersize, flags)
recv(buffersize[, flags]) -> data
  send(self, data, flags)
send(data[, flags]) -> count
  sendall(self, data, flags)
sendall(data[, flags])
  setblocking(self, blocking)
setblocking(flag)
  setsockopt(self, level, option, value)
setsockopt(level, option, value)
  settimeout(self, timeout)
settimeout(timeout)
  shutdown(self, flag)
shutdown(flag)

Method Details

__init__(self, proto=0, _sock=None)
(Constructor)

Create a new Bluetooth socket that uses the specified transport protocol.

proto can be one of RFCOMM, L2CAP, HCI, or SCO

HCI, L2CAP, and SCO sockets are only available in GNU/Linux

accept(self)

accept() -> (BluetoothSocket, addrport)

availability: GNU/Linux, Windows XP

Wait for an incoming connection. Return a new socket representing the connection, and the address/port of the client. For L2CAP sockets, addport is a (host, psm) tuple. For RFCOMM sockets, addport is a (host, channel) tuple. For SCO sockets, addrport is just a Bluetooth address.

bind(self, addrport)

bind(addrport)

availability: GNU/Linux, Windows XP

Bind the socket to a local adapter and port.  addrport must always be a tuple.
  HCI sockets:    ( device number, )
                  device number should be 0, 1, 2, etc.
  L2CAP sockets:  ( host, psm )
                  host should be an address e.g. "01:23:45:67:89:ab"
                  psm should be an unsigned integer
  RFCOMM sockets: ( host, channel )
  SCO sockets:    ( host )

close(self)

close()

availability: GNU/Linux, Windows XP

Close the socket. It cannot be used after this call.

connect(self, addrport)

connect(addrport)

availability: GNU/Linux, Windows XP

Connect the socket to a remote device. For L2CAP sockets, addrport is a (host,psm) tuple. For RFCOMM sockets, addrport is a (host,channel) tuple. For SCO sockets, addrport is just the host.

dup(self)

dup() -> socket object

availability: GNU/Linux

Return a new socket object connected to the same system resource.

fileno(self)

fileno() -> integer

availability: GNU/Linux, Windows XP

Return the integer file descriptor of the socket.

getpeername(self)

getpeername() -> address info

availability: GNU/Linux

Return the address of the remote endpoint. For HCI sockets, the address is a device number (0, 1, 2, etc). For L2CAP sockets, the address is a (host,psm) tuple. For RFCOMM sockets, the address is a (host,channel) tuple. For SCO sockets, the address is just the host.

getsockname(self)

getsockname() -> address info

availability: GNU/Linux, Windows XP Return the address of the local endpoint.

getsockopt(self, level, option, buffersize)

getsockopt(level, option[, buffersize]) -> value

availability: GNU/Linux

Get a socket option. See the Unix manual for level and option. If a nonzero buffersize argument is given, the return value is a string of that length; otherwise it is an integer.

gettimouet(self, timeout)

gettimeout() -> timeout

availability: GNU/Linux

Returns the timeout in floating seconds associated with socket operations. A timeout of None indicates that timeouts on socket operations are disabled.

listen(self, backlog)

listen(backlog)

availability: GNU/Linux, Windows XP

Enable a server to accept connections. The backlog argument must be at least 1; it specifies the number of unaccepted connection that the system will allow before refusing new connections.

makefile(self)

makefile([mode[, buffersize]]) -> file object

availability: GNU/Linux

Return a regular file object corresponding to the socket. The mode and buffersize arguments are as for the built-in open() function.

recv(self, buffersize, flags=None)

recv(buffersize[, flags]) -> data

availability: GNU/Linux, Windows XP

Receive up to buffersize bytes from the socket. For the optional flags argument, see the Unix manual. When no data is available, block until at least one byte is available or until the remote end is closed. When the remote end is closed and all data is read, return the empty string.

send(self, data, flags=None)

send(data[, flags]) -> count

availability: GNU/Linux, Windows XP

Send a data string to the socket. For the optional flags argument, see the Unix manual. Return the number of bytes sent; this may be less than len(data) if the network is busy.

sendall(self, data, flags=None)

sendall(data[, flags])

availability: GNU/Linux

Send a data string to the socket. For the optional flags argument, see the Unix manual. This calls send() repeatedly until all data is sent. If an error occurs, it's impossible to tell how much data has been sent.

setblocking(self, blocking)

setblocking(flag)

availability: GNU/Linux

Set the socket to blocking (flag is true) or non-blocking (false). setblocking(True) is equivalent to settimeout(None); setblocking(False) is equivalent to settimeout(0.0).

setsockopt(self, level, option, value)

setsockopt(level, option, value)

availability: GNU/Linux

Set a socket option. See the Unix manual for level and option. The value argument can either be an integer or a string.

settimeout(self, timeout)

settimeout(timeout)

availability: GNU/Linux

Set a timeout on socket operations. 'timeout' can be a float, giving in seconds, or None. Setting a timeout of None disables the timeout feature and is equivalent to setblocking(1). Setting a timeout of zero is the same as setblocking(0).

shutdown(self, flag)

shutdown(flag)

availability: GNU/Linux

Shut down the reading side of the socket (flag == 0), the writing side of the socket (flag == 1), or both ends (flag == 2).

Generated by Epydoc 2.1 on Tue May 9 02:23:40 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/private/bluetooth.DeviceDiscoverer-class.html000066400000000000000000000271561334611253700265610ustar00rootroot00000000000000 bluetooth.DeviceDiscoverer
Module bluetooth :: Class DeviceDiscoverer
[show private | hide private]
[frames | no frames]

Class DeviceDiscoverer


DeviceDiscoverer

availability: GNU/Linux

Skeleton class for finer control of the device discovery process.

To implement asynchronous device discovery (e.g. if you want to do something *as soon as* a device is discovered), subclass DeviceDiscoverer and override device_discovered() and inquiry_complete()
Method Summary
  __init__(self)
TODO
  cancel_inquiry(self)
Call this method to cancel an inquiry in process.
  device_discovered(self, address, device_class, name)
Called when a bluetooth device is discovered.
  fileno(self)
  find_devices(self, lookup_names, duration, flush_cache)
find_devices( lookup_names=True, service_name=None, duration=8, flush_cache=True ) Call this method to initiate the device discovery process lookup_names - set to True if you want to lookup the user-friendly names for each device found.
  inquiry_complete(self)
Called when an inquiry started by find_devices has completed.
  pre_inquiry(self)
Called just after find_devices is invoked, but just before the inquiry is started.
  process_event(self)
Waits for one event to happen, and proceses it.
  process_inquiry(self)
Repeatedly calls process_event() until the device inquiry has completed.

Method Details

__init__(self)
(Constructor)

TODO

cancel_inquiry(self)

Call this method to cancel an inquiry in process. inquiry_complete will still be called.

device_discovered(self, address, device_class, name)

Called when a bluetooth device is discovered.

address is the bluetooth address of the device

device_class is the Class of Device, as specified in [1]
             passed in as a 3-byte string

name is the user-friendly name of the device if lookup_names was set
     when the inquiry was started.  otherwise None

This method exists to be overriden.

[1] https://www.bluetooth.org/foundry/assignnumb/document/baseband

find_devices(self, lookup_names=True, duration=8, flush_cache=True)

find_devices( lookup_names=True, service_name=None, 
               duration=8, flush_cache=True )

Call this method to initiate the device discovery process

lookup_names - set to True if you want to lookup the user-friendly 
               names for each device found.

service_name - set to the name of a service you're looking for.
               only devices with a service of this name will be 
               returned in device_discovered() NOT YET IMPLEMENTED


ADVANCED PARAMETERS:  (don't change these unless you know what 
                    you're doing)

duration - the number of 1.2 second units to spend searching for
           bluetooth devices.  If lookup_names is True, then the 
           inquiry process can take a lot longer.

flush_cache - return devices discovered in previous inquiries

inquiry_complete(self)

Called when an inquiry started by find_devices has completed.

pre_inquiry(self)

Called just after find_devices is invoked, but just before the inquiry is started.

This method exists to be overriden

process_event(self)

Waits for one event to happen, and proceses it. The event will be either a device discovery, or an inquiry completion.

process_inquiry(self)

Repeatedly calls process_event() until the device inquiry has completed.

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/private/epydoc.css000066400000000000000000000104561334611253700213270ustar00rootroot00000000000000 /* Body color */ body { background: #ffffff; color: #000000; } /* Tables */ table.summary, table.details, table.index { background: #e8f0f8; color: #000000; } tr.summary, tr.details, tr.index { background: #70b0f0; color: #000000; text-align: left; font-size: 120%; } tr.group { background: #c0e0f8; color: #000000; text-align: left; font-size: 120%; font-style: italic; } /* Documentation page titles */ h2.module { margin-top: 0.2em; } h2.class { margin-top: 0.2em; } /* Headings */ h1.heading { font-size: +140%; font-style: italic; font-weight: bold; } h2.heading { font-size: +125%; font-style: italic; font-weight: bold; } h3.heading { font-size: +110%; font-style: italic; font-weight: normal; } /* Base tree */ pre.base-tree { font-size: 80%; margin: 0; } /* Details Sections */ table.func-details { background: #e8f0f8; color: #000000; border: 2px groove #c0d0d0; padding: 0 1em 0 1em; margin: 0.4em 0 0 0; } h3.func-detail { background: transparent; color: #000000; margin: 0 0 1em 0; } table.var-details { background: #e8f0f8; color: #000000; border: 2px groove #c0d0d0; padding: 0 1em 0 1em; margin: 0.4em 0 0 0; } h3.var-details { background: transparent; color: #000000; margin: 0 0 1em 0; } /* Function signatures */ .sig { background: transparent; color: #000000; font-weight: bold; } .sig-name { background: transparent; color: #006080; } .sig-arg, .sig-kwarg, .sig-vararg { background: transparent; color: #008060; } .sig-default { background: transparent; color: #602000; } .summary-sig { background: transparent; color: #000000; } .summary-sig-name { background: transparent; color: #204080; } .summary-sig-arg, .summary-sig-kwarg, .summary-sig-vararg { background: transparent; color: #008060; } /* Doctest blocks */ .py-src { background: transparent; color: #000000; } .py-prompt { background: transparent; color: #005050; font-weight: bold;} .py-string { background: transparent; color: #006030; } .py-comment { background: transparent; color: #003060; } .py-keyword { background: transparent; color: #600000; } .py-output { background: transparent; color: #404040; } pre.doctestblock { background: #f4faff; color: #000000; padding: .5em; margin: 1em; border: 1px solid #708890; } table pre.doctestblock { background: #dce4ec; color: #000000; padding: .5em; margin: 1em; border: 1px solid #708890; } /* Variable values */ pre.variable { background: #dce4ec; color: #000000; padding: .5em; margin: 0; border: 1px solid #708890; } .variable-linewrap { background: transparent; color: #604000; } .variable-ellipsis { background: transparent; color: #604000; } .variable-quote { background: transparent; color: #604000; } .re { background: transparent; color: #000000; } .re-char { background: transparent; color: #006030; } .re-op { background: transparent; color: #600000; } .re-group { background: transparent; color: #003060; } .re-ref { background: transparent; color: #404040; } /* Navigation bar */ table.navbar { background: #a0c0ff; color: #0000ff; border: 2px groove #c0d0d0; } th.navbar { background: #a0c0ff; color: #0000ff; } th.navselect { background: #70b0ff; color: #000000; } .nomargin { margin: 0; } /* Links */ a:link { background: transparent; color: #0000ff; } a:visited { background: transparent; color: #204080; } a.navbar:link { background: transparent; color: #0000ff; text-decoration: none; } a.navbar:visited { background: transparent; color: #204080; text-decoration: none; } /* Lists */ ul { margin-top: 0; } pybluez-0.22+really0.22/docs/private/exceptions.EnvironmentError-class.html000066400000000000000000000107251334611253700270200ustar00rootroot00000000000000 exceptions.EnvironmentError
Module exceptions :: Class EnvironmentError
[show private | hide private]
[frames | no frames]

Class EnvironmentError

Exception --+    
            |    
StandardError --+
                |
               EnvironmentError

Known Subclasses:
IOError

Base class for I/O related errors.
Method Summary
  __init__(...)
  __str__(...)
    Inherited from Exception
  __getitem__(...)

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/private/exceptions.Exception-class.html000066400000000000000000000100401334611253700254260ustar00rootroot00000000000000 exceptions.Exception
Module exceptions :: Class Exception
[show private | hide private]
[frames | no frames]

Class Exception

Known Subclasses:
StandardError

Common base class for all exceptions.
Method Summary
  __init__(...)
  __getitem__(...)
  __str__(...)

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/private/exceptions.IOError-class.html000066400000000000000000000113501334611253700250160ustar00rootroot00000000000000 exceptions.IOError
Module exceptions :: Class IOError
[show private | hide private]
[frames | no frames]

Class IOError

Exception --+        
            |        
StandardError --+    
                |    
 EnvironmentError --+
                    |
                   IOError

Known Subclasses:
BluetoothError

I/O operation failed.
Method Summary
    Inherited from EnvironmentError
  __init__(...)
  __str__(...)
    Inherited from Exception
  __getitem__(...)

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/private/exceptions.StandardError-class.html000066400000000000000000000106621334611253700262540ustar00rootroot00000000000000 exceptions.StandardError
Module exceptions :: Class StandardError
[show private | hide private]
[frames | no frames]

Class StandardError

Exception --+
            |
           StandardError

Known Subclasses:
EnvironmentError

Base class for all standard Python exceptions.
Method Summary
    Inherited from Exception
  __init__(...)
  __getitem__(...)
  __str__(...)

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/private/frames.html000066400000000000000000000005611334611253700214710ustar00rootroot00000000000000 API Documentation pybluez-0.22+really0.22/docs/private/help.html000066400000000000000000000230761334611253700211520ustar00rootroot00000000000000 Help
[show private | hide private]
[frames | no frames]

API Documentation

This document contains the API (Application Programming Interface) documentation for this project. Documentation for the Python objects defined by the project is divided into separate pages for each package, module, and class. The API documentation also includes two pages containing information about the project as a whole: a trees page, and an index page.

Object Documentation

Each Package Documentation page contains:

  • A description of the package.
  • A list of the modules and sub-packages contained by the package.
  • A summary of the classes defined by the package.
  • A summary of the functions defined by the package.
  • A summary of the variables defined by the package.
  • A detailed description of each function defined by the package.
  • A detailed description of each variable defined by the package.

Each Module Documentation page contains:

  • A description of the module.
  • A summary of the classes defined by the module.
  • A summary of the functions defined by the module.
  • A summary of the variables defined by the module.
  • A detailed description of each function defined by the module.
  • A detailed description of each variable defined by the module.

Each Class Documentation page contains:

  • A class inheritance diagram.
  • A list of known subclasses.
  • A description of the class.
  • A summary of the methods defined by the class.
  • A summary of the instance variables defined by the class.
  • A summary of the class (static) variables defined by the class.
  • A detailed description of each method defined by the class.
  • A detailed description of each instance variable defined by the class.
  • A detailed description of each class (static) variable defined by the class.

Project Documentation

The Trees page contains the module and class hierarchies:

  • The module hierarchy lists every package and module, with modules grouped into packages. At the top level, and within each package, modules and sub-packages are listed alphabetically.
  • The class hierarchy lists every class, grouped by base class. If a class has more than one base class, then it will be listed under each base class. At the top level, and under each base class, classes are listed alphabetically.

The Index page contains indices of terms and identifiers:

  • The term index lists every term indexed by any object's documentation. For each term, the index provides links to each place where the term is indexed.
  • The identifier index lists the (short) name of every package, module, class, method, function, variable, and parameter. For each identifier, the index provides a short description, and a link to its documentation.

The Table of Contents

The table of contents occupies the two frames on the left side of the window. The upper-left frame displays the project contents, and the lower-left frame displays the module contents:

Project
Contents
...
API
Documentation
Frame


Module
Contents
 
...
 

The project contents frame contains a list of all packages and modules that are defined by the project. Clicking on an entry will display its contents in the module contents frame. Clicking on a special entry, labeled "Everything," will display the contents of the entire project.

The module contents frame contains a list of every submodule, class, type, exception, function, and variable defined by a module or package. Clicking on an entry will display its documentation in the API documentation frame. Clicking on the name of the module, at the top of the frame, will display the documentation for the module itself.

The "frames" and "no frames" buttons below the top navigation bar can be used to control whether the table of contents is displayed or not.

The Navigation Bar

A navigation bar is located at the top and bottom of every page. It indicates what type of page you are currently viewing, and allows you to go to related pages. The following table describes the labels on the navigation bar. Note that not some labels (such as [Parent]) are not displayed on all pages.

Label Highlighted when... Links to...
[Parent] (never highlighted) the parent of the current package
[Package] viewing a package the package containing the current object
[Module] viewing a module the module containing the current object
[Class] viewing a class the class containing the current object
[Trees] viewing the trees page the trees page
[Index] viewing the index page the index page
[Help] viewing the help page the help page

The "show private" and "hide private" buttons below the top navigation bar can be used to control whether documentation for private objects is displayed. Private objects are usually defined as objects whose (short) names begin with a single underscore, but do not end with an underscore. For example, "_x", "__pprint", and "epydoc.epytext._tokenize" are private objects; but "re.sub", "__init__", and "type_" are not. However, if a module defines the "__all__" variable, then its contents are used to decide which objects are private.

A timestamp below the bottom navigation bar indicates when each page was last updated.

Generated by Epydoc 2.1 on Tue May 9 02:23:40 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/private/index.html000066400000000000000000000005611334611253700213230ustar00rootroot00000000000000 API Documentation pybluez-0.22+really0.22/docs/private/indices.html000066400000000000000000001152011334611253700216300ustar00rootroot00000000000000 Index
[show private | hide private]
[frames | no frames]

Identifier Index
__getitem__ Method in class exceptions.Exception
__init__ Method in class bluetooth.BluetoothSocket
__init__ Method in class bluetooth.DeviceDiscoverer
__init__ Method in class exceptions.EnvironmentError
__init__ Method in class exceptions.Exception
__str__ Method in class exceptions.EnvironmentError
__str__ Method in class exceptions.Exception
accept Method in class bluetooth.BluetoothSocket
ADVANCED_AUDIO_CLASS Variable in module bluetooth
ADVANCED_AUDIO_PROFILE Variable in module bluetooth
advertise_service Function in module bluetooth
AUDIO_SINK_CLASS Variable in module bluetooth
AUDIO_SINK_PROFILE Variable in module bluetooth
AUDIO_SOURCE_CLASS Variable in module bluetooth
AUDIO_SOURCE_PROFILE Variable in module bluetooth
AV_CLASS Variable in module bluetooth
AV_PROFILE Variable in module bluetooth
AV_REMOTE_CLASS Variable in module bluetooth
AV_REMOTE_PROFILE Variable in module bluetooth
AV_REMOTE_TARGET_CLASS Variable in module bluetooth
AV_REMOTE_TARGET_PROFILE Variable in module bluetooth
BASIC_PRINTING_CLASS Variable in module bluetooth
BASIC_PRINTING_PROFILE Variable in module bluetooth
bind Method in class bluetooth.BluetoothSocket
bluetooth Module
BluetoothError Class in module bluetooth
BluetoothSocket Class in module bluetooth
BROWSE_GRP_DESC_CLASS Variable in module bluetooth
BROWSE_GRP_DESC_PROFILE Variable in module bluetooth
cancel_inquiry Method in class bluetooth.DeviceDiscoverer
CIP_CLASS Variable in module bluetooth
CIP_PROFILE Variable in module bluetooth
close Method in class bluetooth.BluetoothSocket
connect Method in class bluetooth.BluetoothSocket
CORDLESS_TELEPHONY_CLASS Variable in module bluetooth
CORDLESS_TELEPHONY_PROFILE Variable in module bluetooth
device_discovered Method in class bluetooth.DeviceDiscoverer
DeviceDiscoverer Class in module bluetooth
DIALUP_NET_CLASS Variable in module bluetooth
DIALUP_NET_PROFILE Variable in module bluetooth
DIRECT_PRINTING_CLASS Variable in module bluetooth
DIRECT_PRINTING_PROFILE Variable in module bluetooth
DIRECT_PRT_REFOBJS_CLASS Variable in module bluetooth
DIRECT_PRT_REFOBJS_PROFILE Variable in module bluetooth
discover_devices Function in module bluetooth
dup Method in class bluetooth.BluetoothSocket
EnvironmentError Class in module exceptions
Exception Class in module exceptions
FAX_CLASS Variable in module bluetooth
FAX_PROFILE Variable in module bluetooth
fileno Method in class bluetooth.BluetoothSocket
fileno Method in class bluetooth.DeviceDiscoverer
find_devices Method in class bluetooth.DeviceDiscoverer
find_service Function in module bluetooth
GENERIC_AUDIO_CLASS Variable in module bluetooth
GENERIC_AUDIO_PROFILE Variable in module bluetooth
GENERIC_FILETRANS_CLASS Variable in module bluetooth
GENERIC_FILETRANS_PROFILE Variable in module bluetooth
GENERIC_NETWORKING_CLASS Variable in module bluetooth
GENERIC_NETWORKING_PROFILE Variable in module bluetooth
GENERIC_TELEPHONY_CLASS Variable in module bluetooth
GENERIC_TELEPHONY_PROFILE Variable in module bluetooth
get_available_port Function in module bluetooth
getpeername Method in class bluetooth.BluetoothSocket
getsockname Method in class bluetooth.BluetoothSocket
getsockopt Method in class bluetooth.BluetoothSocket
gettimouet Method in class bluetooth.BluetoothSocket
GN_CLASS Variable in module bluetooth
GN_PROFILE Variable in module bluetooth
HANDSFREE_AGW_CLASS Variable in module bluetooth
HANDSFREE_AGW_PROFILE Variable in module bluetooth
HANDSFREE_CLASS Variable in module bluetooth
HANDSFREE_PROFILE Variable in module bluetooth
HCR_CLASS Variable in module bluetooth
HCR_PRINT_CLASS Variable in module bluetooth
HCR_PRINT_PROFILE Variable in module bluetooth
HCR_PROFILE Variable in module bluetooth
HCR_SCAN_CLASS Variable in module bluetooth
HCR_SCAN_PROFILE Variable in module bluetooth
HEADSET_AGW_CLASS Variable in module bluetooth
HEADSET_AGW_PROFILE Variable in module bluetooth
HEADSET_CLASS Variable in module bluetooth
HEADSET_PROFILE Variable in module bluetooth
HID_CLASS Variable in module bluetooth
HID_PROFILE Variable in module bluetooth
IMAGING_ARCHIVE_CLASS Variable in module bluetooth
IMAGING_ARCHIVE_PROFILE Variable in module bluetooth
IMAGING_CLASS Variable in module bluetooth
IMAGING_PROFILE Variable in module bluetooth
IMAGING_REFOBJS_CLASS Variable in module bluetooth
IMAGING_REFOBJS_PROFILE Variable in module bluetooth
IMAGING_RESPONDER_CLASS Variable in module bluetooth
IMAGING_RESPONDER_PROFILE Variable in module bluetooth
inquiry_complete Method in class bluetooth.DeviceDiscoverer
INTERCOM_CLASS Variable in module bluetooth
INTERCOM_PROFILE Variable in module bluetooth
IOError Class in module exceptions
IRMC_SYNC_CLASS Variable in module bluetooth
IRMC_SYNC_CMD_CLASS Variable in module bluetooth
IRMC_SYNC_CMD_PROFILE Variable in module bluetooth
IRMC_SYNC_PROFILE Variable in module bluetooth
is_valid_address Function in module bluetooth
is_valid_uuid Function in module bluetooth
L2CAP Variable in module bluetooth
LAN_ACCESS_CLASS Variable in module bluetooth
LAN_ACCESS_PROFILE Variable in module bluetooth
listen Method in class bluetooth.BluetoothSocket
lookup_name Function in module bluetooth
makefile Method in class bluetooth.BluetoothSocket
NAP_CLASS Variable in module bluetooth
NAP_PROFILE Variable in module bluetooth
OBEX_FILETRANS_CLASS Variable in module bluetooth
OBEX_FILETRANS_PROFILE Variable in module bluetooth
OBEX_OBJPUSH_CLASS Variable in module bluetooth
OBEX_OBJPUSH_PROFILE Variable in module bluetooth
PANU_CLASS Variable in module bluetooth
PANU_PROFILE Variable in module bluetooth
PNP_INFO_CLASS Variable in module bluetooth
PNP_INFO_PROFILE Variable in module bluetooth
PORT_ANY Variable in module bluetooth
pre_inquiry Method in class bluetooth.DeviceDiscoverer
PRINTING_STATUS_CLASS Variable in module bluetooth
PRINTING_STATUS_PROFILE Variable in module bluetooth
process_event Method in class bluetooth.DeviceDiscoverer
process_inquiry Method in class bluetooth.DeviceDiscoverer
PUBLIC_BROWSE_GROUP Variable in module bluetooth
recv Method in class bluetooth.BluetoothSocket
REFERENCE_PRINTING_CLASS Variable in module bluetooth
REFERENCE_PRINTING_PROFILE Variable in module bluetooth
REFLECTED_UI_CLASS Variable in module bluetooth
REFLECTED_UI_PROFILE Variable in module bluetooth
RFCOMM Variable in module bluetooth
SAP_CLASS Variable in module bluetooth
SAP_PROFILE Variable in module bluetooth
SDP_SERVER_CLASS Variable in module bluetooth
SDP_SERVER_PROFILE Variable in module bluetooth
send Method in class bluetooth.BluetoothSocket
sendall Method in class bluetooth.BluetoothSocket
SERIAL_PORT_CLASS Variable in module bluetooth
SERIAL_PORT_PROFILE Variable in module bluetooth
set_l2cap_mtu Function in module bluetooth
set_packet_timeout Function in module bluetooth
setblocking Method in class bluetooth.BluetoothSocket
setsockopt Method in class bluetooth.BluetoothSocket
settimeout Method in class bluetooth.BluetoothSocket
shutdown Method in class bluetooth.BluetoothSocket
StandardError Class in module exceptions
stop_advertising Function in module bluetooth
UDI_MT_CLASS Variable in module bluetooth
UDI_MT_PROFILE Variable in module bluetooth
UDI_TA_CLASS Variable in module bluetooth
UDI_TA_PROFILE Variable in module bluetooth
UPNP_CLASS Variable in module bluetooth
UPNP_IP_CLASS Variable in module bluetooth
UPNP_IP_PROFILE Variable in module bluetooth
UPNP_L2CAP_CLASS Variable in module bluetooth
UPNP_L2CAP_PROFILE Variable in module bluetooth
UPNP_LAP_CLASS Variable in module bluetooth
UPNP_LAP_PROFILE Variable in module bluetooth
UPNP_PAN_CLASS Variable in module bluetooth
UPNP_PAN_PROFILE Variable in module bluetooth
UPNP_PROFILE Variable in module bluetooth
VIDEO_CONF_CLASS Variable in module bluetooth
VIDEO_CONF_GW_CLASS Variable in module bluetooth
VIDEO_CONF_GW_PROFILE Variable in module bluetooth
VIDEO_CONF_PROFILE Variable in module bluetooth
VIDEO_SINK_CLASS Variable in module bluetooth
VIDEO_SINK_PROFILE Variable in module bluetooth
VIDEO_SOURCE_CLASS Variable in module bluetooth
VIDEO_SOURCE_PROFILE Variable in module bluetooth
WAP_CLASS Variable in module bluetooth
WAP_CLIENT_CLASS Variable in module bluetooth
WAP_CLIENT_PROFILE Variable in module bluetooth
WAP_PROFILE Variable in module bluetooth

Generated by Epydoc 2.1 on Tue May 9 02:23:40 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/private/toc-bluetooth-module.html000066400000000000000000000334431334611253700242740ustar00rootroot00000000000000 bluetooth
bluetooth

Classes
BluetoothSocket
DeviceDiscoverer

Exceptions
BluetoothError

Functions
advertise_service
discover_devices
find_service
get_available_port
is_valid_address
is_valid_uuid
lookup_name
set_l2cap_mtu
set_packet_timeout
stop_advertising

Variables
ADVANCED_AUDIO_CLASS
ADVANCED_AUDIO_PROFILE
AUDIO_SINK_CLASS
AUDIO_SINK_PROFILE
AUDIO_SOURCE_CLASS
AUDIO_SOURCE_PROFILE
AV_CLASS
AV_PROFILE
AV_REMOTE_CLASS
AV_REMOTE_PROFILE
AV_REMOTE_TARGET_CLASS
AV_REMOTE_TARGET_PROFILE
BASIC_PRINTING_CLASS
BASIC_PRINTING_PROFILE
BROWSE_GRP_DESC_CLASS
BROWSE_GRP_DESC_PROFILE
CIP_CLASS
CIP_PROFILE
CORDLESS_TELEPHONY_CLASS
CORDLESS_TELEPHONY_PROFILE
DIALUP_NET_CLASS
DIALUP_NET_PROFILE
DIRECT_PRINTING_CLASS
DIRECT_PRINTING_PROFILE
DIRECT_PRT_REFOBJS_CLASS
DIRECT_PRT_REFOBJS_PROFILE
FAX_CLASS
FAX_PROFILE
GENERIC_AUDIO_CLASS
GENERIC_AUDIO_PROFILE
GENERIC_FILETRANS_CLASS
GENERIC_FILETRANS_PROFILE
GENERIC_NETWORKING_CLASS
GENERIC_NETWORKING_PROFILE
GENERIC_TELEPHONY_CLASS
GENERIC_TELEPHONY_PROFILE
GN_CLASS
GN_PROFILE
HANDSFREE_AGW_CLASS
HANDSFREE_AGW_PROFILE
HANDSFREE_CLASS
HANDSFREE_PROFILE
HCR_CLASS
HCR_PRINT_CLASS
HCR_PRINT_PROFILE
HCR_PROFILE
HCR_SCAN_CLASS
HCR_SCAN_PROFILE
HEADSET_AGW_CLASS
HEADSET_AGW_PROFILE
HEADSET_CLASS
HEADSET_PROFILE
HID_CLASS
HID_PROFILE
IMAGING_ARCHIVE_CLASS
IMAGING_ARCHIVE_PROFILE
IMAGING_CLASS
IMAGING_PROFILE
IMAGING_REFOBJS_CLASS
IMAGING_REFOBJS_PROFILE
IMAGING_RESPONDER_CLASS
IMAGING_RESPONDER_PROFILE
INTERCOM_CLASS
INTERCOM_PROFILE
IRMC_SYNC_CLASS
IRMC_SYNC_CMD_CLASS
IRMC_SYNC_CMD_PROFILE
IRMC_SYNC_PROFILE
L2CAP
LAN_ACCESS_CLASS
LAN_ACCESS_PROFILE
NAP_CLASS
NAP_PROFILE
OBEX_FILETRANS_CLASS
OBEX_FILETRANS_PROFILE
OBEX_OBJPUSH_CLASS
OBEX_OBJPUSH_PROFILE
PANU_CLASS
PANU_PROFILE
PNP_INFO_CLASS
PNP_INFO_PROFILE
PORT_ANY
PRINTING_STATUS_CLASS
PRINTING_STATUS_PROFILE
PUBLIC_BROWSE_GROUP
REFERENCE_PRINTING_CLASS
REFERENCE_PRINTING_PROFILE
REFLECTED_UI_CLASS
REFLECTED_UI_PROFILE
RFCOMM
SAP_CLASS
SAP_PROFILE
SDP_SERVER_CLASS
SDP_SERVER_PROFILE
SERIAL_PORT_CLASS
SERIAL_PORT_PROFILE
UDI_MT_CLASS
UDI_MT_PROFILE
UDI_TA_CLASS
UDI_TA_PROFILE
UPNP_CLASS
UPNP_IP_CLASS
UPNP_IP_PROFILE
UPNP_L2CAP_CLASS
UPNP_L2CAP_PROFILE
UPNP_LAP_CLASS
UPNP_LAP_PROFILE
UPNP_PAN_CLASS
UPNP_PAN_PROFILE
UPNP_PROFILE
VIDEO_CONF_CLASS
VIDEO_CONF_GW_CLASS
VIDEO_CONF_GW_PROFILE
VIDEO_CONF_PROFILE
VIDEO_SINK_CLASS
VIDEO_SINK_PROFILE
VIDEO_SOURCE_CLASS
VIDEO_SOURCE_PROFILE
WAP_CLASS
WAP_CLIENT_CLASS
WAP_CLIENT_PROFILE
WAP_PROFILE


[show private | hide private] pybluez-0.22+really0.22/docs/private/toc-everything.html000066400000000000000000000334721334611253700231720ustar00rootroot00000000000000 Everything
Everything

All Classes
bluetooth.BluetoothSocket
bluetooth.DeviceDiscoverer

All Exceptions
bluetooth.BluetoothError

All Functions
advertise_service
discover_devices
find_service
get_available_port
is_valid_address
is_valid_uuid
lookup_name
set_l2cap_mtu
set_packet_timeout
stop_advertising

All Variables
ADVANCED_AUDIO_CLASS
ADVANCED_AUDIO_PROFILE
AUDIO_SINK_CLASS
AUDIO_SINK_PROFILE
AUDIO_SOURCE_CLASS
AUDIO_SOURCE_PROFILE
AV_CLASS
AV_PROFILE
AV_REMOTE_CLASS
AV_REMOTE_PROFILE
AV_REMOTE_TARGET_CLASS
AV_REMOTE_TARGET_PROFILE
BASIC_PRINTING_CLASS
BASIC_PRINTING_PROFILE
BROWSE_GRP_DESC_CLASS
BROWSE_GRP_DESC_PROFILE
CIP_CLASS
CIP_PROFILE
CORDLESS_TELEPHONY_CLASS
CORDLESS_TELEPHONY_PROFILE
DIALUP_NET_CLASS
DIALUP_NET_PROFILE
DIRECT_PRINTING_CLASS
DIRECT_PRINTING_PROFILE
DIRECT_PRT_REFOBJS_CLASS
DIRECT_PRT_REFOBJS_PROFILE
FAX_CLASS
FAX_PROFILE
GENERIC_AUDIO_CLASS
GENERIC_AUDIO_PROFILE
GENERIC_FILETRANS_CLASS
GENERIC_FILETRANS_PROFILE
GENERIC_NETWORKING_CLASS
GENERIC_NETWORKING_PROFILE
GENERIC_TELEPHONY_CLASS
GENERIC_TELEPHONY_PROFILE
GN_CLASS
GN_PROFILE
HANDSFREE_AGW_CLASS
HANDSFREE_AGW_PROFILE
HANDSFREE_CLASS
HANDSFREE_PROFILE
HCR_CLASS
HCR_PRINT_CLASS
HCR_PRINT_PROFILE
HCR_PROFILE
HCR_SCAN_CLASS
HCR_SCAN_PROFILE
HEADSET_AGW_CLASS
HEADSET_AGW_PROFILE
HEADSET_CLASS
HEADSET_PROFILE
HID_CLASS
HID_PROFILE
IMAGING_ARCHIVE_CLASS
IMAGING_ARCHIVE_PROFILE
IMAGING_CLASS
IMAGING_PROFILE
IMAGING_REFOBJS_CLASS
IMAGING_REFOBJS_PROFILE
IMAGING_RESPONDER_CLASS
IMAGING_RESPONDER_PROFILE
INTERCOM_CLASS
INTERCOM_PROFILE
IRMC_SYNC_CLASS
IRMC_SYNC_CMD_CLASS
IRMC_SYNC_CMD_PROFILE
IRMC_SYNC_PROFILE
L2CAP
LAN_ACCESS_CLASS
LAN_ACCESS_PROFILE
NAP_CLASS
NAP_PROFILE
OBEX_FILETRANS_CLASS
OBEX_FILETRANS_PROFILE
OBEX_OBJPUSH_CLASS
OBEX_OBJPUSH_PROFILE
PANU_CLASS
PANU_PROFILE
PNP_INFO_CLASS
PNP_INFO_PROFILE
PORT_ANY
PRINTING_STATUS_CLASS
PRINTING_STATUS_PROFILE
PUBLIC_BROWSE_GROUP
REFERENCE_PRINTING_CLASS
REFERENCE_PRINTING_PROFILE
REFLECTED_UI_CLASS
REFLECTED_UI_PROFILE
RFCOMM
SAP_CLASS
SAP_PROFILE
SDP_SERVER_CLASS
SDP_SERVER_PROFILE
SERIAL_PORT_CLASS
SERIAL_PORT_PROFILE
UDI_MT_CLASS
UDI_MT_PROFILE
UDI_TA_CLASS
UDI_TA_PROFILE
UPNP_CLASS
UPNP_IP_CLASS
UPNP_IP_PROFILE
UPNP_L2CAP_CLASS
UPNP_L2CAP_PROFILE
UPNP_LAP_CLASS
UPNP_LAP_PROFILE
UPNP_PAN_CLASS
UPNP_PAN_PROFILE
UPNP_PROFILE
VIDEO_CONF_CLASS
VIDEO_CONF_GW_CLASS
VIDEO_CONF_GW_PROFILE
VIDEO_CONF_PROFILE
VIDEO_SINK_CLASS
VIDEO_SINK_PROFILE
VIDEO_SOURCE_CLASS
VIDEO_SOURCE_PROFILE
WAP_CLASS
WAP_CLIENT_CLASS
WAP_CLIENT_PROFILE
WAP_PROFILE


[show private | hide private] pybluez-0.22+really0.22/docs/private/toc.html000066400000000000000000000017321334611253700210020ustar00rootroot00000000000000 Table of Contents
Table of Contents

Everything

Packages

Modules
bluetooth


[show private | hide private] pybluez-0.22+really0.22/docs/private/trees.html000066400000000000000000000075421334611253700213440ustar00rootroot00000000000000 Module and Class Hierarchies
[show private | hide private]
[frames | no frames]

Module Hierarchy

  • bluetooth: PyBluez - Bluetooth extension module

Class Hierarchy

Generated by Epydoc 2.1 on Tue May 9 02:23:40 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/public/000077500000000000000000000000001334611253700171305ustar00rootroot00000000000000pybluez-0.22+really0.22/docs/public/bluetooth-module.html000066400000000000000000003670131334611253700233200ustar00rootroot00000000000000 bluetooth
Module bluetooth
[show private | hide private]
[frames | no frames]

Module bluetooth

PyBluez - Bluetooth extension module
Classes
BluetoothSocket BluetoothSocket
DeviceDiscoverer DeviceDiscoverer

Exceptions
BluetoothError  

Function Summary
  advertise_service(sock, name, service_id, service_classes, profiles, provider, description)
Advertises a service with the local SDP server.
  discover_devices(duration, flush_cache, lookup_names)
discover_devices( duration=8, flush_cache=True, lookup_names=False ) -> results availability: GNU/Linux, Windows XP performs a bluetooth device discovery using the first available bluetooth resource.
  find_service(name, uuid, address)
find_service( name = None, uuid = None, address = None ) Searches for SDP services that match the specified criteria and returns the search results.
  get_available_port(protocol)
deprecated.
  is_valid_address(address)
is_valid_address(address) -> bool availability: GNU/Linux, Windows XP returns True if address is a valid bluetooth address valid address are always strings of the form XX:XX:XX:XX:XX:XX where X is a hexadecimal character.
  is_valid_uuid(uuid)
is_valid_uuid(uuid) -> bool availability: GNU/Linux, Windows XP returns True if uuid is a valid UUID.
  lookup_name(address, timeout)
lookup_name( address, timeout=10 ) -> name
  set_l2cap_mtu(sock, mtu)
set_l2cap_mtu( sock, mtu )
  set_packet_timeout(address, timeout)
set_packet_timeout( address, timeout )
  stop_advertising(sock)
Instructs the local SDP server to stop advertising the service associated with sock.

Variable Summary
str ADVANCED_AUDIO_CLASS = '110d'
tuple ADVANCED_AUDIO_PROFILE = ('110d', 256)
str AUDIO_SINK_CLASS = '110b'
tuple AUDIO_SINK_PROFILE = ('110b', 256)
str AUDIO_SOURCE_CLASS = '110a'
tuple AUDIO_SOURCE_PROFILE = ('110a', 256)
str AV_CLASS = '112c'
tuple AV_PROFILE = ('112c', 256)
str AV_REMOTE_CLASS = '110e'
tuple AV_REMOTE_PROFILE = ('110e', 256)
str AV_REMOTE_TARGET_CLASS = '110c'
tuple AV_REMOTE_TARGET_PROFILE = ('110c', 256)
str BASIC_PRINTING_CLASS = '1122'
tuple BASIC_PRINTING_PROFILE = ('1122', 256)
str BROWSE_GRP_DESC_CLASS = '1001'
tuple BROWSE_GRP_DESC_PROFILE = ('1001', 256)
str CIP_CLASS = '1128'
tuple CIP_PROFILE = ('1128', 256)
str CORDLESS_TELEPHONY_CLASS = '1109'
tuple CORDLESS_TELEPHONY_PROFILE = ('1109', 256)
str DIALUP_NET_CLASS = '1103'
tuple DIALUP_NET_PROFILE = ('1103', 256)
str DIRECT_PRINTING_CLASS = '1118'
tuple DIRECT_PRINTING_PROFILE = ('1118', 256)
str DIRECT_PRT_REFOBJS_CLASS = '1120'
tuple DIRECT_PRT_REFOBJS_PROFILE = ('1120', 256)
str FAX_CLASS = '1111'
tuple FAX_PROFILE = ('1111', 256)
str GENERIC_AUDIO_CLASS = '1203'
tuple GENERIC_AUDIO_PROFILE = ('1203', 256)
str GENERIC_FILETRANS_CLASS = '1202'
tuple GENERIC_FILETRANS_PROFILE = ('1202', 256)
str GENERIC_NETWORKING_CLASS = '1201'
tuple GENERIC_NETWORKING_PROFILE = ('1201', 256)
str GENERIC_TELEPHONY_CLASS = '1204'
tuple GENERIC_TELEPHONY_PROFILE = ('1204', 256)
str GN_CLASS = '1117'
tuple GN_PROFILE = ('1117', 256)
str HANDSFREE_AGW_CLASS = '111f'
tuple HANDSFREE_AGW_PROFILE = ('111f', 256)
str HANDSFREE_CLASS = '111e'
tuple HANDSFREE_PROFILE = ('111e', 256)
str HCR_CLASS = '1125'
str HCR_PRINT_CLASS = '1126'
tuple HCR_PRINT_PROFILE = ('1126', 256)
tuple HCR_PROFILE = ('1127', 256)
str HCR_SCAN_CLASS = '1127'
tuple HCR_SCAN_PROFILE = ('1127', 256)
str HEADSET_AGW_CLASS = '1112'
tuple HEADSET_AGW_PROFILE = ('1112', 256)
str HEADSET_CLASS = '1108'
tuple HEADSET_PROFILE = ('1108', 256)
str HID_CLASS = '1124'
tuple HID_PROFILE = ('1124', 256)
str IMAGING_ARCHIVE_CLASS = '111c'
tuple IMAGING_ARCHIVE_PROFILE = ('111c', 256)
str IMAGING_CLASS = '111a'
tuple IMAGING_PROFILE = ('111a', 256)
str IMAGING_REFOBJS_CLASS = '111d'
tuple IMAGING_REFOBJS_PROFILE = ('111d', 256)
str IMAGING_RESPONDER_CLASS = '111b'
tuple IMAGING_RESPONDER_PROFILE = ('111b', 256)
str INTERCOM_CLASS = '1110'
tuple INTERCOM_PROFILE = ('1110', 256)
str IRMC_SYNC_CLASS = '1104'
str IRMC_SYNC_CMD_CLASS = '1107'
tuple IRMC_SYNC_CMD_PROFILE = ('1107', 256)
tuple IRMC_SYNC_PROFILE = ('1104', 256)
int L2CAP = 3                                                                     
str LAN_ACCESS_CLASS = '1102'
tuple LAN_ACCESS_PROFILE = ('1102', 256)
str NAP_CLASS = '1116'
tuple NAP_PROFILE = ('1116', 256)
str OBEX_FILETRANS_CLASS = '1106'
tuple OBEX_FILETRANS_PROFILE = ('1106', 256)
str OBEX_OBJPUSH_CLASS = '1105'
tuple OBEX_OBJPUSH_PROFILE = ('1105', 256)
str PANU_CLASS = '1115'
tuple PANU_PROFILE = ('1115', 256)
str PNP_INFO_CLASS = '1200'
tuple PNP_INFO_PROFILE = ('1200', 256)
int PORT_ANY = 0                                                                     
str PRINTING_STATUS_CLASS = '1123'
tuple PRINTING_STATUS_PROFILE = ('1123', 256)
str PUBLIC_BROWSE_GROUP = '1002'
str REFERENCE_PRINTING_CLASS = '1119'
tuple REFERENCE_PRINTING_PROFILE = ('1119', 256)
str REFLECTED_UI_CLASS = '1121'
tuple REFLECTED_UI_PROFILE = ('1121', 256)
int RFCOMM = 0                                                                     
str SAP_CLASS = '112d'
tuple SAP_PROFILE = ('112d', 256)
str SDP_SERVER_CLASS = '1000'
tuple SDP_SERVER_PROFILE = ('1000', 256)
str SERIAL_PORT_CLASS = '1101'
tuple SERIAL_PORT_PROFILE = ('1101', 256)
str UDI_MT_CLASS = '112a'
tuple UDI_MT_PROFILE = ('112a', 256)
str UDI_TA_CLASS = '112b'
tuple UDI_TA_PROFILE = ('112b', 256)
str UPNP_CLASS = '1205'
str UPNP_IP_CLASS = '1206'
tuple UPNP_IP_PROFILE = ('1206', 256)
str UPNP_L2CAP_CLASS = '1302'
tuple UPNP_L2CAP_PROFILE = ('1302', 256)
str UPNP_LAP_CLASS = '1301'
tuple UPNP_LAP_PROFILE = ('1301', 256)
str UPNP_PAN_CLASS = '1300'
tuple UPNP_PAN_PROFILE = ('1300', 256)
tuple UPNP_PROFILE = ('1205', 256)
str VIDEO_CONF_CLASS = '110f'
str VIDEO_CONF_GW_CLASS = '1129'
tuple VIDEO_CONF_GW_PROFILE = ('1129', 256)
tuple VIDEO_CONF_PROFILE = ('110f', 256)
str VIDEO_SINK_CLASS = '1304'
tuple VIDEO_SINK_PROFILE = ('1304', 256)
str VIDEO_SOURCE_CLASS = '1303'
tuple VIDEO_SOURCE_PROFILE = ('1303', 256)
str WAP_CLASS = '1113'
str WAP_CLIENT_CLASS = '1114'
tuple WAP_CLIENT_PROFILE = ('1114', 256)
tuple WAP_PROFILE = ('1113', 256)

Function Details

advertise_service(sock, name, service_id='', service_classes=[], profiles=[], provider='', description='')

Advertises a service with the local SDP server.  sock must be a bound,
listening socket.  name should be the name of the service, and service_id 
(if specified) should be a string of the form 
"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX", where each 'X' is a hexadecimal digit.

service_classes is a list of service classes whose this service belongs to.
Each class service is a 16-bit UUID in the form "XXXX", where each 'X' is a
hexadecimal digit, or a 128-bit UUID in the form
"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX". There are some constants for
standard services, e.g. SERIAL_PORT_CLASS that equals to "1101". Some class
constants:

SERIAL_PORT_CLASS        LAN_ACCESS_CLASS         DIALUP_NET_CLASS 
HEADSET_CLASS            CORDLESS_TELEPHONY_CLASS AUDIO_SOURCE_CLASS
AUDIO_SINK_CLASS         PANU_CLASS               NAP_CLASS
GN_CLASS

profiles is a list of service profiles that thie service fulfills. Each
profile is a tuple with ( uuid, version ). Most standard profiles use
standard classes as UUIDs. PyBluez offers a list of standard profiles,
for example SERIAL_PORT_PROFILE. All standard profiles have the same
name as the classes, except that _CLASS suffix is replaced by _PROFILE.

provider is a text string specifying the provider of the service

description is a text string describing the service

A note on working with Symbian smartphones:
    bt_discover in Python for Series 60 will only detect service records
    with service class SERIAL_PORT_CLASS and profile SERIAL_PORT_PROFILE

discover_devices(duration=8, flush_cache=True, lookup_names=False)

discover_devices( duration=8, flush_cache=True, lookup_names=False ) -> results

availability: GNU/Linux, Windows XP

performs a bluetooth device discovery using the first available bluetooth
resource.

if lookup_names is False, returns a list of bluetooth addresses.
if lookup_names is True, returns a list of (address, name) tuples

duration=8 
    how long, in units of 1.28 seconds, to search for devices.  To find as
    many devices as possible, you should set this to at least 8.  
    This parameter only works with GNU/Linux systems
flush_cache=True 
    if set to False, then discover_devices may return devices found during
    previous discoveries.
lookup_names=False
    if set to True, then discover_devices also attempts to lookup the
    display name of each detected device.

find_service(name=None, uuid=None, address=None)

find_service( name = None, uuid = None, address = None )

Searches for SDP services that match the specified criteria and returns
the search results.  If no criteria are specified, then returns a list of
all nearby services detected.  If more than one is specified, then
the search results will match all the criteria specified.  If uuid is
specified, it must be either a 16-bit UUID in the form "XXXX", where each
'X' is a hexadecimal digit, or as a 128-bit UUID in the form
"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX".  A special case of address is
"localhost", which will search for services on the local machine.

The search results will be a list of dictionaries.  Each dictionary
represents a search match and will have the following key/value pairs:

  host          - the bluetooth address of the device advertising the
                  service
  name          - the name of the service being advertised
  description   - a description of the service being advertised
  provider      - the name of the person/organization providing the service
  protocol      - either 'RFCOMM', 'L2CAP', None if the protocol was not
                  specified, or 'UNKNOWN' if the protocol was specified but
                  unrecognized
  port          - the L2CAP PSM # if the protocol is 'L2CAP', the RFCOMM
                  channel # if the protocol is 'RFCOMM', or None if it
                  wasn't specified
  service-classes - a list of service class IDs (UUID strings).  possibly
                    empty
  profiles        - a list of profiles - (UUID, version) pairs - the
                    service claims to support.  possibly empty.
  service-id      - the Service ID of the service.  None if it wasn't set
                    See the Bluetooth spec for the difference between
                    Service ID and Service Class ID List

get_available_port(protocol)

deprecated. bind to port zero instead.

is_valid_address(address)

is_valid_address(address) -> bool

availability: GNU/Linux, Windows XP

returns True if address is a valid bluetooth address

valid address are always strings of the form XX:XX:XX:XX:XX:XX
where X is a hexadecimal character.  For example,
    01:23:45:67:89:AB is a valid address, but
    IN:VA:LI:DA:DD:RE is not

is_valid_uuid(uuid)

is_valid_uuid(uuid) -> bool

availability: GNU/Linux, Windows XP

returns True if uuid is a valid UUID.

valid UUIDs are always strings taking one of the following forms:
    XXXX
    XXXXXXXX
    XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
where each X is a hexadecimal digit (case insensitive)

lookup_name(address, timeout=10)

lookup_name( address, timeout=10 ) -> name

availability: GNU/Linux

Tries to determine the friendly name (human readable) of the device with the specified bluetooth address. Returns the name on success, and None on failure.

timeout=10 how many seconds to search before giving up.

set_l2cap_mtu(sock, mtu)

set_l2cap_mtu( sock, mtu )

availability: GNU/Linux

Adjusts the MTU for the specified L2CAP socket. This method needs to be invoked on both sides of the connection for it to work! The default mtu that all L2CAP connections start with is 672 bytes.

mtu must be between 48 and 65535, inclusive.

set_packet_timeout(address, timeout)

set_packet_timeout( address, timeout )

Availability: GNU/Linux

Adjusts the ACL flush timeout for the ACL connection to the specified device. This means that all L2CAP and RFCOMM data being sent to that device will be dropped if not acknowledged in timeout milliseconds (maximum 1280). A timeout of 0 means to never drop packets.

Since this affects all Bluetooth connections to that device, and not just those initiated by this process or PyBluez, a call to this method requires superuser privileges.

You must have an active connection to the specified device before invoking this method

stop_advertising(sock)

Instructs the local SDP server to stop advertising the service associated with sock. You should typically call this right before you close sock.

Variable Details

ADVANCED_AUDIO_CLASS

Type:
str
Value:
'110d'                                                                 

ADVANCED_AUDIO_PROFILE

Type:
tuple
Value:
('110d', 256)                                                          

AUDIO_SINK_CLASS

Type:
str
Value:
'110b'                                                                 

AUDIO_SINK_PROFILE

Type:
tuple
Value:
('110b', 256)                                                          

AUDIO_SOURCE_CLASS

Type:
str
Value:
'110a'                                                                 

AUDIO_SOURCE_PROFILE

Type:
tuple
Value:
('110a', 256)                                                          

AV_CLASS

Type:
str
Value:
'112c'                                                                 

AV_PROFILE

Type:
tuple
Value:
('112c', 256)                                                          

AV_REMOTE_CLASS

Type:
str
Value:
'110e'                                                                 

AV_REMOTE_PROFILE

Type:
tuple
Value:
('110e', 256)                                                          

AV_REMOTE_TARGET_CLASS

Type:
str
Value:
'110c'                                                                 

AV_REMOTE_TARGET_PROFILE

Type:
tuple
Value:
('110c', 256)                                                          

BASIC_PRINTING_CLASS

Type:
str
Value:
'1122'                                                                 

BASIC_PRINTING_PROFILE

Type:
tuple
Value:
('1122', 256)                                                          

BROWSE_GRP_DESC_CLASS

Type:
str
Value:
'1001'                                                                 

BROWSE_GRP_DESC_PROFILE

Type:
tuple
Value:
('1001', 256)                                                          

CIP_CLASS

Type:
str
Value:
'1128'                                                                 

CIP_PROFILE

Type:
tuple
Value:
('1128', 256)                                                          

CORDLESS_TELEPHONY_CLASS

Type:
str
Value:
'1109'                                                                 

CORDLESS_TELEPHONY_PROFILE

Type:
tuple
Value:
('1109', 256)                                                          

DIALUP_NET_CLASS

Type:
str
Value:
'1103'                                                                 

DIALUP_NET_PROFILE

Type:
tuple
Value:
('1103', 256)                                                          

DIRECT_PRINTING_CLASS

Type:
str
Value:
'1118'                                                                 

DIRECT_PRINTING_PROFILE

Type:
tuple
Value:
('1118', 256)                                                          

DIRECT_PRT_REFOBJS_CLASS

Type:
str
Value:
'1120'                                                                 

DIRECT_PRT_REFOBJS_PROFILE

Type:
tuple
Value:
('1120', 256)                                                          

FAX_CLASS

Type:
str
Value:
'1111'                                                                 

FAX_PROFILE

Type:
tuple
Value:
('1111', 256)                                                          

GENERIC_AUDIO_CLASS

Type:
str
Value:
'1203'                                                                 

GENERIC_AUDIO_PROFILE

Type:
tuple
Value:
('1203', 256)                                                          

GENERIC_FILETRANS_CLASS

Type:
str
Value:
'1202'                                                                 

GENERIC_FILETRANS_PROFILE

Type:
tuple
Value:
('1202', 256)                                                          

GENERIC_NETWORKING_CLASS

Type:
str
Value:
'1201'                                                                 

GENERIC_NETWORKING_PROFILE

Type:
tuple
Value:
('1201', 256)                                                          

GENERIC_TELEPHONY_CLASS

Type:
str
Value:
'1204'                                                                 

GENERIC_TELEPHONY_PROFILE

Type:
tuple
Value:
('1204', 256)                                                          

GN_CLASS

Type:
str
Value:
'1117'                                                                 

GN_PROFILE

Type:
tuple
Value:
('1117', 256)                                                          

HANDSFREE_AGW_CLASS

Type:
str
Value:
'111f'                                                                 

HANDSFREE_AGW_PROFILE

Type:
tuple
Value:
('111f', 256)                                                          

HANDSFREE_CLASS

Type:
str
Value:
'111e'                                                                 

HANDSFREE_PROFILE

Type:
tuple
Value:
('111e', 256)                                                          

HCR_CLASS

Type:
str
Value:
'1125'                                                                 

HCR_PRINT_CLASS

Type:
str
Value:
'1126'                                                                 

HCR_PRINT_PROFILE

Type:
tuple
Value:
('1126', 256)                                                          

HCR_PROFILE

Type:
tuple
Value:
('1127', 256)                                                          

HCR_SCAN_CLASS

Type:
str
Value:
'1127'                                                                 

HCR_SCAN_PROFILE

Type:
tuple
Value:
('1127', 256)                                                          

HEADSET_AGW_CLASS

Type:
str
Value:
'1112'                                                                 

HEADSET_AGW_PROFILE

Type:
tuple
Value:
('1112', 256)                                                          

HEADSET_CLASS

Type:
str
Value:
'1108'                                                                 

HEADSET_PROFILE

Type:
tuple
Value:
('1108', 256)                                                          

HID_CLASS

Type:
str
Value:
'1124'                                                                 

HID_PROFILE

Type:
tuple
Value:
('1124', 256)                                                          

IMAGING_ARCHIVE_CLASS

Type:
str
Value:
'111c'                                                                 

IMAGING_ARCHIVE_PROFILE

Type:
tuple
Value:
('111c', 256)                                                          

IMAGING_CLASS

Type:
str
Value:
'111a'                                                                 

IMAGING_PROFILE

Type:
tuple
Value:
('111a', 256)                                                          

IMAGING_REFOBJS_CLASS

Type:
str
Value:
'111d'                                                                 

IMAGING_REFOBJS_PROFILE

Type:
tuple
Value:
('111d', 256)                                                          

IMAGING_RESPONDER_CLASS

Type:
str
Value:
'111b'                                                                 

IMAGING_RESPONDER_PROFILE

Type:
tuple
Value:
('111b', 256)                                                          

INTERCOM_CLASS

Type:
str
Value:
'1110'                                                                 

INTERCOM_PROFILE

Type:
tuple
Value:
('1110', 256)                                                          

IRMC_SYNC_CLASS

Type:
str
Value:
'1104'                                                                 

IRMC_SYNC_CMD_CLASS

Type:
str
Value:
'1107'                                                                 

IRMC_SYNC_CMD_PROFILE

Type:
tuple
Value:
('1107', 256)                                                          

IRMC_SYNC_PROFILE

Type:
tuple
Value:
('1104', 256)                                                          

L2CAP

Type:
int
Value:
3                                                                     

LAN_ACCESS_CLASS

Type:
str
Value:
'1102'                                                                 

LAN_ACCESS_PROFILE

Type:
tuple
Value:
('1102', 256)                                                          

NAP_CLASS

Type:
str
Value:
'1116'                                                                 

NAP_PROFILE

Type:
tuple
Value:
('1116', 256)                                                          

OBEX_FILETRANS_CLASS

Type:
str
Value:
'1106'                                                                 

OBEX_FILETRANS_PROFILE

Type:
tuple
Value:
('1106', 256)                                                          

OBEX_OBJPUSH_CLASS

Type:
str
Value:
'1105'                                                                 

OBEX_OBJPUSH_PROFILE

Type:
tuple
Value:
('1105', 256)                                                          

PANU_CLASS

Type:
str
Value:
'1115'                                                                 

PANU_PROFILE

Type:
tuple
Value:
('1115', 256)                                                          

PNP_INFO_CLASS

Type:
str
Value:
'1200'                                                                 

PNP_INFO_PROFILE

Type:
tuple
Value:
('1200', 256)                                                          

PORT_ANY

Type:
int
Value:
0                                                                     

PRINTING_STATUS_CLASS

Type:
str
Value:
'1123'                                                                 

PRINTING_STATUS_PROFILE

Type:
tuple
Value:
('1123', 256)                                                          

PUBLIC_BROWSE_GROUP

Type:
str
Value:
'1002'                                                                 

REFERENCE_PRINTING_CLASS

Type:
str
Value:
'1119'                                                                 

REFERENCE_PRINTING_PROFILE

Type:
tuple
Value:
('1119', 256)                                                          

REFLECTED_UI_CLASS

Type:
str
Value:
'1121'                                                                 

REFLECTED_UI_PROFILE

Type:
tuple
Value:
('1121', 256)                                                          

RFCOMM

Type:
int
Value:
0                                                                     

SAP_CLASS

Type:
str
Value:
'112d'                                                                 

SAP_PROFILE

Type:
tuple
Value:
('112d', 256)                                                          

SDP_SERVER_CLASS

Type:
str
Value:
'1000'                                                                 

SDP_SERVER_PROFILE

Type:
tuple
Value:
('1000', 256)                                                          

SERIAL_PORT_CLASS

Type:
str
Value:
'1101'                                                                 

SERIAL_PORT_PROFILE

Type:
tuple
Value:
('1101', 256)                                                          

UDI_MT_CLASS

Type:
str
Value:
'112a'                                                                 

UDI_MT_PROFILE

Type:
tuple
Value:
('112a', 256)                                                          

UDI_TA_CLASS

Type:
str
Value:
'112b'                                                                 

UDI_TA_PROFILE

Type:
tuple
Value:
('112b', 256)                                                          

UPNP_CLASS

Type:
str
Value:
'1205'                                                                 

UPNP_IP_CLASS

Type:
str
Value:
'1206'                                                                 

UPNP_IP_PROFILE

Type:
tuple
Value:
('1206', 256)                                                          

UPNP_L2CAP_CLASS

Type:
str
Value:
'1302'                                                                 

UPNP_L2CAP_PROFILE

Type:
tuple
Value:
('1302', 256)                                                          

UPNP_LAP_CLASS

Type:
str
Value:
'1301'                                                                 

UPNP_LAP_PROFILE

Type:
tuple
Value:
('1301', 256)                                                          

UPNP_PAN_CLASS

Type:
str
Value:
'1300'                                                                 

UPNP_PAN_PROFILE

Type:
tuple
Value:
('1300', 256)                                                          

UPNP_PROFILE

Type:
tuple
Value:
('1205', 256)                                                          

VIDEO_CONF_CLASS

Type:
str
Value:
'110f'                                                                 

VIDEO_CONF_GW_CLASS

Type:
str
Value:
'1129'                                                                 

VIDEO_CONF_GW_PROFILE

Type:
tuple
Value:
('1129', 256)                                                          

VIDEO_CONF_PROFILE

Type:
tuple
Value:
('110f', 256)                                                          

VIDEO_SINK_CLASS

Type:
str
Value:
'1304'                                                                 

VIDEO_SINK_PROFILE

Type:
tuple
Value:
('1304', 256)                                                          

VIDEO_SOURCE_CLASS

Type:
str
Value:
'1303'                                                                 

VIDEO_SOURCE_PROFILE

Type:
tuple
Value:
('1303', 256)                                                          

WAP_CLASS

Type:
str
Value:
'1113'                                                                 

WAP_CLIENT_CLASS

Type:
str
Value:
'1114'                                                                 

WAP_CLIENT_PROFILE

Type:
tuple
Value:
('1114', 256)                                                          

WAP_PROFILE

Type:
tuple
Value:
('1113', 256)                                                          

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/public/bluetooth.BluetoothError-class.html000066400000000000000000000114271334611253700261110ustar00rootroot00000000000000 bluetooth.BluetoothError
Module bluetooth :: Class BluetoothError
[show private | hide private]
[frames | no frames]

Class BluetoothError

Exception --+            
            |            
StandardError --+        
                |        
 EnvironmentError --+    
                    |    
              IOError --+
                        |
                       BluetoothError


Method Summary
    Inherited from EnvironmentError
  __init__(...)
  __str__(...)
    Inherited from Exception
  __getitem__(...)

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/public/bluetooth.BluetoothSocket-class.html000066400000000000000000000542101334611253700262450ustar00rootroot00000000000000 bluetooth.BluetoothSocket
Module bluetooth :: Class BluetoothSocket
[show private | hide private]
[frames | no frames]

Class BluetoothSocket


BluetoothSocket

availability: GNU/Linux, Windows XP
Method Summary
  __init__(self, proto, _sock)
Create a new Bluetooth socket that uses the specified transport protocol.
  accept(self)
accept() -> (BluetoothSocket, addrport)
  bind(self, addrport)
bind(addrport) availability: GNU/Linux, Windows XP Bind the socket to a local adapter and port.
  close(self)
close()
  connect(self, addrport)
connect(addrport)
  dup(self)
dup() -> socket object
  fileno(self)
fileno() -> integer
  getpeername(self)
getpeername() -> address info
  getsockname(self)
getsockname() -> address info
  getsockopt(self, level, option, buffersize)
getsockopt(level, option[, buffersize]) -> value
  gettimouet(self, timeout)
gettimeout() -> timeout
  listen(self, backlog)
listen(backlog)
  makefile(self)
makefile([mode[, buffersize]]) -> file object
  recv(self, buffersize, flags)
recv(buffersize[, flags]) -> data
  send(self, data, flags)
send(data[, flags]) -> count
  sendall(self, data, flags)
sendall(data[, flags])
  setblocking(self, blocking)
setblocking(flag)
  setsockopt(self, level, option, value)
setsockopt(level, option, value)
  settimeout(self, timeout)
settimeout(timeout)
  shutdown(self, flag)
shutdown(flag)

Method Details

__init__(self, proto=0, _sock=None)
(Constructor)

Create a new Bluetooth socket that uses the specified transport protocol.

proto can be one of RFCOMM, L2CAP, HCI, or SCO

HCI, L2CAP, and SCO sockets are only available in GNU/Linux

accept(self)

accept() -> (BluetoothSocket, addrport)

availability: GNU/Linux, Windows XP

Wait for an incoming connection. Return a new socket representing the connection, and the address/port of the client. For L2CAP sockets, addport is a (host, psm) tuple. For RFCOMM sockets, addport is a (host, channel) tuple. For SCO sockets, addrport is just a Bluetooth address.

bind(self, addrport)

bind(addrport)

availability: GNU/Linux, Windows XP

Bind the socket to a local adapter and port.  addrport must always be a tuple.
  HCI sockets:    ( device number, )
                  device number should be 0, 1, 2, etc.
  L2CAP sockets:  ( host, psm )
                  host should be an address e.g. "01:23:45:67:89:ab"
                  psm should be an unsigned integer
  RFCOMM sockets: ( host, channel )
  SCO sockets:    ( host )

close(self)

close()

availability: GNU/Linux, Windows XP

Close the socket. It cannot be used after this call.

connect(self, addrport)

connect(addrport)

availability: GNU/Linux, Windows XP

Connect the socket to a remote device. For L2CAP sockets, addrport is a (host,psm) tuple. For RFCOMM sockets, addrport is a (host,channel) tuple. For SCO sockets, addrport is just the host.

dup(self)

dup() -> socket object

availability: GNU/Linux

Return a new socket object connected to the same system resource.

fileno(self)

fileno() -> integer

availability: GNU/Linux, Windows XP

Return the integer file descriptor of the socket.

getpeername(self)

getpeername() -> address info

availability: GNU/Linux

Return the address of the remote endpoint. For HCI sockets, the address is a device number (0, 1, 2, etc). For L2CAP sockets, the address is a (host,psm) tuple. For RFCOMM sockets, the address is a (host,channel) tuple. For SCO sockets, the address is just the host.

getsockname(self)

getsockname() -> address info

availability: GNU/Linux, Windows XP Return the address of the local endpoint.

getsockopt(self, level, option, buffersize)

getsockopt(level, option[, buffersize]) -> value

availability: GNU/Linux

Get a socket option. See the Unix manual for level and option. If a nonzero buffersize argument is given, the return value is a string of that length; otherwise it is an integer.

gettimouet(self, timeout)

gettimeout() -> timeout

availability: GNU/Linux

Returns the timeout in floating seconds associated with socket operations. A timeout of None indicates that timeouts on socket operations are disabled.

listen(self, backlog)

listen(backlog)

availability: GNU/Linux, Windows XP

Enable a server to accept connections. The backlog argument must be at least 1; it specifies the number of unaccepted connection that the system will allow before refusing new connections.

makefile(self)

makefile([mode[, buffersize]]) -> file object

availability: GNU/Linux

Return a regular file object corresponding to the socket. The mode and buffersize arguments are as for the built-in open() function.

recv(self, buffersize, flags=None)

recv(buffersize[, flags]) -> data

availability: GNU/Linux, Windows XP

Receive up to buffersize bytes from the socket. For the optional flags argument, see the Unix manual. When no data is available, block until at least one byte is available or until the remote end is closed. When the remote end is closed and all data is read, return the empty string.

send(self, data, flags=None)

send(data[, flags]) -> count

availability: GNU/Linux, Windows XP

Send a data string to the socket. For the optional flags argument, see the Unix manual. Return the number of bytes sent; this may be less than len(data) if the network is busy.

sendall(self, data, flags=None)

sendall(data[, flags])

availability: GNU/Linux

Send a data string to the socket. For the optional flags argument, see the Unix manual. This calls send() repeatedly until all data is sent. If an error occurs, it's impossible to tell how much data has been sent.

setblocking(self, blocking)

setblocking(flag)

availability: GNU/Linux

Set the socket to blocking (flag is true) or non-blocking (false). setblocking(True) is equivalent to settimeout(None); setblocking(False) is equivalent to settimeout(0.0).

setsockopt(self, level, option, value)

setsockopt(level, option, value)

availability: GNU/Linux

Set a socket option. See the Unix manual for level and option. The value argument can either be an integer or a string.

settimeout(self, timeout)

settimeout(timeout)

availability: GNU/Linux

Set a timeout on socket operations. 'timeout' can be a float, giving in seconds, or None. Setting a timeout of None disables the timeout feature and is equivalent to setblocking(1). Setting a timeout of zero is the same as setblocking(0).

shutdown(self, flag)

shutdown(flag)

availability: GNU/Linux

Shut down the reading side of the socket (flag == 0), the writing side of the socket (flag == 1), or both ends (flag == 2).

Generated by Epydoc 2.1 on Tue May 9 02:23:40 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/public/bluetooth.DeviceDiscoverer-class.html000066400000000000000000000271571334611253700263660ustar00rootroot00000000000000 bluetooth.DeviceDiscoverer
Module bluetooth :: Class DeviceDiscoverer
[show private | hide private]
[frames | no frames]

Class DeviceDiscoverer


DeviceDiscoverer

availability: GNU/Linux

Skeleton class for finer control of the device discovery process.

To implement asynchronous device discovery (e.g. if you want to do something *as soon as* a device is discovered), subclass DeviceDiscoverer and override device_discovered() and inquiry_complete()
Method Summary
  __init__(self)
TODO
  cancel_inquiry(self)
Call this method to cancel an inquiry in process.
  device_discovered(self, address, device_class, name)
Called when a bluetooth device is discovered.
  fileno(self)
  find_devices(self, lookup_names, duration, flush_cache)
find_devices( lookup_names=True, service_name=None, duration=8, flush_cache=True ) Call this method to initiate the device discovery process lookup_names - set to True if you want to lookup the user-friendly names for each device found.
  inquiry_complete(self)
Called when an inquiry started by find_devices has completed.
  pre_inquiry(self)
Called just after find_devices is invoked, but just before the inquiry is started.
  process_event(self)
Waits for one event to happen, and proceses it.
  process_inquiry(self)
Repeatedly calls process_event() until the device inquiry has completed.

Method Details

__init__(self)
(Constructor)

TODO

cancel_inquiry(self)

Call this method to cancel an inquiry in process. inquiry_complete will still be called.

device_discovered(self, address, device_class, name)

Called when a bluetooth device is discovered.

address is the bluetooth address of the device

device_class is the Class of Device, as specified in [1]
             passed in as a 3-byte string

name is the user-friendly name of the device if lookup_names was set
     when the inquiry was started.  otherwise None

This method exists to be overriden.

[1] https://www.bluetooth.org/foundry/assignnumb/document/baseband

find_devices(self, lookup_names=True, duration=8, flush_cache=True)

find_devices( lookup_names=True, service_name=None, 
               duration=8, flush_cache=True )

Call this method to initiate the device discovery process

lookup_names - set to True if you want to lookup the user-friendly 
               names for each device found.

service_name - set to the name of a service you're looking for.
               only devices with a service of this name will be 
               returned in device_discovered() NOT YET IMPLEMENTED


ADVANCED PARAMETERS:  (don't change these unless you know what 
                    you're doing)

duration - the number of 1.2 second units to spend searching for
           bluetooth devices.  If lookup_names is True, then the 
           inquiry process can take a lot longer.

flush_cache - return devices discovered in previous inquiries

inquiry_complete(self)

Called when an inquiry started by find_devices has completed.

pre_inquiry(self)

Called just after find_devices is invoked, but just before the inquiry is started.

This method exists to be overriden

process_event(self)

Waits for one event to happen, and proceses it. The event will be either a device discovery, or an inquiry completion.

process_inquiry(self)

Repeatedly calls process_event() until the device inquiry has completed.

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/public/epydoc.css000066400000000000000000000104561334611253700211330ustar00rootroot00000000000000 /* Body color */ body { background: #ffffff; color: #000000; } /* Tables */ table.summary, table.details, table.index { background: #e8f0f8; color: #000000; } tr.summary, tr.details, tr.index { background: #70b0f0; color: #000000; text-align: left; font-size: 120%; } tr.group { background: #c0e0f8; color: #000000; text-align: left; font-size: 120%; font-style: italic; } /* Documentation page titles */ h2.module { margin-top: 0.2em; } h2.class { margin-top: 0.2em; } /* Headings */ h1.heading { font-size: +140%; font-style: italic; font-weight: bold; } h2.heading { font-size: +125%; font-style: italic; font-weight: bold; } h3.heading { font-size: +110%; font-style: italic; font-weight: normal; } /* Base tree */ pre.base-tree { font-size: 80%; margin: 0; } /* Details Sections */ table.func-details { background: #e8f0f8; color: #000000; border: 2px groove #c0d0d0; padding: 0 1em 0 1em; margin: 0.4em 0 0 0; } h3.func-detail { background: transparent; color: #000000; margin: 0 0 1em 0; } table.var-details { background: #e8f0f8; color: #000000; border: 2px groove #c0d0d0; padding: 0 1em 0 1em; margin: 0.4em 0 0 0; } h3.var-details { background: transparent; color: #000000; margin: 0 0 1em 0; } /* Function signatures */ .sig { background: transparent; color: #000000; font-weight: bold; } .sig-name { background: transparent; color: #006080; } .sig-arg, .sig-kwarg, .sig-vararg { background: transparent; color: #008060; } .sig-default { background: transparent; color: #602000; } .summary-sig { background: transparent; color: #000000; } .summary-sig-name { background: transparent; color: #204080; } .summary-sig-arg, .summary-sig-kwarg, .summary-sig-vararg { background: transparent; color: #008060; } /* Doctest blocks */ .py-src { background: transparent; color: #000000; } .py-prompt { background: transparent; color: #005050; font-weight: bold;} .py-string { background: transparent; color: #006030; } .py-comment { background: transparent; color: #003060; } .py-keyword { background: transparent; color: #600000; } .py-output { background: transparent; color: #404040; } pre.doctestblock { background: #f4faff; color: #000000; padding: .5em; margin: 1em; border: 1px solid #708890; } table pre.doctestblock { background: #dce4ec; color: #000000; padding: .5em; margin: 1em; border: 1px solid #708890; } /* Variable values */ pre.variable { background: #dce4ec; color: #000000; padding: .5em; margin: 0; border: 1px solid #708890; } .variable-linewrap { background: transparent; color: #604000; } .variable-ellipsis { background: transparent; color: #604000; } .variable-quote { background: transparent; color: #604000; } .re { background: transparent; color: #000000; } .re-char { background: transparent; color: #006030; } .re-op { background: transparent; color: #600000; } .re-group { background: transparent; color: #003060; } .re-ref { background: transparent; color: #404040; } /* Navigation bar */ table.navbar { background: #a0c0ff; color: #0000ff; border: 2px groove #c0d0d0; } th.navbar { background: #a0c0ff; color: #0000ff; } th.navselect { background: #70b0ff; color: #000000; } .nomargin { margin: 0; } /* Links */ a:link { background: transparent; color: #0000ff; } a:visited { background: transparent; color: #204080; } a.navbar:link { background: transparent; color: #0000ff; text-decoration: none; } a.navbar:visited { background: transparent; color: #204080; text-decoration: none; } /* Lists */ ul { margin-top: 0; } pybluez-0.22+really0.22/docs/public/exceptions.EnvironmentError-class.html000066400000000000000000000107261334611253700266250ustar00rootroot00000000000000 exceptions.EnvironmentError
Module exceptions :: Class EnvironmentError
[show private | hide private]
[frames | no frames]

Class EnvironmentError

Exception --+    
            |    
StandardError --+
                |
               EnvironmentError

Known Subclasses:
IOError

Base class for I/O related errors.
Method Summary
  __init__(...)
  __str__(...)
    Inherited from Exception
  __getitem__(...)

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/public/exceptions.Exception-class.html000066400000000000000000000100411334611253700252330ustar00rootroot00000000000000 exceptions.Exception
Module exceptions :: Class Exception
[show private | hide private]
[frames | no frames]

Class Exception

Known Subclasses:
StandardError

Common base class for all exceptions.
Method Summary
  __init__(...)
  __getitem__(...)
  __str__(...)

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/public/exceptions.IOError-class.html000066400000000000000000000113511334611253700246230ustar00rootroot00000000000000 exceptions.IOError
Module exceptions :: Class IOError
[show private | hide private]
[frames | no frames]

Class IOError

Exception --+        
            |        
StandardError --+    
                |    
 EnvironmentError --+
                    |
                   IOError

Known Subclasses:
BluetoothError

I/O operation failed.
Method Summary
    Inherited from EnvironmentError
  __init__(...)
  __str__(...)
    Inherited from Exception
  __getitem__(...)

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/public/exceptions.StandardError-class.html000066400000000000000000000106631334611253700260610ustar00rootroot00000000000000 exceptions.StandardError
Module exceptions :: Class StandardError
[show private | hide private]
[frames | no frames]

Class StandardError

Exception --+
            |
           StandardError

Known Subclasses:
EnvironmentError

Base class for all standard Python exceptions.
Method Summary
    Inherited from Exception
  __init__(...)
  __getitem__(...)
  __str__(...)

Generated by Epydoc 2.1 on Tue May 9 02:23:39 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/public/frames.html000066400000000000000000000005611334611253700212750ustar00rootroot00000000000000 API Documentation pybluez-0.22+really0.22/docs/public/help.html000066400000000000000000000230771334611253700207570ustar00rootroot00000000000000 Help
[show private | hide private]
[frames | no frames]

API Documentation

This document contains the API (Application Programming Interface) documentation for this project. Documentation for the Python objects defined by the project is divided into separate pages for each package, module, and class. The API documentation also includes two pages containing information about the project as a whole: a trees page, and an index page.

Object Documentation

Each Package Documentation page contains:

  • A description of the package.
  • A list of the modules and sub-packages contained by the package.
  • A summary of the classes defined by the package.
  • A summary of the functions defined by the package.
  • A summary of the variables defined by the package.
  • A detailed description of each function defined by the package.
  • A detailed description of each variable defined by the package.

Each Module Documentation page contains:

  • A description of the module.
  • A summary of the classes defined by the module.
  • A summary of the functions defined by the module.
  • A summary of the variables defined by the module.
  • A detailed description of each function defined by the module.
  • A detailed description of each variable defined by the module.

Each Class Documentation page contains:

  • A class inheritance diagram.
  • A list of known subclasses.
  • A description of the class.
  • A summary of the methods defined by the class.
  • A summary of the instance variables defined by the class.
  • A summary of the class (static) variables defined by the class.
  • A detailed description of each method defined by the class.
  • A detailed description of each instance variable defined by the class.
  • A detailed description of each class (static) variable defined by the class.

Project Documentation

The Trees page contains the module and class hierarchies:

  • The module hierarchy lists every package and module, with modules grouped into packages. At the top level, and within each package, modules and sub-packages are listed alphabetically.
  • The class hierarchy lists every class, grouped by base class. If a class has more than one base class, then it will be listed under each base class. At the top level, and under each base class, classes are listed alphabetically.

The Index page contains indices of terms and identifiers:

  • The term index lists every term indexed by any object's documentation. For each term, the index provides links to each place where the term is indexed.
  • The identifier index lists the (short) name of every package, module, class, method, function, variable, and parameter. For each identifier, the index provides a short description, and a link to its documentation.

The Table of Contents

The table of contents occupies the two frames on the left side of the window. The upper-left frame displays the project contents, and the lower-left frame displays the module contents:

Project
Contents
...
API
Documentation
Frame


Module
Contents
 
...
 

The project contents frame contains a list of all packages and modules that are defined by the project. Clicking on an entry will display its contents in the module contents frame. Clicking on a special entry, labeled "Everything," will display the contents of the entire project.

The module contents frame contains a list of every submodule, class, type, exception, function, and variable defined by a module or package. Clicking on an entry will display its documentation in the API documentation frame. Clicking on the name of the module, at the top of the frame, will display the documentation for the module itself.

The "frames" and "no frames" buttons below the top navigation bar can be used to control whether the table of contents is displayed or not.

The Navigation Bar

A navigation bar is located at the top and bottom of every page. It indicates what type of page you are currently viewing, and allows you to go to related pages. The following table describes the labels on the navigation bar. Note that not some labels (such as [Parent]) are not displayed on all pages.

Label Highlighted when... Links to...
[Parent] (never highlighted) the parent of the current package
[Package] viewing a package the package containing the current object
[Module] viewing a module the module containing the current object
[Class] viewing a class the class containing the current object
[Trees] viewing the trees page the trees page
[Index] viewing the index page the index page
[Help] viewing the help page the help page

The "show private" and "hide private" buttons below the top navigation bar can be used to control whether documentation for private objects is displayed. Private objects are usually defined as objects whose (short) names begin with a single underscore, but do not end with an underscore. For example, "_x", "__pprint", and "epydoc.epytext._tokenize" are private objects; but "re.sub", "__init__", and "type_" are not. However, if a module defines the "__all__" variable, then its contents are used to decide which objects are private.

A timestamp below the bottom navigation bar indicates when each page was last updated.

Generated by Epydoc 2.1 on Tue May 9 02:23:40 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/public/index.html000066400000000000000000000005611334611253700211270ustar00rootroot00000000000000 API Documentation pybluez-0.22+really0.22/docs/public/indices.html000066400000000000000000001152021334611253700214350ustar00rootroot00000000000000 Index
[show private | hide private]
[frames | no frames]

Identifier Index
__getitem__ Method in class exceptions.Exception
__init__ Method in class bluetooth.BluetoothSocket
__init__ Method in class bluetooth.DeviceDiscoverer
__init__ Method in class exceptions.EnvironmentError
__init__ Method in class exceptions.Exception
__str__ Method in class exceptions.EnvironmentError
__str__ Method in class exceptions.Exception
accept Method in class bluetooth.BluetoothSocket
ADVANCED_AUDIO_CLASS Variable in module bluetooth
ADVANCED_AUDIO_PROFILE Variable in module bluetooth
advertise_service Function in module bluetooth
AUDIO_SINK_CLASS Variable in module bluetooth
AUDIO_SINK_PROFILE Variable in module bluetooth
AUDIO_SOURCE_CLASS Variable in module bluetooth
AUDIO_SOURCE_PROFILE Variable in module bluetooth
AV_CLASS Variable in module bluetooth
AV_PROFILE Variable in module bluetooth
AV_REMOTE_CLASS Variable in module bluetooth
AV_REMOTE_PROFILE Variable in module bluetooth
AV_REMOTE_TARGET_CLASS Variable in module bluetooth
AV_REMOTE_TARGET_PROFILE Variable in module bluetooth
BASIC_PRINTING_CLASS Variable in module bluetooth
BASIC_PRINTING_PROFILE Variable in module bluetooth
bind Method in class bluetooth.BluetoothSocket
bluetooth Module
BluetoothError Class in module bluetooth
BluetoothSocket Class in module bluetooth
BROWSE_GRP_DESC_CLASS Variable in module bluetooth
BROWSE_GRP_DESC_PROFILE Variable in module bluetooth
cancel_inquiry Method in class bluetooth.DeviceDiscoverer
CIP_CLASS Variable in module bluetooth
CIP_PROFILE Variable in module bluetooth
close Method in class bluetooth.BluetoothSocket
connect Method in class bluetooth.BluetoothSocket
CORDLESS_TELEPHONY_CLASS Variable in module bluetooth
CORDLESS_TELEPHONY_PROFILE Variable in module bluetooth
device_discovered Method in class bluetooth.DeviceDiscoverer
DeviceDiscoverer Class in module bluetooth
DIALUP_NET_CLASS Variable in module bluetooth
DIALUP_NET_PROFILE Variable in module bluetooth
DIRECT_PRINTING_CLASS Variable in module bluetooth
DIRECT_PRINTING_PROFILE Variable in module bluetooth
DIRECT_PRT_REFOBJS_CLASS Variable in module bluetooth
DIRECT_PRT_REFOBJS_PROFILE Variable in module bluetooth
discover_devices Function in module bluetooth
dup Method in class bluetooth.BluetoothSocket
EnvironmentError Class in module exceptions
Exception Class in module exceptions
FAX_CLASS Variable in module bluetooth
FAX_PROFILE Variable in module bluetooth
fileno Method in class bluetooth.BluetoothSocket
fileno Method in class bluetooth.DeviceDiscoverer
find_devices Method in class bluetooth.DeviceDiscoverer
find_service Function in module bluetooth
GENERIC_AUDIO_CLASS Variable in module bluetooth
GENERIC_AUDIO_PROFILE Variable in module bluetooth
GENERIC_FILETRANS_CLASS Variable in module bluetooth
GENERIC_FILETRANS_PROFILE Variable in module bluetooth
GENERIC_NETWORKING_CLASS Variable in module bluetooth
GENERIC_NETWORKING_PROFILE Variable in module bluetooth
GENERIC_TELEPHONY_CLASS Variable in module bluetooth
GENERIC_TELEPHONY_PROFILE Variable in module bluetooth
get_available_port Function in module bluetooth
getpeername Method in class bluetooth.BluetoothSocket
getsockname Method in class bluetooth.BluetoothSocket
getsockopt Method in class bluetooth.BluetoothSocket
gettimouet Method in class bluetooth.BluetoothSocket
GN_CLASS Variable in module bluetooth
GN_PROFILE Variable in module bluetooth
HANDSFREE_AGW_CLASS Variable in module bluetooth
HANDSFREE_AGW_PROFILE Variable in module bluetooth
HANDSFREE_CLASS Variable in module bluetooth
HANDSFREE_PROFILE Variable in module bluetooth
HCR_CLASS Variable in module bluetooth
HCR_PRINT_CLASS Variable in module bluetooth
HCR_PRINT_PROFILE Variable in module bluetooth
HCR_PROFILE Variable in module bluetooth
HCR_SCAN_CLASS Variable in module bluetooth
HCR_SCAN_PROFILE Variable in module bluetooth
HEADSET_AGW_CLASS Variable in module bluetooth
HEADSET_AGW_PROFILE Variable in module bluetooth
HEADSET_CLASS Variable in module bluetooth
HEADSET_PROFILE Variable in module bluetooth
HID_CLASS Variable in module bluetooth
HID_PROFILE Variable in module bluetooth
IMAGING_ARCHIVE_CLASS Variable in module bluetooth
IMAGING_ARCHIVE_PROFILE Variable in module bluetooth
IMAGING_CLASS Variable in module bluetooth
IMAGING_PROFILE Variable in module bluetooth
IMAGING_REFOBJS_CLASS Variable in module bluetooth
IMAGING_REFOBJS_PROFILE Variable in module bluetooth
IMAGING_RESPONDER_CLASS Variable in module bluetooth
IMAGING_RESPONDER_PROFILE Variable in module bluetooth
inquiry_complete Method in class bluetooth.DeviceDiscoverer
INTERCOM_CLASS Variable in module bluetooth
INTERCOM_PROFILE Variable in module bluetooth
IOError Class in module exceptions
IRMC_SYNC_CLASS Variable in module bluetooth
IRMC_SYNC_CMD_CLASS Variable in module bluetooth
IRMC_SYNC_CMD_PROFILE Variable in module bluetooth
IRMC_SYNC_PROFILE Variable in module bluetooth
is_valid_address Function in module bluetooth
is_valid_uuid Function in module bluetooth
L2CAP Variable in module bluetooth
LAN_ACCESS_CLASS Variable in module bluetooth
LAN_ACCESS_PROFILE Variable in module bluetooth
listen Method in class bluetooth.BluetoothSocket
lookup_name Function in module bluetooth
makefile Method in class bluetooth.BluetoothSocket
NAP_CLASS Variable in module bluetooth
NAP_PROFILE Variable in module bluetooth
OBEX_FILETRANS_CLASS Variable in module bluetooth
OBEX_FILETRANS_PROFILE Variable in module bluetooth
OBEX_OBJPUSH_CLASS Variable in module bluetooth
OBEX_OBJPUSH_PROFILE Variable in module bluetooth
PANU_CLASS Variable in module bluetooth
PANU_PROFILE Variable in module bluetooth
PNP_INFO_CLASS Variable in module bluetooth
PNP_INFO_PROFILE Variable in module bluetooth
PORT_ANY Variable in module bluetooth
pre_inquiry Method in class bluetooth.DeviceDiscoverer
PRINTING_STATUS_CLASS Variable in module bluetooth
PRINTING_STATUS_PROFILE Variable in module bluetooth
process_event Method in class bluetooth.DeviceDiscoverer
process_inquiry Method in class bluetooth.DeviceDiscoverer
PUBLIC_BROWSE_GROUP Variable in module bluetooth
recv Method in class bluetooth.BluetoothSocket
REFERENCE_PRINTING_CLASS Variable in module bluetooth
REFERENCE_PRINTING_PROFILE Variable in module bluetooth
REFLECTED_UI_CLASS Variable in module bluetooth
REFLECTED_UI_PROFILE Variable in module bluetooth
RFCOMM Variable in module bluetooth
SAP_CLASS Variable in module bluetooth
SAP_PROFILE Variable in module bluetooth
SDP_SERVER_CLASS Variable in module bluetooth
SDP_SERVER_PROFILE Variable in module bluetooth
send Method in class bluetooth.BluetoothSocket
sendall Method in class bluetooth.BluetoothSocket
SERIAL_PORT_CLASS Variable in module bluetooth
SERIAL_PORT_PROFILE Variable in module bluetooth
set_l2cap_mtu Function in module bluetooth
set_packet_timeout Function in module bluetooth
setblocking Method in class bluetooth.BluetoothSocket
setsockopt Method in class bluetooth.BluetoothSocket
settimeout Method in class bluetooth.BluetoothSocket
shutdown Method in class bluetooth.BluetoothSocket
StandardError Class in module exceptions
stop_advertising Function in module bluetooth
UDI_MT_CLASS Variable in module bluetooth
UDI_MT_PROFILE Variable in module bluetooth
UDI_TA_CLASS Variable in module bluetooth
UDI_TA_PROFILE Variable in module bluetooth
UPNP_CLASS Variable in module bluetooth
UPNP_IP_CLASS Variable in module bluetooth
UPNP_IP_PROFILE Variable in module bluetooth
UPNP_L2CAP_CLASS Variable in module bluetooth
UPNP_L2CAP_PROFILE Variable in module bluetooth
UPNP_LAP_CLASS Variable in module bluetooth
UPNP_LAP_PROFILE Variable in module bluetooth
UPNP_PAN_CLASS Variable in module bluetooth
UPNP_PAN_PROFILE Variable in module bluetooth
UPNP_PROFILE Variable in module bluetooth
VIDEO_CONF_CLASS Variable in module bluetooth
VIDEO_CONF_GW_CLASS Variable in module bluetooth
VIDEO_CONF_GW_PROFILE Variable in module bluetooth
VIDEO_CONF_PROFILE Variable in module bluetooth
VIDEO_SINK_CLASS Variable in module bluetooth
VIDEO_SINK_PROFILE Variable in module bluetooth
VIDEO_SOURCE_CLASS Variable in module bluetooth
VIDEO_SOURCE_PROFILE Variable in module bluetooth
WAP_CLASS Variable in module bluetooth
WAP_CLIENT_CLASS Variable in module bluetooth
WAP_CLIENT_PROFILE Variable in module bluetooth
WAP_PROFILE Variable in module bluetooth

Generated by Epydoc 2.1 on Tue May 9 02:23:40 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/docs/public/toc-bluetooth-module.html000066400000000000000000000334441334611253700241010ustar00rootroot00000000000000 bluetooth
bluetooth

Classes
BluetoothSocket
DeviceDiscoverer

Exceptions
BluetoothError

Functions
advertise_service
discover_devices
find_service
get_available_port
is_valid_address
is_valid_uuid
lookup_name
set_l2cap_mtu
set_packet_timeout
stop_advertising

Variables
ADVANCED_AUDIO_CLASS
ADVANCED_AUDIO_PROFILE
AUDIO_SINK_CLASS
AUDIO_SINK_PROFILE
AUDIO_SOURCE_CLASS
AUDIO_SOURCE_PROFILE
AV_CLASS
AV_PROFILE
AV_REMOTE_CLASS
AV_REMOTE_PROFILE
AV_REMOTE_TARGET_CLASS
AV_REMOTE_TARGET_PROFILE
BASIC_PRINTING_CLASS
BASIC_PRINTING_PROFILE
BROWSE_GRP_DESC_CLASS
BROWSE_GRP_DESC_PROFILE
CIP_CLASS
CIP_PROFILE
CORDLESS_TELEPHONY_CLASS
CORDLESS_TELEPHONY_PROFILE
DIALUP_NET_CLASS
DIALUP_NET_PROFILE
DIRECT_PRINTING_CLASS
DIRECT_PRINTING_PROFILE
DIRECT_PRT_REFOBJS_CLASS
DIRECT_PRT_REFOBJS_PROFILE
FAX_CLASS
FAX_PROFILE
GENERIC_AUDIO_CLASS
GENERIC_AUDIO_PROFILE
GENERIC_FILETRANS_CLASS
GENERIC_FILETRANS_PROFILE
GENERIC_NETWORKING_CLASS
GENERIC_NETWORKING_PROFILE
GENERIC_TELEPHONY_CLASS
GENERIC_TELEPHONY_PROFILE
GN_CLASS
GN_PROFILE
HANDSFREE_AGW_CLASS
HANDSFREE_AGW_PROFILE
HANDSFREE_CLASS
HANDSFREE_PROFILE
HCR_CLASS
HCR_PRINT_CLASS
HCR_PRINT_PROFILE
HCR_PROFILE
HCR_SCAN_CLASS
HCR_SCAN_PROFILE
HEADSET_AGW_CLASS
HEADSET_AGW_PROFILE
HEADSET_CLASS
HEADSET_PROFILE
HID_CLASS
HID_PROFILE
IMAGING_ARCHIVE_CLASS
IMAGING_ARCHIVE_PROFILE
IMAGING_CLASS
IMAGING_PROFILE
IMAGING_REFOBJS_CLASS
IMAGING_REFOBJS_PROFILE
IMAGING_RESPONDER_CLASS
IMAGING_RESPONDER_PROFILE
INTERCOM_CLASS
INTERCOM_PROFILE
IRMC_SYNC_CLASS
IRMC_SYNC_CMD_CLASS
IRMC_SYNC_CMD_PROFILE
IRMC_SYNC_PROFILE
L2CAP
LAN_ACCESS_CLASS
LAN_ACCESS_PROFILE
NAP_CLASS
NAP_PROFILE
OBEX_FILETRANS_CLASS
OBEX_FILETRANS_PROFILE
OBEX_OBJPUSH_CLASS
OBEX_OBJPUSH_PROFILE
PANU_CLASS
PANU_PROFILE
PNP_INFO_CLASS
PNP_INFO_PROFILE
PORT_ANY
PRINTING_STATUS_CLASS
PRINTING_STATUS_PROFILE
PUBLIC_BROWSE_GROUP
REFERENCE_PRINTING_CLASS
REFERENCE_PRINTING_PROFILE
REFLECTED_UI_CLASS
REFLECTED_UI_PROFILE
RFCOMM
SAP_CLASS
SAP_PROFILE
SDP_SERVER_CLASS
SDP_SERVER_PROFILE
SERIAL_PORT_CLASS
SERIAL_PORT_PROFILE
UDI_MT_CLASS
UDI_MT_PROFILE
UDI_TA_CLASS
UDI_TA_PROFILE
UPNP_CLASS
UPNP_IP_CLASS
UPNP_IP_PROFILE
UPNP_L2CAP_CLASS
UPNP_L2CAP_PROFILE
UPNP_LAP_CLASS
UPNP_LAP_PROFILE
UPNP_PAN_CLASS
UPNP_PAN_PROFILE
UPNP_PROFILE
VIDEO_CONF_CLASS
VIDEO_CONF_GW_CLASS
VIDEO_CONF_GW_PROFILE
VIDEO_CONF_PROFILE
VIDEO_SINK_CLASS
VIDEO_SINK_PROFILE
VIDEO_SOURCE_CLASS
VIDEO_SOURCE_PROFILE
WAP_CLASS
WAP_CLIENT_CLASS
WAP_CLIENT_PROFILE
WAP_PROFILE


[show private | hide private] pybluez-0.22+really0.22/docs/public/toc-everything.html000066400000000000000000000334731334611253700227770ustar00rootroot00000000000000 Everything
Everything

All Classes
bluetooth.BluetoothSocket
bluetooth.DeviceDiscoverer

All Exceptions
bluetooth.BluetoothError

All Functions
advertise_service
discover_devices
find_service
get_available_port
is_valid_address
is_valid_uuid
lookup_name
set_l2cap_mtu
set_packet_timeout
stop_advertising

All Variables
ADVANCED_AUDIO_CLASS
ADVANCED_AUDIO_PROFILE
AUDIO_SINK_CLASS
AUDIO_SINK_PROFILE
AUDIO_SOURCE_CLASS
AUDIO_SOURCE_PROFILE
AV_CLASS
AV_PROFILE
AV_REMOTE_CLASS
AV_REMOTE_PROFILE
AV_REMOTE_TARGET_CLASS
AV_REMOTE_TARGET_PROFILE
BASIC_PRINTING_CLASS
BASIC_PRINTING_PROFILE
BROWSE_GRP_DESC_CLASS
BROWSE_GRP_DESC_PROFILE
CIP_CLASS
CIP_PROFILE
CORDLESS_TELEPHONY_CLASS
CORDLESS_TELEPHONY_PROFILE
DIALUP_NET_CLASS
DIALUP_NET_PROFILE
DIRECT_PRINTING_CLASS
DIRECT_PRINTING_PROFILE
DIRECT_PRT_REFOBJS_CLASS
DIRECT_PRT_REFOBJS_PROFILE
FAX_CLASS
FAX_PROFILE
GENERIC_AUDIO_CLASS
GENERIC_AUDIO_PROFILE
GENERIC_FILETRANS_CLASS
GENERIC_FILETRANS_PROFILE
GENERIC_NETWORKING_CLASS
GENERIC_NETWORKING_PROFILE
GENERIC_TELEPHONY_CLASS
GENERIC_TELEPHONY_PROFILE
GN_CLASS
GN_PROFILE
HANDSFREE_AGW_CLASS
HANDSFREE_AGW_PROFILE
HANDSFREE_CLASS
HANDSFREE_PROFILE
HCR_CLASS
HCR_PRINT_CLASS
HCR_PRINT_PROFILE
HCR_PROFILE
HCR_SCAN_CLASS
HCR_SCAN_PROFILE
HEADSET_AGW_CLASS
HEADSET_AGW_PROFILE
HEADSET_CLASS
HEADSET_PROFILE
HID_CLASS
HID_PROFILE
IMAGING_ARCHIVE_CLASS
IMAGING_ARCHIVE_PROFILE
IMAGING_CLASS
IMAGING_PROFILE
IMAGING_REFOBJS_CLASS
IMAGING_REFOBJS_PROFILE
IMAGING_RESPONDER_CLASS
IMAGING_RESPONDER_PROFILE
INTERCOM_CLASS
INTERCOM_PROFILE
IRMC_SYNC_CLASS
IRMC_SYNC_CMD_CLASS
IRMC_SYNC_CMD_PROFILE
IRMC_SYNC_PROFILE
L2CAP
LAN_ACCESS_CLASS
LAN_ACCESS_PROFILE
NAP_CLASS
NAP_PROFILE
OBEX_FILETRANS_CLASS
OBEX_FILETRANS_PROFILE
OBEX_OBJPUSH_CLASS
OBEX_OBJPUSH_PROFILE
PANU_CLASS
PANU_PROFILE
PNP_INFO_CLASS
PNP_INFO_PROFILE
PORT_ANY
PRINTING_STATUS_CLASS
PRINTING_STATUS_PROFILE
PUBLIC_BROWSE_GROUP
REFERENCE_PRINTING_CLASS
REFERENCE_PRINTING_PROFILE
REFLECTED_UI_CLASS
REFLECTED_UI_PROFILE
RFCOMM
SAP_CLASS
SAP_PROFILE
SDP_SERVER_CLASS
SDP_SERVER_PROFILE
SERIAL_PORT_CLASS
SERIAL_PORT_PROFILE
UDI_MT_CLASS
UDI_MT_PROFILE
UDI_TA_CLASS
UDI_TA_PROFILE
UPNP_CLASS
UPNP_IP_CLASS
UPNP_IP_PROFILE
UPNP_L2CAP_CLASS
UPNP_L2CAP_PROFILE
UPNP_LAP_CLASS
UPNP_LAP_PROFILE
UPNP_PAN_CLASS
UPNP_PAN_PROFILE
UPNP_PROFILE
VIDEO_CONF_CLASS
VIDEO_CONF_GW_CLASS
VIDEO_CONF_GW_PROFILE
VIDEO_CONF_PROFILE
VIDEO_SINK_CLASS
VIDEO_SINK_PROFILE
VIDEO_SOURCE_CLASS
VIDEO_SOURCE_PROFILE
WAP_CLASS
WAP_CLIENT_CLASS
WAP_CLIENT_PROFILE
WAP_PROFILE


[show private | hide private] pybluez-0.22+really0.22/docs/public/toc.html000066400000000000000000000017331334611253700206070ustar00rootroot00000000000000 Table of Contents
Table of Contents

Everything

Packages

Modules
bluetooth


[show private | hide private] pybluez-0.22+really0.22/docs/public/trees.html000066400000000000000000000075431334611253700211510ustar00rootroot00000000000000 Module and Class Hierarchies
[show private | hide private]
[frames | no frames]

Module Hierarchy

  • bluetooth: PyBluez - Bluetooth extension module

Class Hierarchy

Generated by Epydoc 2.1 on Tue May 9 02:23:40 2006 http://epydoc.sf.net
pybluez-0.22+really0.22/examples/000077500000000000000000000000001334611253700165405ustar00rootroot00000000000000pybluez-0.22+really0.22/examples/advanced/000077500000000000000000000000001334611253700203055ustar00rootroot00000000000000pybluez-0.22+really0.22/examples/advanced/inquiry-with-rssi.py000066400000000000000000000120651334611253700243120ustar00rootroot00000000000000# performs a simple device inquiry, followed by a remote name request of each # discovered device import os import sys import struct import bluetooth._bluetooth as bluez import bluetooth def printpacket(pkt): for c in pkt: sys.stdout.write("%02x " % struct.unpack("B",c)[0]) print() def read_inquiry_mode(sock): """returns the current mode, or -1 on failure""" # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # Setup socket filter to receive only events related to the # read_inquiry_mode command flt = bluez.hci_filter_new() opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL, bluez.OCF_READ_INQUIRY_MODE) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE); bluez.hci_filter_set_opcode(flt, opcode) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) # first read the current inquiry mode. bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL, bluez.OCF_READ_INQUIRY_MODE ) pkt = sock.recv(255) status,mode = struct.unpack("xxxxxxBB", pkt) if status != 0: mode = -1 # restore old filter sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return mode def write_inquiry_mode(sock, mode): """returns 0 on success, -1 on failure""" # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # Setup socket filter to receive only events related to the # write_inquiry_mode command flt = bluez.hci_filter_new() opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL, bluez.OCF_WRITE_INQUIRY_MODE) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE); bluez.hci_filter_set_opcode(flt, opcode) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) # send the command! bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL, bluez.OCF_WRITE_INQUIRY_MODE, struct.pack("B", mode) ) pkt = sock.recv(255) status = struct.unpack("xxxxxxB", pkt)[0] # restore old filter sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) if status != 0: return -1 return 0 def device_inquiry_with_with_rssi(sock): # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # perform a device inquiry on bluetooth device #0 # The inquiry should last 8 * 1.28 = 10.24 seconds # before the inquiry is performed, bluez should flush its cache of # previously discovered devices flt = bluez.hci_filter_new() bluez.hci_filter_all_events(flt) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) duration = 4 max_responses = 255 cmd_pkt = struct.pack("BBBBB", 0x33, 0x8b, 0x9e, duration, max_responses) bluez.hci_send_cmd(sock, bluez.OGF_LINK_CTL, bluez.OCF_INQUIRY, cmd_pkt) results = [] done = False while not done: pkt = sock.recv(255) ptype, event, plen = struct.unpack("BBB", pkt[:3]) if event == bluez.EVT_INQUIRY_RESULT_WITH_RSSI: pkt = pkt[3:] nrsp = bluetooth.get_byte(pkt[0]) for i in range(nrsp): addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] ) rssi = bluetooth.byte_to_signed_int( bluetooth.get_byte(pkt[1+13*nrsp+i])) results.append( ( addr, rssi ) ) print("[%s] RSSI: [%d]" % (addr, rssi)) elif event == bluez.EVT_INQUIRY_COMPLETE: done = True elif event == bluez.EVT_CMD_STATUS: status, ncmd, opcode = struct.unpack("BBH", pkt[3:7]) if status != 0: print("uh oh...") printpacket(pkt[3:7]) done = True elif event == bluez.EVT_INQUIRY_RESULT: pkt = pkt[3:] nrsp = bluetooth.get_byte(pkt[0]) for i in range(nrsp): addr = bluez.ba2str( pkt[1+6*i:1+6*i+6] ) results.append( ( addr, -1 ) ) print("[%s] (no RRSI)" % addr) else: print("unrecognized packet type 0x%02x" % ptype) print("event ", event) # restore old filter sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return results dev_id = 0 try: sock = bluez.hci_open_dev(dev_id) except: print("error accessing bluetooth device...") sys.exit(1) try: mode = read_inquiry_mode(sock) except Exception as e: print("error reading inquiry mode. ") print("Are you sure this a bluetooth 1.2 device?") print(e) sys.exit(1) print("current inquiry mode is %d" % mode) if mode != 1: print("writing inquiry mode...") try: result = write_inquiry_mode(sock, 1) except Exception as e: print("error writing inquiry mode. Are you sure you're root?") print(e) sys.exit(1) if result != 0: print("error while setting inquiry mode") print("result: %d" % result) device_inquiry_with_with_rssi(sock) pybluez-0.22+really0.22/examples/advanced/l2-mtu.py000066400000000000000000000031371334611253700220030ustar00rootroot00000000000000import sys import struct import bluetooth def usage(): print("usage: l2-mtu < server | client > [options]") print("") print("l2-mtu server to start in server mode") print("l2-mtu client to start in client mode and connect to addr") sys.exit(2) if len(sys.argv) < 2: usage() mode = sys.argv[1] if mode not in [ "client", "server" ]: usage() if mode == "server": server_sock=bluetooth.BluetoothSocket( bluetooth.L2CAP ) server_sock.bind(("",0x1001)) bluetooth.set_l2cap_mtu( server_sock, 65535 ) server_sock.listen(1) while True: print("waiting for incoming connection") client_sock,address = server_sock.accept() print("Accepted connection from %s" % str(address)) print("waiting for data") total = 0 while True: try: data = client_sock.recv(65535) except bluetooth.BluetoothError as e: break if len(data) == 0: break print("received packet of size %d" % len(data)) client_sock.close() print("connection closed") server_sock.close() else: sock=bluetooth.BluetoothSocket(bluetooth.L2CAP) print("connected. Adjusting link parameters.") bluetooth.set_l2cap_mtu( sock, 65535 ) bt_addr = sys.argv[2] print("trying to connect to %s:1001" % bt_addr) port = 0x1001 sock.connect((bt_addr, port)) totalsent = 0 for i in range(1, 65535, 100): pkt = "0" * i sent = sock.send(pkt) print("sent packet of size %d (tried %d)" % (sent, len(pkt))) sock.close() pybluez-0.22+really0.22/examples/advanced/l2-unreliable-client.py000066400000000000000000000023561334611253700245760ustar00rootroot00000000000000import sys import fcntl import struct import array import bluetooth import bluetooth._bluetooth as bt # low level bluetooth wrappers. # Create the client socket sock=bluetooth.BluetoothSocket(bluetooth.L2CAP) if len(sys.argv) < 4: print("usage: l2capclient.py ") print(" address - device that l2-unreliable-server is running on") print(" timeout - wait timeout * 0.625ms before dropping unACK'd packets") print(" num_packets - number of 627-byte packets to send on connect") sys.exit(2) bt_addr=sys.argv[1] timeout = int(sys.argv[2]) num_packets = int(sys.argv[3]) print("trying to connect to %s:1001" % bt_addr) port = 0x1001 sock.connect((bt_addr, port)) print("connected. Adjusting link parameters.") print("current flush timeout is %d ms" % bluetooth.read_flush_timeout( bt_addr )) try: bluetooth.write_flush_timeout( bt_addr, timeout ) except bt.error as e: print("error setting flush timeout. are you sure you're superuser?") print(e) sys.exit(1) print("new flush timeout is %d ms" % bluetooth.read_flush_timeout( bt_addr )) totalsent = 0 for i in range(num_packets): pkt = "0" * 672 totalsent += sock.send(pkt) print("sent %d bytes total" % totalsent) sock.close() pybluez-0.22+really0.22/examples/advanced/l2-unreliable-server.py000066400000000000000000000012251334611253700246200ustar00rootroot00000000000000import sys import bluetooth server_sock=bluetooth.BluetoothSocket( bluetooth.L2CAP ) server_sock.bind(("",0x1001)) server_sock.listen(1) while True: print("waiting for incoming connection") client_sock,address = server_sock.accept() print("Accepted connection from %s" % str(address)) print("waiting for data") total = 0 while True: try: data = client_sock.recv(1024) except bluetooth.BluetoothError as e: break if len(data) == 0: break total += len(data) print("total byte read: %d" % total) client_sock.close() print("connection closed") server_sock.close() pybluez-0.22+really0.22/examples/advanced/read-local-bdaddr.py000066400000000000000000000021271334611253700241020ustar00rootroot00000000000000import os import sys import struct import bluetooth._bluetooth as _bt if sys.version < '3': get_byte = str else: get_byte = chr def read_local_bdaddr(hci_sock): old_filter = hci_sock.getsockopt( _bt.SOL_HCI, _bt.HCI_FILTER, 14) flt = _bt.hci_filter_new() opcode = _bt.cmd_opcode_pack(_bt.OGF_INFO_PARAM, _bt.OCF_READ_BD_ADDR) _bt.hci_filter_set_ptype(flt, _bt.HCI_EVENT_PKT) _bt.hci_filter_set_event(flt, _bt.EVT_CMD_COMPLETE); _bt.hci_filter_set_opcode(flt, opcode) hci_sock.setsockopt( _bt.SOL_HCI, _bt.HCI_FILTER, flt ) _bt.hci_send_cmd(hci_sock, _bt.OGF_INFO_PARAM, _bt.OCF_READ_BD_ADDR ) pkt = hci_sock.recv(255) status,raw_bdaddr = struct.unpack("xxxxxxB6s", pkt) assert status == 0 t = [ "%X" % ord(get_byte(b)) for b in raw_bdaddr ] t.reverse() bdaddr = ":".join(t) # restore old filter hci_sock.setsockopt( _bt.SOL_HCI, _bt.HCI_FILTER, old_filter ) return bdaddr if __name__ == "__main__": dev_id = 0 hci_sock = _bt.hci_open_dev(dev_id) bdaddr = read_local_bdaddr(hci_sock) print(bdaddr) pybluez-0.22+really0.22/examples/advanced/write-inquiry-scan.py000066400000000000000000000060371334611253700244370ustar00rootroot00000000000000import os import sys import struct import bluetooth._bluetooth as bluez def read_inquiry_scan_activity(sock): """returns the current inquiry scan interval and window, or -1 on failure""" # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # Setup socket filter to receive only events related to the # read_inquiry_mode command flt = bluez.hci_filter_new() opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL, bluez.OCF_READ_INQ_ACTIVITY) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE); bluez.hci_filter_set_opcode(flt, opcode) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) # first read the current inquiry mode. bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL, bluez.OCF_READ_INQ_ACTIVITY ) pkt = sock.recv(255) status,interval,window = struct.unpack("!xxxxxxBHH", pkt) interval = bluez.btohs(interval) interval = (interval >> 8) | ( (interval & 0xFF) << 8 ) window = (window >> 8) | ( (window & 0xFF) << 8 ) if status != 0: mode = -1 # restore old filter sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) return interval, window def write_inquiry_scan_activity(sock, interval, window): """returns 0 on success, -1 on failure""" # save current filter old_filter = sock.getsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, 14) # Setup socket filter to receive only events related to the # write_inquiry_mode command flt = bluez.hci_filter_new() opcode = bluez.cmd_opcode_pack(bluez.OGF_HOST_CTL, bluez.OCF_WRITE_INQ_ACTIVITY) bluez.hci_filter_set_ptype(flt, bluez.HCI_EVENT_PKT) bluez.hci_filter_set_event(flt, bluez.EVT_CMD_COMPLETE); bluez.hci_filter_set_opcode(flt, opcode) sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, flt ) # send the command! bluez.hci_send_cmd(sock, bluez.OGF_HOST_CTL, bluez.OCF_WRITE_INQ_ACTIVITY, struct.pack("HH", interval, window) ) pkt = sock.recv(255) status = struct.unpack("xxxxxxB", pkt)[0] # restore old filter sock.setsockopt( bluez.SOL_HCI, bluez.HCI_FILTER, old_filter ) if status != 0: return -1 return 0 dev_id = 0 try: sock = bluez.hci_open_dev(dev_id) except: print("error accessing bluetooth device...") sys.exit(1) try: interval, window = read_inquiry_scan_activity(sock) except Exception as e: print("error reading inquiry scan activity. ") print(e) sys.exit(1) print("current inquiry scan interval: %d (0x%X) window: %d (0x%X)" % \ (interval, interval, window, window)) if len(sys.argv) == 3: interval = int(sys.argv[1]) window = int(sys.argv[2]) print("target interval: %d window %d" % (interval, window)) write_inquiry_scan_activity(sock, interval, window) interval, window = read_inquiry_scan_activity(sock) print("current inquiry scan interval: %d (0x%X) window: %d (0x%X)" % \ (interval, interval, window, window)) pybluez-0.22+really0.22/examples/ble/000077500000000000000000000000001334611253700173025ustar00rootroot00000000000000pybluez-0.22+really0.22/examples/ble/beacon.py000066400000000000000000000003571334611253700211100ustar00rootroot00000000000000from bluetooth.ble import BeaconService import time service = BeaconService() service.start_advertising("11111111-2222-3333-4444-555555555555", 1, 1, 1, 200) time.sleep(15) service.stop_advertising() print("Done.")pybluez-0.22+really0.22/examples/ble/beacon_scan.py000066400000000000000000000014471334611253700221150ustar00rootroot00000000000000from bluetooth.ble import BeaconService class Beacon(object): def __init__(self, data, address): self._uuid = data[0] self._major = data[1] self._minor = data[2] self._power = data[3] self._rssi = data[4] self._address = address def __str__(self): ret = "Beacon: address:{ADDR} uuid:{UUID} major:{MAJOR}"\ " minor:{MINOR} txpower:{POWER} rssi:{RSSI}"\ .format(ADDR=self._address, UUID=self._uuid, MAJOR=self._major, MINOR=self._minor, POWER=self._power, RSSI=self._rssi) return ret service = BeaconService() devices = service.scan(2) for address, data in list(devices.items()): b = Beacon(data, address) print(b) print("Done.")pybluez-0.22+really0.22/examples/ble/read_name.py000066400000000000000000000017751334611253700216010ustar00rootroot00000000000000#!/usr/bin/python # -*- mode: python; coding: utf-8 -*- # Copyright (C) 2014, Oscar Acena # This software is under the terms of GPLv3 or later. from __future__ import print_function import sys from bluetooth.ble import GATTRequester class Reader(object): def __init__(self, address): self.requester = GATTRequester(address, False) self.connect() self.request_data() def connect(self): print("Connecting...", end=' ') sys.stdout.flush() self.requester.connect(True) print("OK!") def request_data(self): data = self.requester.read_by_uuid( "00002a00-0000-1000-8000-00805f9b34fb")[0] try: print("Device name: " + data.decode("utf-8")) except AttributeError: print("Device name: " + data) if __name__ == '__main__': if len(sys.argv) < 2: print("Usage: {} ".format(sys.argv[0])) sys.exit(1) Reader(sys.argv[1]) print("Done.") pybluez-0.22+really0.22/examples/ble/scan.py000066400000000000000000000003071334611253700206000ustar00rootroot00000000000000from bluetooth.ble import DiscoveryService service = DiscoveryService() devices = service.discover(2) for address, name in devices.items(): print("name: {}, address: {}".format(name, address)) pybluez-0.22+really0.22/examples/bluezchat/000077500000000000000000000000001334611253700205215ustar00rootroot00000000000000pybluez-0.22+really0.22/examples/bluezchat/bluezchat.glade000066400000000000000000000135051334611253700235040ustar00rootroot00000000000000 True bluez chat 240 320 True True True True GTK_SHADOW_IN True True False True True True _Quit True True True S_can True 1 True True _Chat True 2 1 True True GTK_SHADOW_IN True True 1 True True text: False False True True * 3 1 True True _Send True False False 2 2 pybluez-0.22+really0.22/examples/bluezchat/bluezchat.gladep000066400000000000000000000004271334611253700236630ustar00rootroot00000000000000 Bluezchat bluezchat FALSE pybluez-0.22+really0.22/examples/bluezchat/bluezchat.py000077500000000000000000000135661334611253700230720ustar00rootroot00000000000000#!/usr/bin/python """ A simple graphical chat client to demonstrate the use of pybluez. Opens a l2cap socket and listens on PSM 0x1001 Provides the ability to scan for nearby bluetooth devices and establish chat sessions with them. """ import os import sys import time import gtk import gobject import gtk.glade import bluetooth GLADEFILE="bluezchat.glade" # ***************** def alert(text, buttons=gtk.BUTTONS_NONE, type=gtk.MESSAGE_INFO): md = gtk.MessageDialog(buttons=buttons, type=type) md.label.set_text(text) md.run() md.destroy() class BluezChatGui: def __init__(self): self.main_window_xml = gtk.glade.XML(GLADEFILE, "bluezchat_window") # connect our signal handlers dic = { "on_quit_button_clicked" : self.quit_button_clicked, "on_send_button_clicked" : self.send_button_clicked, "on_chat_button_clicked" : self.chat_button_clicked, "on_scan_button_clicked" : self.scan_button_clicked, "on_devices_tv_cursor_changed" : self.devices_tv_cursor_changed } self.main_window_xml.signal_autoconnect(dic) # prepare the floor listbox self.devices_tv = self.main_window_xml.get_widget("devices_tv") self.discovered = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_STRING) self.devices_tv.set_model(self.discovered) renderer = gtk.CellRendererText() column1=gtk.TreeViewColumn("addr", renderer, text=0) column2=gtk.TreeViewColumn("name", renderer, text=1) self.devices_tv.append_column(column1) self.devices_tv.append_column(column2) self.quit_button = self.main_window_xml.get_widget("quit_button") self.scan_button = self.main_window_xml.get_widget("scan_button") self.chat_button = self.main_window_xml.get_widget("chat_button") self.send_button = self.main_window_xml.get_widget("send_button") self.main_text = self.main_window_xml.get_widget("main_text") self.text_buffer = self.main_text.get_buffer() self.input_tb = self.main_window_xml.get_widget("input_tb") self.listed_devs = [] self.chat_button.set_sensitive(False) self.peers = {} self.sources = {} self.addresses = {} # the listening sockets self.server_sock = None # --- gui signal handlers def quit_button_clicked(self, widget): gtk.main_quit() def scan_button_clicked(self, widget): self.quit_button.set_sensitive(False) self.scan_button.set_sensitive(False) # self.chat_button.set_sensitive(False) self.discovered.clear() for addr, name in bluetooth.discover_devices (lookup_names = True): self.discovered.append ((addr, name)) self.quit_button.set_sensitive(True) self.scan_button.set_sensitive(True) # self.chat_button.set_sensitive(True) def send_button_clicked(self, widget): text = self.input_tb.get_text() if len(text) == 0: return for addr, sock in list(self.peers.items()): sock.send(text) self.input_tb.set_text("") self.add_text("\nme - %s" % text) def chat_button_clicked(self, widget): (model, iter) = self.devices_tv.get_selection().get_selected() if iter is not None: addr = model.get_value(iter, 0) if addr not in self.peers: self.add_text("\nconnecting to %s" % addr) self.connect(addr) else: self.add_text("\nAlready connected to %s!" % addr) def devices_tv_cursor_changed(self, widget): (model, iter) = self.devices_tv.get_selection().get_selected() if iter is not None: self.chat_button.set_sensitive(True) else: self.chat_button.set_sensitive(False) # --- network events def incoming_connection(self, source, condition): sock, info = self.server_sock.accept() address, psm = info self.add_text("\naccepted connection from %s" % str(address)) # add new connection to list of peers self.peers[address] = sock self.addresses[sock] = address source = gobject.io_add_watch (sock, gobject.IO_IN, self.data_ready) self.sources[address] = source return True def data_ready(self, sock, condition): address = self.addresses[sock] data = sock.recv(1024) if len(data) == 0: self.add_text("\nlost connection with %s" % address) gobject.source_remove(self.sources[address]) del self.sources[address] del self.peers[address] del self.addresses[sock] sock.close() else: self.add_text("\n%s - %s" % (address, str(data))) return True # --- other stuff def cleanup(self): self.hci_sock.close() def connect(self, addr): sock = bluetooth.BluetoothSocket (bluetooth.L2CAP) try: sock.connect((addr, 0x1001)) except bluez.error as e: self.add_text("\n%s" % str(e)) sock.close() return self.peers[addr] = sock source = gobject.io_add_watch (sock, gobject.IO_IN, self.data_ready) self.sources[addr] = source self.addresses[sock] = addr def add_text(self, text): self.text_buffer.insert(self.text_buffer.get_end_iter(), text) def start_server(self): self.server_sock = bluetooth.BluetoothSocket (bluetooth.L2CAP) self.server_sock.bind(("",0x1001)) self.server_sock.listen(1) gobject.io_add_watch(self.server_sock, gobject.IO_IN, self.incoming_connection) def run(self): self.text_buffer.insert(self.text_buffer.get_end_iter(), "loading..") self.start_server() gtk.main() if __name__ == "__main__": gui = BluezChatGui() gui.run() pybluez-0.22+really0.22/examples/simple/000077500000000000000000000000001334611253700200315ustar00rootroot00000000000000pybluez-0.22+really0.22/examples/simple/asynchronous-inquiry.py000066400000000000000000000040421334611253700246340ustar00rootroot00000000000000# file: asynchronous-inquiry.py # auth: Albert Huang # desc: demonstration of how to do asynchronous device discovery by subclassing # the DeviceDiscoverer class # $Id: asynchronous-inquiry.py 405 2006-05-06 00:39:50Z albert $ # # XXX Linux only (5/5/2006) import bluetooth import select class MyDiscoverer(bluetooth.DeviceDiscoverer): def pre_inquiry(self): self.done = False def device_discovered(self, address, device_class, rssi, name): print("%s - %s" % (address, name)) # get some information out of the device class and display it. # voodoo magic specified at: # # https://www.bluetooth.org/foundry/assignnumb/document/baseband major_classes = ( "Miscellaneous", "Computer", "Phone", "LAN/Network Access point", "Audio/Video", "Peripheral", "Imaging" ) major_class = (device_class >> 8) & 0xf if major_class < 7: print(" %s" % major_classes[major_class]) else: print(" Uncategorized") print(" services:") service_classes = ( (16, "positioning"), (17, "networking"), (18, "rendering"), (19, "capturing"), (20, "object transfer"), (21, "audio"), (22, "telephony"), (23, "information")) for bitpos, classname in service_classes: if device_class & (1 << (bitpos-1)): print(" %s" % classname) print(" RSSI: " + str(rssi)) def inquiry_complete(self): self.done = True d = MyDiscoverer() d.find_devices(lookup_names = True) readfiles = [ d, ] while True: rfds = select.select( readfiles, [], [] )[0] if d in rfds: d.process_event() if d.done: break pybluez-0.22+really0.22/examples/simple/inquiry.py000066400000000000000000000011731334611253700221050ustar00rootroot00000000000000# file: inquiry.py # auth: Albert Huang # desc: performs a simple device inquiry followed by a remote name request of # each discovered device # $Id: inquiry.py 401 2006-05-05 19:07:48Z albert $ # import bluetooth print("performing inquiry...") nearby_devices = bluetooth.discover_devices( duration=8, lookup_names=True, flush_cache=True, lookup_class=False) print("found %d devices" % len(nearby_devices)) for addr, name in nearby_devices: try: print(" %s - %s" % (addr, name)) except UnicodeEncodeError: print(" %s - %s" % (addr, name.encode('utf-8', 'replace'))) pybluez-0.22+really0.22/examples/simple/l2capclient.py000066400000000000000000000012201334611253700225760ustar00rootroot00000000000000# file: l2capclient.py # desc: Demo L2CAP client for bluetooth module. # $Id: l2capclient.py 524 2007-08-15 04:04:52Z albert $ import sys import bluetooth if sys.version < '3': input = raw_input sock=bluetooth.BluetoothSocket(bluetooth.L2CAP) if len(sys.argv) < 2: print("usage: l2capclient.py ") sys.exit(2) bt_addr=sys.argv[1] port = 0x1001 print("trying to connect to %s on PSM 0x%X" % (bt_addr, port)) sock.connect((bt_addr, port)) print("connected. type stuff") while True: data = input() if(len(data) == 0): break sock.send(data) data = sock.recv(1024) print("Data received:", str(data)) sock.close() pybluez-0.22+really0.22/examples/simple/l2capserver.py000066400000000000000000000014721334611253700226370ustar00rootroot00000000000000# file: l2capclient.py # desc: Demo L2CAP server for pybluez. # $Id: l2capserver.py 524 2007-08-15 04:04:52Z albert $ import bluetooth server_sock=bluetooth.BluetoothSocket( bluetooth.L2CAP ) port = 0x1001 server_sock.bind(("",port)) server_sock.listen(1) #uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ef" #bluetooth.advertise_service( server_sock, "SampleServerL2CAP", # service_id = uuid, # service_classes = [ uuid ] # ) client_sock,address = server_sock.accept() print("Accepted connection from ",address) data = client_sock.recv(1024) print("Data received: ", str(data)) while data: client_sock.send('Echo => ' + str(data)) data = client_sock.recv(1024) print("Data received:", str(data)) client_sock.close() server_sock.close() pybluez-0.22+really0.22/examples/simple/rfcomm-client.py000066400000000000000000000022531334611253700231440ustar00rootroot00000000000000# file: rfcomm-client.py # auth: Albert Huang # desc: simple demonstration of a client application that uses RFCOMM sockets # intended for use with rfcomm-server # # $Id: rfcomm-client.py 424 2006-08-24 03:35:54Z albert $ from bluetooth import * import sys if sys.version < '3': input = raw_input addr = None if len(sys.argv) < 2: print("no device specified. Searching all nearby bluetooth devices for") print("the SampleServer service") else: addr = sys.argv[1] print("Searching for SampleServer on %s" % addr) # search for the SampleServer service uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee" service_matches = find_service( uuid = uuid, address = addr ) if len(service_matches) == 0: print("couldn't find the SampleServer service =(") sys.exit(0) first_match = service_matches[0] port = first_match["port"] name = first_match["name"] host = first_match["host"] print("connecting to \"%s\" on %s" % (name, host)) # Create the client socket sock=BluetoothSocket( RFCOMM ) sock.connect((host, port)) print("connected. type stuff") while True: data = input() if len(data) == 0: break sock.send(data) sock.close() pybluez-0.22+really0.22/examples/simple/rfcomm-server.py000066400000000000000000000021161334611253700231720ustar00rootroot00000000000000# file: rfcomm-server.py # auth: Albert Huang # desc: simple demonstration of a server application that uses RFCOMM sockets # # $Id: rfcomm-server.py 518 2007-08-10 07:20:07Z albert $ from bluetooth import * server_sock=BluetoothSocket( RFCOMM ) server_sock.bind(("",PORT_ANY)) server_sock.listen(1) port = server_sock.getsockname()[1] uuid = "94f39d29-7d6d-437d-973b-fba39e49d4ee" advertise_service( server_sock, "SampleServer", service_id = uuid, service_classes = [ uuid, SERIAL_PORT_CLASS ], profiles = [ SERIAL_PORT_PROFILE ], # protocols = [ OBEX_UUID ] ) print("Waiting for connection on RFCOMM channel %d" % port) client_sock, client_info = server_sock.accept() print("Accepted connection from ", client_info) try: while True: data = client_sock.recv(1024) if len(data) == 0: break print("received [%s]" % data) except IOError: pass print("disconnected") client_sock.close() server_sock.close() print("all done") pybluez-0.22+really0.22/examples/simple/sdp-browse.py000066400000000000000000000021351334611253700224710ustar00rootroot00000000000000# file: sdp-browse.py # auth: Albert Huang # desc: displays services being advertised on a specified bluetooth device # $Id: sdp-browse.py 393 2006-02-24 20:30:15Z albert $ import sys import bluetooth if len(sys.argv) < 2: print("usage: sdp-browse ") print(" addr can be a bluetooth address, \"localhost\", or \"all\"") sys.exit(2) target = sys.argv[1] if target == "all": target = None services = bluetooth.find_service(address=target) if len(services) > 0: print("found %d services on %s" % (len(services), sys.argv[1])) print() else: print("no services found") for svc in services: print("Service Name: %s" % svc["name"]) print(" Host: %s" % svc["host"]) print(" Description: %s" % svc["description"]) print(" Provided By: %s" % svc["provider"]) print(" Protocol: %s" % svc["protocol"]) print(" channel/PSM: %s" % svc["port"]) print(" svc classes: %s "% svc["service-classes"]) print(" profiles: %s "% svc["profiles"]) print(" service id: %s "% svc["service-id"]) print() pybluez-0.22+really0.22/msbt/000077500000000000000000000000001334611253700156675ustar00rootroot00000000000000pybluez-0.22+really0.22/msbt/_msbt.c000066400000000000000000000670031334611253700171450ustar00rootroot00000000000000#include #include #include #include #include #include #include #if 1 static void dbg(const char *fmt, ...) { } #else static void dbg(const char *fmt, ...) { va_list ap; va_start (ap, fmt); vprintf (fmt, ap); va_end (ap); } #endif static void Err_SetFromWSALastError(PyObject *exc) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, WSAGetLastError(), 0, (LPTSTR) &lpMsgBuf, 0, NULL ); PyErr_SetString( exc, lpMsgBuf ); LocalFree(lpMsgBuf); } #define _CHECK_OR_RAISE_WSA(cond) \ if( !(cond) ) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } static void ba2str( BTH_ADDR ba, char *addr, size_t len ) { int i; unsigned char bytes[6]; for( i=0; i<6; i++ ) { bytes[5-i] = (unsigned char) ((ba >> (i*8)) & 0xff); } sprintf_s( addr, len, "%02X:%02X:%02X:%02X:%02X:%02X", bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5] ); } static PyObject * msbt_initwinsock(PyObject *self) { WORD wVersionRequested; WSADATA wsaData; int status; wVersionRequested = MAKEWORD( 2, 0 ); status = WSAStartup( wVersionRequested, &wsaData ); if( 0 != status ) { Err_SetFromWSALastError( PyExc_RuntimeError ); return 0; } Py_RETURN_NONE; } PyDoc_STRVAR(msbt_initwinsock_doc, "TODO"); static void dict_set_str_pyobj(PyObject *dict, const char *key, PyObject *valobj) { PyObject *keyobj; keyobj = PyString_FromString( key ); PyDict_SetItem( dict, keyobj, valobj ); Py_DECREF( keyobj ); } static void dict_set_strings(PyObject *dict, const char *key, const char *val) { PyObject *keyobj, *valobj; keyobj = PyString_FromString( key ); valobj = PyString_FromString( val ); PyDict_SetItem( dict, keyobj, valobj ); Py_DECREF( keyobj ); Py_DECREF( valobj ); } static void dict_set_str_long(PyObject *dict, const char *key, long val) { PyObject *keyobj, *valobj; keyobj = PyString_FromString( key ); valobj = PyInt_FromLong(val); PyDict_SetItem( dict, keyobj, valobj ); Py_DECREF( keyobj ); Py_DECREF( valobj ); } static int str2uuid( const char *uuid_str, GUID *uuid) { // Parse uuid128 standard format: 12345678-9012-3456-7890-123456789012 int i; char buf[20] = { 0 }; strncpy_s(buf, _countof(buf), uuid_str, 8); uuid->Data1 = strtoul( buf, NULL, 16 ); memset(buf, 0, sizeof(buf)); strncpy_s(buf, _countof(buf), uuid_str+9, 4); uuid->Data2 = (unsigned short) strtoul( buf, NULL, 16 ); memset(buf, 0, sizeof(buf)); strncpy_s(buf, _countof(buf), uuid_str+14, 4); uuid->Data3 = (unsigned short) strtoul( buf, NULL, 16 ); memset(buf, 0, sizeof(buf)); strncpy_s(buf, _countof(buf), uuid_str+19, 4); strncpy_s(buf+4, _countof(buf)-4, uuid_str+24, 12); for( i=0; i<8; i++ ) { char buf2[3] = { buf[2*i], buf[2*i+1], 0 }; uuid->Data4[i] = (unsigned char)strtoul( buf2, NULL, 16 ); } return 0; } // ====================== SOCKET FUNCTIONS ======================== static PyObject * msbt_socket(PyObject *self, PyObject *args) { int family = AF_BTH; int type; int proto; int sockfd = -1; if(!PyArg_ParseTuple(args, "ii", &type, &proto)) return 0; Py_BEGIN_ALLOW_THREADS; sockfd = socket( AF_BTH, type, proto ); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( SOCKET_ERROR != sockfd ); return PyInt_FromLong( sockfd ); }; PyDoc_STRVAR(msbt_socket_doc, "TODO"); static PyObject * msbt_bind(PyObject *self, PyObject *args) { char *addrstr = NULL; int addrstrlen = -1; int sockfd = -1; int port = -1; char buf[100] = { 0 }; int buf_len = sizeof( buf ); int status; SOCKADDR_BTH sa = { 0 }; int sa_len = sizeof(sa); if(!PyArg_ParseTuple(args, "is#i", &sockfd, &addrstr, &addrstrlen, &port)) return 0; if( addrstrlen == 0 ) { sa.btAddr = 0; } else { _CHECK_OR_RAISE_WSA( NO_ERROR == WSAStringToAddress( addrstr, \ AF_BTH, NULL, (LPSOCKADDR)&sa, &sa_len ) ); } sa.addressFamily = AF_BTH; sa.port = port; Py_BEGIN_ALLOW_THREADS; status = bind( sockfd, (LPSOCKADDR)&sa, sa_len ); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( NO_ERROR == status ); Py_RETURN_NONE; } PyDoc_STRVAR(msbt_bind_doc, "TODO"); static PyObject * msbt_listen(PyObject *self, PyObject *args) { int sockfd = -1; int backlog = -1; DWORD status; if(!PyArg_ParseTuple(args, "ii", &sockfd, &backlog)) return 0; Py_BEGIN_ALLOW_THREADS; status = listen(sockfd, backlog); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( NO_ERROR == status ); Py_RETURN_NONE; } PyDoc_STRVAR(msbt_listen_doc, "TODO"); static PyObject * msbt_accept(PyObject *self, PyObject *args) { int sockfd = -1; int clientfd = -1; SOCKADDR_BTH ca = { 0 }; int ca_len = sizeof(ca); PyObject *result = NULL; char buf[100] = { 0 }; int buf_len = sizeof(buf); if(!PyArg_ParseTuple(args, "i", &sockfd)) return 0; Py_BEGIN_ALLOW_THREADS; clientfd = accept(sockfd, (LPSOCKADDR)&ca, &ca_len); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( SOCKET_ERROR != clientfd ); ba2str(ca.btAddr, buf, _countof(buf)); result = Py_BuildValue( "isi", clientfd, buf, ca.port ); return result; }; PyDoc_STRVAR(msbt_accept_doc, "TODO"); static PyObject * msbt_connect(PyObject *self, PyObject *args) { int sockfd = -1; char *addrstr = NULL; int port = -1; SOCKADDR_BTH sa = { 0 }; int sa_len = sizeof(sa); DWORD status; if(!PyArg_ParseTuple(args, "isi", &sockfd, &addrstr, &port)) return 0; if( SOCKET_ERROR == WSAStringToAddress( addrstr, AF_BTH, NULL, (LPSOCKADDR)&sa, &sa_len ) ) { Err_SetFromWSALastError(PyExc_IOError); return 0; } sa.addressFamily = AF_BTH; sa.port = port; Py_BEGIN_ALLOW_THREADS; status = connect(sockfd, (LPSOCKADDR)&sa, sizeof(sa)); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( NO_ERROR == status ); Py_RETURN_NONE; } PyDoc_STRVAR(msbt_connect_doc, "TODO"); static PyObject * msbt_send(PyObject *self, PyObject *args) { int sockfd = -1; char *data = NULL; int datalen = -1; int flags = 0; int sent = 0; if(!PyArg_ParseTuple(args, "is#|i", &sockfd, &data, &datalen, &flags)) return 0; Py_BEGIN_ALLOW_THREADS; sent = send(sockfd, data, datalen, flags); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( SOCKET_ERROR != sent ); return PyInt_FromLong( sent ); }; PyDoc_STRVAR(msbt_send_doc, "TODO"); static PyObject * msbt_recv(PyObject *self, PyObject *args) { int sockfd = -1; PyObject *buf = NULL; int datalen = -1; int flags = 0; int received = 0; if(!PyArg_ParseTuple(args, "ii|i", &sockfd, &datalen, &flags)) return 0; buf = PyString_FromStringAndSize((char*)0, datalen); Py_BEGIN_ALLOW_THREADS; received = recv(sockfd, PyString_AS_STRING(buf), datalen, flags); Py_END_ALLOW_THREADS; if( SOCKET_ERROR == received ){ Py_DECREF(buf); } _CHECK_OR_RAISE_WSA( SOCKET_ERROR != received ); if( received != datalen ) _PyString_Resize(&buf, received); return buf; }; PyDoc_STRVAR(msbt_recv_doc, "TODO"); static PyObject * msbt_close(PyObject *self, PyObject *args) { int sockfd = -1; int status; if(!PyArg_ParseTuple( args, "i", &sockfd )) return 0; Py_BEGIN_ALLOW_THREADS; status = closesocket(sockfd); Py_END_ALLOW_THREADS; Py_RETURN_NONE; } PyDoc_STRVAR(msbt_close_doc, "TODO"); static PyObject * msbt_getsockname(PyObject *self, PyObject *args) { int sockfd = -1; SOCKADDR_BTH sa = { 0 }; int sa_len = sizeof(sa); char buf[100] = { 0 }; int buf_len = sizeof(buf); int status; if(!PyArg_ParseTuple( args, "i", &sockfd )) return 0; sa.addressFamily = AF_BTH; Py_BEGIN_ALLOW_THREADS; status = getsockname( sockfd, (LPSOCKADDR)&sa, &sa_len ); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( NO_ERROR == status ); ba2str( sa.btAddr, buf, buf_len ); return Py_BuildValue( "si", buf, sa.port ); }; PyDoc_STRVAR(msbt_getsockname_doc, "TODO"); static PyObject * msbt_dup(PyObject *self, PyObject *args) { int sockfd = -1; int newsockfd = -1; int status; DWORD pid; WSAPROTOCOL_INFO pi = { 0 }; if(!PyArg_ParseTuple( args, "i", &sockfd )) return 0; // prepare to duplicate pid = GetCurrentProcessId(); status = WSADuplicateSocket( sockfd, pid, &pi ); _CHECK_OR_RAISE_WSA( NO_ERROR == status ); // duplicate! newsockfd = WSASocket( FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &pi, 0, 0 ); _CHECK_OR_RAISE_WSA( INVALID_SOCKET != newsockfd ); return PyInt_FromLong( newsockfd ); } PyDoc_STRVAR(msbt_dup_doc, "TODO"); // ==================== static int bt_adapter_present() { int hwactive = 1; SOCKADDR_BTH sa = { 0 }; int s = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); sa.addressFamily = AF_BTH; sa.port = BT_PORT_ANY; if (s == INVALID_SOCKET) { closesocket(s); return 0; } if (SOCKET_ERROR == bind(s, (LPSOCKADDR)&sa, sizeof(sa))) { hwactive = 0; } closesocket(s); return hwactive; } static PyObject * msbt_discover_devices(PyObject *self, PyObject *args, PyObject *kwds) { BLUETOOTH_DEVICE_INFO device_info; BLUETOOTH_DEVICE_SEARCH_PARAMS search_criteria; HBLUETOOTH_DEVICE_FIND found_device; BOOL next = TRUE; PyObject * toreturn = NULL; int duration = 8; int flush_cache = 1; static char *keywords[] = {"duration", "flush_cache", 0}; if(!PyArg_ParseTupleAndKeywords(args, kwds, "ii", keywords, &duration, &flush_cache)) { return NULL; } toreturn = PyList_New(0); ZeroMemory(&device_info, sizeof(BLUETOOTH_DEVICE_INFO)); ZeroMemory(&search_criteria, sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS)); device_info.dwSize = sizeof(BLUETOOTH_DEVICE_INFO); search_criteria.dwSize = sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS); search_criteria.fReturnAuthenticated = TRUE; search_criteria.fReturnRemembered = !flush_cache; search_criteria.fReturnConnected = TRUE; search_criteria.fReturnUnknown = TRUE; search_criteria.fIssueInquiry = TRUE; search_criteria.cTimeoutMultiplier = duration; search_criteria.hRadio = NULL; Py_BEGIN_ALLOW_THREADS; found_device = BluetoothFindFirstDevice(&search_criteria, &device_info); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA(found_device != NULL) while(next) { PyObject *tup = NULL; PyObject *item_tuple = NULL; char buf[40] = {0}; BTH_ADDR result = device_info.Address.ullLong; ba2str( result, buf, _countof(buf) ); tup = PyTuple_New(3); item_tuple = PyString_FromString(buf); PyTuple_SetItem( tup, 0, item_tuple ); item_tuple = PyUnicode_FromUnicode( (const Py_UNICODE*)device_info.szName, wcslen(device_info.szName)); PyTuple_SetItem( tup, 1, item_tuple ); item_tuple = PyInt_FromLong(device_info.ulClassofDevice); PyTuple_SetItem( tup, 2, item_tuple ); PyList_Append( toreturn, tup ); Py_DECREF( tup ); Py_BEGIN_ALLOW_THREADS; next = BluetoothFindNextDevice(found_device, &device_info); Py_END_ALLOW_THREADS; } return toreturn; } PyDoc_STRVAR(msbt_discover_devices_doc, "msbt_discover_devices(duration=8, flush_cache=True\n\\n\ Performs a device inquiry. The inquiry will last 1.28 * duration seconds.\ If flush_cache is True, then new inquiry will be performed,\ else cashed devices will be returned(plus paired devices).)"); static PyObject * msbt_lookup_name(PyObject *self, PyObject *args) { HANDLE rhandle = NULL; BLUETOOTH_FIND_RADIO_PARAMS p = { sizeof(p) }; HBLUETOOTH_RADIO_FIND fhandle = NULL; BLUETOOTH_DEVICE_INFO dinfo = { 0 }; char *addrstr = NULL; SOCKADDR_BTH sa = { 0 }; int sa_len = sizeof(sa); DWORD status; if(!PyArg_ParseTuple(args,"s",&addrstr)) return 0; _CHECK_OR_RAISE_WSA( NO_ERROR == WSAStringToAddress( addrstr, \ AF_BTH, NULL, (LPSOCKADDR)&sa, &sa_len ) ); // printf("looking for first radio\n"); fhandle = BluetoothFindFirstRadio(&p, &rhandle); _CHECK_OR_RAISE_WSA( NULL != fhandle ); // printf("found radio 0x%p\n", rhandle ); dinfo.dwSize = sizeof( dinfo ); dinfo.Address.ullLong = sa.btAddr; status = BluetoothGetDeviceInfo( rhandle, &dinfo ); _CHECK_OR_RAISE_WSA( status == ERROR_SUCCESS ); // printf("name: %s\n", dinfo.szName ); _CHECK_OR_RAISE_WSA( TRUE == BluetoothFindRadioClose( fhandle ) ); return PyUnicode_FromWideChar( dinfo.szName, wcslen( dinfo.szName ) ); } PyDoc_STRVAR(msbt_lookup_name_doc, "TODO"); // ======================= SDP FUNCTIONS ====================== static PyObject * msbt_find_service(PyObject *self, PyObject *args) { char *addrstr = NULL; char *uuidstr = NULL; // inquiry data structure DWORD qs_len = sizeof( WSAQUERYSET ); WSAQUERYSET *qs = (WSAQUERYSET*) malloc( qs_len ); DWORD flags = LUP_FLUSHCACHE | LUP_RETURN_ALL; HANDLE h; int done = 0; int status = 0; PyObject *record = NULL; PyObject *toreturn = NULL; GUID uuid = { 0 }; char localAddressBuf[20] = { 0 }; if(!PyArg_ParseTuple(args,"ss", &addrstr, &uuidstr)) return 0; ZeroMemory( qs, qs_len ); qs->dwSize = sizeof(WSAQUERYSET); qs->dwNameSpace = NS_BTH; qs->dwNumberOfCsAddrs = 0; qs->lpszContext = (LPSTR) localAddressBuf; if( 0 == strcmp( addrstr, "localhost" ) ) { // find the Bluetooth address of the first local adapter. #if 0 HANDLE rhandle = NULL; BLUETOOTH_RADIO_INFO info; BLUETOOTH_FIND_RADIO_PARAMS p = { sizeof(p) }; HBLUETOOTH_RADIO_FIND fhandle = NULL; printf("looking for first radio\n"); fhandle = BluetoothFindFirstRadio(&p, &rhandle); _CHECK_OR_RAISE_WSA( NULL != fhandle ); printf("first radio: 0x%p\n", rhandle); _CHECK_OR_RAISE_WSA( \ TRUE == BluetoothFindRadioClose( fhandle ) ); printf("retrieving radio info on handle 0x%p\n", rhandle); info.dwSize = sizeof(info); // XXX why doesn't this work??? _CHECK_OR_RAISE_WSA( \ ERROR_SUCCESS != BluetoothGetRadioInfo( rhandle, &info ) ); ba2str( info.address.ullLong, localAddressBuf, _countof(localAddressBuf) ); #else // bind a temporary socket and get its Bluetooth address SOCKADDR_BTH sa = { 0 }; int sa_len = sizeof(sa); int tmpfd = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); _CHECK_OR_RAISE_WSA( tmpfd >= 0 ); sa.addressFamily = AF_BTH; sa.port = BT_PORT_ANY; _CHECK_OR_RAISE_WSA(NO_ERROR == bind(tmpfd,(LPSOCKADDR)&sa,sa_len) ); _CHECK_OR_RAISE_WSA(NO_ERROR == getsockname(tmpfd, (LPSOCKADDR)&sa,\ &sa_len ) ); ba2str(sa.btAddr, localAddressBuf, _countof(localAddressBuf) ); _close(tmpfd); #endif flags |= LUP_RES_SERVICE; } else { strcpy_s(localAddressBuf, _countof(localAddressBuf), addrstr); } if( strlen(uuidstr) != 36 || uuidstr[8] != '-' || uuidstr[13] != '-' || uuidstr[18] != '-' || uuidstr[23] != '-' ) { PyErr_SetString( PyExc_ValueError, "Invalid UUID!"); return 0; } str2uuid( uuidstr, &uuid ); qs->lpServiceClassId = &uuid; Py_BEGIN_ALLOW_THREADS; status = WSALookupServiceBegin( qs, flags, &h ); Py_END_ALLOW_THREADS; if( SOCKET_ERROR == status) { int err_code = WSAGetLastError(); if( WSASERVICE_NOT_FOUND == err_code ) { // this device does not advertise any services. return an // empty list free( qs ); return PyList_New(0); } else { // unexpected error. raise an exception Err_SetFromWSALastError( PyExc_IOError ); free(qs); return 0; } } toreturn = PyList_New(0); // iterate through the inquiry results while(! done) { Py_BEGIN_ALLOW_THREADS; status = WSALookupServiceNext( h, flags, &qs_len, qs ); Py_END_ALLOW_THREADS; if (NO_ERROR == status) { int proto; int port; PyObject *rawrecord = NULL; CSADDR_INFO *csinfo = NULL; record = PyDict_New(); // set host name dict_set_strings( record, "host", localAddressBuf ); // set service name dict_set_strings( record, "name", qs->lpszServiceInstanceName ); // set description dict_set_strings( record, "description", qs->lpszComment ); // set protocol and port csinfo = qs->lpcsaBuffer; if( csinfo != NULL ) { proto = csinfo->iProtocol; port = ((SOCKADDR_BTH*)csinfo->RemoteAddr.lpSockaddr)->port; dict_set_str_long(record, "port", port); if( proto == BTHPROTO_RFCOMM ) { dict_set_strings(record, "protocol", "RFCOMM"); } else if( proto == BTHPROTO_L2CAP ) { dict_set_strings(record, "protocol", "L2CAP"); } else { dict_set_strings(record, "protocol", "UNKNOWN"); dict_set_str_pyobj(record, "port", Py_None); } } else { dict_set_str_pyobj(record, "port", Py_None); dict_set_strings(record, "protocol", "UNKNOWN"); } // add the raw service record to be parsed in python rawrecord = PyString_FromStringAndSize( qs->lpBlob->pBlobData, qs->lpBlob->cbSize ); dict_set_str_pyobj(record, "rawrecord", rawrecord); Py_DECREF(rawrecord); PyList_Append( toreturn, record ); Py_DECREF( record ); } else { int error = WSAGetLastError(); if( error == WSAEFAULT ) { // the qs data structure is too small. allocate a bigger // buffer and try again. free( qs ); qs = (WSAQUERYSET*) malloc( qs_len ); } else if( error == WSA_E_NO_MORE ) { // no more results. done = 1; } else { // unexpected error. raise an exception. Err_SetFromWSALastError( PyExc_IOError ); Py_DECREF( toreturn ); return 0; } } } Py_BEGIN_ALLOW_THREADS; WSALookupServiceEnd( h ); Py_END_ALLOW_THREADS; free( qs ); return toreturn; } PyDoc_STRVAR(msbt_find_service_doc, "TODO"); static PyObject * msbt_set_service_raw(PyObject *self, PyObject *args) { int advertise = 0; WSAQUERYSET qs = { 0 }; WSAESETSERVICEOP op; char *record = NULL; int reclen = -1; BTH_SET_SERVICE *si = NULL; int silen = -1; ULONG sdpVersion = BTH_SDP_VERSION; BLOB blob = { 0 }; int status = -1; PyObject *result = NULL; HANDLE rh = 0; if(!PyArg_ParseTuple(args, "s#i|i", &record, &reclen, &advertise, &rh)) return 0; silen = sizeof(BTH_SET_SERVICE) + reclen - 1; si = (BTH_SET_SERVICE*) malloc(silen); ZeroMemory( si, silen ); si->pSdpVersion = &sdpVersion; si->pRecordHandle = &rh; si->fCodService = 0; si->Reserved; si->ulRecordLength = reclen; memcpy( si->pRecord, record, reclen ); op = advertise ? RNRSERVICE_REGISTER : RNRSERVICE_DELETE; qs.dwSize = sizeof(qs); qs.lpBlob = &blob; qs.dwNameSpace = NS_BTH; blob.cbSize = silen; blob.pBlobData = (BYTE*)si; status = WSASetService( &qs, op, 0 ); free( si ); if( SOCKET_ERROR == status ) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } return PyInt_FromLong( (unsigned long) rh ); } PyDoc_STRVAR(msbt_set_service_raw_doc, ""); static PyObject * msbt_set_service(PyObject *self, PyObject *args) { int advertise = 0; WSAQUERYSET qs = { 0 }; WSAESETSERVICEOP op; SOCKADDR_BTH sa = { 0 }; int sa_len = sizeof(sa); char *service_name = NULL; char *service_desc = NULL; char *service_class_id_str = NULL; CSADDR_INFO sockInfo = { 0 }; GUID uuid = { 0 }; int sockfd; if(!PyArg_ParseTuple(args, "iisss", &sockfd, &advertise, &service_name, &service_desc, &service_class_id_str)) return 0; op = advertise ? RNRSERVICE_REGISTER : RNRSERVICE_DELETE; if( SOCKET_ERROR == getsockname( sockfd, (SOCKADDR*) &sa, &sa_len ) ) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } sockInfo.iProtocol = BTHPROTO_RFCOMM; sockInfo.iSocketType = SOCK_STREAM; sockInfo.LocalAddr.lpSockaddr = (LPSOCKADDR) &sa; sockInfo.LocalAddr.iSockaddrLength = sizeof(sa); sockInfo.RemoteAddr.lpSockaddr = (LPSOCKADDR) &sa; sockInfo.RemoteAddr.iSockaddrLength = sizeof(sa); qs.dwSize = sizeof(qs); qs.dwNameSpace = NS_BTH; qs.lpcsaBuffer = &sockInfo; qs.lpszServiceInstanceName = service_name; qs.lpszComment = service_desc; str2uuid( service_class_id_str, &uuid ); qs.lpServiceClassId = (LPGUID) &uuid; qs.dwNumberOfCsAddrs = 1; if( SOCKET_ERROR == WSASetService( &qs, op, 0 ) ) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } Py_RETURN_NONE; } PyDoc_STRVAR(msbt_set_service_doc, ""); static PyObject * msbt_setblocking(PyObject *self, PyObject *args) { int sockfd = -1; int block = -1; if(!PyArg_ParseTuple(args, "ii", &sockfd, &block)) return 0; block = !block; //set zero to non-zero and non-zero to zero ioctlsocket( sockfd, FIONBIO, &block); Py_RETURN_NONE; } PyDoc_STRVAR(msbt_setblocking_doc, ""); static PyObject * msbt_settimeout(PyObject *self, PyObject *args) { int sockfd = -1; double secondTimeout = -1; DWORD timeout = -1; int timeoutLen = sizeof(DWORD); if(!PyArg_ParseTuple(args, "id", &sockfd, &secondTimeout)) return 0; timeout = (DWORD) (secondTimeout * 1000); if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, timeoutLen) != 0) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } if(setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, timeoutLen) != 0) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } Py_RETURN_NONE; } PyDoc_STRVAR(msbt_settimeout_doc, ""); static PyObject * msbt_gettimeout(PyObject *self, PyObject *args) { int sockfd = -1; DWORD recv_timeout = -1; int recv_timeoutLen = sizeof(DWORD); double timeout = -1; if(!PyArg_ParseTuple(args, "i", &sockfd)) return 0; if(getsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&recv_timeout, &recv_timeoutLen) != 0) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } timeout = (double)recv_timeout / 1000; return PyFloat_FromDouble(timeout); } PyDoc_STRVAR(msbt_gettimeout_doc, ""); /* s.setsockopt() method. With an integer third argument, sets an integer option. With a string third argument, sets an option from a buffer; use optional built-in module 'struct' to encode the string. */ static PyObject * msbt_setsockopt(PyObject *s, PyObject *args) { int sockfd = -1; int level; ULONG optname; int res; ULONG flag; if (!PyArg_ParseTuple(args, "iiIi:setsockopt", &sockfd, &level, &optname, &flag)) { return 0; } res = setsockopt(sockfd, level, optname, (char*) &flag, sizeof(ULONG)); if (res < 0) { Err_SetFromWSALastError(PyExc_IOError); return 0; } Py_RETURN_NONE; } PyDoc_STRVAR(msbt_setsockopt_doc, "setsockopt(level, option, value)\n\ \n\ Set a socket option. See the Unix manual for level and option.\n\ The value argument can either be an integer or a string."); /* s.getsockopt() method. With two arguments, retrieves an integer option. With a third integer argument, retrieves a string buffer of that size; use optional built-in module 'struct' to decode the string. */ static PyObject * msbt_getsockopt(PyObject *s, PyObject *args) { int sockfd = -1; int level; ULONG optname; int res; ULONG flag; int flagsize = sizeof flag; if (!PyArg_ParseTuple(args, "iiI", &sockfd, &level, &optname)) return 0; res = getsockopt(sockfd, level, optname, (void *) &flag, &flagsize); if (res < 0) { Err_SetFromWSALastError(PyExc_IOError); return 0; } return PyInt_FromLong(flag); } PyDoc_STRVAR(msbt_getsockopt_doc, "getsockopt(level, option[, buffersize]) -> value\n\ \n\ Get a socket option. See the Unix manual for level and option.\n\ If a nonzero buffersize argument is given, the return value is a\n\ string of that length; otherwise it is an integer."); // ======================= ADMINISTRATIVE ========================= static PyMethodDef msbt_methods[] = { { "initwinsock", (PyCFunction)msbt_initwinsock, METH_NOARGS, msbt_initwinsock_doc }, { "socket", (PyCFunction)msbt_socket, METH_VARARGS, msbt_socket_doc }, { "bind", (PyCFunction)msbt_bind, METH_VARARGS, msbt_bind_doc }, { "listen", (PyCFunction)msbt_listen, METH_VARARGS, msbt_listen_doc }, { "accept", (PyCFunction)msbt_accept, METH_VARARGS, msbt_accept_doc }, { "connect", (PyCFunction)msbt_connect, METH_VARARGS, msbt_connect_doc }, { "send", (PyCFunction)msbt_send, METH_VARARGS, msbt_send_doc }, { "recv", (PyCFunction)msbt_recv, METH_VARARGS, msbt_recv_doc }, { "close", (PyCFunction)msbt_close, METH_VARARGS, msbt_close_doc }, { "getsockname", (PyCFunction)msbt_getsockname, METH_VARARGS, msbt_getsockname_doc }, { "dup", (PyCFunction)msbt_dup, METH_VARARGS, msbt_dup_doc }, { "discover_devices", (PyCFunction)msbt_discover_devices, METH_VARARGS | METH_KEYWORDS, msbt_discover_devices_doc }, { "lookup_name", (PyCFunction)msbt_lookup_name, METH_VARARGS, msbt_lookup_name_doc }, { "find_service", (PyCFunction)msbt_find_service, METH_VARARGS, msbt_find_service_doc }, { "set_service", (PyCFunction)msbt_set_service, METH_VARARGS, msbt_set_service_doc }, { "set_service_raw", (PyCFunction)msbt_set_service_raw, METH_VARARGS, msbt_set_service_raw_doc }, { "setblocking", (PyCFunction)msbt_setblocking, METH_VARARGS, msbt_setblocking_doc }, { "settimeout", (PyCFunction)msbt_settimeout, METH_VARARGS, msbt_settimeout_doc }, { "gettimeout", (PyCFunction)msbt_gettimeout, METH_VARARGS, msbt_gettimeout_doc }, { "setsockopt", (PyCFunction)msbt_setsockopt, METH_VARARGS, msbt_setsockopt_doc }, { "getsockopt", (PyCFunction)msbt_getsockopt, METH_VARARGS, msbt_getsockopt_doc }, { NULL, NULL } }; PyDoc_STRVAR(msbt_doc, "TODO\n"); #define ADD_INT_CONSTANT(m,a) PyModule_AddIntConstant(m, #a, a) #if PY_MAJOR_VERSION < 3 PyMODINIT_FUNC init_msbt(void) { PyObject * m = Py_InitModule3("_msbt", msbt_methods, msbt_doc); #else PyMODINIT_FUNC PyInit__msbt(void) { PyObject *m; static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_msbt", NULL, -1, msbt_methods, NULL, NULL, NULL, NULL }; m = PyModule_Create(&moduledef); #endif ADD_INT_CONSTANT(m, SOCK_STREAM); ADD_INT_CONSTANT(m, BTHPROTO_RFCOMM); ADD_INT_CONSTANT(m, BT_PORT_ANY); ADD_INT_CONSTANT(m, SOL_RFCOMM); ADD_INT_CONSTANT(m, SO_BTH_AUTHENTICATE); ADD_INT_CONSTANT(m, SO_BTH_ENCRYPT); ADD_INT_CONSTANT(m, SO_BTH_MTU); ADD_INT_CONSTANT(m, SO_BTH_MTU_MAX); ADD_INT_CONSTANT(m, SO_BTH_MTU_MIN); #if PY_MAJOR_VERSION >= 3 return m; #endif } pybluez-0.22+really0.22/osx/000077500000000000000000000000001334611253700155335ustar00rootroot00000000000000pybluez-0.22+really0.22/osx/_osxbt.c000066400000000000000000000524771334611253700172140ustar00rootroot00000000000000#include #include #include //#include //#include //#include //#include //#include #include #include #if 0 // ====================== SOCKET FUNCTIONS ======================== static PyObject * osxbt_socket(PyObject *self, PyObject *args) { int family = AF_BTH; int type; int proto; int sockfd = -1; if(!PyArg_ParseTuple(args, "ii", &type, &proto)) return 0; Py_BEGIN_ALLOW_THREADS; sockfd = socket( AF_BTH, type, proto ); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( SOCKET_ERROR != sockfd ); return PyInt_FromLong( sockfd ); }; PyDoc_STRVAR(osxbt_socket_doc, "TODO"); static PyObject * osxbt_bind(PyObject *self, PyObject *args) { char *addrstr = NULL; int addrstrlen = -1; int sockfd = -1; int port = -1; char buf[100] = { 0 }; int buf_len = sizeof( buf ); int status; SOCKADDR_BTH sa = { 0 }; int sa_len = sizeof(sa); if(!PyArg_ParseTuple(args, "is#i", &sockfd, &addrstr, &addrstrlen, &port)) return 0; if( addrstrlen == 0 ) { sa.btAddr = 0; } else { _CHECK_OR_RAISE_WSA( NO_ERROR == WSAStringToAddress( addrstr, \ AF_BTH, NULL, (LPSOCKADDR)&sa, &sa_len ) ); } sa.addressFamily = AF_BTH; sa.port = port; Py_BEGIN_ALLOW_THREADS; status = bind( sockfd, (LPSOCKADDR)&sa, sa_len ); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( NO_ERROR == status ); Py_INCREF(Py_None); return Py_None; }; PyDoc_STRVAR(osxbt_bind_doc, "TODO"); static PyObject * osxbt_listen(PyObject *self, PyObject *args) { int sockfd = -1; int backlog = -1; DWORD status; if(!PyArg_ParseTuple(args, "ii", &sockfd, &backlog)) return 0; Py_BEGIN_ALLOW_THREADS; status = listen(sockfd, backlog); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( NO_ERROR == status ); Py_INCREF(Py_None); return Py_None; }; PyDoc_STRVAR(osxbt_listen_doc, "TODO"); static PyObject * osxbt_accept(PyObject *self, PyObject *args) { int sockfd = -1; int clientfd = -1; SOCKADDR_BTH ca = { 0 }; int ca_len = sizeof(ca); PyObject *result = NULL; char buf[100] = { 0 }; int buf_len = sizeof(buf); if(!PyArg_ParseTuple(args, "i", &sockfd)) return 0; Py_BEGIN_ALLOW_THREADS; clientfd = accept(sockfd, (LPSOCKADDR)&ca, &ca_len); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( SOCKET_ERROR != clientfd ); ba2str(ca.btAddr, buf); result = Py_BuildValue( "isi", clientfd, buf, ca.port ); return result; }; PyDoc_STRVAR(osxbt_accept_doc, "TODO"); static PyObject * osxbt_connect(PyObject *self, PyObject *args) { int sockfd = -1; char *addrstr = NULL; int port = -1; SOCKADDR_BTH sa = { 0 }; int sa_len = sizeof(sa); DWORD status; if(!PyArg_ParseTuple(args, "isi", &sockfd, &addrstr, &port)) return 0; if( SOCKET_ERROR == WSAStringToAddress( addrstr, AF_BTH, NULL, (LPSOCKADDR)&sa, &sa_len ) ) { Err_SetFromWSALastError(PyExc_IOError); return 0; } sa.addressFamily = AF_BTH; sa.port = port; Py_BEGIN_ALLOW_THREADS; status = connect(sockfd, (LPSOCKADDR)&sa, sizeof(sa)); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( NO_ERROR == status ); Py_INCREF(Py_None); return Py_None; }; PyDoc_STRVAR(osxbt_connect_doc, "TODO"); static PyObject * osxbt_send(PyObject *self, PyObject *args) { int sockfd = -1; char *data = NULL; int datalen = -1; int flags = 0; int sent = 0; if(!PyArg_ParseTuple(args, "is#|i", &sockfd, &data, &datalen, &flags)) return 0; Py_BEGIN_ALLOW_THREADS; sent = send(sockfd, data, datalen, flags); Py_END_ALLOW_THREADS; if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAETIMEDOUT ) { return PyInt_FromLong ( 0 ); } _CHECK_OR_RAISE_WSA( SOCKET_ERROR != sent ); return PyInt_FromLong( sent ); }; PyDoc_STRVAR(osxbt_send_doc, "TODO"); static PyObject * osxbt_recv(PyObject *self, PyObject *args) { int sockfd = -1; PyObject *buf = NULL; int datalen = -1; int flags = 0; int received = 0; if(!PyArg_ParseTuple(args, "ii|i", &sockfd, &datalen, &flags)) return 0; buf = PyString_FromStringAndSize((char*)0, datalen); Py_BEGIN_ALLOW_THREADS; received = recv(sockfd, PyString_AS_STRING(buf), datalen, flags); Py_END_ALLOW_THREADS; if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAETIMEDOUT ) { _PyString_Resize(&buf, 0); // XXX is this necessary? -albert return buf; } if( SOCKET_ERROR == received ){ Py_DECREF(buf); return 0; } if( received != datalen ) _PyString_Resize(&buf, received); return buf; }; PyDoc_STRVAR(osxbt_recv_doc, "TODO"); static PyObject * osxbt_close(PyObject *self, PyObject *args) { int sockfd = -1; int status; if(!PyArg_ParseTuple( args, "i", &sockfd )) return 0; Py_BEGIN_ALLOW_THREADS; status = closesocket(sockfd); Py_END_ALLOW_THREADS; Py_INCREF(Py_None); return Py_None; }; PyDoc_STRVAR(osxbt_close_doc, "TODO"); static PyObject * osxbt_getsockname(PyObject *self, PyObject *args) { int sockfd = -1; SOCKADDR_BTH sa = { 0 }; int sa_len = sizeof(sa); char buf[100] = { 0 }; int buf_len = sizeof(buf); int status; if(!PyArg_ParseTuple( args, "i", &sockfd )) return 0; sa.addressFamily = AF_BTH; Py_BEGIN_ALLOW_THREADS; status = getsockname( sockfd, (LPSOCKADDR)&sa, &sa_len ); Py_END_ALLOW_THREADS; _CHECK_OR_RAISE_WSA( NO_ERROR == status ); ba2str( sa.btAddr, buf ); return Py_BuildValue( "si", buf, sa.port ); }; PyDoc_STRVAR(osxbt_getsockname_doc, "TODO"); static PyObject * osxbt_dup(PyObject *self, PyObject *args) { int sockfd = -1; int newsockfd = -1; int status; DWORD pid; WSAPROTOCOL_INFO pi = { 0 }; if(!PyArg_ParseTuple( args, "i", &sockfd )) return 0; // prepare to duplicate pid = GetCurrentProcessId(); status = WSADuplicateSocket( sockfd, pid, &pi ); _CHECK_OR_RAISE_WSA( NO_ERROR == status ); // duplicate! newsockfd = WSASocket( FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &pi, 0, 0 ); _CHECK_OR_RAISE_WSA( INVALID_SOCKET != newsockfd ); return PyInt_FromLong( newsockfd ); } PyDoc_STRVAR(osxbt_dup_doc, "TODO"); // ==================== static PyObject * osxbt_lookup_name(PyObject *self, PyObject *args) { HANDLE rhandle = NULL; BLUETOOTH_FIND_RADIO_PARAMS p = { sizeof(p) }; HBLUETOOTH_RADIO_FIND fhandle = NULL; BLUETOOTH_DEVICE_INFO dinfo = { 0 }; char *addrstr = NULL; SOCKADDR_BTH sa = { 0 }; int sa_len = sizeof(sa); DWORD status; if(!PyArg_ParseTuple(args,"s",&addrstr)) return 0; _CHECK_OR_RAISE_WSA( NO_ERROR == WSAStringToAddress( addrstr, \ AF_BTH, NULL, (LPSOCKADDR)&sa, &sa_len ) ); // printf("looking for first radio\n"); fhandle = BluetoothFindFirstRadio(&p, &rhandle); _CHECK_OR_RAISE_WSA( NULL != fhandle ); // printf("found radio 0x%p\n", rhandle ); dinfo.dwSize = sizeof( dinfo ); dinfo.Address.ullLong = sa.btAddr; status = BluetoothGetDeviceInfo( rhandle, &dinfo ); _CHECK_OR_RAISE_WSA( status == ERROR_SUCCESS ); // printf("name: %s\n", dinfo.szName ); _CHECK_OR_RAISE_WSA( TRUE == BluetoothFindRadioClose( fhandle ) ); return PyUnicode_FromWideChar( dinfo.szName, wcslen( dinfo.szName ) ); } PyDoc_STRVAR(osxbt_lookup_name_doc, "TODO"); // ======================= SDP FUNCTIONS ====================== static PyObject * osxbt_find_service(PyObject *self, PyObject *args) { char *addrstr = NULL; char *uuidstr = NULL; // inquiry data structure DWORD qs_len = sizeof( WSAQUERYSET ); WSAQUERYSET *qs = (WSAQUERYSET*) malloc( qs_len ); DWORD flags = LUP_FLUSHCACHE | LUP_RETURN_ALL; HANDLE h; int done = 0; PyObject *record = NULL; PyObject *toreturn = NULL; GUID uuid = { 0 }; char localAddressBuf[20] = { 0 }; if(!PyArg_ParseTuple(args,"ss", &addrstr, &uuidstr)) return 0; ZeroMemory( qs, qs_len ); qs->dwSize = sizeof(WSAQUERYSET); qs->dwNameSpace = NS_BTH; qs->dwNumberOfCsAddrs = 0; qs->lpszContext = (LPSTR) localAddressBuf; if( 0 == strcmp( addrstr, "localhost" ) ) { // find the Bluetooth address of the first local adapter. #if 0 HANDLE rhandle = NULL; BLUETOOTH_RADIO_INFO info; BLUETOOTH_FIND_RADIO_PARAMS p = { sizeof(p) }; HBLUETOOTH_RADIO_FIND fhandle = NULL; printf("looking for first radio\n"); fhandle = BluetoothFindFirstRadio(&p, &rhandle); _CHECK_OR_RAISE_WSA( NULL != fhandle ); printf("first radio: 0x%p\n", rhandle); _CHECK_OR_RAISE_WSA( \ TRUE == BluetoothFindRadioClose( fhandle ) ); printf("retrieving radio info on handle 0x%p\n", rhandle); info.dwSize = sizeof(info); // XXX why doesn't this work??? _CHECK_OR_RAISE_WSA( \ ERROR_SUCCESS != BluetoothGetRadioInfo( rhandle, &info ) ); ba2str( info.address.ullLong, localAddressBuf ); #else // bind a temporary socket and get its Bluetooth address SOCKADDR_BTH sa = { 0 }; int sa_len = sizeof(sa); int tmpfd = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); _CHECK_OR_RAISE_WSA( tmpfd >= 0 ); sa.addressFamily = AF_BTH; sa.port = BT_PORT_ANY; _CHECK_OR_RAISE_WSA(NO_ERROR == bind(tmpfd,(LPSOCKADDR)&sa,sa_len) ); _CHECK_OR_RAISE_WSA(NO_ERROR == getsockname(tmpfd, (LPSOCKADDR)&sa,\ &sa_len ) ); ba2str(sa.btAddr, localAddressBuf ); close(tmpfd); #endif flags |= LUP_RES_SERVICE; } else { strcpy( localAddressBuf, addrstr ); } if( strlen(uuidstr) != 36 || uuidstr[8] != '-' || uuidstr[13] != '-' || uuidstr[18] != '-' || uuidstr[23] != '-' ) { PyErr_SetString( PyExc_ValueError, "Invalid UUID!"); return 0; } str2uuid( uuidstr, &uuid ); qs->lpServiceClassId = &uuid; if( SOCKET_ERROR == WSALookupServiceBegin( qs, flags, &h )) { int err_code = WSAGetLastError(); if( WSASERVICE_NOT_FOUND == err_code ) { // this device does not advertise any services. return an // empty list free( qs ); return PyList_New(0); } else { // unexpected error. raise an exception Err_SetFromWSALastError( PyExc_IOError ); free(qs); return 0; } } toreturn = PyList_New(0); // iterate through the inquiry results while(! done) { if( NO_ERROR == WSALookupServiceNext( h, flags, &qs_len, qs )) { int proto; int port; PyObject *rawrecord = NULL; CSADDR_INFO *csinfo = NULL; record = PyDict_New(); // set host name dict_set_strings( record, "host", localAddressBuf ); // set service name dict_set_strings( record, "name", qs->lpszServiceInstanceName ); // set description dict_set_strings( record, "description", qs->lpszComment ); // set protocol and port csinfo = qs->lpcsaBuffer; if( csinfo != NULL ) { proto = csinfo->iProtocol; port = ((SOCKADDR_BTH*)csinfo->RemoteAddr.lpSockaddr)->port; dict_set_str_long(record, "port", port); if( proto == BTHPROTO_RFCOMM ) { dict_set_strings(record, "protocol", "RFCOMM"); } else if( proto == BTHPROTO_L2CAP ) { dict_set_strings(record, "protocol", "L2CAP"); } else { dict_set_strings(record, "protocol", "UNKNOWN"); dict_set_str_pyobj(record, "port", Py_None); } } else { dict_set_str_pyobj(record, "port", Py_None); dict_set_strings(record, "protocol", "UNKNOWN"); } // add the raw service record to be parsed in python rawrecord = PyString_FromStringAndSize( qs->lpBlob->pBlobData, qs->lpBlob->cbSize ); dict_set_str_pyobj(record, "rawrecord", rawrecord); Py_DECREF(rawrecord); PyList_Append( toreturn, record ); Py_DECREF( record ); } else { int error = WSAGetLastError(); if( error == WSAEFAULT ) { // the qs data structure is too small. allocate a bigger // buffer and try again. free( qs ); qs = (WSAQUERYSET*) malloc( qs_len ); } else if( error == WSA_E_NO_MORE ) { // no more results. done = 1; } else { // unexpected error. raise an exception. Err_SetFromWSALastError( PyExc_IOError ); Py_DECREF( toreturn ); return 0; } } } WSALookupServiceEnd( h ); free( qs ); return toreturn; } PyDoc_STRVAR(osxbt_find_service_doc, "TODO"); static PyObject * osxbt_set_service_raw(PyObject *self, PyObject *args) { int advertise = 0; WSAQUERYSET qs = { 0 }; WSAESETSERVICEOP op; char *record = NULL; int reclen = -1; BTH_SET_SERVICE *si = NULL; int silen = -1; ULONG sdpVersion = BTH_SDP_VERSION; BLOB blob = { 0 }; int status = -1; PyObject *result = NULL; HANDLE rh = 0; if(!PyArg_ParseTuple(args, "s#i|i", &record, &reclen, &advertise, &rh)) return 0; silen = sizeof(BTH_SET_SERVICE) + reclen - 1; si = (BTH_SET_SERVICE*) malloc(silen); ZeroMemory( si, silen ); si->pSdpVersion = &sdpVersion; si->pRecordHandle = &rh; si->fCodService = 0; si->Reserved; si->ulRecordLength = reclen; memcpy( si->pRecord, record, reclen ); op = advertise ? RNRSERVICE_REGISTER : RNRSERVICE_DELETE; qs.dwSize = sizeof(qs); qs.lpBlob = &blob; qs.dwNameSpace = NS_BTH; blob.cbSize = silen; blob.pBlobData = (BYTE*)si; status = WSASetService( &qs, op, 0 ); free( si ); if( SOCKET_ERROR == status ) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } return PyInt_FromLong( (unsigned long) rh ); } PyDoc_STRVAR(osxbt_set_service_raw_doc, ""); static PyObject * osxbt_set_service(PyObject *self, PyObject *args) { int advertise = 0; WSAQUERYSET qs = { 0 }; WSAESETSERVICEOP op; SOCKADDR_BTH sa = { 0 }; int sa_len = sizeof(sa); char *service_name = NULL; char *service_desc = NULL; char *service_class_id_str = NULL; CSADDR_INFO sockInfo = { 0 }; GUID uuid = { 0 }; int sockfd; if(!PyArg_ParseTuple(args, "iisss", &sockfd, &advertise, &service_name, &service_desc, &service_class_id_str)) return 0; op = advertise ? RNRSERVICE_REGISTER : RNRSERVICE_DELETE; if( SOCKET_ERROR == getsockname( sockfd, (SOCKADDR*) &sa, &sa_len ) ) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } sockInfo.iProtocol = BTHPROTO_RFCOMM; sockInfo.iSocketType = SOCK_STREAM; sockInfo.LocalAddr.lpSockaddr = (LPSOCKADDR) &sa; sockInfo.LocalAddr.iSockaddrLength = sizeof(sa); sockInfo.RemoteAddr.lpSockaddr = (LPSOCKADDR) &sa; sockInfo.RemoteAddr.iSockaddrLength = sizeof(sa); qs.dwSize = sizeof(qs); qs.dwNameSpace = NS_BTH; qs.lpcsaBuffer = &sockInfo; qs.lpszServiceInstanceName = service_name; qs.lpszComment = service_desc; str2uuid( service_class_id_str, &uuid ); qs.lpServiceClassId = (LPGUID) &uuid; qs.dwNumberOfCsAddrs = 1; if( SOCKET_ERROR == WSASetService( &qs, op, 0 ) ) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } Py_INCREF( Py_None ); return Py_None; } PyDoc_STRVAR(osxbt_set_service_doc, ""); static PyObject * osxbt_setblocking(PyObject *self, PyObject *args) { int sockfd = -1; int block = -1; PyObject* blockingArg; if(!PyArg_ParseTuple(args, "iO", &sockfd, &blockingArg)) return 0; block = PyInt_AsLong(blockingArg); if (block == -1 && PyErr_Occurred()) return NULL; if (block) { block = 0; ioctlsocket( sockfd, FIONBIO, &block); } else { block = 1; ioctlsocket( sockfd, FIONBIO, &block); } Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(osxbt_setblocking_doc, ""); static PyObject * osxbt_settimeout(PyObject *self, PyObject *args) { int sockfd = -1; double secondTimeout = -1; DWORD timeout = -1; int timeoutLen = sizeof(DWORD); if(!PyArg_ParseTuple(args, "id", &sockfd, &secondTimeout)) return 0; timeout = (DWORD) (secondTimeout * 1000); if(setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, timeoutLen) != 0) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } if(setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, timeoutLen) != 0) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(osxbt_settimeout_doc, ""); static PyObject * osxbt_gettimeout(PyObject *self, PyObject *args) { int sockfd = -1; DWORD recv_timeout = -1; int recv_timeoutLen = sizeof(DWORD); double timeout = -1; if(!PyArg_ParseTuple(args, "i", &sockfd)) return 0; if(getsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char*)&recv_timeout, &recv_timeoutLen) != 0) { Err_SetFromWSALastError( PyExc_IOError ); return 0; } timeout = (double)recv_timeout / 1000; return PyFloat_FromDouble(timeout); } PyDoc_STRVAR(osxbt_gettimeout_doc, ""); #endif typedef struct _discover_data { PyObject *results; IOBluetoothDeviceInquiryRef inquiry; } discover_data_t; static void timer_test (CFRunLoopTimerRef timer, void *info) { printf ("smack\n"); CFRunLoopRef runloop = CFRunLoopGetCurrent (); CFRunLoopStop (runloop); } static void on_inquiry_complete( void *user_data, IOBluetoothDeviceInquiryRef inquiryRef, IOReturn error, Boolean aborted ) { printf ("inquiry complete\n"); CFRunLoopRef runloop = CFRunLoopGetCurrent (); CFRunLoopStop (runloop); } static void * discover_thread (void *user_data) { printf ("discover thread!\n"); discover_data_t *dd = (discover_data_t*) user_data; dd->inquiry = IOBluetoothDeviceInquiryCreateWithCallbackRefCon (&dd); IOBluetoothDeviceInquirySetCompleteCallback (dd->inquiry, on_inquiry_complete); CFRunLoopRef runloop = CFRunLoopGetCurrent(); CFAbsoluteTime now = CFAbsoluteTimeGetCurrent(); CFRunLoopTimerRef timer = CFRunLoopTimerCreate (NULL, now, 20, 0, 0, timer_test, NULL); CFRunLoopAddTimer (runloop, timer, kCFRunLoopCommonModes); IOBluetoothDeviceInquiryStart (dd->inquiry); CFRunLoopRun (); IOBluetoothDeviceInquiryDelete (dd->inquiry); return NULL; } static PyObject * osxbt_discover_devices(PyObject *self, PyObject *args) { PyObject * toreturn = PyList_New(0); discover_data_t dd; dd.results = toreturn; pthread_t tid; pthread_create (&tid, NULL, discover_thread, &dd); void *thread_status = NULL; pthread_join (tid, &thread_status); return toreturn; } PyDoc_STRVAR(osxbt_discover_devices_doc, "TODO"); // ======================= ADMINISTRATIVE ========================= static PyMethodDef osxbt_methods[] = { // { "socket", (PyCFunction)osxbt_socket, METH_VARARGS, osxbt_socket_doc }, // { "bind", (PyCFunction)osxbt_bind, METH_VARARGS, osxbt_bind_doc }, // { "listen", (PyCFunction)osxbt_listen, METH_VARARGS, osxbt_listen_doc }, // { "accept", (PyCFunction)osxbt_accept, METH_VARARGS, osxbt_accept_doc }, // { "connect", (PyCFunction)osxbt_connect, METH_VARARGS, osxbt_connect_doc }, // { "send", (PyCFunction)osxbt_send, METH_VARARGS, osxbt_send_doc }, // { "recv", (PyCFunction)osxbt_recv, METH_VARARGS, osxbt_recv_doc }, // { "close", (PyCFunction)osxbt_close, METH_VARARGS, osxbt_close_doc }, // { "getsockname", (PyCFunction)osxbt_getsockname, METH_VARARGS, // osxbt_getsockname_doc }, // { "dup", (PyCFunction)osxbt_dup, METH_VARARGS, osxbt_dup_doc }, { "discover_devices", (PyCFunction)osxbt_discover_devices, METH_VARARGS, osxbt_discover_devices_doc }, // { "lookup_name", (PyCFunction)osxbt_lookup_name, METH_VARARGS, osxbt_lookup_name_doc }, // { "find_service", (PyCFunction)osxbt_find_service, METH_VARARGS, osxbt_find_service_doc }, // { "set_service", (PyCFunction)osxbt_set_service, METH_VARARGS, osxbt_set_service_doc }, // { "set_service_raw", (PyCFunction)osxbt_set_service_raw, METH_VARARGS, osxbt_set_service_raw_doc }, // { "setblocking", (PyCFunction)osxbt_setblocking, METH_VARARGS, osxbt_setblocking_doc }, // { "settimeout", (PyCFunction)osxbt_settimeout, METH_VARARGS, osxbt_settimeout_doc }, // { "gettimeout", (PyCFunction)osxbt_gettimeout, METH_VARARGS, osxbt_gettimeout_doc }, { NULL, NULL } }; PyDoc_STRVAR(osxbt_doc, "TODO\n"); PyMODINIT_FUNC init_osxbt(void) { PyObject *m; m = Py_InitModule3("_osxbt", osxbt_methods, osxbt_doc); //#define ADD_INT_CONSTANT(m,a) PyModule_AddIntConstant(m, #a, a) // // ADD_INT_CONSTANT(m, SOCK_STREAM); // ADD_INT_CONSTANT(m, BTHPROTO_RFCOMM); // ADD_INT_CONSTANT(m, BT_PORT_ANY); } pybluez-0.22+really0.22/port3/000077500000000000000000000000001334611253700157715ustar00rootroot00000000000000pybluez-0.22+really0.22/port3/port3.h000066400000000000000000000011471334611253700172140ustar00rootroot00000000000000 #if PY_MAJOR_VERSION >= 3 #define PyInt_FromLong PyLong_FromLong #define PyString_FromString PyUnicode_FromString #define PyString_FromStringAndSize PyBytes_FromStringAndSize #define _PyString_Resize _PyBytes_Resize #define PyString_AS_STRING PyBytes_AS_STRING #define PyInt_AsLong PyLong_AsLong #define PyString_AsString PyBytes_AsString #define PyInt_Check PyLong_Check #define PyInt_AS_LONG PyLong_AS_LONG #define BYTES_FORMAT_CHR "y#" #else #ifndef Py_TYPE #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) #endif #define BYTES_FORMAT_CHR "s#" #endif pybluez-0.22+really0.22/release_checklist000066400000000000000000000004711334611253700203200ustar00rootroot000000000000001. update CHANGELOG 2. bump version number in setup.py and in __init__.py 3. check out a clean copy of the repository git clone https://github.com/karulis/pybluez.git 3. run python setup.py sdist 4. test installer 5. tag git repo with new release X.XX 6. upload release to https://pypi.python.org/pypi/PyBluez pybluez-0.22+really0.22/setup.py000066400000000000000000000101501334611253700164310ustar00rootroot00000000000000#!/usr/bin/env python from setuptools import setup, Extension import sys import platform import os mods = list() def find_MS_SDK(): candidate_roots = (os.getenv('ProgramFiles'), os.getenv('ProgramW6432'), os.getenv('ProgramFiles(x86)')) if sys.version < '3.3': MS_SDK = r'Microsoft SDKs\Windows\v6.0A' # Visual Studio 9 else: MS_SDK = r'Microsoft SDKs\Windows\v7.0A' # Visual Studio 10 candidate_paths = (MS_SDK, 'Microsoft Platform SDK for Windows XP', 'Microsoft Platform SDK') for candidate_root in candidate_roots: for candidate_path in candidate_paths: candidate_sdk = os.path.join(candidate_root, candidate_path) if os.path.exists(candidate_sdk): return candidate_sdk if sys.platform == 'win32': PSDK_PATH = find_MS_SDK() if PSDK_PATH is None: raise SystemExit("Could not find the Windows Platform SDK") lib_path = os.path.join(PSDK_PATH, 'Lib') if '64' in platform.architecture()[0]: lib_path = os.path.join(lib_path, 'x64') mods.append(Extension('bluetooth._msbt', include_dirs=["%s\\Include" % PSDK_PATH, ".\\port3"], library_dirs=[lib_path], libraries=["WS2_32", "Irprops"], sources=['msbt\\_msbt.c'])) # widcomm WC_BASE = os.path.join(os.getenv('ProgramFiles'), r"Widcomm\BTW DK\SDK") if os.path.exists(WC_BASE): mods.append(Extension('bluetooth._widcomm', include_dirs=["%s\\Inc" % WC_BASE, ".\\port3"], define_macros=[('_BTWLIB', None)], library_dirs=["%s\\Release" % WC_BASE, "%s\\Lib" % PSDK_PATH], libraries=["WidcommSdklib", "ws2_32", "version", "user32", "Advapi32", "Winspool", "ole32", "oleaut32"], sources=["widcomm\\_widcomm.cpp", "widcomm\\inquirer.cpp", "widcomm\\rfcommport.cpp", "widcomm\\rfcommif.cpp", "widcomm\\l2capconn.cpp", "widcomm\\l2capif.cpp", "widcomm\\sdpservice.cpp", "widcomm\\util.cpp"])) elif sys.platform.startswith('linux'): mods.append(Extension('bluetooth._bluetooth', include_dirs=["./port3"], libraries=['bluetooth'], #extra_compile_args=['-O0'], sources=['bluez/btmodule.c', 'bluez/btsdp.c'])) elif sys.platform == 'darwin': mods.append(Extension('bluetooth._osxbt', include_dirs=["/System/Library/Frameworks/IOBluetooth.framework/Headers", "/System/Library/Frameworks/CoreFoundation.framework/Headers"], extra_link_args=['-framework IOBluetooth -framework CoreFoundation'], sources=['osx/_osxbt.c'])) else: raise Exception("This platform (%s) is currently not supported by pybluez." % sys.platform) setup(name='PyBluez', version='0.22', description='Bluetooth Python extension module', author="Albert Huang", author_email="ashuang@alum.mit.edu", url="http://karulis.github.io/pybluez/", ext_modules=mods, packages=["bluetooth"], # for the python cheese shop classifiers=['Development Status :: 4 - Beta', 'License :: OSI Approved :: GNU General Public License (GPL)', 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 3', 'Topic :: Communications'], download_url='https://github.com/karulis/pybluez', long_description='Bluetooth Python extension module to allow Python "\ "developers to use system Bluetooth resources. PyBluez works "\ "with GNU/Linux and Windows XP.', maintainer='Piotr Karulis', license='GPL', extras_require={'ble': ['gattlib==0.20150805']}) pybluez-0.22+really0.22/widcomm/000077500000000000000000000000001334611253700163615ustar00rootroot00000000000000pybluez-0.22+really0.22/widcomm/_widcomm.cpp000066400000000000000000000166131334611253700206720ustar00rootroot00000000000000#include #ifndef _BTWLIB #error "_BTWLIB is not defined" #endif #include #include #include #include #include "inquirer.hpp" #include "rfcommport.hpp" #include "l2capconn.hpp" extern PyTypeObject wcinquirer_type; extern PyTypeObject wcrfcommport_type; extern PyTypeObject wcrfcommif_type; extern PyTypeObject wcl2capif_type; extern PyTypeObject wcl2capconn_type; extern PyTypeObject wcsdpservice_type; static PyMethodDef widcomm_methods[] = { { NULL, NULL } }; extern "C" { #if PY_MAJOR_VERSION < 3 PyMODINIT_FUNC init_widcomm(void) { PyObject *m; wcinquirer_type.ob_type = &PyType_Type; wcrfcommport_type.ob_type = &PyType_Type; wcrfcommif_type.ob_type = &PyType_Type; wcl2capif_type.ob_type = &PyType_Type; wcl2capconn_type.ob_type = &PyType_Type; wcsdpservice_type.ob_type = &PyType_Type; m = Py_InitModule("_widcomm", widcomm_methods); // inquirer Py_INCREF((PyObject *)&wcinquirer_type); if (PyModule_AddObject(m, "_WCInquirer", (PyObject *)&wcinquirer_type) != 0) { return; } // rfcomm port Py_INCREF((PyObject *)&wcrfcommport_type); if (PyModule_AddObject(m, "_WCRfCommPort", (PyObject *)&wcrfcommport_type) != 0) { return; } // rfcomm if Py_INCREF((PyObject *)&wcrfcommif_type); if (PyModule_AddObject(m, "_WCRfCommIf", (PyObject *)&wcrfcommif_type) != 0) { return; } // l2cap if Py_INCREF((PyObject *)&wcl2capif_type); if (PyModule_AddObject(m, "_WCL2CapIf", (PyObject *)&wcl2capif_type) != 0) { return; } // l2cap conn Py_INCREF((PyObject *)&wcl2capconn_type); if (PyModule_AddObject(m, "_WCL2CapConn", (PyObject *)&wcl2capconn_type) != 0) { return; } // sdp service advertisement Py_INCREF((PyObject *)&wcsdpservice_type); if (PyModule_AddObject(m, "_WCSdpService", (PyObject *)&wcsdpservice_type) != 0) { return; } #else PyMODINIT_FUNC PyInit__widcomm(void) { PyObject *m; Py_TYPE(&wcinquirer_type) = &PyType_Type; Py_TYPE(&wcrfcommport_type) = &PyType_Type; Py_TYPE(&wcrfcommif_type) = &PyType_Type; Py_TYPE(&wcl2capif_type) = &PyType_Type; Py_TYPE(&wcl2capconn_type) = &PyType_Type; Py_TYPE(&wcsdpservice_type) = &PyType_Type; //m = Py_InitModule("_widcomm", widcomm_methods); static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "_widcomm", NULL, -1, widcomm_methods, NULL, NULL, NULL, NULL }; m = PyModule_Create(&moduledef); // inquirer Py_INCREF((PyObject *)&wcinquirer_type); if (PyModule_AddObject(m, "_WCInquirer", (PyObject *)&wcinquirer_type) != 0) { return NULL; } // rfcomm port Py_INCREF((PyObject *)&wcrfcommport_type); if (PyModule_AddObject(m, "_WCRfCommPort", (PyObject *)&wcrfcommport_type) != 0) { return NULL; } // rfcomm if Py_INCREF((PyObject *)&wcrfcommif_type); if (PyModule_AddObject(m, "_WCRfCommIf", (PyObject *)&wcrfcommif_type) != 0) { return NULL; } // l2cap if Py_INCREF((PyObject *)&wcl2capif_type); if (PyModule_AddObject(m, "_WCL2CapIf", (PyObject *)&wcl2capif_type) != 0) { return NULL; } // l2cap conn Py_INCREF((PyObject *)&wcl2capconn_type); if (PyModule_AddObject(m, "_WCL2CapConn", (PyObject *)&wcl2capconn_type) != 0) { return NULL; } // sdp service advertisement Py_INCREF((PyObject *)&wcsdpservice_type); if (PyModule_AddObject(m, "_WCSdpService", (PyObject *)&wcsdpservice_type) != 0) { return NULL; } #endif #define ADD_INT_CONST(m, a) PyModule_AddIntConstant(m, #a, a) ADD_INT_CONST(m, RFCOMM_DEFAULT_MTU); // CRfCommPort::PORT_RETURN_CODE enum PyModule_AddIntConstant(m, "RFCOMM_SUCCESS", CRfCommPort::SUCCESS); PyModule_AddIntConstant(m, "RFCOMM_ALREADY_OPENED", CRfCommPort::ALREADY_OPENED); PyModule_AddIntConstant(m, "RFCOMM_NOT_OPENED", CRfCommPort::NOT_OPENED); PyModule_AddIntConstant(m, "RFCOMM_HANDLE_ERROR", CRfCommPort::HANDLE_ERROR); PyModule_AddIntConstant(m, "RFCOMM_LINE_ERR", CRfCommPort::LINE_ERR); PyModule_AddIntConstant(m, "RFCOMM_START_FAILED", CRfCommPort::START_FAILED); PyModule_AddIntConstant(m, "RFCOMM_PAR_NEG_FAILED", CRfCommPort::PAR_NEG_FAILED); PyModule_AddIntConstant(m, "RFCOMM_PORT_NEG_FAILED", CRfCommPort::PORT_NEG_FAILED); PyModule_AddIntConstant(m, "RFCOMM_PEER_CONNECTION_FAILED", CRfCommPort::PEER_CONNECTION_FAILED); PyModule_AddIntConstant(m, "RFCOMM_PEER_TIMEOUT", CRfCommPort::PEER_TIMEOUT); PyModule_AddIntConstant(m, "RFCOMM_INVALID_PARAMETER", CRfCommPort::INVALID_PARAMETER); PyModule_AddIntConstant(m, "RFCOMM_UNKNOWN_ERROR", CRfCommPort::UNKNOWN_ERROR); ADD_INT_CONST (m, PORT_EV_RXFLAG); ADD_INT_CONST (m, PORT_EV_TXEMPTY); ADD_INT_CONST (m, PORT_EV_CTS); ADD_INT_CONST (m, PORT_EV_DSR); ADD_INT_CONST (m, PORT_EV_RLSD); ADD_INT_CONST (m, PORT_EV_BREAK); ADD_INT_CONST (m, PORT_EV_ERR); ADD_INT_CONST (m, PORT_EV_RING); ADD_INT_CONST (m, PORT_EV_CTSS); ADD_INT_CONST (m, PORT_EV_DSRS); ADD_INT_CONST (m, PORT_EV_RLSDS); ADD_INT_CONST (m, PORT_EV_OVERRUN); ADD_INT_CONST (m, PORT_EV_TXCHAR); ADD_INT_CONST (m, PORT_EV_CONNECTED); ADD_INT_CONST (m, PORT_EV_CONNECT_ERR); ADD_INT_CONST (m, PORT_EV_FC); ADD_INT_CONST (m, PORT_EV_FCS); ADD_INT_CONST (m, BTM_SEC_NONE); ADD_INT_CONST (m, BTM_SEC_IN_AUTHORIZE); ADD_INT_CONST (m, BTM_SEC_IN_AUTHENTICATE); ADD_INT_CONST (m, BTM_SEC_IN_ENCRYPT); ADD_INT_CONST (m, BTM_SEC_OUT_AUTHORIZE); ADD_INT_CONST (m, BTM_SEC_OUT_AUTHENTICATE); ADD_INT_CONST (m, BTM_SEC_OUT_ENCRYPT); ADD_INT_CONST (m, BTM_SEC_BOND); PyModule_AddIntConstant(m, "INQ_DEVICE_RESPONDED", WCInquirer::DEVICE_RESPONDED); PyModule_AddIntConstant(m, "INQ_INQUIRY_COMPLETE", WCInquirer::INQUIRY_COMPLETE); PyModule_AddIntConstant(m, "INQ_DISCOVERY_COMPLETE", WCInquirer::DISCOVERY_COMPLETE); PyModule_AddIntConstant(m, "INQ_STACK_STATUS_CHANGE", WCInquirer::STACK_STATUS_CHAGE); PyModule_AddIntConstant(m, "RFCOMM_DATA_RECEIVED", WCRfCommPort::DATA_RECEIVED); PyModule_AddIntConstant(m, "RFCOMM_EVENT_RECEIVED", WCRfCommPort::EVENT_RECEIVED); PyModule_AddIntConstant(m, "L2CAP_DATA_RECEIVED", WCL2CapConn::DATA_RECEIVED); PyModule_AddIntConstant(m, "L2CAP_INCOMING_CONNECTION", WCL2CapConn::INCOMING_CONNECTION); PyModule_AddIntConstant(m, "L2CAP_REMOTE_DISCONNECTED", WCL2CapConn::REMOTE_DISCONNECTED); PyModule_AddIntConstant(m, "L2CAP_CONNECTED", WCL2CapConn::CONNECTED); ADD_INT_CONST (m, SDP_OK); ADD_INT_CONST (m, SDP_COULD_NOT_ADD_RECORD); ADD_INT_CONST (m, SDP_INVALID_RECORD); ADD_INT_CONST (m, SDP_INVALID_PARAMETERS); #if PY_MAJOR_VERSION >= 3 return m; #endif } } // extern "C" pybluez-0.22+really0.22/widcomm/inquirer.cpp000066400000000000000000000415151334611253700207310ustar00rootroot00000000000000#include #include #include #include #include #include "util.h" #include #include "inquirer.hpp" static inline void dbg (const char *fmt, ...) { return; va_list ap; va_start (ap, fmt); vfprintf (stderr, fmt, ap); va_end (ap); } static void dict_set_str_pyobj(PyObject *dict, const char *key, PyObject *valobj) { PyObject *keyobj; keyobj = PyString_FromString (key); PyDict_SetItem (dict, keyobj, valobj); Py_DECREF (keyobj); } static void dict_set_strings(PyObject *dict, const char *key, const char *val) { PyObject *keyobj, *valobj; keyobj = PyString_FromString (key); valobj = PyString_FromString (val); PyDict_SetItem (dict, keyobj, valobj); Py_DECREF (keyobj); Py_DECREF (valobj); } static void dict_set_str_long(PyObject *dict, const char *key, long val) { PyObject *keyobj, *valobj; keyobj = PyString_FromString (key); valobj = PyInt_FromLong(val); PyDict_SetItem (dict, keyobj, valobj); Py_DECREF (keyobj); Py_DECREF (valobj); } WCInquirer::WCInquirer (PyObject *wcinq) { this->wcinq = wcinq; this->serverfd = socket (AF_INET, SOCK_STREAM, 0); this->threadfd = socket (AF_INET, SOCK_STREAM, 0); int status = SOCKET_ERROR; struct sockaddr_in saddr = { 0, }; for (int i=0; i<10; i++) { this->sockport = 3000 + (unsigned short) (20000 * (rand () / (RAND_MAX + 1.0))); saddr.sin_family = AF_INET; saddr.sin_port = htons (this->sockport); saddr.sin_addr.s_addr = inet_addr ("127.0.0.1"); status = bind (this->serverfd, (struct sockaddr*) &saddr, sizeof (saddr)); if (0 == status) break; } assert (0 == status); // instruct server socket to accept one connection status = listen (this->serverfd, 1); // TODO error checking // // connect the client socket to the server socket // status = connect (this->threadfd, (struct sockaddr*) &saddr, // sizeof (saddr)); // // TODO error checking } WCInquirer::~WCInquirer () { closesocket (this->threadfd); } int WCInquirer::AcceptClient () { struct sockaddr_in useless; int useless_sz = sizeof (useless); this->threadfd = accept (this->serverfd, (struct sockaddr*)&useless, &useless_sz); if (this->threadfd >= 0) { // put sockets into nonblocking mode unsigned long nonblocking = 1; ioctlsocket (this->threadfd, FIONBIO, &nonblocking); closesocket (this->serverfd); return 0; } return -1; } #pragma pack(push) #pragma pack(1) typedef struct { int msg_type; unsigned char bda[6]; unsigned char devClass[3]; unsigned char bdName[248]; int bConnected; } device_responded_msg_t; void WCInquirer::OnDeviceResponded (BD_ADDR bda, DEV_CLASS devClass, BD_NAME bdName, BOOL bConnected) { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); device_responded_msg_t msg; memset (&msg, 0, sizeof (msg)); msg.msg_type = DEVICE_RESPONDED; memcpy (msg.bda, bda, BD_ADDR_LEN); memcpy (msg.devClass, devClass, sizeof (devClass)); memcpy (msg.bdName, bdName, strlen ((char*)bdName)); msg.bConnected = bConnected; send (this->threadfd, reinterpret_cast (&msg), sizeof (msg), 0); } typedef struct { int msg_type; int success; short num_responses; } inquiry_complete_msg_t; void WCInquirer::OnInquiryComplete (BOOL success, short num_responses) { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); inquiry_complete_msg_t msg; msg.msg_type = INQUIRY_COMPLETE; msg.success = success; msg.num_responses = num_responses; send (this->threadfd, reinterpret_cast (&msg), sizeof (msg), 0); } typedef struct { int msg_type; } discovery_complete_msg_t; void WCInquirer::OnDiscoveryComplete () { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); discovery_complete_msg_t msg; msg.msg_type = DISCOVERY_COMPLETE; send (this->threadfd, reinterpret_cast (&msg), sizeof (msg), 0); } typedef struct { int msg_type; CBtIf::STACK_STATUS new_status; } stack_status_change_msg_t; void WCInquirer::OnStackStatusChange (STACK_STATUS new_status) { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); stack_status_change_msg_t msg; msg.msg_type = STACK_STATUS_CHAGE; msg.new_status = new_status; send (this->threadfd, reinterpret_cast (&msg), sizeof (msg), 0); } #pragma pack(pop) // =================== typedef struct _WCInquirerPyObject WCInquirerPyObject; struct _WCInquirerPyObject { PyObject_HEAD WCInquirer *inq; int readfd; int writefd; }; PyDoc_STRVAR(wcinquirer_doc, "CBtIf wrapper"); extern PyTypeObject wcinquirer_type; static PyObject * get_sockport (PyObject *s) { WCInquirerPyObject *self = (WCInquirerPyObject*) s; return PyInt_FromLong (self->inq->GetSockPort ()); } static PyObject * accept_client (PyObject *s) { WCInquirerPyObject *self = (WCInquirerPyObject*) s; return PyInt_FromLong (self->inq->AcceptClient ()); } static PyObject * start_inquiry (PyObject *s) { WCInquirerPyObject *self = (WCInquirerPyObject*) s; BOOL success = TRUE; Py_BEGIN_ALLOW_THREADS success = self->inq->StartInquiry (); Py_END_ALLOW_THREADS if (success) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * start_discovery (PyObject *s, PyObject *args) { WCInquirerPyObject *self = (WCInquirerPyObject*) s; dbg ("%s:%d start_discovery\n", __FILE__, __LINE__); char *bdaddr_in = NULL; int bdaddr_in_len = 0; char *uuid_str = NULL; int uuid_str_len = 0; BD_ADDR bdaddr; if (!PyArg_ParseTuple (args, "s#|s#", &bdaddr_in, &bdaddr_in_len, &uuid_str, &uuid_str_len)) return 0; if (bdaddr_in_len != BD_ADDR_LEN) { PyErr_SetString (PyExc_ValueError, "invalid bdaddr"); return NULL; } memcpy (bdaddr, bdaddr_in, BD_ADDR_LEN); GUID uuid = { 0 }; GUID *puuid = NULL; if (uuid_str) { PyWidcomm::str2uuid (uuid_str, &uuid); puuid = &uuid; } BOOL result; Py_BEGIN_ALLOW_THREADS result = self->inq->StartDiscovery (bdaddr, puuid); Py_END_ALLOW_THREADS if (result) Py_RETURN_TRUE; else Py_RETURN_FALSE; } static PyObject * is_device_ready (PyObject *s) { WCInquirerPyObject *self = (WCInquirerPyObject*) s; dbg ("IsDeviceReady: %d\n", (self->inq->IsDeviceReady ())); if (self->inq->IsDeviceReady ()) Py_RETURN_TRUE; else Py_RETURN_FALSE; } static PyObject * is_stack_server_up (PyObject *s) { WCInquirerPyObject *self = (WCInquirerPyObject*) s; if (self->inq->IsStackServerUp ()) Py_RETURN_TRUE; else Py_RETURN_FALSE; } static PyObject * get_local_device_name (PyObject *s) { WCInquirerPyObject *self = (WCInquirerPyObject*) s; BD_NAME name; if (self->inq->GetLocalDeviceName (&name)) { return PyString_FromString ( (const char *)name); } else { Py_RETURN_NONE; } } static PyObject * get_local_device_version_info (PyObject *s) { WCInquirerPyObject *self = (WCInquirerPyObject*) s; Py_RETURN_NONE; // DEV_VER_INFO info; // BOOL success = self->inq->GetLocalDeviceVersionInfo (&info); // if (success) { // return Py_BuildValue ("s#BHBHH", // info.bd_addr, 6, // info.hci_version, // info.hci_revision, // info.lmp_version, // info.manufacturer, // info.lmp_sub_version); // } else { // Py_RETURN_NONE; // } } #define MAX_SDP_DISCOVERY_RECORDS 2000 static PyObject * read_discovery_records (PyObject *s, PyObject *args) { WCInquirerPyObject *self = (WCInquirerPyObject*) s; UINT8 *bdaddr_in = NULL; int bdaddr_in_len = 0; char *uuid_str = NULL; int uuid_str_len = 0; BD_ADDR bdaddr; if (!PyArg_ParseTuple (args, "s#|s#", &bdaddr_in, &bdaddr_in_len, &uuid_str, &uuid_str_len)) return 0; if (bdaddr_in_len != BD_ADDR_LEN) { PyErr_SetString (PyExc_ValueError, "invalid bdaddr"); return NULL; } memcpy (bdaddr, bdaddr_in, BD_ADDR_LEN); int nrecords = 0; CSdpDiscoveryRec *records = new CSdpDiscoveryRec[MAX_SDP_DISCOVERY_RECORDS]; if (uuid_str) { dbg ("filtering by uuid %s\n", uuid_str); GUID uuid = { 0 }; PyWidcomm::str2uuid (uuid_str, &uuid); nrecords = self->inq->ReadDiscoveryRecords (bdaddr, MAX_SDP_DISCOVERY_RECORDS, records, &uuid); } else { dbg ("no uuid specified.\n"); nrecords = self->inq->ReadDiscoveryRecords (bdaddr, MAX_SDP_DISCOVERY_RECORDS, records); dbg ("nrecords: %d\n", nrecords); } char bdaddr_str[18]; sprintf_s (bdaddr_str, sizeof(bdaddr_str), "%02X:%02X:%02X:%02X:%02X:%02X", bdaddr_in[0], bdaddr_in[1], bdaddr_in[2], bdaddr_in[3], bdaddr_in[4], bdaddr_in[5]); PyObject *result = PyList_New (nrecords); for (int i=0; i 0 && desc.elem[0].type == ATTR_TYPE_ARRAY) { dict_set_strings (dict, "description", (char*)desc.elem[0].val.array); } else { dict_set_strings (dict, "description", ""); } dict_set_strings (dict, "provider", ""); PyObject *profiles_list = PyList_New (0); dict_set_str_pyobj (dict, "profiles", profiles_list); Py_DECREF (profiles_list); dict_set_strings (dict, "service-id", ""); // service class list PyObject *uuid_list = PyList_New (0); // SDP_DISC_ATTTR_VAL service_classes; // if (records[i].FindAttribute (0x0001, &service_classes)) { // // printf ("service-classes: %d\n", desc.num_elem); // for (int j=0; jinq->GetLocalDeviceInfo (); if (result) { return Py_BuildValue ("s", self->inq->m_BdName); } else { Py_RETURN_NONE; } } static PyObject * get_btw_version_info (PyObject *s) { WCInquirerPyObject *self = (WCInquirerPyObject*) s; char buf[MAX_PATH]; BOOL result = self->inq->GetBTWVersionInfo (buf, MAX_PATH); if (result) { return PyString_FromString (buf); } else { Py_RETURN_NONE; } } static PyMethodDef wcinquirer_methods[] = { { "get_sockport", (PyCFunction) get_sockport, METH_NOARGS, "" }, { "accept_client", (PyCFunction) accept_client, METH_NOARGS, "" }, { "start_inquiry", (PyCFunction)start_inquiry, METH_NOARGS, "" }, { "start_discovery", (PyCFunction)start_discovery, METH_VARARGS, "" }, { "is_device_ready", (PyCFunction)is_device_ready, METH_NOARGS, "" }, { "is_stack_server_up", (PyCFunction)is_stack_server_up, METH_NOARGS, "" }, { "get_local_device_name", (PyCFunction)get_local_device_name, METH_NOARGS, "" }, { "get_local_device_version_info", (PyCFunction)get_local_device_version_info, METH_NOARGS, ""}, { "read_discovery_records", (PyCFunction)read_discovery_records, METH_VARARGS, "" }, { "get_remote_device_info", (PyCFunction)get_remote_device_info, METH_VARARGS, "" }, { "get_next_remote_device_info", (PyCFunction)get_next_remote_device_info, METH_VARARGS, "" }, { "get_local_device_address", (PyCFunction)get_local_device_address, METH_NOARGS, "" }, { "get_btw_version_info", (PyCFunction)get_btw_version_info, METH_NOARGS, "" }, { NULL, NULL } }; static PyObject * wcinquirer_repr(WCInquirerPyObject *s) { return PyString_FromString("_WCInquirer object"); } static PyObject * wcinquirer_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *newobj; newobj = type->tp_alloc(type, 0); if (newobj != NULL) { WCInquirerPyObject *self = (WCInquirerPyObject *)newobj; self->inq = NULL; } return newobj; } static void wcinquirer_dealloc(WCInquirerPyObject *self) { if (self->inq) { delete self->inq; self->inq = NULL; } Py_TYPE(self)->tp_free((PyObject*)self); } int wcinquirer_initobj(PyObject *s, PyObject *args, PyObject *kwds) { WCInquirerPyObject *self = (WCInquirerPyObject *)s; self->inq = new WCInquirer (s); return 0; } /* Type object for socket objects. */ PyTypeObject wcinquirer_type = { #if PY_MAJOR_VERSION < 3 PyObject_HEAD_INIT(0) /* Must fill in type value later */ 0, /* ob_size */ #else PyVarObject_HEAD_INIT(NULL, 0) /* Must fill in type value later */ #endif "_widcomm._WCInquirer", /* tp_name */ sizeof(WCInquirerPyObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)wcinquirer_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)wcinquirer_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ wcinquirer_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ wcinquirer_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ wcinquirer_initobj, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ wcinquirer_new, /* tp_new */ PyObject_Del, /* tp_free */ }; pybluez-0.22+really0.22/widcomm/inquirer.hpp000066400000000000000000000014601334611253700207310ustar00rootroot00000000000000#pragma once class WCInquirer : public CBtIf { public: enum { DEVICE_RESPONDED, INQUIRY_COMPLETE, DISCOVERY_COMPLETE, STACK_STATUS_CHAGE }; WCInquirer::WCInquirer (PyObject *wcinq); virtual ~WCInquirer (); int AcceptClient (); inline unsigned short GetSockPort () { return sockport; } private: void OnDeviceResponded (BD_ADDR bda, DEV_CLASS devClass, BD_NAME bdName, BOOL bConnected); void OnInquiryComplete (BOOL success, short num_responses); void OnDiscoveryComplete (); void OnStackStatusChange (STACK_STATUS new_status); PyObject * wcinq; SOCKET threadfd; SOCKET serverfd; unsigned short sockport; }; pybluez-0.22+really0.22/widcomm/l2capconn.cpp000066400000000000000000000270341334611253700207520ustar00rootroot00000000000000#include #include #include #include #include #include #include "l2capconn.hpp" #include "l2capif.hpp" static inline void dbg (const char *fmt, ...) { return; va_list ap; va_start (ap, fmt); vfprintf (stderr, fmt, ap); va_end (ap); } WCL2CapConn::WCL2CapConn (PyObject *pyobj) : CL2CapConn () { this->pyobj = pyobj; this->serverfd = socket (AF_INET, SOCK_STREAM, 0); this->threadfd = socket (AF_INET, SOCK_STREAM, 0); int status = SOCKET_ERROR; struct sockaddr_in saddr = { 0, }; for (int i=0; i<10; i++) { this->sockport = 3000 + (unsigned short) (20000 * (rand () / (RAND_MAX + 1.0))); saddr.sin_family = AF_INET; saddr.sin_port = htons (this->sockport); saddr.sin_addr.s_addr = inet_addr ("127.0.0.1"); status = bind (this->serverfd, (struct sockaddr*) &saddr, sizeof (saddr)); if (0 == status) break; } assert (0 == status); // instruct server socket to accept one connection status = listen (this->serverfd, 1); } WCL2CapConn::~WCL2CapConn () { closesocket (this->threadfd); } int WCL2CapConn::AcceptClient () { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); struct sockaddr_in useless; int useless_sz = sizeof (useless); this->threadfd = accept (this->serverfd, (struct sockaddr*)&useless, &useless_sz); if (this->threadfd >= 0) { // put sockets into nonblocking mode unsigned long nonblocking = 1; ioctlsocket (this->threadfd, FIONBIO, &nonblocking); closesocket (this->serverfd); return 0; } return -1; } #pragma pack(push) #pragma pack(1) typedef struct { int msg_type; int len; } data_received_t; void WCL2CapConn::OnDataReceived (void *p_data, UINT16 len) { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); data_received_t msg; msg.msg_type = DATA_RECEIVED; msg.len = len; send (this->threadfd, reinterpret_cast (&msg), sizeof (msg), 0); send (this->threadfd, reinterpret_cast (p_data), len, 0); } void WCL2CapConn::OnIncomingConnection () { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); int msg = INCOMING_CONNECTION; send (this->threadfd, reinterpret_cast (&msg), sizeof (msg), 0); } void WCL2CapConn::OnConnectPendingReceived () { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); // TODO } void WCL2CapConn::OnConnected () { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); int msg = CONNECTED; send (this->threadfd, reinterpret_cast (&msg), sizeof (msg), 0); } void WCL2CapConn::OnCongestionStatus (BOOL is_congested) { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); // TODO } void WCL2CapConn::OnRemoteDisconnected (UINT16 reason) { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); int msg = REMOTE_DISCONNECTED; send (this->threadfd, reinterpret_cast (&msg), sizeof (msg), 0); } #pragma pack(pop) // =================== typedef struct _WCL2CapConnPyObject WCL2CapConnPyObject; struct _WCL2CapConnPyObject { PyObject_HEAD WCL2CapConn *l2cap; }; PyDoc_STRVAR(wcl2capconn_doc, "CL2CapConn wrapper"); extern PyTypeObject wcl2capconn_type; static PyObject * get_sockport (PyObject *s) { WCL2CapConnPyObject *self = (WCL2CapConnPyObject*) s; return PyInt_FromLong (self->l2cap->GetSockPort ()); } static PyObject * accept_client (PyObject *s) { WCL2CapConnPyObject *self = (WCL2CapConnPyObject*) s; return PyInt_FromLong (self->l2cap->AcceptClient ()); } static PyObject * wc_listen (PyObject *s, PyObject *a) { WCL2CapConnPyObject *self = (WCL2CapConnPyObject*) s; dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); if (! PyObject_IsInstance (a, (PyObject*)&wcl2capif_type)) { return NULL; } WCL2CapIfPyObject *l2cap_if = (WCL2CapIfPyObject*) a; BOOL result; Py_BEGIN_ALLOW_THREADS; result = self->l2cap->Listen (l2cap_if->l2capif); Py_END_ALLOW_THREADS; dbg (" listen: %d\n", result); if (result) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * wc_accept (PyObject *s, PyObject *args) { WCL2CapConnPyObject *self = (WCL2CapConnPyObject*) s; dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); UINT16 desired_mtu = L2CAP_DEFAULT_MTU; if (!PyArg_ParseTuple (args, "|H", &desired_mtu)) return NULL; BOOL result; Py_BEGIN_ALLOW_THREADS; dbg (" calling accept (%p)\n", self->l2cap); result = self->l2cap->Accept (); dbg (" accept: %d\n", result); Py_END_ALLOW_THREADS; if (result) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * wc_connect (PyObject *s, PyObject *args) { WCL2CapConnPyObject *self = (WCL2CapConnPyObject*) s; WCL2CapIfPyObject *l2cap_if = NULL; char *bdaddr_in = NULL; int bdaddr_in_len; UINT16 desired_mtu = L2CAP_DEFAULT_MTU;; if(!PyArg_ParseTuple (args, "O!s#|H", &wcl2capif_type, &l2cap_if, &bdaddr_in, &bdaddr_in_len, &desired_mtu)) return NULL; if (bdaddr_in_len != BD_ADDR_LEN) { PyErr_SetString (PyExc_ValueError, "invalid bdaddr"); return NULL; } BD_ADDR bdaddr; memcpy (bdaddr, bdaddr_in, BD_ADDR_LEN); BOOL result; Py_BEGIN_ALLOW_THREADS; result = self->l2cap->Connect (l2cap_if->l2capif, bdaddr, desired_mtu); Py_END_ALLOW_THREADS; return PyInt_FromLong (result); } static PyObject * wc_disconnect (PyObject *s) { WCL2CapConnPyObject *self = (WCL2CapConnPyObject*) s; dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); Py_BEGIN_ALLOW_THREADS; self->l2cap->Disconnect (); Py_END_ALLOW_THREADS; Py_RETURN_NONE; } static PyObject * wc_remote_bd_addr (PyObject *s) { WCL2CapConnPyObject *self = (WCL2CapConnPyObject*) s; dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); tBT_CONN_STATS connstats; if (!self->l2cap->GetConnectionStats (&connstats)) { Py_RETURN_NONE; } if (!connstats.bIsConnected) Py_RETURN_NONE; return Py_BuildValue ("s#", &self->l2cap->m_RemoteBdAddr, BD_ADDR_LEN); } static PyObject * wc_write (PyObject *s, PyObject *args) { _WCL2CapConnPyObject *self = (_WCL2CapConnPyObject*) s; dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); char *data = NULL; int datalen; if (!PyArg_ParseTuple (args, "s#", &data, &datalen)) return NULL; UINT16 written = 0; BOOL result; Py_BEGIN_ALLOW_THREADS; result = self->l2cap->Write (data, datalen, &written); Py_END_ALLOW_THREADS; return Py_BuildValue ("II", result, written); } static PyObject * wc_get_connection_stats (PyObject *s) { _WCL2CapConnPyObject *self = (_WCL2CapConnPyObject*) s; dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); tBT_CONN_STATS stats; memset (&stats, 0, sizeof (stats)); BOOL result; Py_BEGIN_ALLOW_THREADS; result = self->l2cap->GetConnectionStats (&stats); Py_END_ALLOW_THREADS; return Py_BuildValue ("iIiIII", result, stats.bIsConnected, stats.Rssi, stats.BytesSent, stats.BytesRcvd, stats.Duration); } static PyObject * wc_switch_role (PyObject *s, PyObject *arg) { _WCL2CapConnPyObject *self = (_WCL2CapConnPyObject*) s; dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); MASTER_SLAVE_ROLE new_role = static_cast (PyInt_AsLong (arg)); BOOL result = self->l2cap->SwitchRole (new_role); return PyInt_FromLong (result); } static PyObject * wc_set_link_supervision_timeout (PyObject *s, PyObject *arg) { _WCL2CapConnPyObject *self = (_WCL2CapConnPyObject*) s; dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); UINT16 timeoutSlot = static_cast (PyInt_AsLong (arg)); BOOL result = self->l2cap->SetLinkSupervisionTimeOut (timeoutSlot); return PyInt_FromLong (result); } static PyMethodDef wcl2capconn_methods[] = { { "get_sockport", (PyCFunction) get_sockport, METH_NOARGS, "" }, { "accept_client", (PyCFunction) accept_client, METH_NOARGS, "" }, { "listen", (PyCFunction) wc_listen, METH_O, "" }, { "accept", (PyCFunction) wc_accept, METH_VARARGS, "" }, { "connect", (PyCFunction) wc_connect, METH_VARARGS, "" }, { "disconnect", (PyCFunction) wc_disconnect, METH_NOARGS, "" }, { "remote_bd_addr", (PyCFunction) wc_remote_bd_addr, METH_NOARGS, "" }, { "write", (PyCFunction)wc_write, METH_VARARGS, "" }, { "get_connection_stats", (PyCFunction)wc_get_connection_stats, METH_NOARGS, "" }, { "switch_role", (PyCFunction)wc_switch_role, METH_O, "" }, { "set_link_supervision_timeout", (PyCFunction)wc_set_link_supervision_timeout, METH_O, "" }, { NULL, NULL } }; static PyObject * wcl2capconn_repr(WCL2CapConnPyObject *s) { return PyString_FromString("_WCL2CapConn object"); } static PyObject * wcl2capconn_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *newobj; newobj = type->tp_alloc(type, 0); if (newobj != NULL) { WCL2CapConnPyObject *self = (WCL2CapConnPyObject *)newobj; self->l2cap = NULL; } return newobj; } static void wcl2capconn_dealloc(WCL2CapConnPyObject *self) { if (self->l2cap) { delete self->l2cap; self->l2cap = NULL; } Py_TYPE(self)->tp_free((PyObject*)self); } int wcl2capconn_initobj(PyObject *s, PyObject *args, PyObject *kwds) { WCL2CapConnPyObject *self = (WCL2CapConnPyObject *)s; self->l2cap = new WCL2CapConn (s); return 0; } /* Type object for socket objects. */ PyTypeObject wcl2capconn_type = { #if PY_MAJOR_VERSION < 3 PyObject_HEAD_INIT(0) /* Must fill in type value later */ 0, /* ob_size */ #else PyVarObject_HEAD_INIT(NULL, 0) /* Must fill in type value later */ #endif "_widcomm._WCL2CapConn", /* tp_name */ sizeof(WCL2CapConnPyObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)wcl2capconn_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)wcl2capconn_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ wcl2capconn_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ wcl2capconn_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ wcl2capconn_initobj, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ wcl2capconn_new, /* tp_new */ PyObject_Del, /* tp_free */ }; pybluez-0.22+really0.22/widcomm/l2capconn.hpp000066400000000000000000000014501334611253700207510ustar00rootroot00000000000000#pragma once class WCL2CapConn : public CL2CapConn { public: enum { DATA_RECEIVED, INCOMING_CONNECTION, REMOTE_DISCONNECTED, CONNECTED }; WCL2CapConn (PyObject *pyobj); virtual ~WCL2CapConn (); int AcceptClient (); inline unsigned short GetSockPort () { return sockport; } private: CL2CapIf rfcommif; void OnIncomingConnection (); void OnConnectPendingReceived (); void OnConnected (); void OnDataReceived (void *p_data, UINT16 len); void OnCongestionStatus (BOOL is_congested); void OnRemoteDisconnected (UINT16 reason); PyObject * pyobj; SOCKET threadfd; SOCKET serverfd; unsigned short sockport; }; pybluez-0.22+really0.22/widcomm/l2capif.cpp000066400000000000000000000125111334611253700204050ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "util.h" #include "l2capif.hpp" // =================== static inline void dbg (const char *fmt, ...) { return; va_list ap; va_start (ap, fmt); vfprintf (stderr, fmt, ap); va_end (ap); } PyDoc_STRVAR(wcl2capif_doc, "CL2CapIf wrapper"); static PyObject * assign_psm_value (PyObject *s, PyObject *args) { // dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); WCL2CapIfPyObject *self = (WCL2CapIfPyObject*) s; char *uuid_str = NULL; int uuid_str_len = 0; UINT16 psm = 0; char *service_name = _T(""); if(!PyArg_ParseTuple (args, "s#|H", &uuid_str, &uuid_str_len, &psm)) return NULL; GUID uuid = { 0 }; PyWidcomm::str2uuid (uuid_str, &uuid); BOOL result = self->l2capif->AssignPsmValue (&uuid, psm); dbg ("%s:%d:%s (%d)\n", __FILE__, __LINE__, __FUNCTION__, self->l2capif->GetPsm()); if (result) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * wc_register (PyObject *s) { WCL2CapIfPyObject *self = (WCL2CapIfPyObject*) s; return PyInt_FromLong (self->l2capif->Register ()); } static PyObject * wc_deregister (PyObject *s) { WCL2CapIfPyObject *self = (WCL2CapIfPyObject*) s; self->l2capif->Deregister (); Py_RETURN_NONE; } static PyObject * get_psm (PyObject *s) { WCL2CapIfPyObject *self = (WCL2CapIfPyObject*) s; return PyInt_FromLong (self->l2capif->GetPsm ()); } static PyObject * set_security_level (PyObject *s, PyObject *args) { char *service_name = NULL; UINT8 security_level = BTM_SEC_NONE; int is_server; if(!PyArg_ParseTuple (args, "sBi", &service_name, &security_level, &is_server)) return NULL; dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); WCL2CapIfPyObject *self = (WCL2CapIfPyObject*) s; BOOL result = self->l2capif->SetSecurityLevel (service_name, security_level, (BOOL) is_server); // dbg ("%s:%d:%s %d\n", __FILE__, __LINE__, __FUNCTION__, result); if (result) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyMethodDef wcl2capif_methods[] = { { "assign_psm_value", (PyCFunction)assign_psm_value, METH_VARARGS, "" }, { "register", (PyCFunction)wc_register, METH_NOARGS, "" }, { "deregister", (PyCFunction)wc_deregister, METH_NOARGS, "" }, { "get_psm", (PyCFunction)get_psm, METH_NOARGS, "" }, { "set_security_level", (PyCFunction)set_security_level, METH_VARARGS, "" }, { NULL, NULL } }; static PyObject * wcl2capif_repr(WCL2CapIfPyObject *s) { return PyString_FromString("_WCL2CapIf object"); } static PyObject * wcl2capif_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *newobj; newobj = type->tp_alloc(type, 0); if (newobj != NULL) { WCL2CapIfPyObject *self = (WCL2CapIfPyObject *)newobj; self->l2capif = NULL; } return newobj; } static void wcl2capif_dealloc(WCL2CapIfPyObject *self) { if (self->l2capif) { delete self->l2capif; self->l2capif = NULL; } Py_TYPE(self)->tp_free((PyObject*)self); } int wcl2capif_initobj(PyObject *s, PyObject *args, PyObject *kwds) { WCL2CapIfPyObject *self = (WCL2CapIfPyObject *)s; self->l2capif = new CL2CapIf (); return 0; } /* Type object for socket objects. */ PyTypeObject wcl2capif_type = { #if PY_MAJOR_VERSION < 3 PyObject_HEAD_INIT(0) /* Must fill in type value later */ 0, /* ob_size */ #else PyVarObject_HEAD_INIT(NULL, 0) /* Must fill in type value later */ #endif "_widcomm._WCL2CapIf", /* tp_name */ sizeof(WCL2CapIfPyObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)wcl2capif_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)wcl2capif_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ wcl2capif_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ wcl2capif_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ wcl2capif_initobj, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ wcl2capif_new, /* tp_new */ PyObject_Del, /* tp_free */ }; pybluez-0.22+really0.22/widcomm/l2capif.hpp000066400000000000000000000002641334611253700204140ustar00rootroot00000000000000#pragma once typedef struct _WCL2CapIfPyObject WCL2CapIfPyObject; struct _WCL2CapIfPyObject { PyObject_HEAD CL2CapIf * l2capif; }; extern PyTypeObject wcl2capif_type; pybluez-0.22+really0.22/widcomm/rfcommif.cpp000066400000000000000000000113271334611253700206730ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "util.h" // =================== typedef struct _WCRfCommIfPyObject WCRfCommIfPyObject; struct _WCRfCommIfPyObject { PyObject_HEAD CRfCommIf * rfcommif; }; PyDoc_STRVAR(wcrfcommif_doc, "CRfCommIf wrapper"); extern PyTypeObject wcrfcommif_type; static PyObject * assign_scn_value (PyObject *s, PyObject *args) { WCRfCommIfPyObject *self = (WCRfCommIfPyObject*) s; char *uuid_str = NULL; int uuid_str_len = 0; UINT8 scn = 0; char *service_name = _T(""); if(!PyArg_ParseTuple (args, "s#|Bs", &uuid_str, &uuid_str_len, &scn, &service_name)) return NULL; GUID uuid = { 0 }; PyWidcomm::str2uuid (uuid_str, &uuid); // printf ("AssignScnValue\n"); BOOL result = self->rfcommif->AssignScnValue (&uuid, scn, service_name); if (result) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyObject * get_scn (PyObject *s) { WCRfCommIfPyObject *self = (WCRfCommIfPyObject*) s; return PyInt_FromLong (self->rfcommif->GetScn ()); } static PyObject * set_security_level (PyObject *s, PyObject *args) { char *service_name = NULL; UINT8 security_level = BTM_SEC_NONE; int is_server; if(!PyArg_ParseTuple (args, "sBi", &service_name, &security_level, &is_server)) return NULL; WCRfCommIfPyObject *self = (WCRfCommIfPyObject*) s; BOOL result = self->rfcommif->SetSecurityLevel (service_name, security_level, (BOOL) is_server); if (result) { Py_RETURN_TRUE; } else { Py_RETURN_FALSE; } } static PyMethodDef wcrfcommif_methods[] = { { "assign_scn_value", (PyCFunction)assign_scn_value, METH_VARARGS, "" }, { "get_scn", (PyCFunction)get_scn, METH_NOARGS, "" }, { "set_security_level", (PyCFunction)set_security_level, METH_VARARGS, "" }, { NULL, NULL } }; static PyObject * wcrfcommif_repr(WCRfCommIfPyObject *s) { return PyString_FromString("_WCRfCommIf object"); } static PyObject * wcrfcommif_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *newobj; newobj = type->tp_alloc(type, 0); if (newobj != NULL) { WCRfCommIfPyObject *self = (WCRfCommIfPyObject *)newobj; self->rfcommif = NULL; } return newobj; } static void wcrfcommif_dealloc(WCRfCommIfPyObject *self) { if (self->rfcommif) { delete self->rfcommif; self->rfcommif = NULL; } Py_TYPE(self)->tp_free((PyObject*)self); } int wcrfcommif_initobj(PyObject *s, PyObject *args, PyObject *kwds) { WCRfCommIfPyObject *self = (WCRfCommIfPyObject *)s; self->rfcommif = new CRfCommIf (); return 0; } /* Type object for socket objects. */ PyTypeObject wcrfcommif_type = { #if PY_MAJOR_VERSION < 3 PyObject_HEAD_INIT(0) /* Must fill in type value later */ 0, /* ob_size */ #else PyVarObject_HEAD_INIT(NULL, 0) /* Must fill in type value later */ #endif "_widcomm._WCRfCommIf", /* tp_name */ sizeof(WCRfCommIfPyObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)wcrfcommif_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)wcrfcommif_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ wcrfcommif_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ wcrfcommif_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ wcrfcommif_initobj, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ wcrfcommif_new, /* tp_new */ PyObject_Del, /* tp_free */ }; pybluez-0.22+really0.22/widcomm/rfcommport.cpp000066400000000000000000000272621334611253700212660ustar00rootroot00000000000000#include #include #include #include #include #include #include "rfcommport.hpp" static inline void dbg (const char *fmt, ...) { return; va_list ap; va_start (ap, fmt); vfprintf (stderr, fmt, ap); va_end (ap); } WCRfCommPort::WCRfCommPort (PyObject *pyobj) : CRfCommPort () { this->pyobj = pyobj; this->serverfd = socket (AF_INET, SOCK_STREAM, 0); this->threadfd = socket (AF_INET, SOCK_STREAM, 0); int status = SOCKET_ERROR; struct sockaddr_in saddr = { 0, }; for (int i=0; i<10; i++) { this->sockport = 3000 + (unsigned short) (20000 * (rand () / (RAND_MAX + 1.0))); saddr.sin_family = AF_INET; saddr.sin_port = htons (this->sockport); saddr.sin_addr.s_addr = inet_addr ("127.0.0.1"); status = bind (this->serverfd, (struct sockaddr*) &saddr, sizeof (saddr)); if (0 == status) break; } assert (0 == status); // instruct server socket to accept one connection status = listen (this->serverfd, 1); } WCRfCommPort::~WCRfCommPort () { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); closesocket (this->threadfd); } int WCRfCommPort::AcceptClient () { struct sockaddr_in useless; int useless_sz = sizeof (useless); this->threadfd = accept (this->serverfd, (struct sockaddr*)&useless, &useless_sz); if (this->threadfd >= 0) { // put sockets into nonblocking mode unsigned long nonblocking = 1; ioctlsocket (this->threadfd, FIONBIO, &nonblocking); closesocket (this->serverfd); return 0; } return -1; } #pragma pack(push) #pragma pack(1) typedef struct { int msg_type; int len; } data_received_t; void WCRfCommPort::OnDataReceived (void *p_data, UINT16 len) { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); data_received_t msg; msg.msg_type = DATA_RECEIVED; msg.len = len; send (this->threadfd, reinterpret_cast (&msg), sizeof (msg), 0); send (this->threadfd, reinterpret_cast (p_data), len, 0); } typedef struct { int msg_type; unsigned int event_code; } event_received_msg_t; void WCRfCommPort::OnEventReceived (UINT32 event_code) { dbg ("%s:%d event %u received\n", __FILE__, __LINE__, event_code); event_received_msg_t msg; msg.msg_type = EVENT_RECEIVED; msg.event_code = event_code; send (this->threadfd, reinterpret_cast (&msg), sizeof (msg), 0); } #pragma pack(pop) // =================== typedef struct _WCRfCommPortPyObject WCRfCommPortPyObject; struct _WCRfCommPortPyObject { PyObject_HEAD WCRfCommPort *rfcp; }; PyDoc_STRVAR(wcrfcommport_doc, "CRfCommPort wrapper"); extern PyTypeObject wcrfcommport_type; static PyObject * get_sockport (PyObject *s) { WCRfCommPortPyObject *self = (WCRfCommPortPyObject*) s; return PyInt_FromLong (self->rfcp->GetSockPort ()); } static PyObject * accept_client (PyObject *s) { WCRfCommPortPyObject *self = (WCRfCommPortPyObject*) s; return PyInt_FromLong (self->rfcp->AcceptClient ()); } static PyObject * wc_open_server (PyObject *s, PyObject *args) { WCRfCommPortPyObject *self = (WCRfCommPortPyObject*) s; UINT8 scn; UINT16 desired_mtu = RFCOMM_DEFAULT_MTU; if (!PyArg_ParseTuple (args, "B|H", &scn, &desired_mtu)) return NULL; CRfCommPort::PORT_RETURN_CODE result = self->rfcp->OpenServer (scn, desired_mtu); return PyInt_FromLong (result); } static PyObject * wc_open_client (PyObject *s, PyObject *args) { UINT8 scn; char *bdaddr_in = NULL; int bdaddr_in_len; UINT16 desired_mtu = RFCOMM_DEFAULT_MTU; if(!PyArg_ParseTuple (args, "Bs#|H", &scn, &bdaddr_in, &bdaddr_in_len, &desired_mtu)) return NULL; if (bdaddr_in_len != BD_ADDR_LEN) { PyErr_SetString (PyExc_ValueError, "invalid bdaddr"); return NULL; } BD_ADDR bdaddr; memcpy (bdaddr, bdaddr_in, BD_ADDR_LEN); _WCRfCommPortPyObject *self = (_WCRfCommPortPyObject*) s; CRfCommPort::PORT_RETURN_CODE result; Py_BEGIN_ALLOW_THREADS; result = self->rfcp->OpenClient (scn, bdaddr, desired_mtu); Py_END_ALLOW_THREADS; return PyInt_FromLong (result); } static PyObject * wc_is_connected (PyObject *s) { _WCRfCommPortPyObject *self = (_WCRfCommPortPyObject*) s; BD_ADDR remote_addr; if (self->rfcp->IsConnected (&remote_addr)) { return Py_BuildValue ("s#", &remote_addr, BD_ADDR_LEN); } else { Py_RETURN_NONE; } } static PyObject * wc_close (PyObject *s) { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); _WCRfCommPortPyObject *self = (_WCRfCommPortPyObject*) s; self->rfcp->Close (); Py_RETURN_NONE; } static PyObject * wc_set_flow_enabled (PyObject *s, PyObject *arg) { _WCRfCommPortPyObject *self = (_WCRfCommPortPyObject*) s; int enable = PyInt_AsLong (arg); CRfCommPort::PORT_RETURN_CODE result = self->rfcp->SetFlowEnabled (enable); return PyInt_FromLong (result); } static PyObject * wc_set_modem_signal (PyObject *s, PyObject *arg) { _WCRfCommPortPyObject *self = (_WCRfCommPortPyObject*) s; UINT8 signal = static_cast (PyInt_AsLong (arg)); CRfCommPort::PORT_RETURN_CODE result = self->rfcp->SetModemSignal (signal); return PyInt_FromLong (result); } static PyObject * wc_get_modem_status (PyObject *s) { _WCRfCommPortPyObject *self = (_WCRfCommPortPyObject*) s; UINT8 signal; CRfCommPort::PORT_RETURN_CODE result = self->rfcp->GetModemStatus (&signal); return Py_BuildValue ("ii", result, signal); } static PyObject * wc_send_error (PyObject *s, PyObject *arg) { _WCRfCommPortPyObject *self = (_WCRfCommPortPyObject*) s; UINT8 errors = static_cast (PyInt_AsLong (arg)); CRfCommPort::PORT_RETURN_CODE result = self->rfcp->SendError (errors); return PyInt_FromLong (result); } static PyObject * wc_purge (PyObject *s, PyObject *arg) { _WCRfCommPortPyObject *self = (_WCRfCommPortPyObject*) s; UINT8 purge_flags = static_cast (PyInt_AsLong (arg)); CRfCommPort::PORT_RETURN_CODE result = self->rfcp->Purge (purge_flags); return PyInt_FromLong (result); } static PyObject * wc_write (PyObject *s, PyObject *args) { _WCRfCommPortPyObject *self = (_WCRfCommPortPyObject*) s; char *data = NULL; int datalen; if (!PyArg_ParseTuple (args, "s#", &data, &datalen)) return NULL; UINT16 written = 0; CRfCommPort::PORT_RETURN_CODE status; Py_BEGIN_ALLOW_THREADS; status = self->rfcp->Write (data, datalen, &written); Py_END_ALLOW_THREADS; return Py_BuildValue ("II", status, written); } static PyObject * wc_get_connection_stats (PyObject *s) { _WCRfCommPortPyObject *self = (_WCRfCommPortPyObject*) s; tBT_CONN_STATS stats; memset (&stats, 0, sizeof (stats)); CRfCommPort::PORT_RETURN_CODE result = self->rfcp->GetConnectionStats (&stats); return Py_BuildValue ("iIiIII", result, stats.bIsConnected, stats.Rssi, stats.BytesSent, stats.BytesRcvd, stats.Duration); } static PyObject * wc_switch_role (PyObject *s, PyObject *arg) { _WCRfCommPortPyObject *self = (_WCRfCommPortPyObject*) s; MASTER_SLAVE_ROLE new_role = static_cast (PyInt_AsLong (arg)); BOOL result = self->rfcp->SwitchRole (new_role); return PyInt_FromLong (result); } static PyObject * wc_set_link_supervision_timeout (PyObject *s, PyObject *arg) { _WCRfCommPortPyObject *self = (_WCRfCommPortPyObject*) s; UINT16 timeoutSlot = static_cast (PyInt_AsLong (arg)); CRfCommPort::PORT_RETURN_CODE result = self->rfcp->SetLinkSupervisionTimeOut (timeoutSlot); return PyInt_FromLong (result); } static PyMethodDef wcrfcommport_methods[] = { { "get_sockport", (PyCFunction) get_sockport, METH_NOARGS, "" }, { "accept_client", (PyCFunction) accept_client, METH_NOARGS, "" }, { "open_server", (PyCFunction)wc_open_server, METH_VARARGS, "" }, { "open_client", (PyCFunction)wc_open_client, METH_VARARGS, "" }, { "close", (PyCFunction)wc_close, METH_NOARGS, "" }, { "is_connected", (PyCFunction)wc_is_connected, METH_NOARGS, "" }, { "set_flow_enabled", (PyCFunction)wc_set_flow_enabled, METH_O, "" }, { "set_modem_signal", (PyCFunction)wc_set_modem_signal, METH_O, "" }, { "get_modem_status", (PyCFunction)wc_get_modem_status, METH_NOARGS, "" }, { "send_error", (PyCFunction)wc_send_error, METH_O, "" }, { "purge", (PyCFunction)wc_purge, METH_O, "" }, { "write", (PyCFunction)wc_write, METH_VARARGS, "" }, { "get_connection_stats", (PyCFunction)wc_get_connection_stats, METH_NOARGS, "" }, { "switch_role", (PyCFunction)wc_switch_role, METH_O, "" }, { "set_link_supervision_timeout", (PyCFunction)wc_set_link_supervision_timeout, METH_O, "" }, { NULL, NULL } }; static PyObject * wcrfcommport_repr(WCRfCommPortPyObject *s) { return PyString_FromString("_WCRfCommPort object"); } static PyObject * wcrfcommport_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *newobj; newobj = type->tp_alloc(type, 0); if (newobj != NULL) { WCRfCommPortPyObject *self = (WCRfCommPortPyObject *)newobj; self->rfcp = NULL; } return newobj; } static void wcrfcommport_dealloc(WCRfCommPortPyObject *self) { dbg ("%s:%d:%s\n", __FILE__, __LINE__, __FUNCTION__); if (self->rfcp) { delete self->rfcp; self->rfcp = NULL; } Py_TYPE(self)->tp_free((PyObject*)self); } int wcrfcommport_initobj(PyObject *s, PyObject *args, PyObject *kwds) { WCRfCommPortPyObject *self = (WCRfCommPortPyObject *)s; self->rfcp = new WCRfCommPort (s); return 0; } /* Type object for socket objects. */ PyTypeObject wcrfcommport_type = { #if PY_MAJOR_VERSION < 3 PyObject_HEAD_INIT(0) /* Must fill in type value later */ 0, /* ob_size */ #else PyVarObject_HEAD_INIT(NULL, 0) /* Must fill in type value later */ #endif "_widcomm._WCRfCommPort", /* tp_name */ sizeof(WCRfCommPortPyObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)wcrfcommport_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)wcrfcommport_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ wcrfcommport_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ wcrfcommport_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ wcrfcommport_initobj, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ wcrfcommport_new, /* tp_new */ PyObject_Del, /* tp_free */ }; pybluez-0.22+really0.22/widcomm/rfcommport.hpp000066400000000000000000000011151334611253700212600ustar00rootroot00000000000000#pragma once class WCRfCommPort : public CRfCommPort { public: enum { DATA_RECEIVED, EVENT_RECEIVED }; WCRfCommPort (PyObject *pyobj); virtual ~WCRfCommPort (); int AcceptClient (); inline unsigned short GetSockPort () { return sockport; } private: CRfCommIf rfcommif; void OnDataReceived (void *p_data, UINT16 len); void OnEventReceived (UINT32 event_code); PyObject * pyobj; SOCKET threadfd; SOCKET serverfd; unsigned short sockport; }; pybluez-0.22+really0.22/widcomm/sdpservice.cpp000066400000000000000000000150401334611253700212340ustar00rootroot00000000000000#include #include #include #include #include #include #include "util.h" // =================== typedef struct _WCSdpServicePyObject WCSdpServicePyObject; struct _WCSdpServicePyObject { PyObject_HEAD CSdpService * sdpservice; }; PyDoc_STRVAR(wcsdpservice_doc, "CSdpService wrapper"); extern PyTypeObject wcsdpservice_type; static PyObject * add_service_class_id_list (WCSdpServicePyObject *self, PyObject *arg) { int nuids = PySequence_Size (arg); if (nuids < 0) { return NULL; } GUID *uuids = (GUID*) malloc (nuids * sizeof (GUID)); for (int i=0; isdpservice->AddServiceClassIdList (nuids, uuids); free (uuids); return PyInt_FromLong (result); fail: free (uuids); return NULL; } static PyObject * add_profile_descriptor_list (WCSdpServicePyObject *self, PyObject *args) { char *uuid_str = NULL; int uuid_str_len = 0; UINT16 version = 0; GUID uuid; if (!PyArg_ParseTuple (args, "s#H", &uuid_str, &uuid_str_len, &version)) return NULL; PyWidcomm::str2uuid (uuid_str, &uuid); SDP_RETURN_CODE result = self->sdpservice->AddProfileDescriptorList (&uuid, version); return PyInt_FromLong (result); } static PyObject * add_service_name (WCSdpServicePyObject *self, PyObject *arg) { char *name = PyString_AsString (arg); if (!name) return NULL; SDP_RETURN_CODE result = self->sdpservice->AddServiceName (name); return PyInt_FromLong (result); } static PyObject * add_rfcomm_protocol_descriptor (WCSdpServicePyObject *self, PyObject *arg) { int port = PyInt_AsLong (arg); if (PyErr_Occurred ()) return NULL; UINT8 scn = static_cast (port); SDP_RETURN_CODE result = self->sdpservice->AddRFCommProtocolDescriptor (scn); return PyInt_FromLong (result); } static PyObject * add_l2cap_protocol_descriptor (WCSdpServicePyObject *self, PyObject *arg) { int port = PyInt_AsLong (arg); if (PyErr_Occurred ()) return NULL; UINT16 psm = static_cast (port); SDP_RETURN_CODE result = self->sdpservice->AddL2CapProtocolDescriptor (psm); return PyInt_FromLong (result); } static PyObject * make_public_browseable (WCSdpServicePyObject *self) { SDP_RETURN_CODE result = self->sdpservice->MakePublicBrowseable (); return PyInt_FromLong (result); } static PyObject * set_availability (WCSdpServicePyObject *self, PyObject *arg) { UINT8 available = static_cast (PyInt_AsLong (arg)); if (PyErr_Occurred ()) return NULL; SDP_RETURN_CODE result = self->sdpservice->SetAvailability (available); return PyInt_FromLong (result); } static PyMethodDef wcsdpservice_methods[] = { { "add_service_class_id_list", (PyCFunction)add_service_class_id_list, METH_O, "" }, { "add_profile_descriptor_list", (PyCFunction)add_profile_descriptor_list, METH_VARARGS, "" }, { "add_service_name", (PyCFunction)add_service_name, METH_O, "" }, { "add_rfcomm_protocol_descriptor", (PyCFunction)add_rfcomm_protocol_descriptor, METH_O, "" }, { "add_l2cap_protocol_descriptor", (PyCFunction)add_l2cap_protocol_descriptor, METH_O, "" }, { "make_public_browseable", (PyCFunction)make_public_browseable, METH_NOARGS, "" }, { "set_availability", (PyCFunction)set_availability, METH_O, "" }, { NULL, NULL } }; static PyObject * wcsdpservice_repr(WCSdpServicePyObject *s) { return PyString_FromString("_WCSdpService object"); } static PyObject * wcsdpservice_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *newobj; newobj = type->tp_alloc(type, 0); if (newobj != NULL) { WCSdpServicePyObject *self = (WCSdpServicePyObject *)newobj; self->sdpservice = NULL; } return newobj; } static void wcsdpservice_dealloc(WCSdpServicePyObject *self) { if (self->sdpservice) { delete self->sdpservice; self->sdpservice = NULL; } Py_TYPE(self)->tp_free((PyObject*)self); } int wcsdpservice_initobj(PyObject *s, PyObject *args, PyObject *kwds) { WCSdpServicePyObject *self = (WCSdpServicePyObject *)s; self->sdpservice = new CSdpService (); return 0; } /* Type object for socket objects. */ PyTypeObject wcsdpservice_type = { #if PY_MAJOR_VERSION < 3 PyObject_HEAD_INIT(0) /* Must fill in type value later */ 0, /* ob_size */ #else PyVarObject_HEAD_INIT(NULL, 0) /* Must fill in type value later */ #endif "_widcomm._WCSdpService", /* tp_name */ sizeof(WCSdpServicePyObject), /* tp_basicsize */ 0, /* tp_itemsize */ (destructor)wcsdpservice_dealloc, /* tp_dealloc */ 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ (reprfunc)wcsdpservice_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */ wcsdpservice_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ wcsdpservice_methods, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ wcsdpservice_initobj, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ wcsdpservice_new, /* tp_new */ PyObject_Del, /* tp_free */ }; pybluez-0.22+really0.22/widcomm/util.cpp000066400000000000000000000016271334611253700200500ustar00rootroot00000000000000#include #include "util.h" namespace PyWidcomm { int str2uuid( const char *uuid_str, GUID *uuid) { // Parse uuid128 standard format: 12345678-9012-3456-7890-123456789012 int i; char buf[20] = { 0 }; strncpy_s(buf, sizeof(buf), uuid_str, 8); uuid->Data1 = strtoul( buf, NULL, 16 ); memset(buf, 0, sizeof(buf)); strncpy_s(buf, sizeof(buf), uuid_str+9, 4); uuid->Data2 = (unsigned short) strtoul( buf, NULL, 16 ); memset(buf, 0, sizeof(buf)); strncpy_s(buf, sizeof(buf), uuid_str+14, 4); uuid->Data3 = (unsigned short) strtoul( buf, NULL, 16 ); memset(buf, 0, sizeof(buf)); strncpy_s(buf, sizeof(buf), uuid_str+19, 4); strncpy_s(buf+4, sizeof(buf)-4, uuid_str+24, 12); for( i=0; i<8; i++ ) { char buf2[3] = { buf[2*i], buf[2*i+1], 0 }; uuid->Data4[i] = (unsigned char)strtoul( buf2, NULL, 16 ); } return 0; } } pybluez-0.22+really0.22/widcomm/util.h000066400000000000000000000001601334611253700175040ustar00rootroot00000000000000#pragma once #include namespace PyWidcomm { int str2uuid( const char *uuid_str, GUID *uuid); };