Received: by 2002:ac2:5a04:0:0:0:0:0 with SMTP id q4csp1073185lfn; Wed, 23 Feb 2022 18:18:44 -0800 (PST) X-Google-Smtp-Source: ABdhPJx94LvO8qtoG6Gr7NdB0qE3Pdaomh0Fm5YGFz+WWMQXQCD79hAJsWDP583fXWcpWe6tDxeX X-Received: by 2002:a63:7f56:0:b0:36c:8494:eb5 with SMTP id p22-20020a637f56000000b0036c84940eb5mr572169pgn.332.1645669123666; Wed, 23 Feb 2022 18:18:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1645669123; cv=none; d=google.com; s=arc-20160816; b=QEbsBeBZGl1ztvnUXYQYXgyrrhCVyux1ufycnB5rDBDczgOu7AKEG0kNCB6tle0FSQ 87Aw+4mtd5PuyUPGQtzc1Hk2/oERnZANkjh+WFdm3WzI4cEkSm8KUdcRPYG/HlJcWSss 0283ekkzNKfXIwko1El2XLE9iXdWdHad6Xi6S+ncCUGVPLQQg5lsEktwqk8iUmZMg8yp bZcZiFiUOfVe/LyTGOEl/Lr4ykzoKLBaR74gXm+I5k6YsHtLMcLAafi8ox8u0ZfPUYAw Gq7Y5n9YFaSus/oipRzCk0Qc5IuC9RvQvFrJtgIVFajzr9rZJVXBA9vzgReXdmtXF1Z3 lEkQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=0fVW6A7lSMGWp1La+BRSP1Ijt9S/cVYTwP4fJoWIk8w=; b=awaLlMbOivczlLp6mMbng9AXm8JDs2JAJwLCRBXEovkebqSRkXtjAmbZK5/lg4FbQc uxt6jT3gU9+tpPcEqAjzjZrjN3b0fvw7mBX9SPY+nQd9AFxdfACpfoVIYVTUIK02kqAA VXV9luGVnhkO0olOgEExV3ErsBgopws5yUIOS5tUvLWPPpcHJ/ATN4SAtye99gEt9gFz dEmScZ2b7S2DCPIkCiQFw1dGSVUyaxCk01ciLwMyQ7zz/Qds0zfSSNUkOd85U1aLfwuI ys/O6xBQJ53Ks8tw1Xki2VIMAVTWHut1zDWylI89mLaJtHWF8JS13IhGwWG4OA0hxyQA PMuQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=OL4hSSq9; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net. [2620:137:e000::1:18]) by mx.google.com with ESMTPS id u69si1214826pgd.449.2022.02.23.18.18.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Feb 2022 18:18:43 -0800 (PST) Received-SPF: pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) client-ip=2620:137:e000::1:18; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=OL4hSSq9; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:18 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 280AB2DF9; Wed, 23 Feb 2022 18:06:44 -0800 (PST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229901AbiBXCHI (ORCPT + 99 others); Wed, 23 Feb 2022 21:07:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229941AbiBXCHH (ORCPT ); Wed, 23 Feb 2022 21:07:07 -0500 Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 51E1DB853 for ; Wed, 23 Feb 2022 18:06:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1645668397; x=1677204397; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=81ea5c0d54wLGPgGbtraKs9AyWMBNQkSxgLGbaTQ3bQ=; b=OL4hSSq9wDzpyX9v5xNwW2XeVsp0iRIh+Mnx+WWWES+MZt0O6s9n/Qdg znpWlSSNqE5hEFHaYHgZtWsLRSwZqZ7hKovjfeEw9kDP+9Q+XgNNXMqVV +Db2r7Jr6TVo6XXQBM+cusrgH/s47NoujM8efwrf1tagSNGXtJOnHj7gW PaCuuI1fSIuz6et3RfdCUdmXGyXhSj7n0oGKy9LUmaw2tpByQz9jQA7Vg XEtZxw+xwRftnjILX+J49oWPiXx324alB+NRIMJfMpr4Sg+JqlMUZPwi4 R0n6A5GXDRYM1mk2d7i/ytGhTmKT/md7x49Hw4Z9Qjv2Up6DePdmP70Ya A==; X-IronPort-AV: E=McAfee;i="6200,9189,10267"; a="239525000" X-IronPort-AV: E=Sophos;i="5.88,392,1635231600"; d="scan'208";a="239525000" Received: from fmsmga004.fm.intel.com ([10.253.24.48]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Feb 2022 18:06:33 -0800 X-IronPort-AV: E=Sophos;i="5.88,392,1635231600"; d="scan'208";a="607268568" Received: from tjsmith-mobl1.amr.corp.intel.com (HELO bgi1-mobl2.amr.corp.intel.com) ([10.209.34.213]) by fmsmga004-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 23 Feb 2022 18:06:33 -0800 From: Brian Gix To: linux-bluetooth@vger.kernel.org Cc: brian.gix@intel.com, inga.stotland@intel.com Subject: [PATCH 3/7] mesh: Add common MGMT command accessors Date: Wed, 23 Feb 2022 18:06:20 -0800 Message-Id: <20220224020624.159247-4-brian.gix@intel.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220224020624.159247-1-brian.gix@intel.com> References: <20220224020624.159247-1-brian.gix@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RDNS_NONE,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org While mesh-io-mgmt is the main consumer of MGMT services, we also use MGMT to identify controllers and their capabilities, when determining the appropriate Mesh IO carrier. This centralizes all MGMT access to a single socket, shared accross all consumers. Also fixes the Controller added/removed handling so that a controller disappearing or reappearing gets handled rationally. --- mesh/mesh-mgmt.c | 149 ++++++++++++++++++++++++++++++++++++----------- mesh/mesh-mgmt.h | 12 +++- 2 files changed, 125 insertions(+), 36 deletions(-) diff --git a/mesh/mesh-mgmt.c b/mesh/mesh-mgmt.c index 754093dbc..e878a4f11 100644 --- a/mesh/mesh-mgmt.c +++ b/mesh/mesh-mgmt.c @@ -12,35 +12,63 @@ #include #endif +#include + #include "lib/bluetooth.h" #include "lib/mgmt.h" #include "src/shared/mgmt.h" -#include "ell/queue.h" -#include "ell/log.h" -#include "ell/util.h" - #include "mesh/mesh-mgmt.h" -struct read_info_reg { - mesh_mgmt_read_info_func_t cb; - void *user_data; -}; - -struct read_info_req { - int index; - struct mesh_io *io; +struct mesh_controler { + int index; + bool mesh_support; + bool powered; }; +static mesh_mgmt_read_info_func_t ctl_info; static struct mgmt *mgmt_mesh; -static struct l_queue *read_info_regs; +static struct l_queue *ctl_list; +static void *list_user_data; +static bool mesh_detected; + +static bool by_index(const void *a, const void *b) +{ + const struct mesh_controler *ctl = a; + int index = L_PTR_TO_UINT(b); -static void process_read_info_req(void *data, void *user_data) + return ctl->index == index; +} + +static void index_removed(uint16_t index, uint16_t length, const void *param, + void *user_data); +static void features_cb(uint8_t status, uint16_t length, + const void *param, void *user_data) { - struct read_info_reg *reg = data; int index = L_PTR_TO_UINT(user_data); + struct mesh_controler *ctl; + - reg->cb(index, reg->user_data); + ctl = l_queue_find(ctl_list, by_index, L_UINT_TO_PTR(index)); + if (!ctl) + return; + + l_debug("Status: %d, Length: %d", status, length); + if (status != MGMT_STATUS_NOT_SUPPORTED && + status != MGMT_STATUS_UNKNOWN_COMMAND) { + ctl->mesh_support = true; + if (!mesh_detected) { + mgmt_register(mgmt_mesh, MGMT_EV_INDEX_REMOVED, + MGMT_INDEX_NONE, index_removed, + NULL, NULL); + } + mesh_detected = true; + } else + l_debug("Kernel mesh not supported for hci%u", index); + + if (ctl_info) + ctl_info(index, true, ctl->powered, ctl->mesh_support, + list_user_data); } static void read_info_cb(uint8_t status, uint16_t length, @@ -49,12 +77,25 @@ static void read_info_cb(uint8_t status, uint16_t length, int index = L_PTR_TO_UINT(user_data); const struct mgmt_rp_read_info *rp = param; uint32_t current_settings, supported_settings; + struct mesh_controler *ctl; l_debug("hci %u status 0x%02x", index, status); + ctl = l_queue_find(ctl_list, by_index, L_UINT_TO_PTR(index)); + if (!ctl) + return; + if (status != MGMT_STATUS_SUCCESS) { + ctl = l_queue_remove_if(ctl_list, by_index, + L_UINT_TO_PTR(index)); l_error("Failed to read info for hci index %u: %s (0x%02x)", index, mgmt_errstr(status), status); + + l_warn("Hci dev %d removal detected", index); + if (ctl && ctl_info) + ctl_info(index, false, false, false, list_user_data); + + l_free(ctl); return; } @@ -69,23 +110,34 @@ static void read_info_cb(uint8_t status, uint16_t length, l_debug("settings: supp %8.8x curr %8.8x", supported_settings, current_settings); - if (current_settings & MGMT_SETTING_POWERED) { - l_info("Controller hci %u is in use", index); - return; - } - if (!(supported_settings & MGMT_SETTING_LE)) { l_info("Controller hci %u does not support LE", index); + l_queue_remove(ctl_list, ctl); + l_free(ctl); return; } - l_queue_foreach(read_info_regs, process_read_info_req, - L_UINT_TO_PTR(index)); + if (current_settings & MGMT_SETTING_POWERED) + ctl->powered = true; + + mesh_mgmt_send(MGMT_OP_MESH_READ_FEATURES, index, 0, NULL, + features_cb, L_UINT_TO_PTR(index), NULL); } static void index_added(uint16_t index, uint16_t length, const void *param, void *user_data) { + struct mesh_controler *ctl = l_queue_find(ctl_list, by_index, + L_UINT_TO_PTR(index)); + + if (!ctl) { + ctl = l_new(struct mesh_controler, 1); + ctl->index = index; + l_queue_push_head(ctl_list, ctl); + } else { + ctl->mesh_support = ctl->powered = false; + } + mgmt_send(mgmt_mesh, MGMT_OP_READ_INFO, index, 0, NULL, read_info_cb, L_UINT_TO_PTR(index), NULL); } @@ -93,7 +145,9 @@ static void index_added(uint16_t index, uint16_t length, const void *param, static void index_removed(uint16_t index, uint16_t length, const void *param, void *user_data) { - l_warn("Hci dev %4.4x removed", index); + mgmt_send(mgmt_mesh, MGMT_OP_READ_INFO, index, 0, NULL, + read_info_cb, L_UINT_TO_PTR(index), NULL); + } static void read_index_list_cb(uint8_t status, uint16_t length, @@ -133,8 +187,8 @@ static void read_index_list_cb(uint8_t status, uint16_t length, static bool mesh_mgmt_init(void) { - if (!read_info_regs) - read_info_regs = l_queue_new(); + if (!ctl_list) + ctl_list = l_queue_new(); if (!mgmt_mesh) { mgmt_mesh = mgmt_new_default(); @@ -146,8 +200,6 @@ static bool mesh_mgmt_init(void) mgmt_register(mgmt_mesh, MGMT_EV_INDEX_ADDED, MGMT_INDEX_NONE, index_added, NULL, NULL); - mgmt_register(mgmt_mesh, MGMT_EV_INDEX_REMOVED, - MGMT_INDEX_NONE, index_removed, NULL, NULL); } return true; @@ -155,16 +207,11 @@ static bool mesh_mgmt_init(void) bool mesh_mgmt_list(mesh_mgmt_read_info_func_t cb, void *user_data) { - struct read_info_reg *reg; - if (!mesh_mgmt_init()) return false; - reg = l_new(struct read_info_reg, 1); - reg->cb = cb; - reg->user_data = user_data; - - l_queue_push_tail(read_info_regs, reg); + ctl_info = cb; + list_user_data = user_data; /* Use MGMT to find a candidate controller */ l_debug("send read index_list"); @@ -175,3 +222,35 @@ bool mesh_mgmt_list(mesh_mgmt_read_info_func_t cb, void *user_data) return true; } + +void mesh_mgmt_destroy() +{ + mgmt_unref(mgmt_mesh); + mgmt_mesh = NULL; + ctl_info = NULL; + list_user_data = NULL; + l_queue_destroy(ctl_list, l_free); + ctl_list = NULL; +} + +unsigned int mesh_mgmt_send(uint16_t opcode, uint16_t index, + uint16_t length, const void *param, + mgmt_request_func_t callback, + void *user_data, mgmt_destroy_func_t destroy) +{ + return mgmt_send_timeout(mgmt_mesh, opcode, index, length, param, + callback, user_data, destroy, 0); +} + +unsigned int mesh_mgmt_register(uint16_t event, uint16_t index, + mgmt_notify_func_t callback, + void *user_data, mgmt_destroy_func_t destroy) +{ + return mgmt_register(mgmt_mesh, event, index, callback, + user_data, destroy); +} + +bool mesh_mgmt_unregister(unsigned int id) +{ + return mgmt_unregister(mgmt_mesh, id); +} diff --git a/mesh/mesh-mgmt.h b/mesh/mesh-mgmt.h index 90ac14e73..a3cd72faf 100644 --- a/mesh/mesh-mgmt.h +++ b/mesh/mesh-mgmt.h @@ -9,6 +9,16 @@ */ #include -typedef void (*mesh_mgmt_read_info_func_t)(int index, void *user_data); +typedef void (*mesh_mgmt_read_info_func_t)(int index, bool added, bool powered, + bool mesh, void *user_data); bool mesh_mgmt_list(mesh_mgmt_read_info_func_t cb, void *user_data); +unsigned int mesh_mgmt_send(uint16_t opcode, uint16_t index, + uint16_t length, const void *param, + mgmt_request_func_t callback, + void *user_data, mgmt_destroy_func_t destroy); +unsigned int mesh_mgmt_register(uint16_t event, uint16_t index, + mgmt_notify_func_t callback, + void *user_data, mgmt_destroy_func_t destroy); +bool mesh_mgmt_unregister(unsigned int id); +void mesh_mgmt_destroy(void); -- 2.35.1