Sub-procedure used to write a Characteristic Value to a server when
the client knows the Characteristic Value Handle and the client does
not need acknowledgement.
If callback is not informed, Write Command will be used to execute
a Write Without Response sub-procedure. Error is not returned by the
server no matter the result of the operation.
This patch adds support to destroying the GATT connection
when a GATT server doesn't respond for more than 30 seconds.
A function to destroy the GAttrib is introduced and it is used
in the timeout case and when the last GAttrib reference is
dropped.
These callbacks will allow profiles to act before an attribute is read
and after it is written, to e.g. update the attribute value to/from an
external source.
Note that by the time the callback is called, the necessary security
checks (attribute permissions, authentication and encryption) were
already performed by the core attribute server.
The callback can optionally return an ATT status code, which will be
sent to the client using an Error Response PDU.
GATT related SDP records should not be added if "AttributeServer" option
is false in the configuration file. Problem happens only when attribute
plugin is enabled.
Removes "le" parameter of gatt_connect() as well the global variables
used to store the le option. LE is now the default transport, if a PSM
value different than zero is given BR/EDR will be selected
Mode required to allow better GATT procedures control. Some scenarios
require sequential commands without disconnection and delay between
operations. It is also desirable to change some connection parameters
of an active connection.
It is important for the Attribute Server to be aware of and completely
fill response packets up to the full MTU when reading long attributes.
Some remote devices will only request additional (READ_BLOB) data if the
preceding read sent the maximum amount of data.
Incoming connections are identified as L2CAP or LE by pointers to the
Service IO channel the incoming connection was recieved on in the
user_data parameter. L2CAP channels are set to the BR/EDR minimum MTU of
48, and LE channels to the LE payload size of 23.
The attribute client (attrib/client.c) and gatttool share similar code
to parse the PDU coming from server. This commit moves this common code
to attrib/gatt.c, and simplifies the callbacks implemented by the
clients. The client callbacks are now called just once and get a GSList
of characteristics, instead of the raw PDU.
GATT service (like GAP one) should be moved to the core attribute server
because there can be only one instance of it.
There was a "Attribute Opcodes Supported" characteristic inside the GATT
service in attrib/example.c which is not defined by the Core
specification and was removed before moving the code.
GAP service shall be registered only once, so it makes sense to move it
to the core attribute server code.
The GAP "Device Name" characteristic was always "Example Device" on the
example server. This has been changed to use the Name attribute from
main.conf.
Fix gatt_read_char() to support long Attribute Values by recognizing
that results longer that 21 octets may include data beyond
what has been returned with the first read. Extra data is
obtained by issuing READ_BLOB requests until either a
result is returned shorter than 22 octets, or an error
is recieved indicating that no further data is available.
The API for this function has not changed.
Overall purpose of change is to enable a GATT procedure to be
executed atomically, even if it requires multiple ATT
request/response transactions.
Fix g_attrib_send() to include an ID parameter, if the pkt to
be sent should be added to the Head of the pkt queue. If the
ID is Zero, legacy functionality is maintained, and the pkt will
be added at the tail of the queuer, and a new ID will be generated,
and returned to the caller. If ID is non-zero, the pkt will be
added to the head of the queue, with the ID value requested, which
will also be returned to the caller.
Fix received_data() to not service the send queue until after the
received data has been processed by calling the cmd->func()
callback, to allow the callback to insert another pkt on the head
of the queue.
Fix all callers of g_attrib_send() to include new parameter.
If a characteristic requires a higher security level, change it on
demand and re-send the GATT Charateristic Value Read. Request will not
be sent until the SMP negotiation finishes. This change doesn't affect
GATT over BR/EDR, since encryption is mandatory for BR/EDR.
Now GATT client should be able to make LE connections. The information
used to determine if we should make a LE connection is the psm stored
in the gatt_service structure.
As the comparison method used for find what to de-register was
wrong, it was causing the btd_device reference that the attrib
plugin was keeping never to be dropped.
DBus error handling in BlueZ is a mess. This is the first patch to unify
all DBus error handling like in ConnMan and oFono. This unifies all
.InvalidArguments errors.
If the GIOChannel is in the buffered state (the default) the watch
function is called without receiving a POLLOUT from the socket. GLib
adds a G_IO_OUT condition just because there is space in the GIOChannel
internal buffer.
The solution is disabling the internal buffer, which in turn, makes the
call of g_io_channel_flush() useless.
Add enums for attribute read/write requirements, which may be "none",
"authentication required" or "authorization required". Additionally, a
"not permitted" requirement means that operation is not permitted,
allowing read-only or write-only attributes.
The attrib_db_add() API was changed to allow setting these requirements,
and the example server was changed to set requirements for its
attributes.
Discover All Primary Services should not be trigged by the attribute
client when a given device is registered. Discover services is now done
by the device entity.
Discover primary services implemented inside the device entity to allow
proper integration of attribute plugin. Implements a single entry point
to the attribute plugin no matter the transport(BR/EDR or LE), the device
probe callback is called for both types.
Add a new function to discover all primary services without additional
calls to fetch the remaining primary services, sub-procedure iterations
is handled inside this function.
The next action are: clean the attribute client removing implicity service
and characteristics discovery, issue the Discover Primary Service based on
the remote properties and fetch the characteristic on demand.
Sub-procedure used to read a Characteristic Value when the client
only knows the characteristic UUID and doesn't know the handle.
More than one handle and attribute value pair can be returned,
it is up to the user define the handles range based on the service
handles range.
Usage example:
$gatttool --char-read --uuid=2a00 -i hcix -b xx:xx:xx:xx:xx:xx
Implement only the first interaction of the discovery procedure. If the
response doesn't fit in the MTU, "start" and "end" options can be used
to discover the handles ranges of the remaining primary service instances.
UUID16 and UUID128 are supported in the uuid option.
Usage example:
$gatttool -i hcix -b xx:xx:xx:xx:xx:xx --uuid=1801 --primary
Extends discover primary function to perform discover by UUID. UUID
parameter defines which procedure will be executed: Discover All
Primary Services or Discover Primary Service by Service UUID.
Implement encoders/decoders for Write Request/Response and the handling
on attribute server. The attribute client still uses the Write Command
because currently SetProperty() has no means to wait for the server
response.
Add an optional Client Characteristic Configuration attribute for
Battery State to control which clients want notification/indication
when this attribute value changes.
Add new option --char-write for char value write (write without
response). Reuse current handle option and create the -n for new value.
Update variable names and help messages.
Note: characteristics_write callback is empty.
Initial implementation of SetProperty. Add D-Bus method declaration and
extracts the arguments. The new requested characteristic value is not being
sent to the remote device yet.
GAttrib ref counter shall be used to control when the remote shall be
disconnected. Ref counter is incremented when the watcher is registered
and decremented when it leaves the bus.
When multiples requests are queued, GAttrib ref count shall be
incremented to control disconnection. Allowing to disconnect from the
remote only the last response is received. This approach allow to
address errors and continue to process queued requests.
In the client, after local or remote initiated disconnection the GAttrib
reference shall be set to NULL to allow a proper control of references
and further connections.
Add a new function to notify the GAttrib "users" when the GAttrib has
beed destroyed. The disconnect function is called only for remote initiated
disconnections or external events(not unref).
Thermometer Humidity Service contains <<Include>> attributes that it is
not supported at the momment. For this service, Characteristics D-Bus
paths are not being registered properly. This patch allows watchers
testing registered for Battery State changes.
Each registered watcher instance is associated with a characteristic
path. Value() method shall not be sent to all watchers, characteristic
path shall match.
This adds support for calling the ValueChanged() method on the registered
watcher, when a characteristic on the associated service gets updated.
For now this method will be called when we get a Notification or an
Indication from the server.
When receiving a Indication from the server, the Characteristic Value
associated with that indication is updated.
There's still no support for updating Characteristic Descriptors in
case they arrive, primarily because we don't know if it makes sense.
Now gatttol is able to receive indication events and repond to them.
For now, this response is just sending the confirmation response back
to the server and printing the received update.
When there is watcher active, the client shall set the Client
Characteristic Configuration attribute to receive Notifications or
Indications. This patch introduces the initial changes to re-connect and
watch for events.
For descriptors, a comment is added explaining why UUID 128-bit support
is not necessary yet. For characteristic discovery, characteristics with
128-bit UUID types are now loaded.
This primary service contains 128-bit UUIDs on the service declaration
and characteristic declaration attributes, useful to test the 128-bit
UUID support.
Besides registering the characteristics when we receive the Attribute
Not Found Error, we should also register the characteristics when we
get to the end of the handle range contained in that service.
When using the minimum MTU, in some cases, mostly when using 128-bit UUIDs,
the PDU is exactly the size of the minimum MTU. In those case there were
off-by-one errors. Errors are returned if can't put anything useful inside
the requested PDU.
In some cases, there could be a file descriptor leak, when the
connection is not succesful. As the connection callback keeps a
reference, there's no problem unref'ing it at this point.
When encoding long responses, there could be situations where the
attribute value length could be larger than the buffer size and the
encoder would try to put more data than the space available.
When GAttrib last reference is dropped inside the command callback,
there was a invalid memory access. For now, there's a small time
window between the last reference being dropped and GAttrib being
free'd.
The encoding functions should return only the bytes which can be
inserted in buffer (maximum size is defined by ATT_MTU). The other ones
should be requested by client again.
Create a new storage called "attributes" to save attribute data.
Format description:
<bt_addr>#<attr_handle> <attr_type>#<attr_value>
- the key is composed of the device address and the attribute handle;
- the value is composed of the attribute type UUID (converted to
printable 128-bit format) and the attribute value (hex encoded).
- the key/value components are joined with "#", and separated from each
other by a space.
The --start/--end options are reused to allow specifying the
starting/ending handles. Both 16-bit and 128-bit UUIDs are
pretty-printed using sdp_uuid2strn() function.
Initial changes in attribute server to send notifications to all
connected clients when an attribute has changed. Characteristic
Configuration descriptor is not being addressed yet.
When encoding/decoding PDU fields, we have to be careful and use
alignment safe functions to load/store the values.
These functions will be exported so other parts of the code can reuse
them.
When doing the Descriptor Discovery procedure, the wrong starting
handle was being used (the characteristic value handle). This is what
the spec mandates:
"The Attribute Protocol Find Information Request shall be used with the
Starting Handle set to the handle of the specified characteristic value
+ 1 and the Ending Handle set to the ending handle of the specified
characteristic."
This adds support for cancelling commands. In case the command to be removed
is the first in the queue, cancelling it would cause its ResultFunc to not be
called. In the other cases, it will be removed from the queue.
We need to be more specific about what is the expected response opcode
(if any) for each request command and about if some command is already a
response.
Unix channel reference count must be decremented before exiting. Do not
exit main loop on recursive callbacks, thus allowing queued
g_attrib_send() commands to be finished. Free memory allocated for
opt_src/opt_dst.
All descriptors associated to every characteristic are discovered, which means,
that we know its handle and type. With this information we can later read the
values of the descriptors that we find interesting.
The new option is useful for reading either characteristic values or
descriptors, which use the same Read Request. This commit also fixes a
few errors related to the handle options.
The connection operations (do_connect) were moved to main. So, the
internal call to do_connect() were removed and GAttrib structure is
initialized/freed in main. All callbacks receive the GAttrib structure
through the user_data parameter.
The primary callback in gatttool was updated to use
dec_read_by_grp_resp() function. Also, the printed message was updated
to use same spec nomenclature.
Characteristic objects shall provide GetProperties() method. Primary
service objects: GetCharacteristics(), RegisterCharacteristicsWatcher()
and UnregisterCharacteristicsWatcher().
Now every known characteristic object is restored from storage with
essential information. Each characteristic DBus object path is registered
from that information.
This adds support for loading the GATT primary services information
that may exist. This will allow registering the DBus interface of a
service without connecting to the remote device.
Returns an attribute data list containing found services. Each
element of the list contains the start, end group handle and the
UUID16 of the given service. UUID128 is not being addressed yet.
This adds encoders and decoders for Requests and Responses of this type. The
value extracted/inserted is just copied, the user shall ensure that it is in
the right byte order.
Add new command line options to change the fields of discover primary
services requests:
--start: Starting handle(default 0x0001)
--end: Ending handle(default 0xffff)
Add all attributes of the Thermometer Primary Service according to
example described in the SPEC. See "APPENDIX: Example Attribute
server attributes". Includes of secondary services are not supported yet.
Add all attributes of the Battery Primary Service according to example
described in the SPEC. See "APPENDIX: Example Attribute server
attributes". Battery service and state UUID are not defined yet, random
values have been selected: 0xA002 and 0xA003.
Add all attributes of the GATT Primary Service according to example
described in the SPEC. See "APPENDIX: Example Attribute server
attributes". Attribute Opcodes Supported UUID is not defined yet, a
random value has been selected: 0xA001.