Example #1
0
 def run(self, getnames, duration):
     if self._inquiring:
         raise _lightbluecommon.BluetoothError(
             "Another inquiry in progress")
         
     # set inquiry attributes
     self._inquiry.updatenames = getnames
     self._inquiry.length = duration
     
     # start the inquiry
     err = self._inquiry.start()
     if err != _macutil.kIOReturnSuccess:
         raise _lightbluecommon.BluetoothError(
             err, "Error starting device inquiry")      
         
     # if error occurs during inquiry, set _inquiryerr to the error code
     self._inquiryerr = _macutil.kIOReturnSuccess
     
     # wait until the inquiry is complete
     self._inquiring = True
     _macutil.waituntil(lambda: not self._inquiring)
     
     # if error occured during inquiry, raise exception
     if self._inquiryerr != _macutil.kIOReturnSuccess:
         raise _lightbluecommon.BluetoothError(self._inquiryerr, 
             "Error during device inquiry")
def _getavailableport(proto):
    # Just advertise a service and see what channel it was assigned, then
    # stop advertising the service and return the channel.
    # It's a hacky way of doing it, but IOBluetooth doesn't seem to provide
    # functionality for just getting an available channel.

    if proto == _lightbluecommon.RFCOMM:
        try:
            result, channelID, servicerecordhandle = BBServiceAdvertiser.addRFCOMMServiceDictionary_withName_UUID_channelID_serviceRecordHandle_(
                BBServiceAdvertiser.serialPortProfileDictionary(),
                "DummyService", None, None, None)
        except:
            result, channelID, servicerecordhandle = BBServiceAdvertiser.addRFCOMMServiceDictionary_withName_UUID_channelID_serviceRecordHandle_(
                BBServiceAdvertiser.serialPortProfileDictionary(),
                "DummyService", None)
        if result != _macutil.kIOReturnSuccess:
            raise _lightbluecommon.BluetoothError(result, \
                "Could not retrieve an available service channel")
        result = BBServiceAdvertiser.removeService_(servicerecordhandle)
        if result != _macutil.kIOReturnSuccess:
            raise _lightbluecommon.BluetoothError(result, \
                "Could not retrieve an available service channel")
        return channelID

    else:
        raise NotImplementedError(
            "L2CAP server sockets not currently supported")
Example #3
0
def stopadvertise(sock):
    if not sock._advertised:
        raise _lightbluecommon.BluetoothError("no service advertised")
    try:
        bluetooth.stop_advertising(sock._sock)
    except bluetooth.BluetoothError, e:
        raise _lightbluecommon.BluetoothError(str(e))
Example #4
0
def stopadvertise(sock):
    if sock is None:
        raise TypeError("Given socket is None")

    servicerecordhandle = __advertised.get(id(sock))
    if servicerecordhandle is None:
        raise _lightbluecommon.BluetoothError("no service advertised")
        
    result = _LightAquaBlue.BBServiceAdvertiser.removeService_(servicerecordhandle)
    if result != _macutil.kIOReturnSuccess:
        raise _lightbluecommon.BluetoothError(
            result, "Error stopping advertising of service")
 def _getport(self):
     if self.__isconnected():
         return self.__conn.getport()
     if self.__isbound():
         return self.__port
     raise _lightbluecommon.BluetoothError(
         "socket is neither connected nor bound")
Example #6
0
def stopadvertise(sock):
    details = __advertised.get(id(sock))
    if details is None:
        raise _lightbluecommon.BluetoothError("no service advertised")
    
    name, servicetype = details
    _socket.bt_advertise_service(name, sock._sock, False, servicetype)
Example #7
0
def _gethostname():
    import _lightblueutil
    try:
        name = _lightblueutil.getLocalName()
    except SymbianError, exc:
        raise _lightbluecommon.BluetoothError(
            "Cannot read local device name: " + str(exc))
Example #8
0
def gethostclass():
    import _lightblueutil
    try:
        cod = _lightblueutil.getLocalDeviceClass()
    except SymbianError, exc:
        raise _lightbluecommon.BluetoothError(
            "Cannot read local device class: " + str(exc))
Example #9
0
def gethostaddr():
    import _lightblueutil
    try:
        addr = _lightblueutil.getLocalAddress()
    except SymbianError, exc:
        raise _lightbluecommon.BluetoothError(
            "Cannot read local device address: " + str(exc))
Example #10
0
def advertise(servicename, sock, serviceclass):
    try:
        if serviceclass == _lightbluecommon.RFCOMM:
            bluetooth.advertise_service(
                sock._sock,
                servicename,
                service_classes=[bluetooth.SERIAL_PORT_CLASS],
                profiles=[bluetooth.SERIAL_PORT_PROFILE])
        elif serviceclass == _lightbluecommon.OBEX:
            # for pybluez, socket do need to be listening in order to
            # advertise a service, so we'll call listen() here. This should be
            # safe since user shouldn't have called listen() already, because
            # obex.recvfile() docs state that an obex server socket should
            # *not* be listening before recvfile() is called (due to Series60's
            # particular implementation)
            if not sock._listening:
                sock.listen(1)

            # advertise Object Push Profile not File Transfer Profile because
            # obex.recvfile() implementations run OBEX servers which only
            # advertise Object Push operations
            bluetooth.advertise_service(
                sock._sock,
                servicename,
                service_classes=[bluetooth.OBEX_OBJPUSH_CLASS],
                profiles=[bluetooth.OBEX_OBJPUSH_PROFILE],
                protocols=["0008"])  # OBEX protocol
        else:
            raise ValueError("Unknown serviceclass, " + \
                "should be either RFCOMM or OBEX constants")
        # set flag
        sock._advertised = True
    except bluetooth.BluetoothError, e:
        raise _lightbluecommon.BluetoothError(str(e))
Example #11
0
def gethostaddr():
    addr = _LightAquaBlue.BBLocalDevice.getAddressString()
    if addr is not None:
        # PyObjC returns all strings as unicode, but the address doesn't need 
        # to be unicode cos it's just hex values
        return _macutil.formatdevaddr(addr)
    raise _lightbluecommon.BluetoothError("Cannot read local device address")                            
Example #12
0
 def query(self, device, timeout=10.0):
     # do SDP query
     err = device.performSDPQuery_(self)
     if err != _macutil.kIOReturnSuccess:
         raise _lightbluecommon.BluetoothError(err, self._errmsg(device))
     
     # performSDPQuery_ is async, so block-wait
     self._queryresult = None
     if not _macutil.waituntil(lambda: self._queryresult is not None,
                                       timeout):
         raise _lightbluecommon.BluetoothError(
             "Timed out getting services for %s" % \
                 device.getNameOrAddress())
     # query is now complete
     if self._queryresult != _macutil.kIOReturnSuccess:  
         raise _lightbluecommon.BluetoothError(
             self._queryresult, self._errmsg(device))
Example #13
0
def findservices(addr=None, name=None, servicetype=None):
    if servicetype not in (_lightbluecommon.RFCOMM, _lightbluecommon.OBEX, None):
        raise ValueError("servicetype must be RFCOMM, OBEX or None, was %s" % \
            servicetype)

    if addr is None:
        try:
            founddevices = finddevices()
        except _lightbluecommon.BluetoothError as e:
            msg = "findservices() failed, " +\
                    "error while finding devices: " + str(e)
            raise _lightbluecommon.BluetoothError(msg)
            
        #print founddevices
        addresses = [dev[0] for dev in founddevices]
    else:
        addresses = [addr]

    services = []
    for devaddr in addresses:
        iobtdevice = _IOBluetooth.IOBluetoothDevice.withAddress_(
            _macutil.createbtdevaddr(devaddr))
            
        try:
            lastseen = iobtdevice.getLastServicesUpdate()
            if lastseen is None or lastseen.timeIntervalSinceNow() < -2:
                # perform SDP query to update known services.
                # wait at least a few seconds between service discovery cos 
                # sometimes it doesn't work if doing updates too often.
                # In future should have option to not do updates.
                serviceupdater = _SDPQueryRunner.alloc().init()
                try:
                    serviceupdater.query(iobtdevice)  # blocks until updated
                except _lightbluecommon.BluetoothError as e:
                    msg = "findservices() couldn't get services for %s: %s" % \
                        (iobtdevice.getNameOrAddress(), str(e))
                    warnings.warn(msg)
                    # or should I use cached services instead of warning?
                    # but sometimes the cached ones are totally wrong.
                    
            # if searching for RFCOMM, exclude OBEX services
            if servicetype == _lightbluecommon.RFCOMM:
                uuidbad = _macutil.PROTO_UUIDS.get(_lightbluecommon.OBEX)
            else:
                uuidbad = None
                    
            filtered = _searchservices(iobtdevice, name=name, 
                uuid=_macutil.PROTO_UUIDS.get(servicetype), 
                uuidbad=uuidbad)
            
            #print "unfiltered:", iobtdevice.getServices()
            services.extend([_getservicetuple(s) for s in filtered])
        finally:            
            # close baseband connection (not sure if this is necessary, but 
            # sometimes the transport connection seems to stay open?)
            iobtdevice.closeConnection()
        
    return services
Example #14
0
 def initWithAddress_(self, address):
     try:
         attr = _IOBluetooth.IOBluetoothDevicePair
     except AttributeError:
         raise ImportError("Cannot find IOBluetoothDevicePair class " +\
             "to perform device discovery. This class was introduced in " +\
             "Mac OS X 10.7, are you running an earlier version?")
     self = super(_AsyncPair, self).init()
     self.device = _IOBluetooth.IOBluetoothDevice.withAddressString_(address)
     if not self.device:
         raise _lightbluecommon.BluetoothError(
             "Could not find device name for %s" % address) 
     self.pair = _IOBluetooth.IOBluetoothDevicePair.pairWithDevice_(self.device)
     if not self.pair:
         raise _lightbluecommon.BluetoothError(
             "Could not create pairing state machine.") 
     self.pair.setDelegate_(self)
     return self
Example #15
0
def advertise(name, sock, servicetype):
    if not isinstance(name, types.StringTypes):
        raise TypeError("name must be string, was %s" % \
            type(name))
        
    # raises exception if socket is not bound
    boundchannelID = sock._getport()
    
    # advertise the service
    if servicetype == _lightbluecommon.RFCOMM:
        try:
            result, finalchannelID, servicerecordhandle = _LightAquaBlue.BBServiceAdvertiser.addRFCOMMServiceDictionary_withName_UUID_channelID_serviceRecordHandle_(
                _LightAquaBlue.BBServiceAdvertiser.serialPortProfileDictionary(), 
                name, 
                None, None, None)
        except:
            result, finalchannelID, servicerecordhandle = _LightAquaBlue.BBServiceAdvertiser.addRFCOMMServiceDictionary_withName_UUID_channelID_serviceRecordHandle_(
                _LightAquaBlue.BBServiceAdvertiser.serialPortProfileDictionary(), 
                name, 
                None)       
    elif servicetype == _lightbluecommon.OBEX:
        try:
            result, finalchannelID, servicerecordhandle = _LightAquaBlue.BBServiceAdvertiser.addRFCOMMServiceDictionary_withName_UUID_channelID_serviceRecordHandle_(
                _LightAquaBlue.BBServiceAdvertiser.objectPushProfileDictionary(), 
                name, 
                None, None, None)
        except:
            result, finalchannelID, servicerecordhandle = _LightAquaBlue.BBServiceAdvertiser.addRFCOMMServiceDictionary_withName_UUID_channelID_serviceRecordHandle_(
                _LightAquaBlue.BBServiceAdvertiser.objectPushProfileDictionary(), 
                name, 
                None)       
    else:
        raise ValueError("servicetype must be either RFCOMM or OBEX")

    if result != _macutil.kIOReturnSuccess:
        raise _lightbluecommon.BluetoothError(
            result, "Error advertising service")
    if boundchannelID != finalchannelID:
        msg = "socket bound to unavailable channel (%d), " % boundchannelID +\
              "use channel value of 0 to bind to dynamically assigned channel"
        raise _lightbluecommon.BluetoothError(msg)
    
    # note service record handle, so that the service can be stopped later
    __advertised[id(sock)] = servicerecordhandle
Example #16
0
def _gethostname():
    sock = _gethcisock()
    try:
        try:
            name = _lightblueutil.hci_read_local_name(sock.fileno(), 1000)
        except IOError, e:
            raise _lightbluecommon.BluetoothError(str(e))
    finally:
        sock.close()
    return name
Example #17
0
def gethostaddr():
    sock = _gethcisock()
    try:
        try:
            addr = _lightblueutil.hci_read_bd_addr(sock.fileno(), 1000)
        except IOError, e:
            raise _lightbluecommon.BluetoothError(str(e))
    finally:
        sock.close()

    return addr
Example #18
0
def gethostclass():
    sock = _gethcisock()
    try:
        try:
            cod = _lightblueutil.hci_read_class_of_dev(sock.fileno(), 1000)
        except IOError, e:
            raise _lightbluecommon.BluetoothError(str(e))
    finally:
        sock.close()

    return _lightbluecommon._joinclass(cod)
Example #19
0
    def run(self, getnames=True, length=10):
        self._founddevices = []

        self._inquiry = _MyDiscoverer(self._founddevice, self._inquirycomplete)
        try:
            self._inquiry.find_devices(lookup_names=getnames, duration=length)

            # block until inquiry finishes
            self._inquiry.process_inquiry()
        except bluetooth.BluetoothError, e:
            try:
                self._inquiry.cancel_inquiry()
            finally:
                raise _lightbluecommon.BluetoothError(e)
Example #20
0
def finddevicename(address, usecache=True):
    if not _lightbluecommon._isbtaddr(address):
        raise ValueError("%s is not a valid bluetooth address" % str(address))
        
    if address == gethostaddr():
        return _gethostname()
    
    try:
        # lookupName() expects address without colon separators
        import _lightblueutil        
        address_no_sep = address.replace(":", "").replace("-", "")
        name = _lightblueutil.lookupName(address_no_sep, (not usecache))
    except SymbianError, e:
        raise _lightbluecommon.BluetoothError(
            "Cannot find device name for %s: %s" % (address, str(e)))
Example #21
0
def findservices(addr=None, name=None, servicetype=None):
    if servicetype not in (_lightbluecommon.RFCOMM, _lightbluecommon.OBEX, None):
        raise ValueError("servicetype must be RFCOMM, OBEX or None, was %s" % \
            servicetype)

    if addr is None:
        try:
            founddevices = finddevices()
        except _lightbluecommon.BluetoothError, e:
            msg = "findservices() failed, " +\
                    "error while finding devices: " + str(e)
            raise _lightbluecommon.BluetoothError(msg)
            
        #print founddevices
        addresses = [dev[0] for dev in founddevices]
Example #22
0
def finddevicename(address, usecache=True):
    if not _lightbluecommon._isbtaddr(address):
        raise ValueError("%s is not a valid bluetooth address" % str(address))

    if address == gethostaddr():
        return _gethostname()

    if usecache:
        name = _devicenames.get(address)
        if name is not None:
            return name

    name = bluetooth.lookup_name(address)
    if name is None:
        raise _lightbluecommon.BluetoothError(
            "Could not find device name for %s" % address)
    _devicenames[address] = name
    return name
Example #23
0
def finddevicename(address, usecache=True):
    if not _lightbluecommon._isbtaddr(address):
        raise TypeError("%s is not a valid bluetooth address" % str(address))

    if address == gethostaddr():
        return _gethostname()

    device = _IOBluetooth.IOBluetoothDevice.withAddressString_(address)
    if usecache:
        name = device.getName()
        if name is not None:
            return name
    
    # do name request with timeout of 10 seconds    
    result = device.remoteNameRequest_withPageTimeout_(None, 10000)
    if result == _macutil.kIOReturnSuccess:
        return device.getName()
    raise _lightbluecommon.BluetoothError(
        "Could not find device name for %s" % address)      
Example #24
0
def findservices(addr=None, name=None, servicetype=None):
    # This always passes a uuid, to force PyBluez to use BlueZ 'search' instead
    # of 'browse', otherwise some services won't get found. If you use BlueZ's
    # <sdptool search> or <sdptool records> sometimes you'll get services that
    # aren't returned through <sdptool browse> -- I think 'browse' only returns
    # services with recognised protocols or profiles or something.

    if servicetype is None:
        uuid = "0100"  # L2CAP -- i.e. pretty much all services
    elif servicetype == _lightbluecommon.RFCOMM:
        uuid = "0003"
    elif servicetype == _lightbluecommon.OBEX:
        uuid = "0008"
    else:
        raise ValueError("servicetype must be RFCOMM, OBEX or None, was %s" % \
            servicetype)
    try:
        services = bluetooth.find_service(name=name, uuid=uuid, address=addr)
    except bluetooth.BluetoothError, e:
        raise _lightbluecommon.BluetoothError(str(e))
 def __startevents(self):
     if self.__eventlistener is not None:
         raise _lightbluecommon.BluetoothError("socket already listening")
     self.__eventlistener = self.__createlistener()
Example #26
0
def selectdevice():
    import _lightblueutil
    try:
        result = _lightblueutil.selectDevice()
    except SymbianError, e:
        raise _lightbluecommon.BluetoothError(str(e))
Example #27
0
def _gethcisock(devid=-1):
    try:
        sock = _bluetooth.hci_open_dev(devid)
    except Exception, e:
        raise _lightbluecommon.BluetoothError("Cannot access local device: " +
                                              str(e))
# Copyright (c) 2009 Bea Lam. All rights reserved.
Example #29
0
def gethostclass():
    cod = _LightAquaBlue.BBLocalDevice.getClassOfDevice()
    if cod != -1:
        return int(cod)
    raise _lightbluecommon.BluetoothError("Cannot read local device class")                            
Example #30
0
def _gethostname():
    name = _LightAquaBlue.BBLocalDevice.getName()
    if name is not None:
        return name
    raise _lightbluecommon.BluetoothError("Cannot read local device name")