diff options
author | Inga Stotland <inga.stotland@intel.com> | 2018-07-14 12:58:58 -0700 |
---|---|---|
committer | Brian Gix <brian.gix@intel.com> | 2018-08-20 12:48:23 -0700 |
commit | e594aefd3a5c42b2e0644a6f822266b3abb9026f (patch) | |
tree | 3d570b10cdd9ac703970eabeb4b4b3fb91ce28ed /mesh/mesh.c | |
parent | 6fbc4c83e13470d669e16ea05cc1def297e71665 (diff) | |
download | bluez-e594aefd3a5c42b2e0644a6f822266b3abb9026f.tar.gz |
mesh: Source files for mesh access layer and utilities
This adds initial implementation of BT Mesh access layer
functionality plus utilities.
Diffstat (limited to 'mesh/mesh.c')
-rw-r--r-- | mesh/mesh.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/mesh/mesh.c b/mesh/mesh.c new file mode 100644 index 000000000..a6f733f5c --- /dev/null +++ b/mesh/mesh.c @@ -0,0 +1,184 @@ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <time.h> +#include <ell/ell.h> + +#include "lib/bluetooth.h" + +#include "mesh/mesh-defs.h" + +#include "mesh/mesh-io.h" +#include "mesh/node.h" +#include "mesh/net.h" +#include "mesh/storage.h" +#include "mesh/cfgmod.h" +#include "mesh/model.h" +#include "mesh/mesh.h" + +struct scan_filter { + uint8_t id; + const char *pattern; +}; + +struct bt_mesh { + struct mesh_net *net; + int ref_count; + struct l_queue *filters; + uint8_t max_filters; +}; + +static void save_exit_config(struct bt_mesh *mesh) +{ + const char *cfg_filename; + + if (!mesh_net_cfg_file_get(mesh->net, &cfg_filename) || !cfg_filename) + return; + + /* Preserve the last sequence number before saving configuration */ + storage_local_write_sequence_number(mesh->net, + mesh_net_get_seq_num(mesh->net)); + + if (storage_save_config(mesh->net, cfg_filename, true, NULL, NULL)) + l_info("Saved final configuration to %s", cfg_filename); +} + +struct bt_mesh *mesh_create(uint16_t index) +{ + struct bt_mesh *mesh; + struct mesh_io *io; + struct mesh_io_caps caps; + + mesh = l_new(struct bt_mesh, 1); + if (!mesh) + return NULL; + + mesh->net = mesh_net_new(index); + if (!mesh->net) { + l_free(mesh); + return NULL; + } + + io = mesh_io_new(index, MESH_IO_TYPE_GENERIC); + if (!io) { + mesh_net_unref(mesh->net); + l_free(mesh); + return NULL; + } + + mesh_io_get_caps(io, &caps); + mesh->max_filters = caps.max_num_filters; + + mesh_net_attach(mesh->net, io); + mesh_net_set_window_accuracy(mesh->net, caps.window_accuracy); + + return mesh_ref(mesh); +} + +struct bt_mesh *mesh_ref(struct bt_mesh *mesh) +{ + if (!mesh) + return NULL; + + __sync_fetch_and_add(&mesh->ref_count, 1); + + return mesh; +} + +void mesh_unref(struct bt_mesh *mesh) +{ + struct mesh_io *io; + + if (!mesh) + return; + + if (__sync_sub_and_fetch(&mesh->ref_count, 1)) + return; + + if (mesh_net_provisioned_get(mesh->net)) + save_exit_config(mesh); + + node_cleanup(mesh->net); + + storage_release(mesh->net); + io = mesh_net_detach(mesh->net); + if (io) + mesh_io_destroy(io); + + mesh_net_unref(mesh->net); + l_free(mesh); +} + +bool mesh_load_config(struct bt_mesh *mesh, const char *in_config_name) +{ + if (!storage_parse_config(mesh->net, in_config_name)) + return false; + + /* Register foundational models */ + mesh_config_srv_init(mesh->net, PRIMARY_ELE_IDX); + + return true; +} + +bool mesh_set_output(struct bt_mesh *mesh, const char *config_name) +{ + if (!config_name) + return false; + + return mesh_net_cfg_file_set(mesh->net, config_name); +} + +const char *mesh_status_str(uint8_t err) +{ + switch (err) { + case MESH_STATUS_SUCCESS: return "Success"; + case MESH_STATUS_INVALID_ADDRESS: return "Invalid Address"; + case MESH_STATUS_INVALID_MODEL: return "Invalid Model"; + case MESH_STATUS_INVALID_APPKEY: return "Invalid AppKey"; + case MESH_STATUS_INVALID_NETKEY: return "Invalid NetKey"; + case MESH_STATUS_INSUFF_RESOURCES: return "Insufficient Resources"; + case MESH_STATUS_IDX_ALREADY_STORED: return "Key Idx Already Stored"; + case MESH_STATUS_INVALID_PUB_PARAM: return "Invalid Publish Parameters"; + case MESH_STATUS_NOT_SUB_MOD: return "Not a Subscribe Model"; + case MESH_STATUS_STORAGE_FAIL: return "Storage Failure"; + case MESH_STATUS_FEATURE_NO_SUPPORT: return "Feature Not Supported"; + case MESH_STATUS_CANNOT_UPDATE: return "Cannot Update"; + case MESH_STATUS_CANNOT_REMOVE: return "Cannot Remove"; + case MESH_STATUS_CANNOT_BIND: return "Cannot bind"; + case MESH_STATUS_UNABLE_CHANGE_STATE: return "Unable to change state"; + case MESH_STATUS_CANNOT_SET: return "Cannot set"; + case MESH_STATUS_UNSPECIFIED_ERROR: return "Unspecified error"; + case MESH_STATUS_INVALID_BINDING: return "Invalid Binding"; + + default: return "Unknown"; + } +} + +struct mesh_net *mesh_get_net(struct bt_mesh *mesh) +{ + if (!mesh) + return NULL; + + return mesh->net; +} |