diff --git a/Makefile.dep b/Makefile.dep index 654daa430d..fdf45f1a7d 100644 --- a/Makefile.dep +++ b/Makefile.dep @@ -68,7 +68,16 @@ ifneq (,$(filter nordic_softdevice_ble,$(USEPKG))) USEMODULE += ble_6lowpan USEMODULE += gnrc_sixlowpan USEMODULE += gnrc_sixlowpan_iphc + USEMODULE += gnrc_ipv6_nib_6ln USEMODULE += gnrc_ipv6_default + # prevent application from being a router + # TODO: maybe find a nicer solution in future build system update + _ROUTER_MODULES = gnrc_ipv6_router% gnrc_rpl netstats_rpl auto_init_gnrc_rpl + ifneq (,$(filter $(_ROUTER_MODULES),$(USEMODULE))) + $(warning nordic_softdevice_ble: Disabling router modules:\ + $(filter $(_ROUTER_MODULES),$(USEMODULE))) + endif + USEMODULE := $(filter-out $(_ROUTER_MODULES),$(USEMODULE)) endif ifneq (,$(filter gnrc_%,$(filter-out gnrc_netapi gnrc_netreg gnrc_netif% gnrc_pkt%,$(USEMODULE)))) diff --git a/boards/common/nrf52xxxdk/Makefile.include b/boards/common/nrf52xxxdk/Makefile.include index 891d306833..21cd813ecd 100644 --- a/boards/common/nrf52xxxdk/Makefile.include +++ b/boards/common/nrf52xxxdk/Makefile.include @@ -1,6 +1,9 @@ # this module contains shared code for all boards using the nrf52 CPU export CPU = nrf52 +# get SoftDevice dependency if needed (dirty hack!) +include $(RIOTBOARD)/$(BOARD)/Makefile.dep + # include this module into the build ifeq (,$(filter thingy52 acd52832,$(BOARD))) INCLUDES += -I$(RIOTBOARD)/common/nrf52xxxdk/include @@ -15,6 +18,11 @@ include $(RIOTMAKE)/tools/serial.inc.mk # setup JLink for flashing export JLINK_DEVICE := nrf52 +# The following configuration is dependencies specific +# but they are resolved later +# Hack to know now if 'nordic_softdevice_ble' is used +include $(RIOTBOARD)/$(BOARD)/Makefile.dep + # special options when using SoftDevice ifneq (,$(filter nordic_softdevice_ble,$(USEPKG))) export JLINK_PRE_FLASH := erase\nloadfile $(BINDIR)/softdevice.hex diff --git a/cpu/nrf52/cpu.c b/cpu/nrf52/cpu.c index 2d01ff28ff..e0dfd28c65 100644 --- a/cpu/nrf52/cpu.c +++ b/cpu/nrf52/cpu.c @@ -68,14 +68,13 @@ void cpu_init(void) #ifdef SOFTDEVICE_PRESENT softdevice_handler_init(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, &_ble_evt_buffer, BLE_STACK_EVT_MSG_BUF_SIZE, NULL); -#endif - /* call cortexm default initialization */ - cortexm_init(); -#ifdef SOFTDEVICE_PRESENT /* fixup swi0 (used as softdevice PendSV trampoline) */ NVIC_EnableIRQ(SWI0_EGU0_IRQn); NVIC_SetPriority(SWI0_EGU0_IRQn, 6); +#else + /* call cortexm default initialization */ + cortexm_init(); #endif /* enable wake up on events for __WFE CPU sleep */ diff --git a/drivers/include/net/netdev.h b/drivers/include/net/netdev.h index 51910edeb5..29dc18170e 100644 --- a/drivers/include/net/netdev.h +++ b/drivers/include/net/netdev.h @@ -211,6 +211,7 @@ enum { NETDEV_TYPE_RAW, NETDEV_TYPE_ETHERNET, NETDEV_TYPE_IEEE802154, + NETDEV_TYPE_BLE, NETDEV_TYPE_CC110X, NETDEV_TYPE_LORA, NETDEV_TYPE_NRFMIN, diff --git a/pkg/nordic_softdevice_ble/src/gnrc_nordic_ble_6lowpan.c b/pkg/nordic_softdevice_ble/src/gnrc_nordic_ble_6lowpan.c index 394da94575..312a6135b4 100644 --- a/pkg/nordic_softdevice_ble/src/gnrc_nordic_ble_6lowpan.c +++ b/pkg/nordic_softdevice_ble/src/gnrc_nordic_ble_6lowpan.c @@ -63,6 +63,9 @@ #define BLE_PRIO (GNRC_NETIF_PRIO) +/* XXX: netdev required by gnrc_netif, but not implemented fully for + * nordic_softdevice_ble for legacy reasons */ + static char _stack[(THREAD_STACKSIZE_DEFAULT + DEBUG_EXTRA_STACKSIZE)]; static gnrc_netif_t *_ble_netif = NULL; @@ -73,7 +76,7 @@ static void _ble_mac_callback(ble_mac_event_enum_t event, void* arg) { msg_t m = { .type=event, .content.ptr=arg }; - if ((_ble_netif != NULL) || !msg_send_int(&m, _ble_netif->pid)) { + if ((_ble_netif == NULL) || !msg_send_int(&m, _ble_netif->pid)) { puts("_ble_mac_callback(): possibly lost interrupt"); } } @@ -174,45 +177,51 @@ static int _send(gnrc_pktsnip_t *pkt) return 0; } -static int _handle_get(gnrc_netapi_opt_t *_opt) + +static int _netdev_init(netdev_t *dev) +{ + _ble_netif = dev->context; + ble_stack_init(); + ble_mac_init(_ble_mac_callback); + _ble_netif->l2addr_len = BLE_SIXLOWPAN_L2_ADDR_LEN; + ble_get_mac(_ble_netif->l2addr); + ble_advertising_init("RIOT BLE"); + ble_advertising_start(); + return 0; +} + +static int _netdev_get(netdev_t *netdev, netopt_t opt, + void *v, size_t max_len) { int res = -ENOTSUP; - uint8_t *value = _opt->data; + uint8_t *value = v; - switch (_opt->opt) { - case NETOPT_ACK_REQ: - case NETOPT_CHANNEL: - case NETOPT_NID: - case NETOPT_ADDRESS: - /* -ENOTSUP */ - break; + (void)netdev; + switch (opt) { case NETOPT_ADDRESS_LONG: - assert(_opt->data_len >= BLE_SIXLOWPAN_L2_ADDR_LEN); + assert(max_len >= BLE_SIXLOWPAN_L2_ADDR_LEN); memcpy(value, _ble_netif->l2addr, BLE_SIXLOWPAN_L2_ADDR_LEN); - value[0] = IPV6_IID_FLIP_VALUE; res = BLE_SIXLOWPAN_L2_ADDR_LEN; break; case NETOPT_ADDR_LEN: case NETOPT_SRC_LEN: - assert(_opt->data_len == sizeof(uint16_t)); + assert(max_len == sizeof(uint16_t)); *((uint16_t *)value) = BLE_SIXLOWPAN_L2_ADDR_LEN; res = sizeof(uint16_t); break; -#ifdef MODULE_GNRC case NETOPT_PROTO: - assert(_opt->data_len == sizeof(gnrc_nettype_t)); + assert(max_len == sizeof(gnrc_nettype_t)); *((gnrc_nettype_t *)value) = GNRC_NETTYPE_SIXLOWPAN; res = sizeof(gnrc_nettype_t); break; -#endif -/* case NETOPT_DEVICE_TYPE: - assert(_opt->data_len == sizeof(uint16_t)); - *((uint16_t *)value) = NETDEV_TYPE_IEEE802154; + case NETOPT_DEVICE_TYPE: + assert(max_len == sizeof(uint16_t)); + *((uint16_t *)value) = NETDEV_TYPE_BLE; res = sizeof(uint16_t); - break;*/ + break; case NETOPT_IPV6_IID: memcpy(value, _ble_netif->l2addr, BLE_SIXLOWPAN_L2_ADDR_LEN); - value[0] = IPV6_IID_FLIP_VALUE; + value[0] ^= IPV6_IID_FLIP_VALUE; res = BLE_SIXLOWPAN_L2_ADDR_LEN; break; default: @@ -221,20 +230,20 @@ static int _handle_get(gnrc_netapi_opt_t *_opt) return res; } -static void _netif_init(gnrc_netif_t *netif) +static int _netdev_set(netdev_t *netdev, netopt_t opt, + const void *value, size_t value_len) { - ble_stack_init(); - ble_mac_init(_ble_mac_callback); - netif->l2addr_len = BLE_SIXLOWPAN_L2_ADDR_LEN; - ble_get_mac(netif->l2addr); - ble_advertising_init("RIOT BLE"); - ble_advertising_start(); + (void)netdev; + (void)opt; + (void)value; + (void)value_len; + return -ENOTSUP; } static int _netif_send(gnrc_netif_t *netif, gnrc_pktsnip_t *pkt) { (void)netif; - assert(netif != _ble_netif); + assert(netif == _ble_netif); return _send(pkt); } @@ -245,21 +254,6 @@ static gnrc_pktsnip_t *_netif_recv(gnrc_netif_t *netif) return NULL; } -static int _netif_get(gnrc_netif_t *netif, gnrc_netapi_opt_t *opt) -{ - (void)netif; - assert(netif != _ble_netif); - return _handle_get(opt); -} - -static int _netif_set(gnrc_netif_t *netif, const gnrc_netapi_opt_t *opt) -{ - (void)netif; - (void)opt; - /* not supported */ - return -ENOTSUP; -} - static void _netif_msg_handler(gnrc_netif_t *netif, msg_t *msg) { switch (msg->type) { @@ -274,16 +268,29 @@ static void _netif_msg_handler(gnrc_netif_t *netif, msg_t *msg) } static const gnrc_netif_ops_t _ble_ops = { - .init = _netif_init, + .init = NULL, .send = _netif_send, .recv = _netif_recv, - .get = _netif_get, - .set = _netif_set, + .get = gnrc_netif_get_from_netdev, + .set = gnrc_netif_set_from_netdev, .msg_handler = _netif_msg_handler, }; +static const netdev_driver_t _ble_netdev_driver = { + .send = NULL, + .recv = NULL, + .init = _netdev_init, + .isr = NULL, + .get = _netdev_get, + .set = _netdev_set, +}; + +static netdev_t _ble_dummy_dev = { + .driver = &_ble_netdev_driver, +}; + void gnrc_nordic_ble_6lowpan_init(void) { - _ble_netif = gnrc_netif_create(_stack, sizeof(_stack), BLE_PRIO, - "ble", NULL, &_ble_ops); + gnrc_netif_create(_stack, sizeof(_stack), BLE_PRIO, + "ble", &_ble_dummy_dev, &_ble_ops); } diff --git a/sys/net/gnrc/netif/gnrc_netif.c b/sys/net/gnrc/netif/gnrc_netif.c index 4b2953e625..7068d3b7f0 100644 --- a/sys/net/gnrc/netif/gnrc_netif.c +++ b/sys/net/gnrc/netif/gnrc_netif.c @@ -819,6 +819,13 @@ int gnrc_netif_ipv6_get_iid(gnrc_netif_t *netif, eui64_t *eui64) } break; #endif +#ifdef MODULE_NORDIC_SOFTDEVICE_BLE + case NETDEV_TYPE_BLE: + assert(netif->l2addr_len == sizeof(eui64_t)); + memcpy(eui64, netif->l2addr, sizeof(eui64_t)); + eui64->uint8[0] ^= 0x02; + return 0; +#endif #if defined(MODULE_CC110X) || defined(MODULE_NRFMIN) case NETDEV_TYPE_CC110X: case NETDEV_TYPE_NRFMIN: @@ -1105,6 +1112,7 @@ bool gnrc_netif_is_6ln(const gnrc_netif_t *netif) switch (netif->device_type) { case NETDEV_TYPE_IEEE802154: case NETDEV_TYPE_CC110X: + case NETDEV_TYPE_BLE: case NETDEV_TYPE_NRFMIN: return true; default: @@ -1120,7 +1128,9 @@ static void _update_l2addr_from_dev(gnrc_netif_t *netif) netopt_t opt = NETOPT_ADDRESS; switch (netif->device_type) { -#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) +#if defined(MODULE_NETDEV_IEEE802154) || defined(MODULE_XBEE) \ + || defined(MODULE_NORDIC_SOFTDEVICE_BLE) + case NETDEV_TYPE_BLE: case NETDEV_TYPE_IEEE802154: { uint16_t tmp; @@ -1181,6 +1191,14 @@ static void _init_from_device(gnrc_netif_t *netif) netif->ipv6.mtu = ETHERNET_DATA_LEN; #endif break; +#endif +#ifdef MODULE_NORDIC_SOFTDEVICE_BLE + case NETDEV_TYPE_BLE: + netif->ipv6.mtu = IPV6_MIN_MTU; +#ifdef MODULE_GNRC_SIXLOWPAN_IPHC + netif->flags |= GNRC_NETIF_FLAGS_6LO_HC; +#endif + break; #endif default: #ifdef MODULE_GNRC_IPV6 diff --git a/sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c b/sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c index a1f361b953..7b18baca08 100644 --- a/sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c +++ b/sys/net/gnrc/network_layer/sixlowpan/gnrc_sixlowpan.c @@ -257,11 +257,10 @@ static void _send(gnrc_pktsnip_t *pkt) DEBUG("6lo: iface->sixlo.max_frag_size = %" PRIu8 " for interface %" PRIkernel_pid "\n", iface->sixlo.max_frag_size, hdr->if_pid); - /* IP should not send anything here if it is not a 6LoWPAN interface, - * so we don't need to check for NULL pointers. - * Note, that datagram_size cannot be used here, because the header size + /* Note, that datagram_size cannot be used here, because the header size * might be changed by IPHC. */ - if (gnrc_pkt_len(pkt2->next) <= iface->sixlo.max_frag_size) { + if ((iface->sixlo.max_frag_size == 0) || + (gnrc_pkt_len(pkt2->next) <= iface->sixlo.max_frag_size)) { DEBUG("6lo: Send SND command for %p to %" PRIu16 "\n", (void *)pkt2, hdr->if_pid); if (gnrc_netapi_send(hdr->if_pid, pkt2) < 1) {