3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2019 SILVAIR sp. z o.o. All rights reserved.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
24 #include "lib/bluetooth.h"
26 #include "src/shared/mgmt.h"
28 #include "ell/queue.h"
32 #include "mesh/mesh-mgmt.h"
34 struct read_info_reg {
35 mesh_mgmt_read_info_func_t cb;
39 struct read_info_req {
44 static struct mgmt *mgmt_mesh;
45 static struct l_queue *read_info_regs;
47 static void process_read_info_req(void *data, void *user_data)
49 struct read_info_reg *reg = data;
50 int index = L_PTR_TO_UINT(user_data);
52 reg->cb(index, reg->user_data);
55 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
56 static void set_powered_complete(uint8_t status, uint16_t length,
57 const void *param, void *user_data)
59 int index = L_PTR_TO_UINT(user_data);
62 if (status != MGMT_STATUS_SUCCESS) {
63 l_error("Failed to set powered: %s (0x%02x)",
64 mgmt_errstr(status), status);
68 settings = l_get_le32(param);
70 if (!(settings & MGMT_SETTING_POWERED)) {
71 l_error("Controller is not powered");
75 l_debug("set powered success on index %d", index);
76 /** <TO-DO> update current settings of adapter */
79 bool set_powered(uint16_t mode, int index)
83 memset(&cp, 0, sizeof(cp));
86 /** <TO-DO> check current settings of adapter */
87 if (mgmt_send(mgmt_mesh, MGMT_OP_SET_POWERED, index, sizeof(cp), &cp,
88 set_powered_complete, L_UINT_TO_PTR(index), NULL) > 0)
96 static void read_info_cb(uint8_t status, uint16_t length,
97 const void *param, void *user_data)
99 int index = L_PTR_TO_UINT(user_data);
100 const struct mgmt_rp_read_info *rp = param;
101 uint32_t current_settings, supported_settings;
103 l_debug("hci %u status 0x%02x", index, status);
105 if (status != MGMT_STATUS_SUCCESS) {
106 l_error("Failed to read info for hci index %u: %s (0x%02x)",
107 index, mgmt_errstr(status), status);
111 if (length < sizeof(*rp)) {
112 l_error("Read info response too short");
116 current_settings = btohl(rp->current_settings);
117 supported_settings = btohl(rp->supported_settings);
119 l_debug("settings: supp %8.8x curr %8.8x",
120 supported_settings, current_settings);
122 if (current_settings & MGMT_SETTING_POWERED) {
123 l_info("Controller hci %u is in use", index);
124 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
129 if (!(supported_settings & MGMT_SETTING_LE)) {
130 l_info("Controller hci %u does not support LE", index);
134 l_queue_foreach(read_info_regs, process_read_info_req,
135 L_UINT_TO_PTR(index));
138 static void index_added(uint16_t index, uint16_t length, const void *param,
141 mgmt_send(mgmt_mesh, MGMT_OP_READ_INFO, index, 0, NULL,
142 read_info_cb, L_UINT_TO_PTR(index), NULL);
145 static void index_removed(uint16_t index, uint16_t length, const void *param,
148 l_warn("Hci dev %4.4x removed", index);
151 static void read_index_list_cb(uint8_t status, uint16_t length,
152 const void *param, void *user_data)
154 const struct mgmt_rp_read_index_list *rp = param;
158 if (status != MGMT_STATUS_SUCCESS) {
159 l_error("Failed to read index list: %s (0x%02x)",
160 mgmt_errstr(status), status);
164 if (length < sizeof(*rp)) {
165 l_error("Read index list response sixe too short");
169 num = btohs(rp->num_controllers);
171 l_debug("Number of controllers: %u", num);
173 if (num * sizeof(uint16_t) + sizeof(*rp) != length) {
174 l_error("Incorrect packet size for index list response");
178 for (i = 0; i < num; i++) {
181 index = btohs(rp->index[i]);
182 index_added(index, 0, NULL, user_data);
186 static bool mesh_mgmt_init(void)
189 read_info_regs = l_queue_new();
192 mgmt_mesh = mgmt_new_default();
195 l_error("Failed to initialize mesh management");
199 mgmt_register(mgmt_mesh, MGMT_EV_INDEX_ADDED,
200 MGMT_INDEX_NONE, index_added, NULL, NULL);
201 mgmt_register(mgmt_mesh, MGMT_EV_INDEX_REMOVED,
202 MGMT_INDEX_NONE, index_removed, NULL, NULL);
208 bool mesh_mgmt_list(mesh_mgmt_read_info_func_t cb, void *user_data)
210 struct read_info_reg *reg;
212 if (!mesh_mgmt_init())
215 reg = l_new(struct read_info_reg, 1);
217 reg->user_data = user_data;
219 l_queue_push_tail(read_info_regs, reg);
221 /* Use MGMT to find a candidate controller */
222 l_debug("send read index_list");
223 if (mgmt_send(mgmt_mesh, MGMT_OP_READ_INDEX_LIST,
224 MGMT_INDEX_NONE, 0, NULL,
225 read_index_list_cb, NULL, NULL) <= 0)