Skip to content

Commit

Permalink
ll: add events and callback function for connection state
Browse files Browse the repository at this point in the history
  • Loading branch information
tommag committed Sep 10, 2014
1 parent 09b510c commit a98ab9d
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 14 deletions.
8 changes: 8 additions & 0 deletions include/blessed/errcodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,11 @@
#define ENOREADY 0x04 /* Not ready */
#define EBUSY 0x05 /* Device or resource busy */
#define EINTERN 0x06 /* Internal error */

/* Reasons for disconnection
* Error codes, Section 1.3, Core 4.1 p. 666 */
#define BLE_HCI_CONNECTION_TIMEOUT 0x08
#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13
#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14
#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15
#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16
61 changes: 61 additions & 0 deletions include/blessed/events.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* The MIT License (MIT)
*
* Copyright (c) 2013 Paulo B. de Oliveira Filho <[email protected]>
* Copyright (c) 2013 Claudio Takahasi <[email protected]>
* Copyright (c) 2013 João Paulo Rechi Vita <[email protected]>
* Copyright (c) 2014 Tom Magnier <[email protected]>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

/* Maximum size of parameters structure (to allocate a static buffer) */
#define BLE_EVT_PARAMS_MAX_SIZE 8

/* HCI Specification, Section 7.7, Core 4.1 p.1132-1239 */
typedef enum ble_evt {
BLE_EVT_LL_CONNECTION_COMPLETE, /* Sec 7.7.3 p.1135 */
BLE_EVT_LL_DISCONNECT_COMPLETE, /* Sec 7.7.5 p.1138 */
BLE_EVT_LL_PACKETS_SENT,
BLE_EVT_LL_PACKETS_RECEIVED
}ble_evt_t;

/* Events parameters structure for BLE_EVT_LL_CONNECTION_COMPLETE event */
typedef struct ble_evt_ll_connection_complete {
uint8_t index; /* Connection index */
bdaddr_t peer_addr; /* Peer address */
} ble_evt_ll_connection_complete_t;

/* Events parameters structure for BLE_EVT_LL_DISCONNECT_COMPLETE event */
typedef struct ble_evt_ll_disconnect_complete {
uint8_t index; /* Connection index */
uint8_t reason; /* Reason for disconnection */
} ble_evt_ll_disconnect_complete_t;

/* Events parameters structure for BLE_EVT_LL_PACKETS_SENT event */
typedef struct ble_evt_ll_packets_sent {
uint8_t index; /* Connection index */
} ble_evt_ll_packets_sent_t;

/* Events parameters structure for BLE_EVT_LL_PACKETS_RECEIVED event */
typedef struct ble_evt_ll_packets_received {
uint8_t index; /* Connection index */
uint8_t length; /* Number of bytes received */
} ble_evt_ll_packets_received_t;

1 change: 1 addition & 0 deletions platform/nrf51822/ll-plat.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include <blessed/errcodes.h>
#include <blessed/bdaddr.h>
#include <blessed/events.h>

#include "ll.h"
#include "nrf51822.h"
Expand Down
1 change: 1 addition & 0 deletions stack/bci.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#include <blessed/errcodes.h>
#include <blessed/bdaddr.h>
#include <blessed/events.h>
#include <blessed/bci.h>

#include "ll.h"
Expand Down
78 changes: 65 additions & 13 deletions stack/ll.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <blessed/log.h>
#include <blessed/bdaddr.h>
#include <blessed/random.h>
#include <blessed/events.h>

#include "radio.h"
#include "timer.h"
Expand Down Expand Up @@ -213,6 +214,10 @@ static void t_ll_ifs_cb(void)
static adv_report_cb_t ll_adv_report_cb = NULL;
static struct adv_report ll_adv_report;

/** Callback function to report connection events (CONNECTION state) */
static conn_evt_cb_t ll_conn_evt_cb = NULL;
static uint8_t ll_conn_evt_params[BLE_EVT_PARAMS_MAX_SIZE];

static __inline void send_scan_rsp(const struct ll_pdu_adv *pdu)
{
struct ll_pdu_scan_req *scn;
Expand Down Expand Up @@ -299,8 +304,8 @@ static void prepare_next_data_pdu(bool control_pdu, uint8_t control_pdu_opcode)
pdu_data_tx.llid = LL_PDU_CONTROL;
pdu_data_tx.length = 2;
pdu_data_tx.payload[0] = LL_TERMINATE_IND;
/* REMOTE USER TERMINATED CONNECTION error code */
pdu_data_tx.payload[1] = 0x13;
pdu_data_tx.payload[1] =
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION;

}
else if (control_pdu) {
Expand Down Expand Up @@ -346,6 +351,12 @@ static void prepare_next_data_pdu(bool control_pdu, uint8_t control_pdu_opcode)

/* Data in the TX buffer is now outdated */
conn_context.tx_length = 0;

/* Notify upper layers that data has been sent */
ble_evt_ll_packets_sent_t *packets_tx_params =
(ble_evt_ll_packets_sent_t*)ll_conn_evt_params;
packets_tx_params->index = 0;
ll_conn_evt_cb(BLE_EVT_LL_PACKETS_SENT, ll_conn_evt_params);
}
else {
/* No new data => send Empty Data PDU */
Expand All @@ -354,6 +365,23 @@ static void prepare_next_data_pdu(bool control_pdu, uint8_t control_pdu_opcode)
}
}

/**@brief Handle the end of a connection, which can be caused by various reasons
*
* @param[in] reason: an error code indicating why the connection is being
* closed.
*/
static void end_connection(uint8_t reason)
{
current_state = LL_STATE_STANDBY;

/* Notify upper layers */
ble_evt_ll_disconnect_complete_t *disconn_params =
(ble_evt_ll_disconnect_complete_t*)ll_conn_evt_params;
disconn_params->index = 0;
disconn_params->reason = reason;
ll_conn_evt_cb(BLE_EVT_LL_DISCONNECT_COMPLETE, ll_conn_evt_params);
}

static __inline uint8_t first_adv_ch_idx(void)
{
if (adv_ch_map & LL_ADV_CH_37)
Expand Down Expand Up @@ -881,6 +909,8 @@ int16_t ll_set_data_ch_map(uint64_t ch_map)
static void conn_master_radio_recv_cb(const uint8_t *pdu, bool crc, bool active)
{
struct ll_pdu_data *rcvd_pdu = (struct ll_pdu_data *)(pdu);
ble_evt_ll_packets_received_t *packets_rx_params =
(ble_evt_ll_packets_received_t*)ll_conn_evt_params;

timer_stop(t_ll_ifs);

Expand Down Expand Up @@ -913,7 +943,12 @@ static void conn_master_radio_recv_cb(const uint8_t *pdu, bool crc, bool active)
memcpy(conn_context.rx_buffer, rcvd_pdu->payload,
rcvd_pdu->length);

/* TODO notify app that new data is available */
/* Send an event to upper layers to notify that new
* data is available */
packets_rx_params->index = 0;
packets_rx_params->length = conn_context.rx_length;
ll_conn_evt_cb(BLE_EVT_LL_PACKETS_RECEIVED,
ll_conn_evt_params);
}
}
else {
Expand All @@ -930,9 +965,13 @@ static void conn_master_radio_recv_cb(const uint8_t *pdu, bool crc, bool active)

/* If a terminating procedure has been requested we can exit
* connection state now */
if (conn_context.flags & (LL_CONN_FLAGS_TERM_PEER |
LL_CONN_FLAGS_TERM_LOCAL)) {
current_state = LL_STATE_STANDBY;
if (conn_context.flags & LL_CONN_FLAGS_TERM_PEER) {
end_connection(
BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
return;
} else if (conn_context.flags & LL_CONN_FLAGS_TERM_LOCAL) {
end_connection(
BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION);
return;
}

Expand Down Expand Up @@ -964,11 +1003,7 @@ static void conn_master_interval_cb(void)
conn_context.superv_tmr >=
(ll_conn_params.supervision_timeout /
ll_conn_params.conn_interval_min))) {
timer_stop(t_ll_interval);
current_state = LL_STATE_STANDBY;
/* TODO notify the app. */
DBG("Connection lost (supervision timeout), timer value : %u",
conn_context.superv_tmr);
end_connection(BLE_HCI_CONNECTION_TIMEOUT);
return;
}

Expand All @@ -990,6 +1025,9 @@ static void conn_master_interval_cb(void)
static void init_radio_recv_cb(const uint8_t *pdu, bool crc, bool active)
{
struct ll_pdu_adv *rcvd_pdu = (struct ll_pdu_adv*) pdu;
ble_evt_ll_connection_complete_t *conn_complete_params =
(ble_evt_ll_connection_complete_t*)ll_conn_evt_params;


/* Answer to ADV_IND (connectable undirected advertising event) and
* ADV_DIRECT_IND (connectable directed advertising event) PDUs from
Expand Down Expand Up @@ -1021,7 +1059,14 @@ static void init_radio_recv_cb(const uint8_t *pdu, bool crc, bool active)
/* Prepare the Data PDU that will be sent */
prepare_next_data_pdu(false, 0x00);

/* TODO notify application (cb function) */
/* Send an event to the upper layers */
conn_complete_params->index = 0;
conn_complete_params->peer_addr.type = rcvd_pdu->tx_add;
memcpy(conn_complete_params->peer_addr.addr, rcvd_pdu->payload,
BDADDR_LEN);

ll_conn_evt_cb(BLE_EVT_LL_CONNECTION_COMPLETE,
ll_conn_evt_params);
}
else {
radio_stop();
Expand Down Expand Up @@ -1055,9 +1100,14 @@ static void init_interval_cb(void)
* @param [in] peer_addresses: a pointer to an array of Bluetooth addresses
* to try to connect
* @param [in] num_addresses: the size of the peer_addresses array
* @param [out] rx_buf: a pointer to an array to store incoming data from the
* peer device
* @param [out] conn_evt_cb: the function to call on connection events
*/

int16_t ll_conn_create(uint32_t interval, uint32_t window,
bdaddr_t* peer_addresses, uint16_t num_addresses)
bdaddr_t* peer_addresses, uint16_t num_addresses, uint8_t* rx_buf,
conn_evt_cb_t conn_evt_cb)
{
int16_t err_code;

Expand All @@ -1076,10 +1126,12 @@ int16_t ll_conn_create(uint32_t interval, uint32_t window,

ll_peer_addresses = peer_addresses;
ll_num_peer_addresses = num_addresses;
ll_conn_evt_cb = conn_evt_cb;

/* Generate new connection parameters and init CONNECT_REQ PDU */
init_connect_req_pdu();
init_conn_context();
conn_context.rx_buffer = rx_buf;

radio_set_callbacks(init_radio_recv_cb, NULL);

Expand Down
6 changes: 5 additions & 1 deletion stack/ll.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ struct adv_report {
* See HCI Funcional Specification Section 7.7.65.2, Core 4.1 page 1220 */
typedef void (*adv_report_cb_t)(struct adv_report *report);

/* Callback function for connection events */
typedef void (*conn_evt_cb_t)(ble_evt_t type, const uint8_t *data);

int16_t ll_init(const bdaddr_t *addr);

/* Advertising */
Expand All @@ -158,7 +161,8 @@ int16_t ll_scan_stop(void);
int16_t ll_set_conn_params(ll_conn_params_t* conn_params);
int16_t ll_set_data_ch_map(uint64_t ch_map);
int16_t ll_conn_create(uint32_t interval, uint32_t window,
bdaddr_t* peer_addresses, uint16_t num_addresses);
bdaddr_t* peer_addresses, uint16_t num_addresses, uint8_t* rx_buf,
conn_evt_cb_t conn_evt_cb);
int16_t ll_conn_cancel(void);
int16_t ll_conn_terminate(void);
int16_t ll_conn_send_data(uint8_t *data, uint8_t len);
Expand Down

0 comments on commit a98ab9d

Please sign in to comment.