Hello World !!
This is simple code which is compatible for nRF Blinky App which is based on Zephyr OS Bluetooth APIs. I've tested it on #nRF52840-PDK board. Isn't it simple ?
You have to just replace $zephyr_base/samples/bluetooth/peripheral/src/main.c with following code.
These are some useful links for reference,
( https://play.google.com/store/apps/details?id=no.nordicsemi.android.nrfblinky&hl=en )
(http://docs.zephyrproject.org/api/bluetooth.html )
(http://docs.zephyrproject.org/samples/bluetooth/bluetooth.html#bluetooth-setup)
#include <zephyr/types.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <misc/printk.h>
#include <misc/byteorder.h>
#include <zephyr.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/conn.h>
#include <bluetooth/uuid.h>
#include <bluetooth/gatt.h>
#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
#include <nrf.h>
#include <device.h>
#include <gpio.h>
#include <board.h>
#define SETB(x,y) (x|=(1<<y)) //for o/p
#define CLRB(x,y) (x&=(~(1<<y))) //for o/p
#define TGLB(x,y) (x^=(1<<y)) //for o/p
#define CHECKB(x,y) (x&(1<<y)) //for i/p
/* Custom Service Variables */
static struct bt_uuid_128 srv_uuid = BT_UUID_INIT_128(
0x23, 0xd1, 0xbc, 0xea, 0x5f, 0x78, 0x23, 0x15,
0xde, 0xef, 0x12, 0x12, 0x23, 0x15, 0x00, 0x00);
static struct bt_uuid_128 button_uuid = BT_UUID_INIT_128(
0x23, 0xd1, 0xbc, 0xea, 0x5f, 0x78, 0x23, 0x15,
0xde, 0xef, 0x12, 0x12, 0x24, 0x15, 0x00, 0x00);
static struct bt_uuid_128 led_uuid = BT_UUID_INIT_128(
0x23, 0xd1, 0xbc, 0xea, 0x5f, 0x78, 0x23, 0x15,
0xde, 0xef, 0x12, 0x12, 0x25, 0x15, 0x00, 0x00);
static u8_t led_value;
static u8_t button_value;
static struct bt_gatt_ccc_cfg vnd_ccc_cfg[BT_GATT_CCC_MAX] = {};
static u8_t simulate_vnd;
static ssize_t read_led(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset);
static ssize_t write_led(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, u16_t len, u16_t offset, u8_t flags);
static ssize_t read_button(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset);
static void vnd_ccc_cfg_changed(const struct bt_gatt_attr *attr, u16_t value);
/* Vendor Primary Service Declaration */
static struct bt_gatt_attr vnd_attrs[] =
{
/* Vendor Primary Service Declaration */
BT_GATT_PRIMARY_SERVICE(&srv_uuid),
BT_GATT_CHARACTERISTIC(&button_uuid.uuid, BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY),
BT_GATT_DESCRIPTOR(&button_uuid.uuid, BT_GATT_PERM_READ, read_button, NULL, &button_value),
BT_GATT_CCC(vnd_ccc_cfg, vnd_ccc_cfg_changed),
BT_GATT_CHARACTERISTIC(&led_uuid.uuid, BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE),
BT_GATT_DESCRIPTOR(&led_uuid.uuid, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, read_led, write_led, &led_value),
};
static struct bt_gatt_service vnd_svc = BT_GATT_SERVICE(vnd_attrs);
static const struct bt_data ad[] =
{
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
BT_DATA_BYTES(BT_DATA_UUID128_ALL,
0x23, 0xd1, 0xbc, 0xea, 0x5f, 0x78, 0x23, 0x15,
0xde, 0xef, 0x12, 0x12, 0x23, 0x15, 0x00, 0x00),
};
static const struct bt_data sd[] =
{
BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};
static void bt_ready(int err)
{
if (err) {
printk("Bluetooth init failed (err %d)\n", err);
return;
}
printk("Bluetooth initialized\n");
bt_gatt_service_register(&vnd_svc);
err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad),
sd, ARRAY_SIZE(sd));
if (err) {
printk("Advertising failed to start (err %d)\n", err);
return;
}
printk("Advertising successfully started\n");
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
static void connected(struct bt_conn *conn, u8_t err)
{
if (err)
{
printk("Connection failed (err %u)\n", err);
}
else
{
printk("Connected\n");
}
}
static void disconnected(struct bt_conn *conn, u8_t reason)
{
printk("Disconnected (reason %u)\n", reason);
}
static struct bt_conn_cb conn_callbacks = {
.connected = connected,
.disconnected = disconnected,
};
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
static void auth_passkey_display(struct bt_conn *conn, unsigned int passkey)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
printk("Passkey for %s: %06u\n", addr, passkey);
}
static void auth_cancel(struct bt_conn *conn)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
printk("Pairing cancelled: %s\n", addr);
}
static struct bt_conn_auth_cb auth_cb_display = {
.passkey_display = auth_passkey_display,
.passkey_entry = NULL,
.cancel = auth_cancel,
};
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
struct device *button_device[1];
static struct k_work button_work;
static void button_pressed(struct device *dev, struct gpio_callback *cb,
uint32_t pins)
{
k_work_submit(&button_work);
}
void publish(struct k_work *work)
{
if(CHECKB(NRF_P0->IN,11)==0)
{
button_value=1;
}
else
{
button_value=0;
}
bt_gatt_notify(NULL, &vnd_attrs[2], &button_value, sizeof(button_value));
}
//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void main(void)
{
int err;
static struct gpio_callback button_cb[1];
k_work_init(&button_work, publish);
button_device[0] = device_get_binding(SW0_GPIO_NAME);
gpio_pin_configure(button_device[0], SW0_GPIO_PIN, (GPIO_DIR_IN | GPIO_INT | GPIO_INT_EDGE | GPIO_PUD_PULL_UP | GPIO_INT_DEBOUNCE | GPIO_INT_DOUBLE_EDGE));
gpio_init_callback(&button_cb[0], button_pressed, BIT(SW0_GPIO_PIN));
gpio_add_callback(button_device[0], &button_cb[0]);
gpio_pin_enable_callback(button_device[0], SW0_GPIO_PIN);
NRF_P0->DIR |= 0x0001E000;
NRF_P0->OUTSET |= 0x0001E000;
err = bt_enable(bt_ready);
if (err) {
printk("Bluetooth init failed (err %d)\n", err);
return;
}
bt_conn_cb_register(&conn_callbacks);
bt_conn_auth_cb_register(&auth_cb_display);
}
static ssize_t read_led(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset)
{
char *value = attr->user_data;
return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(led_value));
}
static ssize_t write_led(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, u16_t len, u16_t offset, u8_t flags)
{
u8_t *value = attr->user_data;
if (offset + len > sizeof(led_value)) {
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
}
memcpy(value + offset, buf, len);
if(value[0])
{
led_value=1;
NRF_P0->OUT &= ~(1<<13);
}
else
{
led_value=0;
NRF_P0->OUT |= (1<<13);
}
return len;
}
static ssize_t read_button(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset)
{
char *value = attr->user_data;
if(CHECKB(NRF_P0->IN,11)==0)
{
button_value=1;
}
else
{
button_value=0;
}
return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(button_value));
}
static void vnd_ccc_cfg_changed(const struct bt_gatt_attr *attr, u16_t value)
{
simulate_vnd = (value == BT_GATT_CCC_INDICATE) ? 1 : 0;
bt_gatt_notify(NULL, &vnd_attrs[2], &button_value, sizeof(button_value));
}