Publishing for Bluetooth Asia 2018 developer session: mesh session. This repo is for GenericOnOff client side firmware.

EULA

PLEASE READ MESH_DEMO_TUTORIAL_EULA.TXT BEFORE START DEVELOPMENT.

Overview

This sample demonstrates Bluetooth Mesh functionality on micro:bit. It doesn't need provisioning because all the credential material (DevKey, NetKey, AppKey, Key Index, IVI and Unicast address) is pre-configured. This sample work as a GenericOnOff client:

  • Pressing Button A on micro:bit will send GenericOnOffSet access message with on or off state alternatively and specific group address;
  • Pressing Button B on micro:bit will switch the group address from 0xC000 to 0xC003 and back to 0xC000 again like round robin;

Requirements

micro:bit board

Building and Running

0. Download source code, it's zip file, the link is on this page, Download repository.

1. Following below link to set the development environment up on your Windows computer. http://docs.zephyrproject.org/getting_started/installation_win.html . Please make sure git checkout this commit, commit: 88dfd399f480b1593a8e13f5a68d512921a55502 , the detail is here, https://github.com/zephyrproject-rtos/zephyr/commit/88dfd399f480b1593a8e13f5a68d512921a55502

2. copy zip file into ./zephyr/sample/ in the Zephyr tree.

3. unzip the file by "Extract Here".

3. access into the extracted folder and rename prj_bbc_microbit.txt to prj_bbc_microbit.conf

4. if adopting Windows Command Prompt, use it to access into the unzip folder and type following commands on the console:

mkdir build & cd build

cmake -GNinja -DBOARD=bbc_microbit ..

ninja

if adopting MSYS2, use it to access into the unzip folder and type following commands on the console:

mkdir build & cd build

cmake -GNinja -DBOARD=bbc_microbit ..

ninja

5. connect micro:bit with your computer by USB cable, the board will be enumerated as a massive storage device;

6. drag the hex file (which is in ./zephyr/sample/[unzip folder]/build/zephyr/zephyr.hex) into Microbit massive storage device to flash the firmware;

7. micro:bit is ready to work as a GenericOnOff client.

Committer:
krenbluetoothsig
Date:
Tue May 01 10:22:24 2018 +0000
Revision:
0:876e59f87d50
Child:
1:fb4893064dd4
import the client project.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
krenbluetoothsig 0:876e59f87d50 1 /* main.c - Application main entry point */
krenbluetoothsig 0:876e59f87d50 2
krenbluetoothsig 0:876e59f87d50 3 /*
krenbluetoothsig 0:876e59f87d50 4 * Copyright (c) 2017 Intel Corporation
krenbluetoothsig 0:876e59f87d50 5 *
krenbluetoothsig 0:876e59f87d50 6 * SPDX-License-Identifier: Apache-2.0
krenbluetoothsig 0:876e59f87d50 7 */
krenbluetoothsig 0:876e59f87d50 8
krenbluetoothsig 0:876e59f87d50 9 #include <stdio.h>
krenbluetoothsig 0:876e59f87d50 10
krenbluetoothsig 0:876e59f87d50 11 #include <gpio.h>
krenbluetoothsig 0:876e59f87d50 12 #include <board.h>
krenbluetoothsig 0:876e59f87d50 13
krenbluetoothsig 0:876e59f87d50 14 #include <misc/printk.h>
krenbluetoothsig 0:876e59f87d50 15
krenbluetoothsig 0:876e59f87d50 16 #include <bluetooth/bluetooth.h>
krenbluetoothsig 0:876e59f87d50 17 #include <bluetooth/mesh.h>
krenbluetoothsig 0:876e59f87d50 18 #include <display/mb_display.h>
krenbluetoothsig 0:876e59f87d50 19
krenbluetoothsig 0:876e59f87d50 20
krenbluetoothsig 0:876e59f87d50 21 #include "board.h"
krenbluetoothsig 0:876e59f87d50 22
krenbluetoothsig 0:876e59f87d50 23 #define BT_MESH_MODEL_OP_GEN_ONOFF_GET BT_MESH_MODEL_OP_2(0x82, 0x01)
krenbluetoothsig 0:876e59f87d50 24 #define BT_MESH_MODEL_OP_GEN_ONOFF_SET BT_MESH_MODEL_OP_2(0x82, 0x02)
krenbluetoothsig 0:876e59f87d50 25 #define BT_MESH_MODEL_OP_GEN_ONOFF_SET_UNACK BT_MESH_MODEL_OP_2(0x82, 0x03)
krenbluetoothsig 0:876e59f87d50 26 #define BT_MESH_MODEL_OP_GEN_ONOFF_STATUS BT_MESH_MODEL_OP_2(0x82, 0x04)
krenbluetoothsig 0:876e59f87d50 27
krenbluetoothsig 0:876e59f87d50 28 #define BUTTON_DEBOUNCE_DELAY_MS 250
krenbluetoothsig 0:876e59f87d50 29
krenbluetoothsig 0:876e59f87d50 30 BT_MESH_MODEL_PUB_DEFINE(gen_onoff_pub_cli, NULL, 2 + 2);
krenbluetoothsig 0:876e59f87d50 31
krenbluetoothsig 0:876e59f87d50 32 static struct device *gpio;
krenbluetoothsig 0:876e59f87d50 33 static u8_t genericOnOffValue;
krenbluetoothsig 0:876e59f87d50 34 static u8_t trans_id = 0;
krenbluetoothsig 0:876e59f87d50 35 static u32_t time, last_time;
krenbluetoothsig 0:876e59f87d50 36 static struct k_work button_work;
krenbluetoothsig 0:876e59f87d50 37
krenbluetoothsig 0:876e59f87d50 38
krenbluetoothsig 0:876e59f87d50 39 static struct bt_mesh_cfg_srv cfg_srv = {
krenbluetoothsig 0:876e59f87d50 40 .relay = BT_MESH_RELAY_DISABLED,
krenbluetoothsig 0:876e59f87d50 41 .beacon = BT_MESH_BEACON_ENABLED,
krenbluetoothsig 0:876e59f87d50 42 #if defined(CONFIG_BT_MESH_FRIEND)
krenbluetoothsig 0:876e59f87d50 43 .frnd = BT_MESH_FRIEND_ENABLED,
krenbluetoothsig 0:876e59f87d50 44 #else
krenbluetoothsig 0:876e59f87d50 45 .frnd = BT_MESH_FRIEND_NOT_SUPPORTED,
krenbluetoothsig 0:876e59f87d50 46 #endif
krenbluetoothsig 0:876e59f87d50 47 #if defined(CONFIG_BT_MESH_GATT_PROXY)
krenbluetoothsig 0:876e59f87d50 48 .gatt_proxy = BT_MESH_GATT_PROXY_ENABLED,
krenbluetoothsig 0:876e59f87d50 49 #else
krenbluetoothsig 0:876e59f87d50 50 .gatt_proxy = BT_MESH_GATT_PROXY_NOT_SUPPORTED,
krenbluetoothsig 0:876e59f87d50 51 #endif
krenbluetoothsig 0:876e59f87d50 52 .default_ttl = 7,
krenbluetoothsig 0:876e59f87d50 53
krenbluetoothsig 0:876e59f87d50 54 /* 3 transmissions with 20ms interval */
krenbluetoothsig 0:876e59f87d50 55 .net_transmit = BT_MESH_TRANSMIT(2, 20),
krenbluetoothsig 0:876e59f87d50 56 .relay_retransmit = BT_MESH_TRANSMIT(2, 20),
krenbluetoothsig 0:876e59f87d50 57 };
krenbluetoothsig 0:876e59f87d50 58
krenbluetoothsig 0:876e59f87d50 59
krenbluetoothsig 0:876e59f87d50 60 static void gen_onoff_status(struct bt_mesh_model *model,
krenbluetoothsig 0:876e59f87d50 61 struct bt_mesh_msg_ctx *ctx,
krenbluetoothsig 0:876e59f87d50 62 struct net_buf_simple *buf)
krenbluetoothsig 0:876e59f87d50 63 {
krenbluetoothsig 0:876e59f87d50 64 u8_t state;
krenbluetoothsig 0:876e59f87d50 65
krenbluetoothsig 0:876e59f87d50 66 state = net_buf_simple_pull_u8(buf);
krenbluetoothsig 0:876e59f87d50 67
krenbluetoothsig 0:876e59f87d50 68 printk("Node 0x%04x OnOff status from 0x%04x with state 0x%02x",
krenbluetoothsig 0:876e59f87d50 69 model->elem->addr, ctx->addr, state);
krenbluetoothsig 0:876e59f87d50 70 }
krenbluetoothsig 0:876e59f87d50 71
krenbluetoothsig 0:876e59f87d50 72 static const struct bt_mesh_model_op gen_onoff_cli_op[] = {
krenbluetoothsig 0:876e59f87d50 73 { BT_MESH_MODEL_OP_GEN_ONOFF_STATUS, 1, gen_onoff_status },
krenbluetoothsig 0:876e59f87d50 74 BT_MESH_MODEL_OP_END,
krenbluetoothsig 0:876e59f87d50 75 };
krenbluetoothsig 0:876e59f87d50 76
krenbluetoothsig 0:876e59f87d50 77 static struct bt_mesh_model root_models[] = {
krenbluetoothsig 0:876e59f87d50 78 BT_MESH_MODEL_CFG_SRV(&cfg_srv),
krenbluetoothsig 0:876e59f87d50 79 BT_MESH_MODEL(BT_MESH_MODEL_ID_GEN_ONOFF_CLI, gen_onoff_cli_op,
krenbluetoothsig 0:876e59f87d50 80 &gen_onoff_pub_cli, NULL),
krenbluetoothsig 0:876e59f87d50 81 };
krenbluetoothsig 0:876e59f87d50 82
krenbluetoothsig 0:876e59f87d50 83 static struct bt_mesh_elem elements[] = {
krenbluetoothsig 0:876e59f87d50 84 BT_MESH_ELEM(0, root_models, BT_MESH_MODEL_NONE),
krenbluetoothsig 0:876e59f87d50 85 };
krenbluetoothsig 0:876e59f87d50 86
krenbluetoothsig 0:876e59f87d50 87 static const struct bt_mesh_comp comp = {
krenbluetoothsig 0:876e59f87d50 88 .cid = BT_COMP_ID_LF,
krenbluetoothsig 0:876e59f87d50 89 .elem = elements,
krenbluetoothsig 0:876e59f87d50 90 .elem_count = ARRAY_SIZE(elements),
krenbluetoothsig 0:876e59f87d50 91 };
krenbluetoothsig 0:876e59f87d50 92
krenbluetoothsig 0:876e59f87d50 93 void genericOnOffSet(uint8_t value)
krenbluetoothsig 0:876e59f87d50 94 {
krenbluetoothsig 0:876e59f87d50 95
krenbluetoothsig 0:876e59f87d50 96 if (gen_onoff_pub_cli.addr == BT_MESH_ADDR_UNASSIGNED) {
krenbluetoothsig 0:876e59f87d50 97 printk("No\n");
krenbluetoothsig 0:876e59f87d50 98 return;
krenbluetoothsig 0:876e59f87d50 99 }
krenbluetoothsig 0:876e59f87d50 100
krenbluetoothsig 0:876e59f87d50 101 printk("Yes\n");
krenbluetoothsig 0:876e59f87d50 102
krenbluetoothsig 0:876e59f87d50 103 bt_mesh_model_msg_init(gen_onoff_pub_cli.msg,
krenbluetoothsig 0:876e59f87d50 104 BT_MESH_MODEL_OP_GEN_ONOFF_SET);
krenbluetoothsig 0:876e59f87d50 105 net_buf_simple_add_u8(gen_onoff_pub_cli.msg, value);
krenbluetoothsig 0:876e59f87d50 106 net_buf_simple_add_u8(gen_onoff_pub_cli.msg, trans_id++);
krenbluetoothsig 0:876e59f87d50 107 bt_mesh_model_publish(&root_models[1]);
krenbluetoothsig 0:876e59f87d50 108 }
krenbluetoothsig 0:876e59f87d50 109
krenbluetoothsig 0:876e59f87d50 110 void button_send_pressed(struct k_work *work)
krenbluetoothsig 0:876e59f87d50 111 {
krenbluetoothsig 0:876e59f87d50 112
krenbluetoothsig 0:876e59f87d50 113 genericOnOffSet(genericOnOffValue);
krenbluetoothsig 0:876e59f87d50 114 printk("button_send_pressed( %d )\n", genericOnOffValue);
krenbluetoothsig 0:876e59f87d50 115 }
krenbluetoothsig 0:876e59f87d50 116
krenbluetoothsig 0:876e59f87d50 117 void button_pressed(struct device *dev, struct gpio_callback *cb,
krenbluetoothsig 0:876e59f87d50 118 uint32_t pins)
krenbluetoothsig 0:876e59f87d50 119 {
krenbluetoothsig 0:876e59f87d50 120 /*
krenbluetoothsig 0:876e59f87d50 121 * One button press within a 1 second interval sends an on message
krenbluetoothsig 0:876e59f87d50 122 * More than one button press sends an off message
krenbluetoothsig 0:876e59f87d50 123 */
krenbluetoothsig 0:876e59f87d50 124 time = k_uptime_get_32();
krenbluetoothsig 0:876e59f87d50 125
krenbluetoothsig 0:876e59f87d50 126 /* debounce the switch */
krenbluetoothsig 0:876e59f87d50 127 if (time < last_time + BUTTON_DEBOUNCE_DELAY_MS) {
krenbluetoothsig 0:876e59f87d50 128 last_time = time;
krenbluetoothsig 0:876e59f87d50 129 return;
krenbluetoothsig 0:876e59f87d50 130 }
krenbluetoothsig 0:876e59f87d50 131
krenbluetoothsig 0:876e59f87d50 132 if (pins & BIT(SW0_GPIO_PIN)) {
krenbluetoothsig 0:876e59f87d50 133 genericOnOffValue = 1;
krenbluetoothsig 0:876e59f87d50 134 }
krenbluetoothsig 0:876e59f87d50 135 else{
krenbluetoothsig 0:876e59f87d50 136 genericOnOffValue = 0;
krenbluetoothsig 0:876e59f87d50 137 }
krenbluetoothsig 0:876e59f87d50 138
krenbluetoothsig 0:876e59f87d50 139 //submit to ksystem
krenbluetoothsig 0:876e59f87d50 140 k_work_submit(&button_work);
krenbluetoothsig 0:876e59f87d50 141
krenbluetoothsig 0:876e59f87d50 142 last_time = time;
krenbluetoothsig 0:876e59f87d50 143 }
krenbluetoothsig 0:876e59f87d50 144
krenbluetoothsig 0:876e59f87d50 145
krenbluetoothsig 0:876e59f87d50 146 static int output_number(bt_mesh_output_action_t action, uint32_t number)
krenbluetoothsig 0:876e59f87d50 147 {
krenbluetoothsig 0:876e59f87d50 148 struct mb_display *disp = mb_display_get();
krenbluetoothsig 0:876e59f87d50 149
krenbluetoothsig 0:876e59f87d50 150 printk("OOB Number: %u\n", number);
krenbluetoothsig 0:876e59f87d50 151 mb_display_print(disp, MB_DISPLAY_MODE_SINGLE, -1, "%d", number);
krenbluetoothsig 0:876e59f87d50 152
krenbluetoothsig 0:876e59f87d50 153
krenbluetoothsig 0:876e59f87d50 154 return 0;
krenbluetoothsig 0:876e59f87d50 155 }
krenbluetoothsig 0:876e59f87d50 156
krenbluetoothsig 0:876e59f87d50 157 static int output_string(const char *str)
krenbluetoothsig 0:876e59f87d50 158 {
krenbluetoothsig 0:876e59f87d50 159 struct mb_display *disp = mb_display_get();
krenbluetoothsig 0:876e59f87d50 160
krenbluetoothsig 0:876e59f87d50 161 printk("OOB String: %s\n", str);
krenbluetoothsig 0:876e59f87d50 162
krenbluetoothsig 0:876e59f87d50 163 mb_display_print(disp, MB_DISPLAY_MODE_SCROLL, K_SECONDS(1), "%s", str);
krenbluetoothsig 0:876e59f87d50 164
krenbluetoothsig 0:876e59f87d50 165 return 0;
krenbluetoothsig 0:876e59f87d50 166 }
krenbluetoothsig 0:876e59f87d50 167
krenbluetoothsig 0:876e59f87d50 168 static void prov_complete(u16_t net_idx, u16_t addr)
krenbluetoothsig 0:876e59f87d50 169 {
krenbluetoothsig 0:876e59f87d50 170 //board_prov_complete();
krenbluetoothsig 0:876e59f87d50 171 }
krenbluetoothsig 0:876e59f87d50 172
krenbluetoothsig 0:876e59f87d50 173 static void prov_reset(void)
krenbluetoothsig 0:876e59f87d50 174 {
krenbluetoothsig 0:876e59f87d50 175 bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
krenbluetoothsig 0:876e59f87d50 176 }
krenbluetoothsig 0:876e59f87d50 177
krenbluetoothsig 0:876e59f87d50 178 static uint8_t dev_uuid[16] = { 0xdd, 0xdd };
krenbluetoothsig 0:876e59f87d50 179
krenbluetoothsig 0:876e59f87d50 180 static const struct bt_mesh_prov prov = {
krenbluetoothsig 0:876e59f87d50 181 .uuid = dev_uuid,
krenbluetoothsig 0:876e59f87d50 182 .output_size = 4,
krenbluetoothsig 0:876e59f87d50 183 .output_actions = BT_MESH_DISPLAY_STRING,
krenbluetoothsig 0:876e59f87d50 184 .output_number = output_number,
krenbluetoothsig 0:876e59f87d50 185 .output_string = output_string,
krenbluetoothsig 0:876e59f87d50 186 .complete = prov_complete,
krenbluetoothsig 0:876e59f87d50 187 .reset = prov_reset,
krenbluetoothsig 0:876e59f87d50 188 };
krenbluetoothsig 0:876e59f87d50 189
krenbluetoothsig 0:876e59f87d50 190 static void configure_button(void)
krenbluetoothsig 0:876e59f87d50 191 {
krenbluetoothsig 0:876e59f87d50 192 static struct gpio_callback button_cb;
krenbluetoothsig 0:876e59f87d50 193
krenbluetoothsig 0:876e59f87d50 194 /* Initialize the button debouncer */
krenbluetoothsig 0:876e59f87d50 195 last_time = k_uptime_get_32();
krenbluetoothsig 0:876e59f87d50 196
krenbluetoothsig 0:876e59f87d50 197 k_work_init(&button_work, button_send_pressed);
krenbluetoothsig 0:876e59f87d50 198
krenbluetoothsig 0:876e59f87d50 199 gpio = device_get_binding(SW0_GPIO_NAME);
krenbluetoothsig 0:876e59f87d50 200
krenbluetoothsig 0:876e59f87d50 201 //initial button A
krenbluetoothsig 0:876e59f87d50 202 gpio_pin_configure(gpio, SW0_GPIO_PIN,
krenbluetoothsig 0:876e59f87d50 203 (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
krenbluetoothsig 0:876e59f87d50 204 GPIO_INT_ACTIVE_LOW));
krenbluetoothsig 0:876e59f87d50 205
krenbluetoothsig 0:876e59f87d50 206 gpio_pin_configure(gpio, SW1_GPIO_PIN,
krenbluetoothsig 0:876e59f87d50 207 (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE |
krenbluetoothsig 0:876e59f87d50 208 GPIO_INT_ACTIVE_LOW));
krenbluetoothsig 0:876e59f87d50 209
krenbluetoothsig 0:876e59f87d50 210 gpio_init_callback(&button_cb, button_pressed,
krenbluetoothsig 0:876e59f87d50 211 BIT(SW0_GPIO_PIN) | BIT(SW1_GPIO_PIN));
krenbluetoothsig 0:876e59f87d50 212
krenbluetoothsig 0:876e59f87d50 213 gpio_add_callback(gpio, &button_cb);
krenbluetoothsig 0:876e59f87d50 214
krenbluetoothsig 0:876e59f87d50 215 gpio_pin_enable_callback(gpio, SW0_GPIO_PIN);
krenbluetoothsig 0:876e59f87d50 216 gpio_pin_enable_callback(gpio, SW1_GPIO_PIN);
krenbluetoothsig 0:876e59f87d50 217 }
krenbluetoothsig 0:876e59f87d50 218
krenbluetoothsig 0:876e59f87d50 219 void board_init(void)
krenbluetoothsig 0:876e59f87d50 220 {
krenbluetoothsig 0:876e59f87d50 221 gpio = device_get_binding(CONFIG_GPIO_NRF5_P0_DEV_NAME);
krenbluetoothsig 0:876e59f87d50 222
krenbluetoothsig 0:876e59f87d50 223 configure_button();
krenbluetoothsig 0:876e59f87d50 224 }
krenbluetoothsig 0:876e59f87d50 225
krenbluetoothsig 0:876e59f87d50 226 static void bt_ready(int err)
krenbluetoothsig 0:876e59f87d50 227 {
krenbluetoothsig 0:876e59f87d50 228 uint64_t uuidFICR = NRF_FICR->DEVICEADDR[0] | ( ( (uint64_t)(NRF_FICR->DEVICEADDR[01]) ) << 32 );
krenbluetoothsig 0:876e59f87d50 229
krenbluetoothsig 0:876e59f87d50 230 if (err) {
krenbluetoothsig 0:876e59f87d50 231 printk("Bluetooth init failed (err %d)\n", err);
krenbluetoothsig 0:876e59f87d50 232 return;
krenbluetoothsig 0:876e59f87d50 233 }
krenbluetoothsig 0:876e59f87d50 234
krenbluetoothsig 0:876e59f87d50 235 printk("Bluetooth initialized\n");
krenbluetoothsig 0:876e59f87d50 236
krenbluetoothsig 0:876e59f87d50 237 board_init();
krenbluetoothsig 0:876e59f87d50 238
krenbluetoothsig 0:876e59f87d50 239 /* Use identity address as device UUID */
krenbluetoothsig 0:876e59f87d50 240 memcpy(dev_uuid, &uuidFICR, sizeof(uint64_t));
krenbluetoothsig 0:876e59f87d50 241
krenbluetoothsig 0:876e59f87d50 242 err = bt_mesh_init(&prov, &comp);
krenbluetoothsig 0:876e59f87d50 243 if (err) {
krenbluetoothsig 0:876e59f87d50 244 printk("Initializing mesh failed (err %d)\n", err);
krenbluetoothsig 0:876e59f87d50 245 return;
krenbluetoothsig 0:876e59f87d50 246 }
krenbluetoothsig 0:876e59f87d50 247
krenbluetoothsig 0:876e59f87d50 248 bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT);
krenbluetoothsig 0:876e59f87d50 249
krenbluetoothsig 0:876e59f87d50 250 printk("Mesh initialized\n");
krenbluetoothsig 0:876e59f87d50 251 }
krenbluetoothsig 0:876e59f87d50 252
krenbluetoothsig 0:876e59f87d50 253 void board_prov_complete(void)
krenbluetoothsig 0:876e59f87d50 254 {
krenbluetoothsig 0:876e59f87d50 255 //gpio_pin_disable_callback(gpio, SW0_GPIO_PIN);
krenbluetoothsig 0:876e59f87d50 256 }
krenbluetoothsig 0:876e59f87d50 257
krenbluetoothsig 0:876e59f87d50 258 void main(void)
krenbluetoothsig 0:876e59f87d50 259 {
krenbluetoothsig 0:876e59f87d50 260 int err;
krenbluetoothsig 0:876e59f87d50 261 struct mb_display *disp = mb_display_get();
krenbluetoothsig 0:876e59f87d50 262
krenbluetoothsig 0:876e59f87d50 263 printk("GenericOnOff Client Initializing...\n");
krenbluetoothsig 0:876e59f87d50 264 printk("UUID: 0x%08x%08X\n", NRF_FICR->DEVICEADDR[1], NRF_FICR->DEVICEADDR[0]);
krenbluetoothsig 0:876e59f87d50 265 mb_display_print(disp, MB_DISPLAY_MODE_SCROLL, K_MSEC(500), "%s", "Client");
krenbluetoothsig 0:876e59f87d50 266
krenbluetoothsig 0:876e59f87d50 267
krenbluetoothsig 0:876e59f87d50 268 /* Initialize the Bluetooth Subsystem */
krenbluetoothsig 0:876e59f87d50 269 err = bt_enable(bt_ready);
krenbluetoothsig 0:876e59f87d50 270 if (err) {
krenbluetoothsig 0:876e59f87d50 271 printk("Bluetooth init failed (err %d)\n", err);
krenbluetoothsig 0:876e59f87d50 272 }
krenbluetoothsig 0:876e59f87d50 273 }