Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Bluetooth: Introduce debug feature when dynamic debug is disabled

In case dynamic debug is disabled, this feature allows a vendor platform
to provide debug statement printing.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>

+138
+11
include/net/bluetooth/bluetooth.h
··· 153 153 void bt_warn(const char *fmt, ...); 154 154 __printf(1, 2) 155 155 void bt_err(const char *fmt, ...); 156 + #if IS_ENABLED(CONFIG_BT_FEATURE_DEBUG) 157 + void bt_dbg_set(bool enable); 158 + bool bt_dbg_get(void); 159 + __printf(1, 2) 160 + void bt_dbg(const char *fmt, ...); 161 + #endif 156 162 __printf(1, 2) 157 163 void bt_warn_ratelimited(const char *fmt, ...); 158 164 __printf(1, 2) ··· 167 161 #define BT_INFO(fmt, ...) bt_info(fmt "\n", ##__VA_ARGS__) 168 162 #define BT_WARN(fmt, ...) bt_warn(fmt "\n", ##__VA_ARGS__) 169 163 #define BT_ERR(fmt, ...) bt_err(fmt "\n", ##__VA_ARGS__) 164 + 165 + #if IS_ENABLED(CONFIG_BT_FEATURE_DEBUG) 166 + #define BT_DBG(fmt, ...) bt_dbg(fmt "\n", ##__VA_ARGS__) 167 + #else 170 168 #define BT_DBG(fmt, ...) pr_debug(fmt "\n", ##__VA_ARGS__) 169 + #endif 171 170 172 171 #define bt_dev_info(hdev, fmt, ...) \ 173 172 BT_INFO("%s: " fmt, (hdev)->name, ##__VA_ARGS__)
+7
net/bluetooth/Kconfig
··· 135 135 Run test cases for SMP cryptographic functionality, including both 136 136 legacy SMP as well as the Secure Connections features. 137 137 138 + config BT_FEATURE_DEBUG 139 + bool "Enable runtime option for debugging statements" 140 + depends on BT && !DYNAMIC_DEBUG 141 + help 142 + This provides an option to enable/disable debugging statements 143 + at runtime via the experimental features interface. 144 + 138 145 source "drivers/bluetooth/Kconfig"
+33
net/bluetooth/lib.c
··· 183 183 } 184 184 EXPORT_SYMBOL(bt_err); 185 185 186 + #ifdef CONFIG_BT_FEATURE_DEBUG 187 + static bool debug_enable; 188 + 189 + void bt_dbg_set(bool enable) 190 + { 191 + debug_enable = enable; 192 + } 193 + 194 + bool bt_dbg_get(void) 195 + { 196 + return debug_enable; 197 + } 198 + 199 + void bt_dbg(const char *format, ...) 200 + { 201 + struct va_format vaf; 202 + va_list args; 203 + 204 + if (likely(!debug_enable)) 205 + return; 206 + 207 + va_start(args, format); 208 + 209 + vaf.fmt = format; 210 + vaf.va = &args; 211 + 212 + printk(KERN_DEBUG pr_fmt("%pV"), &vaf); 213 + 214 + va_end(args); 215 + } 216 + EXPORT_SYMBOL(bt_dbg); 217 + #endif 218 + 186 219 void bt_warn_ratelimited(const char *format, ...) 187 220 { 188 221 struct va_format vaf;
+87
net/bluetooth/mgmt.c
··· 3715 3715 rp, sizeof(*rp) + sec_len); 3716 3716 } 3717 3717 3718 + #ifdef CONFIG_BT_FEATURE_DEBUG 3719 + /* d4992530-b9ec-469f-ab01-6c481c47da1c */ 3720 + static const u8 debug_uuid[16] = { 3721 + 0x1c, 0xda, 0x47, 0x1c, 0x48, 0x6c, 0x01, 0xab, 3722 + 0x9f, 0x46, 0xec, 0xb9, 0x30, 0x25, 0x99, 0xd4, 3723 + }; 3724 + #endif 3725 + 3718 3726 static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev, 3719 3727 void *data, u16 data_len) 3720 3728 { ··· 3733 3725 bt_dev_dbg(hdev, "sock %p", sk); 3734 3726 3735 3727 memset(&buf, 0, sizeof(buf)); 3728 + 3729 + #ifdef CONFIG_BT_FEATURE_DEBUG 3730 + if (!hdev) { 3731 + u32 flags = bt_dbg_get() ? BIT(0) : 0; 3732 + 3733 + memcpy(rp->features[idx].uuid, debug_uuid, 16); 3734 + rp->features[idx].flags = cpu_to_le32(flags); 3735 + idx++; 3736 + } 3737 + #endif 3736 3738 3737 3739 rp->feature_count = cpu_to_le16(idx); 3738 3740 ··· 3756 3738 0, rp, sizeof(*rp) + (20 * idx)); 3757 3739 } 3758 3740 3741 + #ifdef CONFIG_BT_FEATURE_DEBUG 3742 + static int exp_debug_feature_changed(bool enabled, struct sock *skip) 3743 + { 3744 + struct mgmt_ev_exp_feature_changed ev; 3745 + 3746 + memset(&ev, 0, sizeof(ev)); 3747 + memcpy(ev.uuid, debug_uuid, 16); 3748 + ev.flags = cpu_to_le32(enabled ? BIT(0) : 0); 3749 + 3750 + return mgmt_limited_event(MGMT_EV_EXP_FEATURE_CHANGED, NULL, 3751 + &ev, sizeof(ev), 3752 + HCI_MGMT_EXP_FEATURE_EVENTS, skip); 3753 + } 3754 + #endif 3755 + 3759 3756 static int set_exp_feature(struct sock *sk, struct hci_dev *hdev, 3760 3757 void *data, u16 data_len) 3761 3758 { ··· 3783 3750 memset(rp.uuid, 0, 16); 3784 3751 rp.flags = cpu_to_le32(0); 3785 3752 3753 + #ifdef CONFIG_BT_FEATURE_DEBUG 3754 + if (!hdev) { 3755 + bool changed = bt_dbg_get(); 3756 + 3757 + bt_dbg_set(false); 3758 + 3759 + if (changed) 3760 + exp_debug_feature_changed(false, sk); 3761 + } 3762 + #endif 3763 + 3786 3764 hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); 3787 3765 3788 3766 return mgmt_cmd_complete(sk, hdev ? hdev->id : MGMT_INDEX_NONE, 3789 3767 MGMT_OP_SET_EXP_FEATURE, 0, 3790 3768 &rp, sizeof(rp)); 3791 3769 } 3770 + 3771 + #ifdef CONFIG_BT_FEATURE_DEBUG 3772 + if (!memcmp(cp->uuid, debug_uuid, 16)) { 3773 + bool val, changed; 3774 + int err; 3775 + 3776 + /* Command requires to use the non-controller index */ 3777 + if (hdev) 3778 + return mgmt_cmd_status(sk, hdev->id, 3779 + MGMT_OP_SET_EXP_FEATURE, 3780 + MGMT_STATUS_INVALID_INDEX); 3781 + 3782 + /* Parameters are limited to a single octet */ 3783 + if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1) 3784 + return mgmt_cmd_status(sk, MGMT_INDEX_NONE, 3785 + MGMT_OP_SET_EXP_FEATURE, 3786 + MGMT_STATUS_INVALID_PARAMS); 3787 + 3788 + /* Only boolean on/off is supported */ 3789 + if (cp->param[0] != 0x00 && cp->param[0] != 0x01) 3790 + return mgmt_cmd_status(sk, MGMT_INDEX_NONE, 3791 + MGMT_OP_SET_EXP_FEATURE, 3792 + MGMT_STATUS_INVALID_PARAMS); 3793 + 3794 + val = !!cp->param[0]; 3795 + changed = val ? !bt_dbg_get() : bt_dbg_get(); 3796 + bt_dbg_set(val); 3797 + 3798 + memcpy(rp.uuid, debug_uuid, 16); 3799 + rp.flags = cpu_to_le32(val ? BIT(0) : 0); 3800 + 3801 + hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); 3802 + 3803 + err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE, 3804 + MGMT_OP_SET_EXP_FEATURE, 0, 3805 + &rp, sizeof(rp)); 3806 + 3807 + if (changed) 3808 + exp_debug_feature_changed(val, sk); 3809 + 3810 + return err; 3811 + } 3812 + #endif 3792 3813 3793 3814 return mgmt_cmd_status(sk, hdev ? hdev->id : MGMT_INDEX_NONE, 3794 3815 MGMT_OP_SET_EXP_FEATURE,