mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
175 lines
4.7 KiB
C
175 lines
4.7 KiB
C
/*
|
|
* Copyright (C) 2019 Freie Universität Berlin
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup tests
|
|
* @{
|
|
*
|
|
* @file
|
|
* @brief Server to test and benchmark raw L2CAP COC for NimBLE
|
|
*
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
|
*
|
|
* @}
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "nimble_riot.h"
|
|
#include "host/ble_hs.h"
|
|
#include "host/ble_gap.h"
|
|
#include "host/util/util.h"
|
|
|
|
#include "test_utils/expect.h"
|
|
#include "net/bluetil/ad.h"
|
|
|
|
#include "nimble_l2cap_test_conf.h"
|
|
|
|
/* BLE connection state */
|
|
static uint16_t _handle = 0;
|
|
static struct ble_l2cap_chan *_coc = NULL;
|
|
|
|
/* buffer allocation */
|
|
static os_membuf_t _coc_mem[OS_MEMPOOL_SIZE(MBUFCNT, MBUFSIZE)];
|
|
static struct os_mempool _coc_mempool;
|
|
static struct os_mbuf_pool _coc_mbuf_pool;
|
|
static uint32_t _rxbuf[APP_MTU / 4];
|
|
|
|
/* safe AD fields */
|
|
static uint8_t _ad_buf[BLE_HS_ADV_MAX_SZ];
|
|
static bluetil_ad_t _ad;
|
|
static struct ble_gap_adv_params _adv_params = { 0 };
|
|
|
|
static void _advertise_now(void);
|
|
|
|
static void _on_data(struct ble_l2cap_event *event)
|
|
{
|
|
int res;
|
|
struct os_mbuf *rxd;
|
|
|
|
rxd = event->receive.sdu_rx;
|
|
expect(rxd != NULL);
|
|
int rx_len = (int)OS_MBUF_PKTLEN(rxd);
|
|
expect(rx_len <= (int)APP_MTU);
|
|
|
|
res = os_mbuf_copydata(rxd, 0, rx_len, _rxbuf);
|
|
expect(res == 0);
|
|
|
|
res = ble_l2cap_send(_coc, rxd);
|
|
expect((res == 0) || (res == BLE_HS_ESTALLED));
|
|
|
|
/* allocate new mbuf for receiving new data */
|
|
rxd = os_mbuf_get_pkthdr(&_coc_mbuf_pool, 0);
|
|
expect(rxd != NULL);
|
|
res = ble_l2cap_recv_ready(_coc, rxd);
|
|
expect(res == 0);
|
|
|
|
printf("# Received: len %5i, seq %5u\n", rx_len, (unsigned)_rxbuf[POS_SEQ]);
|
|
}
|
|
|
|
static int _on_gap_evt(struct ble_gap_event *event, void *arg)
|
|
{
|
|
(void)arg;
|
|
printf("# GAP event %i\n", (int)event->type);
|
|
|
|
switch (event->type) {
|
|
case BLE_GAP_EVENT_CONNECT:
|
|
_handle = event->connect.conn_handle;
|
|
break;
|
|
case BLE_GAP_EVENT_DISCONNECT:
|
|
_coc = NULL;
|
|
_handle = 0;
|
|
_advertise_now();
|
|
break;
|
|
case BLE_GAP_EVENT_CONN_UPDATE:
|
|
case BLE_GAP_EVENT_CONN_UPDATE_REQ:
|
|
default:
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int _on_l2cap_evt(struct ble_l2cap_event *event, void *arg)
|
|
{
|
|
(void)arg;
|
|
|
|
switch (event->type) {
|
|
case BLE_L2CAP_EVENT_COC_CONNECTED: {
|
|
_coc = event->connect.chan;
|
|
struct ble_l2cap_chan_info info;
|
|
ble_l2cap_get_chan_info(_coc, &info);
|
|
puts("# L2CAP: CONNECTED");
|
|
printf("# MTUs: our %i, remote %i\n",
|
|
(int)info.our_l2cap_mtu, (int)info.peer_l2cap_mtu);
|
|
break;
|
|
}
|
|
case BLE_L2CAP_EVENT_COC_DISCONNECTED:
|
|
_coc = NULL;
|
|
puts("# L2CAP: DISCONNECTED");
|
|
break;
|
|
case BLE_L2CAP_EVENT_COC_ACCEPT: {
|
|
struct os_mbuf *sdu_rx = os_mbuf_get_pkthdr(&_coc_mbuf_pool, 0);
|
|
expect(sdu_rx != NULL);
|
|
ble_l2cap_recv_ready(event->accept.chan, sdu_rx);
|
|
break;
|
|
}
|
|
case BLE_L2CAP_EVENT_COC_DATA_RECEIVED:
|
|
_on_data(event);
|
|
break;
|
|
case BLE_L2CAP_EVENT_COC_TX_UNSTALLED:
|
|
/* this event is expected, but we have nothing to do here */
|
|
break;
|
|
default:
|
|
expect(0);
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void _advertise_now(void)
|
|
{
|
|
int res = ble_gap_adv_start(nimble_riot_own_addr_type, NULL, BLE_HS_FOREVER,
|
|
&_adv_params, _on_gap_evt, NULL);
|
|
expect(res == 0);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
int res;
|
|
(void)res;
|
|
puts("NimBLE L2CAP test server");
|
|
|
|
/* initialize buffers and setup the test environment */
|
|
res = os_mempool_init(&_coc_mempool, MBUFCNT, MBUFSIZE, _coc_mem, "appbuf");
|
|
expect(res == 0);
|
|
res = os_mbuf_pool_init(&_coc_mbuf_pool, &_coc_mempool, MBUFSIZE, MBUFCNT);
|
|
expect(res == 0);
|
|
|
|
/* create l2cap server */
|
|
res = ble_l2cap_create_server(APP_CID, APP_MTU, _on_l2cap_evt, NULL);
|
|
expect(res == 0);
|
|
|
|
/* initialize advertising data and parameters */
|
|
_adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
|
|
_adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
|
|
bluetil_ad_init_with_flags(&_ad, _ad_buf, sizeof(_ad_buf),
|
|
BLUETIL_AD_FLAGS_DEFAULT);
|
|
bluetil_ad_add_name(&_ad, APP_NODENAME);
|
|
res = ble_gap_adv_set_data(_ad.buf, (int)_ad.pos);
|
|
expect(res == 0);
|
|
|
|
/* start advertising the test server */
|
|
_advertise_now();
|
|
puts("# now advertising");
|
|
|
|
/* nothing else to be done in the main thread */
|
|
return 0;
|
|
}
|