Since IV Index is used in application nonces, we need to honor IVI flag
not only in network layer crypto, but also in application layer.
This means that if IVI field of incoming packet is different than in
current IV Index, try to decode *both* net and app layers using IV Index
decreased by one.
This removes check for "mesh" as the parent directory name and, instead,
verifies that the node configuration directory name is the hexadecimal
string representating the node's UUID.
Mesh daemon internally implements the Config Server SIG model.
When generating node, if the Mesh Element in mesh application
returns modelId 0 among its supported models, it should be skipped,
otherwise it will be duplicated and saved in the storage file.
This patch fixes correctly skipping Config Server model during node
creation.
This patch separates 'mesh' module from 'mesh_io', particularly
regarding configuration and initialization.
Main code is no longer aware of MGMT and HCI usage - querying available
HCI interfaces now happens in mesh-io-generic.
MGMT code is now extracted into mesh-mgmt module, which mesh-io-generic
uses to query interfaces.
This patch cleans up redundant checks in add_key() and mesh_net_set_key():
no need to check the result of l_queue_push_tail() and no need to check
if subnet is valid after it was successfully created.
This patch modifies the behavior of node configuration parsing:
if "elements" property is not present, th configuration file
for this node is regarded as malformed.
Also, clean up style.
Due to known AEAD encryption deficiencies in old versions of the
kernel, we have added a section on identifying and back-porting
mesh to otherwise non-supporting platforms.
Implements following org.bluez.mesh.Management1 methods:
ImportRemoteNode()
DeleteRemoteNode()
These methods are used to maintain Device Key keyring storage.
Implements following org.bluez.mesh.Management1 methods:
CompleteAppKeyUpdate()
SetKeyPhase()
These methods are used to maintain Key Refresh settings
in the keyring storage.
Implements following org.bluez.mesh.Management1 methods:
CreateAppKey()
ImportAppKey()
UpdateAppKey()
DeleteAppKey()
These methods are used to maintain App Key keyring storage.
Implements following org.bluez.mesh.Management1 methods:
CreateSubnet()
ImportSubnet()
UpdateSubnet()
DeleteSubnet()
These methods are used to maintain Net Key keyring storage.
This adds check for the presence of org.bluez.mesh.Provisioner1
interface when collecting information about mesh application
that is received in callback of GetManagedObjects() method.
Set "provisioner" flag in the node structure to trueto indicate
that the node may act aa a provisioner.
This implements internal key storage add/delete/fetch for the three
basic key types managed in Mesh: Network, Application and Device.
This key storage is separate from keys assigned to nodes within the
mesh, and are used to support Configuration Client functionality.
Add a tree structure to a nodes data storage, in order to safely handle
Replay Protection list, Refactor local Sequence Numbers, and add Key
storage for Config Client nodes.
This implements CreateNetwork() method on org.bluez.mesh.Network1
interface. Invoking this method generates a self-provisioned
local node associated with a brand new mesh network. This new
network is bare bones: only one network key is defined. The new node
assumes the role of mesh network manager and will be able to use
soon to be implemented methods of org.bluez.mesh.Management1 interface
to provision remote nodes into its network and to add/update/remove
network and application keys.
Instead of keeping track of unique 16bit node identifiers, reuse their
UUIDs to create both storage directories and dbus objects.
Because of that:
- UUID is no longer stored in the JSON file, it's inferred from the
directory name instead
- Join(), CreateNetwork() and ImportLocalNode() APIs return an error if
given UUID already registered within the daemon
Consolidate functions to parse and process properties of mesh
element objects. Also, add validation of element composition
when processing Attach() method.
This changes the prototype for the callback function of
Attach() method call: remove unused node_path argument and make the
callback more generalized and re-usable for other method calls.
This fixes the accidental swap of conditional checks: on failure,
remove agent info if agent is registered and remove temporary node,
if one has been created.
If a node is already attached to an application process,
disallow another appication to attach to the same node.
This means that an Attach() method called with the token
identifying a node that is already in use, returns an error
org.bluez.mesh.Error.AlreadyExists
Fix issue assuming that failed calls to json_object_object_get_ex() will
always NULL the out parameter. Re-coded to always check the returned
boolean for success or failure.
This fixes the situation when a new app key binding is being
added to a model and the list of bindings does not exist yet.
If the list does not exist, it is created and the binding is
added to it.
Also, remove unnecessary memory alloc check when model subscriptions
are added.
Use correct parameters when calling l_dbus_message_iter_get_fixed_array().
Also, check the return value and the length of the processed array and
return an error if the checks fail.
This implements D-Bus Leave() method that results in complete removal
of node information from the system, including configuration files
from storage directory.
To remove a node config directory completely, the directory
needs to be empty. Both node.json and node,json.bak files must
are deleted.
Also, change storage_save_config() type to void to eliminate
meaningless checks.
This separates mesh_db_app_key_add() into distinct functions:
mesh_db_app_key_add() and mesh_db_app_key_update() which will be called
based on whether an application key is newly added or updated.
This splits appkey_key_add() into two separate functions:
app_key_add() and app_key_update().
Fix checks for miscellaneous invalid conditions and return
appropriate error status.
This separates mesh_db_net_key_add() into distinct functions:
mesh_db_net_key_add() and mesh_db_net_key_update() which will be called
based on whether a network key was newly added or updated.
This adds implementation for saving the key refresh phase to
a node configuration file in JSON format. When the key refresh
procedure is finished, the old network keys are remove from the
configuration file.
This renames mesh_net_key_refresh_finish() to key_refresh_finish() and
mesh_net_key_phase_two() to key_refresh_phase_wo() and changes the
function declaration to static since they are called only within net.c
This creates subnet state based on saved network key state:
current keys and, if present, updated keys.
Secure network beacon is generated according to key refresh phase.
This splits mesh_net_key_add() into two separate functions:
mesh_net_key_add() and mesh_net_key_update().
mesh_net_key_update() essentially replaces mesh_net_kr_phase_one()
since switching to Key Refresh phase one can only be triggered
by successful network key update.
If Daemon is started with an explicit controller specified, the
MGMT search for an unused shared controller is bypassed, and
the controller is opened directly.
Do not call acceptor_cancel() if the provisioning has been completed,
either fail or success. Acceptor automatically takes care of cleanup
on completion, either successful or not.
Relay is now a cooperation between all the nodes on the daemon.
If any one or more nodes have relay enabled and a received packet
is addressed to a Group, or a non-present Unicast address, then the
packet's TTL is decremented and it is resent.
Consolidate multiple instances where the pending Join data is freed
into calling one function free_pending_join_call().
Also, add checks for NULL data in cleanup functions for storage, agent
and provisioning acceptor.
Fix miscellaneous issues: use l_debug instead of l_info for debug logs;
remove "local" from functions names (this handles only local app keys);
add missing App Key index initialization.
This implements the time limited and user interaction D-Bus API as
required for Out-Of-Band authentication during provisioning, and as
described in doc/mesh-api.txt.
This handles checking that incoming Mesh messages obey all
authentication rules regarding subscriptions and encryption
key bindings on a per node basis, before forwarding via D-Bus
to external applications that are authorized to handle them.
Restructured access to Bluetooth Controllers to allow the usage of
multiple controllers, and potentially functionality tailored to Mesh
specific features.
The Config Server model is rewritten to allow control of mutiple nodes
on the local device. The updates to a node configuration (e.g., keys,
model subscriptions/publications, etc.) as set by a remote Config Client
are routed to a properly addressed node and stored in a protected
configuration file corresponding to that node.
This implements the following methods of org.bluez.mesh.Network
interface: Join(), Attach(), Cancel(). The methods are described in
doc/mesh-api.txt document.
Also, add changes to reflect that the single daemon now handles multiple
local mesh nodes.
Functionaility has been added to allow a BT 4.0 or later controller
to be used for Advertising based Mesh usage, regardless of how it
was previously initialized.
This functionaility (originally found in provision.c) was rewritten
as the Initiator side only of the provisioning procedure. If the
local device owns and controls access to a mesh network, this is the
side of the provisioning procedure that it must use to bring new
unprovisioned devices into the network as Nodes.
This implements acceptor side of the provisioning procedure when an
unprovisioned device is brought into an existing mesh network by a
remote Provisioner. Upon the successful completion of the procedure
the device becomes a participating mesh node in thie network.
Originally found in prov.c, this file implements the PB-ADV
provisioning transport. It may be used by either the
Acceptor or the Initiator side of the Provisioning procedure,
but only one session may be active at a time.
The Network layer of the Mesh Daemon has access to all
network keys that have been entrusted to Nodes on the local
device, and acts as a MUX by forwarding incoming messages
to some, all or none of the local Nodes, based on addressing
and keys.
It also is reponsible for for applying Network layer encryption
to outgoing messages, and for relaying messages based on TTL.
Add support for maintaining multiple local nodes within a single daemon.
A mesh node is an adressable entity in Bluetooth mesh. A local mesh
capable device may have multiple distinct representations as a mesh
node on different mesh networks. Each such representation (aka "node
configuration") maintains runtime storage of encryption/decryption
keys, model subscriptions and publications, etc.
Also, implement D-Bus methods for org.bluez.mesh.Node interaface:
Send(), Publish(), VendorPublish()
Also, add support for generating temporary mesh node entity for Join()
method and verification of credentials for Attach() method
Multiple node configurations are now stored in priviledged location
to prevent unauthorized access to the security material entrusted to
each node.
Default storage location is /var/lib/bluetooth/mesh.
Delete composition.json since it not used for initialization anymore.
Delete btmesh.c as it is not used anymore.
Delete display.c and display.h, move retained functionality to util.c
Delete prov.c, move retained PB-ADV functionality to pb-adv.c
Delete provision.c, split retained functionality between
prov-acceptor.c and prov-initiator.c
This allows co-existense of meshd and bluetoothd. meshd will
automatically take control of the first available LE-capable
controller that is powered down.
This fixes the following error:
mesh/cfgmod-server.c: In function ‘cfg_srv_pkt’:
mesh/cfgmod-server.c:103:5: error: ‘pub’ may be used uninitialized in
this function [-Werror=maybe-uninitialized]
In Mesh Profile spec 4.2.17.4 Heartbeat Publication TTL value range is
0x00-0x7F. In cmd_hb_pub_set heartbeat ttl was set to DEFAULT_TTL 0xFF, this
patch fix this by adding ttl param to hb-pub-set.
This addresses the following issue: if the program exits
after bt_shell_init() has been called, but prior to calling
bt_shell_run() (e.g., failing to start meshctl due to invalid
input configuration), the original shell is messed up after that.
Calling bt_shell_cleanup() on faiure fixes this.
In read_pipe function there was a mishandled case when the msg has
more than one segment. As a result e.g. after provisioning the
capabilities discovery was incorrect parsed.
On device disconnection, net session is not closed. On next
attempt to provision/connect a device, net session proxy is
not updated by net_session_open() as proxy_in is not NULL.
This causes meshctl to use invalid proxy resulting in below
crash.
0 strlen () at ../sysdeps/x86_64/strlen.S:106
1 0x00007f3a3c8b1ac4 in _dbus_string_init_const () from libdbus-1.so.3
2 0x00007f3a3c89ed15 in ?? () from libdbus-1.so.3
3 0x00007f3a3c89fba0 in dbus_message_new_method_call () from libdbus-1.so.3
4 0x0000000000419880 in g_dbus_proxy_method_call at gdbus/client.c:997
5 0x000000000040ab9d in mesh_gatt_write at mesh/gatt.c:347
6 0x000000000040d761 in send_mesh_pkt at mesh/net.c:1227
7 send_seg at mesh/net.c:1325
8 0x000000000040fa60 in net_access_layer_send at mesh/net.c:2163
9 0x0000000000413c74 in config_send at mesh/config-client.c:418
10 0x0000000000414886 in cmd_composition_get at mesh/config-client.c:470
11 0x000000000041ffd9 in cmd_exec at src/shared/shell.c:356
12 menu_exec at src/shared/shell.c:383
13 0x00000000004203a5 in shell_exec at src/shared/shell.c:426
14 0x0000000000420d24 in rl_handler (input=0x2259aa0 "composition-get ")
at src/shared/shell.c:571
15 0x00007f3a3c45d6f5 in rl_callback_read_char () from libreadline.so.6
16 0x0000000000420229 in input_read at src/shared/shell.c:1034
17 0x0000000000421655 in watch_callback at src/shared/io-glib.c:170
18 0x00007f3a3cb1a04a in g_main_context_dispatch () from libglib-2.0.so.0
19 0x00007f3a3cb1a3f0 in ?? () from libglib-2.0.so.0
20 0x00007f3a3cb1a712 in g_main_loop_run () from libglib-2.0.so.0
21 0x0000000000421bf5 in mainloop_run () at src/shared/mainloop-glib.c:73
22 0x000000000042115a in bt_shell_run () at src/shared/shell.c:962
23 0x0000000000405c5d in main at mesh/main.c:1992
Remove redundant status tests
mesh_status_str() also decodes MESH_STATUS_SUCCESS
Regularize text in status messages
Add helper function to print model id
Extract functionality for finding an existing model from
parse_configuration_models() into new function find_configured_model().
This removes confusing logic from overloaded implementation of
parse_configuration_models().
Add a CID parameter to both commands similar to bind.
Correct the prior assumption that a model id > 0xffff
was a vendor model.
pub-set 0100 c000 1 0 0 1000
03 0001 00c0 01 00 ff 00 00 0010
pub-set 0100 c000 1 0 0 1000 1
03 0001 00c0 01 00 ff 00 00 0100 0010
Setting identity will cause connectable identity
beacons to be transmitted. The connect command
has an option to connect in this mode.
Sets the identity state to 1 in node 0100 on network
0000.
[config: Target = 0100]# ident-set 0 1
Network index 0x0000 has Node Identity state 0x01 Success
Fetched the identity state from node 0100
[config: Target = 0100]# ident-get 0
Network index 0x0000 has Node Identity state 0x01 Success
Set the current proxy state of node 0100
Setting the proxy state to 0 will disconnect
the GATT proxy connection.
[config: Target = 0100]# proxy-set 1
Node 0100 Proxy state: 0x01
Get the current proxy state of element 0100
[config: Target = 0100]# proxy-get
Node 0100 Proxy state: 0x01
Get the publish address for model 1001 in element 0100
[config: Target = 0100]# pub-get 0100 1001
Set publication for node 0100 status: Success
Publication address: 0xc000
Period: 0 ms
Retransmit count: 0
Retransmit Interval Steps: 0
List application keys of model 1000 in element 0100.
[config: Target = 0100]# app-get 0100 1000
Model App Key list for node 0100 length: 7 status: Success
Element Addr: 0100
Model ID: 1000
Model App Key: 0001
Adds a subscription for group address c000 to
model 1000 in element 0100.
[config: Target = 0100]# sub-add 0100 c000 1000
Subscription changed for node 0100 status: Success
ModelId 1000
Element Addr: 0100
Subscr Addr: c000
Gets the current subscription list for model 1000
on element 0100.
[config: Target = 0100]# sub-get 0100 1000
Subscription list for node 0100 length: 7 status: Success
Element Addr: 0100
Model ID: 1000
Subscr Addr: c000
If the first command output in a new connection exceeds 20 bytes,
mesh_gatt_write sets the SAR to FIRST as the write_mtu is initially 0
and the default is GATT_MTU-3 (20).
When pipe_write gets called, a new larger write_mtu has been set, but
the SAR is still set to FIRST. It's assumed that data->gatt_len >
max_len. However, it's not which causes lots of bogus output.
This adds the option to connect via either Node Identity or Network ID
advertisements. Adding the node unicast address selects Node Identity.
See Mesh Profile Specification 7.2.2.2 for further details.
There is an error in meshctl while displaying transition time. 1000 ms
is being presented as 16 sec, 40 ms. The reason is incorrect
conversion of milliseconds to seconds. The fix is pretty trivial.
This adds 'security' command which can be used to display and change
the provision security level:
[meshctl]# security
Provision Security Level set to 1 (medium)
[meshctl]# security 2
Provision Security Level set to 2 (high)
Note: This doesn't change the default which is still medium.