Service plugins using the new GATT API may need to know if their
attributes were successfully registered. In this way, plugins might
abort loading operation if they weren't registered.
This new internal API can be used for implementing GATT services (server
role). It is built around the current attribute API (attrib_db_add() and
others).
The enconding and decoding of ATT pdus should be kept as much
free of dependences from other parts of the code as possible, so
it can be used in many contexts.
In this case, for encoding and decoding notifications and indications
we did have to pass an instance of an attribute instead of direct
values.
Prior to this commit, the assignments were made with memcpy(). This can
be unsafe and less readable, therefore it was replaced with code like:
<dst> = *src;
This also allows more compiler safety checks.
On commit 6a6da5de10 the struct
attribute "data[0]" member was replaced with a dynamically allocated
"data" pointer. This commit fixes remaining places where the old
allocation scheme was still assumed.
In the Generic Attribute API, when DiscoverCharacteristics is called
ATT connection should be requested if the link is not up. A query
list is required to control when the link can be disconnected since
the discover finishes after receiving all caracteristic declarations.
In the Generic Attribute API, the ATT connection should be requested
on demand. In the case of watchers, the connection doesn't need to be
stay up if there isn't watcher registered.
Generic attribute API should not actively manage L2CAP connections.
GAttrib instance is notified through registered callbacks. SetProperty
or DiscoverCharacteristic now returns NotConnected error if the link
is down.
Get rid of local structure to store all GATT primary services of a
given device. "primary" struct has been renamed to "gatt_service"
to avoid misinterpretation or confusion with "att_primary".
This patch registers the object paths for primary services exported
through SDP. PSM, start and end handle information are available in
the Protocol Descriptor List.
The Characteristic read by UUID GATT procedure is not incremental, i.e.
it returns the entire list in a single Read By Type request. Therefore
it should not be called recursively.
The attrib plugin is deprecated and it is not used anymore. Remove it
and all related configuration. Note that GATT utility (gatttool)
configuration item was moved to Makefile.tools and it is compiled when
--enable-tools is used in configure.
In some cases, when the device is already connected there's no need
to create another GAttrib instance.
This will allow the Attrib client to use the connection already
estabilished, this will be very useful when we support more
LE profiles.
Now that Attrib client is being moved to the core, there's no
need to have explicit _init and _exit methods.
This also means that we need to pass the DBusConnection explicitly
to the registration method.
The new buffer is allocated in g_attrib_new() and it will be used to
send/receive PDUs. The buffer size is the MTU read from L2CAP channel
limited to ATT_MAX_MTU. Functions to handle the buffer size were also
created.
According to the specification the characteristics discover and
characteristics discover by UUID use the same opcode and the result
should be filtered by callback.
This patch puts the new UUID functions into use for GATT-related
code, and adds some convenience functions to ATT API (att.h).
Example GATT server is also changed.
When the connection fails an error should be returned to inform
the user.
This adds a field to store the DBusMessage that caused the error,
so we can send the correct reply.
The previous behaviour could lead to some problems, as it returned
as soon as possible. To avoid problems we return just after as the
characteristics are discovered, and to save a few round trips we
return the path of all characteristics that belong to this service.
After this method return it will try to read the characteristics
values.
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.