module lightblue.obex:

class OBEXClient

    An OBEX client class. (Note this is not available on Python for Series 60.)

    For example, to connect to an OBEX server and send a file:
        >>> import lightblue
        >>> client = lightblue.obex.OBEXClient("aa:bb:cc:dd:ee:ff", 10)
        >>> client.connect()
        <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
        >>> client.put({"name": "photo.jpg"}, file("photo.jpg", "rb"))
        <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
        >>> client.disconnect()
        <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
        >>>
A client must call connect() to establish a connection before it can send any other requests. The connect(), disconnect(), put(), delete(), get() and setpath() methods all accept the request headers as a dictionary of header-value mappings. The request headers are used to provide the server with additional information for the request. For example, this sends a Put request that includes Name, Type and Length headers in the request headers, to provide details about the transferred file:
        >>> f = file("file.txt")
        >>> client.put({"name": "file.txt", "type": "text/plain",
        ...         "length": 5192}, f)
        >>>
Here is a list of all the different string header keys that you can use in the request headers, and the expected type of the value for each header: - "name" -> a string - "type" -> a string - "length" -> an int - "time" -> a datetime object from the datetime module - "description" -> a string - "target" -> a string or buffer - "http" -> a string or buffer - "who" -> a string or buffer - "connection-id" -> an int - "application-parameters" -> a string or buffer - "authentication-challenge" -> a string or buffer - "authentication-response" -> a string or buffer - "creator-id" -> an int - "wan-uuid" -> a string or buffer - "object-class" -> a string or buffer - "session-parameters" -> a string or buffer - "session-sequence-number" -> an int less than 256 (The string header keys are not case-sensitive.) Alternatively, you can use raw header ID values instead of the above convenience strings. So, the previous example can be rewritten as:
        >>> client.put({0x01: "file.txt", 0x42: "text/plain", 0xC3: 5192},
        ...     fileobject)
        >>>
This is also useful for inserting custom headers. For example, a PutImage request for a Basic Imaging client requires the Img-Descriptor (0x71) header:
        >>> client.put({"type": "x-bt/img-img",
        ...     "name": "photo.jpg",
        ...     0x71: '<image-descriptor version="1.0"><image encoding="JPEG" pixel="160*120" size="37600"/></image-descriptor>'},
        ...     file('photo.jpg', 'rb'))
        >>>
Notice that the connection-id header is not sent, because this is automatically included by OBEXClient in the request headers if a connection-id was received in a previous Connect response. See the included src/examples/obex_ftp_client.py for an example of using OBEXClient to implement a File Transfer client for browsing the files on a remote device.

Methods

__init__(address, channel)

    Creates an OBEX client.

    Arguments:
        - address: the address of the remote device
        - channel: the RFCOMM channel of the remote OBEX service

connect(headers={})

    Establishes the Bluetooth connection to the remote OBEX server and sends
    a Connect request to open the OBEX session. Returns an OBEXResponse 
    instance containing the server response.
    
    Raises lightblue.obex.OBEXError if the session is already connected, or if
    an error occurs during the request.
    
    If the server refuses the Connect request (i.e. if it sends a response code
    other than OK/Success), the Bluetooth connection will be closed.

    Arguments:
        - headers={}: the headers to send for the Connect request

disconnect(headers={})

    Sends a Disconnect request to end the OBEX session and closes the Bluetooth
    connection to the remote OBEX server. Returns an OBEXResponse 
    instance containing the server response.
    
    Raises lightblue.obex.OBEXError if connect() has not been called, or if an
    error occurs during the request.

    Note that you don't need to send any connection-id headers - this is
    automatically included if the client received one in a Connect response.

    Arguments:
        - headers={}: the headers to send for the request

put(headers, fileobj)

    Sends a Put request. Returns an OBEXResponse instance containing the
    server response.

    Raises lightblue.obex.OBEXError if connect() has not been called, or if an
    error occurs during the request.

    Note that you don't need to send any connection-id headers - this is
    automatically included if the client received one in a Connect response.

    Arguments:
        - headers: the headers to send for the request
        - fileobj: a file-like object containing the file data to be sent for
          the request

    For example, to send a file named 'photo.jpg', using the request headers 
    to notify the server of the file's name, MIME type and length:
        >>> client = lightblue.obex.OBEXClient("aa:bb:cc:dd:ee:ff", 10)
        >>> client.connect()
        <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
        >>> client.put({"name": "photo.jpg", "type": "image/jpeg",
                "length": 28566}, file("photo.jpg", "rb"))
        <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
        >>>

delete(headers)

    Sends a Put-Delete request in order to delete a file or folder on the remote
    server. Returns an OBEXResponse instance containing the server response.

    Raises lightblue.obex.OBEXError if connect() has not been called, or if an
    error occurs during the request.

    Note that you don't need to send any connection-id headers - this is
    automatically included if the client received one in a Connect response.

    Arguments:
        - headers: the headers to send for the request - you should use the
          'name' header to specify the file you want to delete

    If the file on the server can't be deleted because it's a read-only file,
    you might get an 'Unauthorized' response, like this:
        >>> client = lightblue.obex.OBEXClient("aa:bb:cc:dd:ee:ff", 10)
        >>> client.connect()
        <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
        >>> client.delete({"name": "random_file.txt"})
        <OBEXResponse reason='Unauthorized' code=0x41 (0xc1) headers={}>
        >>>

get(headers, fileobj)

    Sends a Get request. Returns an OBEXResponse instance containing the server 
    response.

    Raises lightblue.obex.OBEXError if connect() has not been called, or if an
    error occurs during the request.

    Note that you don't need to send any connection-id headers - this is
    automatically included if the client received one in a Connect response.

    Arguments:
        - headers: the headers to send for the request - you should use these
          to specify the file you want to retrieve
        - fileobj: a file-like object, to which the received data will be
          written

    An example:
        >>> client.connect()
        <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
        >>> f = file("received_file.txt", "w+")
        >>> client.get({"name": "testfile.txt"}, f)
        <OBEXResponse reason='OK' code=0x20 (0xa0) headers={'length':9}>
        >>> f.seek(0)
        >>> f.read()
        'test file'
        >>>

setpath(headers, cdtoparent=False, createdirs=False)

    Sends a SetPath request in order to set the "current path" on the remote
    server for file transfers. Returns an OBEXResponse instance containing the 
    server response.

    Raises lightblue.obex.OBEXError if connect() has not been called, or if an
    error occurs during the request.

    Note that you don't need to send any connection-id headers - this is
    automatically included if the client received one in a Connect response.

    Arguments:
        - headers: the headers to send for the request - you should use the
          'name' header to specify the directory you want to change to
        - cdtoparent=False: True if the remote server should move up one
          directory before applying the specified directory (i.e. 'cd
          ../dirname')
        - createdirs=False: True if the specified directory should be created
          if it doesn't exist (if False, the server will return an error
          response if the directory doesn't exist)

    For example:
        # change to the "images" subdirectory
        >>> client.setpath({"name": "images"})
        <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
        >>>
        # change to the parent directory
        >>> client.setpath({}, cdtoparent=True)
        <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
        >>>
        # make a directory "My_Files"
        >>> client.setpath({"name": "My_Files"}, createdirs=True)
        <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
        >>>
        # change to the root directory - you can use an empty "name" header
        # to specify this
        >>> client.setpath({"name": ""})
        <OBEXResponse reason='OK' code=0x20 (0xa0) headers={}>
        >>>