Coder Social home page Coder Social logo

crownstone / bluenet Goto Github PK

View Code? Open in Web Editor NEW
90.0 18.0 61.0 171.54 MB

Bluenet is the in-house firmware on Crownstone hardware. Functions: switching, dimming, energy monitoring, presence detection, indoor localization, switchcraft.

Home Page: https://crownstone.rocks

CMake 7.13% C++ 65.14% C 25.58% Shell 0.25% HTML 0.30% Python 1.49% JavaScript 0.02% Ruby 0.01% Dockerfile 0.08%
crownstone smartphone bluenet wearables bluetooth-low-energy bluetooth firmware nrf52 smart-home smart-plug

bluenet's Introduction

Bluenet

Crownstone Logo in Light Mode Crownstone Logo in Dark Mode

Documentation Build Status Forum Twitter


Bluenet is code running on Crownstone compatible devices such as electronic connectors, electronic EU plugs and grid-powered beacons, Guidestones. Each Crownstone or Guidestone is a node in a network that uses signal strength for indoor localization of smartphones and wearables.

Features

  • Made for indoor localization.
  • Includes a mesh network.
  • Power measuring.
  • iBeacon compliant.
  • Configurable over the air.

Usage

To use a device with bluenet code on it, you only need to know the Bluetooth protocol that bluenet uses. You can find the protocol definitions in the protocol document.

Build

To build the bluenet code yourself, follow the installation instructions.

Communication

You can best communicate bugs and feature requests via the issue tracker. For all other questions, please, feel free to ask us anything on our website.

Resources

A short list for a quick overview:

Resource Description
Bluenet firmware This repository, open-source firmware (C++) for smart plugs
Bluenet documentation Documentation of the firmware (doxygen-based)
Android library Android library (Kotlin)
iOS library iOS library (Swift)
Python library Python library
Crownstone website Website and shop for the Crownstone products
Crownstone Android app Android app on the Play Store
Crownstone iOS app iOS app on the Apple Store
Crownstone app source Source code for the cross-platform app (React Native)

Commercial use

This code is used in a commercial product, the Crownstone. Our intellectual property exists on two levels:

  • The hardware is patented under Dutch law with the main aim to protect you as a developer against fraudulent claims.
  • The software in these repositories allow developers to build a complete indoor localization system. We do have pro-versions of e.g. the basic indoor localization library to be used by other companies under a commercial license.

Summarized, as a developer you can build your own services on top of the Crownstone stack. Benefit from our software development as much as you want! For PR reasons, it would be much appreciated to if you mention us of course!

Help us

There are many ways to help us!

  • Crownstone sells the Crownstone products through our own channels. Buying our products is the best way in which you can support open-source projects like these!
  • Crownstone also integrates their hardware technology in third-party products, ranging from lights to desks. Ask us for our expertise!
  • If you want to contribute yourself, please do! Fork this repository, work on your favorite feature, and issue a pull request!
  • If you appreciate open-source and privacy-oriented hardware projects, but you're not into this type of tech or product, feel free to help by starring โญ our repository!

Contributors


Bart van Vliet

Dominik Egger

Anne van Rossum

Alex de Mulder

Marc Hulscher

Christian Haas

Peet van Tooren

Arend de Jonge

Naveen Chakravarthy

Aniket Samant

Merijn Plagge

Martijn van der Marel

Copyrights

Copyrights belong to the team of Crownstone B.V.:

  • Authors: Dominik Egger, Bart van Vliet, Anne van Rossum, Marc Hulscher, Peet van Tooren, Alex de Mulder, Christian Haas, Naveen Chakravarthy, Aniket Samant, Arend de Jonge
  • Creation date: 27 Jan. 2014
  • Crownstone B.V., https://crownstone.rocks
  • Stationsplein 45 d1.118, 3013 AK Rotterdam, The Netherlands

Open-source license

This firmware is provided under a noncontagious open-source license towards the open-source community. It's available under three open-source licenses:

  • License: LGPL v3+, Apache, MIT

Our special thanks go to Christopher Mason for the initial C++ code base at http://hg.cmason.com/nrf and Nordic Semiconductor for the beautiful SoftDevices they have developed. The code of Mason falls under the same triple license. The code by Nordic falls under the license from Nordic (see their repositories).

License: LGPL v3 License: MIT License: Apache 2.0

Commercial license

This firmware can also be provided under a commercial license. If you are not an open-source developer or are not planning to release adaptations to the code under one or multiple of the mentioned licenses, contact us to obtain a commercial license.

  • License: Crownstone commercial license

Contact

For any question contact us at https://crownstone.rocks/contact/ or on our discord server through https://crownstone.rocks/forum/.

bluenet's People

Contributors

alexdm0 avatar arrowacrobatics avatar chaasfr avatar kurkesmurfer avatar marciwi avatar martijnvandermarel avatar mplagge avatar vliedel avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bluenet's Issues

Gradual change between two different states for dimming

Currently, when going from a dimming state of around 60% to say 20%, a Crownstone receiving this command will immediately switch between the mentioned states.

The code for controlling the relays (for switching) and the IGBTs (for dimming) can be found in https://github.com/crownstone/bluenet/blob/master/src/processing/cs_Switch.cpp.

It would be great to have the Crownstone gradually change from 60% to 20% and have slowly diminishing brightness. And the other way around in the opposite case.

Get installation manual to normal size

Normal installation procedure:

git clone [email protected]:crownstone/bluenet.git bluenet
cd bluenet
make get-deps
make
(sudo) make install

The current installation manual can be found at https://github.com/crownstone/bluenet/blob/master/docs/INSTALL.md and is too large.

  • introduce make get-deps and get rid of all the stuff about Nordic, J-Link, and the arm compiler by maintaining the script https://github.com/crownstone/crownstone-sdk/blob/master/scripts/install.sh or moving the relevant parts to this repository
  • get rid of the Nordic bugs, by something like make apply-patches and don't bother the reader with it, preferably run it automatically after make get-deps
  • multiple devices: include something like make add-device and automate obtaining serial number of JLink devices
  • get rid of st-link and openocd
  • uart: add a cmake target, e.g. make debug and incorporate in that script directions if needed
  • get rid of everything irrelevant/old in the /scripts directory
  • have only the scripts that a third-party developer should use in /scripts and move helper scripts, release scripts, etc. to something like /scripts/advanced
  • separate out all the configuration options that you can set afterwards to a separate .md file, the defaults should be good

Create an installer script (with those 5 lines at the top) for Travis. If that is not possible the installation is unnecessarily complicated.

Characteristic is still trying to use encryption in setup mode

[cs_main_crownstone.cpp         : 153  ] Configure setup mode                                          
[cs_main_crownstone.cpp         : 493  ] Create all services                                           
[cs_DeviceInformationService.cp : 32   ] Device Information Service init                               
[cs_DeviceInformationService.cp : 34   ] Characteristic Hardware Revision added                        
[cs_DeviceInformationService.cp : 37   ] Characteristic Firmware Revision added                        
[cs_DeviceInformationService.cp : 41   ] Characteristic Software Revision added                        
[cs_SetupService.cpp            : 26   ] Setup Service init                                            
[cs_SetupService.cpp            : 33   ] Characteristic Control added                                  
[cs_SetupService.cpp            : 36   ] Characteristic MAC Address added                              
[cs_SetupService.cpp            : 40   ] Characteristic Setup Encryption Key added                     
[cs_SetupService.cpp            : 43   ] Characteristic Configuration added                            
[cs_Stack.cpp                   : 311  ] Set tx power to -40                                           
[cs_main_crownstone.cpp         : 168  ] Enable AES encryption                                         
[cs_main_crownstone.cpp         : 212  ] ---- init services ----                                       
[cs_Characteristic.cpp          : 87   ] Hardware Revision init with buffer[20] with 0x200056c8        
[cs_Characteristic.cpp          : 87   ] Firmware Revision init with buffer[20] with 0x200057f8        
[cs_Characteristic.cpp          : 87   ] Software Revision init with buffer[20] with 0x20005810        
[cs_Characteristic.cpp          : 87   ] Control init with buffer[300] with 0x20004b48                 
[cs_Characteristic.cpp          : 87   ] MAC Address init with buffer[6] with 0x20005419               
[cs_Characteristic.cpp          : 87   ] Setup Encryption Key init with buffer[16] with 0x20005660     
[cs_Characteristic.cpp          : 87   ] Config Control init with buffer[300] with 0x20004b48          
[cs_Characteristic.cpp          : 87   ] Config Read init with buffer[300] with 0x20004b48
[cs_EncryptionHandler.cpp       : 434  ] Can't use this setup key                                      
[cs_Characteristic.cpp          : 228  ] error encrypting data.

How to turn on beacon discovery ?

Hey , i tried creating a sample HRM application and have flashed it successfully into nordic nRF51822.
I want the chip to be discovered as a beacon in my android phone on nRF beacon app but it is not discoverable as a beacon but as a simple bluetooth device.
How is the beacon recovery switched on ? Is it via application code .. if so then what library/method/way is used ?

Packet build-up

A lot of packets at https://github.com/crownstone/bluenet/blob/master/docs/PROTOCOL.md seem to be nicely 4-byte aligned. A state packet starts for example with two uint8_t values and then a length of uint16_t.

However, this is not done consistently. A setup package has a lot of fields that cross 4-byte boundaries. This makes storing them much more cumbersome. In the worst case, it requires copying every field to the right alignment. A protocol redesign that takes into 4 bytes separation would be useful.

For now, I'll construct wrapper structs that prepend for example the setup package with a few bytes so that most of the large fields will be 4-byte aligned.

Standardize accessors

Standardize the accessors on the data structures.

Introduce const to indicate if a container will be left unchanged.

Introduce checks on size.

Just one example of things that are not caught is index < -1 in peek_next_state_item, but it is much more satisfying to debug proper accessors than going through all the corner cases of custom for loops.

S130 error in sd_ble_gap_sec_params_reply

When using the s130 (or the s120) rather than the s110 the signature of the sd_ble_gap_sec_params_reply requires an additional argument:

error: too few arguments to function 'uint32_t sd_ble_gap_sec_params_reply(uint16_t, uint8_t, const ble_gap_sec_params_t*, const ble_gap_sec_keyset_t*)'
       &sec_params) );
                  ^

Switch state needlessly written after reset

After a reset through e.g. ./reset.sh, the switch state is written to flash, even though the last value written is exactly the same. This needlessly writes to flash.

empty page
new page
type=  0 len=  4 data: 80 FF FF FF  
type=  0 len=  4 data: 01 00 FF FF  
type=  0 len=  4 data: 02 00 FF FF  
type=  0 len=  4 data: 80 FF FF FF  
type=  0 len=  4 data: 03 00 FF FF  
type=  0 len=  4 data: 80 FF FF FF  
type=  0 len=  4 data: 04 00 FF FF  
type=  0 len=  4 data: 80 FF FF FF  
type=  0 len=  4 data: 05 00 FF FF  
type=  0 len=  4 data: 80 FF FF FF  
type=  0 len=  4 data: 06 00 FF FF  
type=  0 len=  4 data: 80 FF FF FF  
type=  0 len=  4 data: 07 00 FF FF  
type=  0 len=  4 data: 80 FF FF FF  
type=  0 len=  4 data: 08 00 FF FF  
type=  0 len=  4 data: 09 00 FF FF  
type=129 len=  4 data: 80 FF FF FF  [STATE_SWITCH_STATE]
type=128 len=  4 data: 0A 00 FF FF  [STATE_RESET_COUNTER]

Refactor build system

Related to #55, but different.

CMake is a cross-platform meta build tool that generates files that can be used by build tools. It is possible to generate a Makefile, a Ninja file, or project files for Visual Studio, Xcode, Eclipse, Sublime, etc. It is important to realize that you should run cmake only once. Subsequently you can run e.g. make multiple times. Each time make should only rebuild the files of which the dependencies have changed. It is worthwhile to also use >3.0.0 features and do it right.

  1. One of the issues we have to cope with is the diversity of boards we want to build for. We would like to generate a Makefile (or other file) that is able to generate the binaries for each of these boards.

  2. Another issue is the bootloader. We would like to be able to build all relevant code in one sweep for a particular board. This means that the bootloader and the softdevice also should be built for that board. If we run make again, the dependencies should be tracked properly.

Instead of cmake it is also possible to use e.g. scons. An interesting option is to actually immediately integrate with platform.io.

We can then specify the following environments:

[platformio]
env_default = pca10040,acr01b7b

[env:pca10040]
platform = nrf52832
framework = crownstone
board = pca10040
build_flags = -D MESHING=1

[env:acr01b7b]
platform = nrf52832
framework = crownstone
board = acr01b7b

Dummy Platform

Ideally, we would abstract the hardware in such a way that we can also run the code on x86 where:

  • the different reads and writes to registers are printed or visualized
  • the normal gcc (or clang) can be used, no cross-compilation flags e.g.
  • the CTest unit tests can be used to test functionality on the machine of the developer

The way to do this is to provide a clone of the Nordic repository where the header files are almost the same, but the C files are different. The implementation is at times part of the header files, so at times the header files need to be adjusted as well. This will allow anyone developing for the nRF52 to swap out the Nordic repository for this "dummy platform" repository and build everything with only a few changes to the compiler flags.

Dynamic creation / deletion of services

The setup procedure performs a reboot. This of course will make sure that a new configuration is loaded, however it is a cop out. It should be possible to load a new configuration on-the-fly.

It would be convenient if consecutive function calls can be initiated through an ordered set of events. In that case we can push this vector of events on some kind of stack and pop them of sequentially after each event has been executed. For example:

In setup mode we have the following sequence:

  • create setup services
  • loop through services and create corresponding characteristics
  • set to low TX mode
  • set encryption to true

In normal mode we have the sequence:

  • prepare normal mode (enable scanning and meshing)
  • create crownstone services
  • loop through services and create corresponding characteristics
  • set encryption to true

We also have a onStart function where in setup mode:

  • the switch is turned on after a delay

And in normal mode:

  • zero crossing detection is enabled
  • the scheduler is started
  • the scanner is started (with a randomized delay)
  • the tracker is started
  • the mesh is started

Every tick in normal mode:

  • the advertisement parameters are updated
  • the data in the advertisement is updated

nRF52 port of mesh

Currently, there is hardfault in version_handler.c:

vh_data_status_t vh_local_update(rbc_mesh_value_handle_t handle, uint8_t* data, uint8_t length)
{
   ...
   const uint64_t ts_time = timer_get_timestamp();
   ...
}

And in timer_get_timestamp() in timer_control.c it is:

uint32_t timer_get_timestamp(void)
{
    TIMER_SAFE_START();
    uint32_t time = 0;
    if (is_in_ts)
    {
        NRF_TIMER0->EVENTS_COMPARE[TIMER_INDEX_TIMESTAMP] = 0;
        (void)NRF_TIMER0->EVENTS_COMPARE[TIMER_INDEX_TIMESTAMP];
        NRF_TIMER0->TASKS_CAPTURE[TIMER_INDEX_TIMESTAMP] = 1;
        time = NRF_TIMER0->CC[TIMER_INDEX_TIMESTAMP];
    }
    TIMER_SAFE_END();
    return time;
}

I've added already the migration recommendation to read a COMPARE register after writing it because its effect is not immediate on the new Cortex: http://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52%2Fdita%2Fnrf52%2Fmigration%2Ffunctional.html

If I add debug information in this function it will be displayed on UART, but I will mess up the timing of course. So that doesn't work. If I skip the timer_get_timestamp call I won't have any hardfault.

@vliedel already allocated the struct as indicated at https://devzone.nordicsemi.com/question/59882/create-timer-hardfault/ with app_timer_t besides app_timer_id_t.

The app_timer.c file in the /third/nrf folder comes directly from Nordic, so it's up to date (see references to nRF52 in it).

NRF51 bug traceback

Triggers on 4 times not filling in the bonding keycode correctly:

UART:

[cs_main_crownstone.cpp         : 660  ] ---- running ----
[cs_main_crownstone.cpp         : 323  ] onConnect...
[cs_main_crownstone.cpp         : 349  ] onDisconnect...
[cs_Stack.cpp                   : 547  ] Start advertising
[cs_Mesh.cpp                    : 78   ] Failed to restart mesh (8)
[cs_main_crownstone.cpp         : 323  ] onConnect...
[cs_Stack.cpp                   : 812  ] going into low power mode for bonding ...
[cs_Stack.cpp                   : 825  ] bonding failed with error: 129 (0x81)
[cs_main_crownstone.cpp         : 349  ] onDisconnect...
[cs_Stack.cpp                   : 547  ] Start advertising
[cs_Mesh.cpp                    : 78   ] Failed to restart mesh (8)
[cs_main_crownstone.cpp         : 323  ] onConnect...
[cs_Stack.cpp                   : 812  ] going into low power mode for bonding ...
[cs_Stack.cpp                   : 825  ] bonding failed with error: 129 (0x81)
[cs_main_crownstone.cpp         : 349  ] onDisconnect...
[cs_Stack.cpp                   : 547  ] Start advertising
[cs_Mesh.cpp                    : 78   ] Failed to restart mesh (8)
[cs_main_crownstone.cpp         : 323  ] onConnect...
[cs_Stack.cpp                   : 812  ] going into low power mode for bonding ...
[cs_Stack.cpp                   : 825  ] bonding failed with error: 129 (0x81)
[cs_main_crownstone.cpp         : 349  ] onDisconnect...
[cs_Stack.cpp                   : 547  ] Start advertising
[cs_Mesh.cpp                    : 78   ] Failed to restart mesh (8)
[cs_main_crownstone.cpp         : 323  ] onConnect...
[cs_Stack.cpp                   : 812  ] going into low power mode for bonding ...
[cs_BleError.cpp                : 28   ] FATAL ERROR 4, at /home/alex/Dropbox/DoBots/Projects/eclipseWorkspace/bluenet/include/drivers/cs_Timer.h:52

GDB BT

Read 4 bytes @ address 0x200030F0 (Data = 0x00000009)
#1  0x0001f0fa in Timer::createSingleShot (timer_handle=@0x200030f0: 9, func=func@entry=0x1f975 <Nrf51822BluetoothStack::lowPowerTimeout(void*)>, this=<optimized out>)
    at /home/alex/Dropbox/DoBots/Projects/eclipseWorkspace/bluenet/include/drivers/cs_Timer.h:52
Read 4 bytes @ address 0x0001FF42 (Data = 0xB5F8BD70)
#2  0x0001f9e0 in Nrf51822BluetoothStack::deviceManagerEvtHandler (this=0x20003080 <Nrf51822BluetoothStack::getInstance()::instance>, p_handle=p_handle@entry=0x20007ed0, 
    p_event=p_event@entry=0x20007ed4, event_result=event_result@entry=0) at /home/alex/Dropbox/DoBots/Projects/eclipseWorkspace/bluenet/src/ble/cs_Stack.cpp:815
#3  0x0001ff42 in device_manager_evt_handler (p_handle=0x20007ed0, p_event=0x20007ed4, event_result=0) at /home/alex/Dropbox/DoBots/Projects/eclipseWorkspace/bluenet/src/ble/cs_Stack.cpp:758
Read 4 bytes @ address 0x00029F74 (Data = 0x2B127823)
Reading 64 bytes @ address 0x20007F00
#4  0x00029f74 in app_evt_notify (event_result=<optimized out>, p_event=0x20007ed4, p_handle=0x20007ed0)
    at /home/alex/Dropbox/DoBots/Projects/eclipseWorkspace/bluenet/src/third/nrf/device_manager_peripheral.c:842
#5  dm_ble_evt_handler (p_ble_evt=<optimized out>) at /home/alex/Dropbox/DoBots/Projects/eclipseWorkspace/bluenet/src/third/nrf/device_manager_peripheral.c:2874
Read 4 bytes @ address 0x0001FC2E (Data = 0x2B1B882B)
Reading 64 bytes @ address 0x20007EC0
Read 4 bytes @ address 0x0001FF1A (Data = 0xB510BD10)
#6  0x0001fc2e in Nrf51822BluetoothStack::on_ble_evt (this=0x20003080 <Nrf51822BluetoothStack::getInstance()::instance>, 
    p_ble_evt=p_ble_evt@entry=0x200031b0 <Nrf51822BluetoothStack::init()::BLE_EVT_BUFFER>) at /home/alex/Dropbox/DoBots/Projects/eclipseWorkspace/bluenet/src/ble/cs_Stack.cpp:921
#7  0x0001ff1a in ble_evt_dispatch (p_ble_evt=0x200031b0 <Nrf51822BluetoothStack::init()::BLE_EVT_BUFFER>)

Crownstone becomes undiscoverable

After sufficient enough time one of the two Crownstones needs to be plugged out and in to become visible again.

  • It is not seen in the Nordic scanner app either.
  • It only has a lamp attached to it.
  • It is rarely switched.
  • The other Crownstone kept working.
  • This is after a few days.

No env.config.template file

I am trying to fresh install the repo in my $HOME as instructed in the /bluenet/blob/master/docs/INSTALL.md

Now we need to set up the environment variables to keep track of the different folders required to build bluenet

cd ~/bluenet_workspace/bluenet
cp env.config.template env.config

There is no file called env.config.template and the copy command fails.
Where should I look for the config template file?

In /scripts/env.sh I see that loading from env.config is optional. So will the installation work without the env.config ?

The setup script in crownstone-sdk does not have a way to automate installation of mesh

This requires:

  • automatically downloading mesh repository
  • being able to refer to mesh directory relative to BLUENET_WORKSPACE_DIR, for example by introducing MESH_SUBDIR apart from MESH_DIR.
  • removing MESH_DIR from default config, so that when it is defined by the user it gets precedence over MESH_SUBDIR.

This breaks for users that use MESH_DIR without overwriting its location. Considering the current awkward default of MESH_DIR to /opt/nordic/ etc. this is likely not the case for many users.

Introduce CTests for arm targets

There should be three modes of operandi:

  1. cross-compile for the bluenet binaries (and pack it with softdevice/bootloader)
  2. compile unit tests that can run on the host to test data structures
  3. cross-compile unit tests, e.g. to single out the ADC, LPCOMP, etc.

Currently /test only contains code for 2. There are no unit tests for 3.

Advantages to also have 3:

  • it is not always possible to properly test with 2 due to dependencies on the target architecture
  • when asking questions on a Nordic forum we can point to only a few files that are relevant
  • we can faster pinpoint bugs that have to do with the simultaneous operation of multiple hardware peripherals
  • we can find bugs, e.g. with respect to memory management that are tied to the target architecture
  • we can setup test procedures that belong to a particular unit tests, e.g. connect "this pin" to "that pin" on a development board
  • we can have unit test generate data for us that simulate BLE advertisements or ADC input

sdk15 - enable dimming

When enabling dimming, cs_State will attempt to write a single byte. This leads to cs_Storage trying to write a size of 0 words, resulting in an fstorage error.

This should not be the case when st_value_t is used, but maybe a check in cs_State is handy as well?

Request scan response from the mesh code

Currently, advertising, scanning, and meshing is all done separately. This introduces competition with respect to the same radio peripheral in the end. The new mesh SDK has implemented code where this can (partly!) be done in a proper manner:

  • In mesh/bearer/advertiser.h the advertiser_instance_init function allows us to initialize different advertiser instances. It uses advertiser_t which uses the struct advertiser_config_t that has a field ble_gap_addr_t that can be used to set a different address for different advertising instances. That means we can both send proper iBeacon messages and Crownstone messages (with scan responses) in parallel.
  • In the beaconing example there is also an rx callback rx_cb This allows the application to receive all non-filtered, BLE advertisement packets. That means that the application receives BLE advertisements.
  • There is no manner to receive scan responses. See this Nordic post. 1.) The stack provides advertisement packets, but not scan responses to the application. This needs to be added. 2.) The stack must send a scan request when a scannable advertisement has been received. This needs to be added as well.

protocol docs do not match the uuids

The general service in the docs is
f5f90000-f5f9-11e4-aa15-123b93f75cba
f5f90000-59f9-11e4-aa15-123b93f75cba <-- actual value

Same for the characteristics. Please double check the docs

Advertisement switch delay

Switching from connectable to non-connectable advertisements is done by sd_ble_gap_adv_stop and sd_ble_gap_adv_start. This takes considerable time (20 msec) and if not careful throws off processes that run on interrupt level 6 or higher.

ADC conversion using the driver in scan mode seems to swap/shift channels

Nordic's comments about the ADC driver can be found online. Documentation on the SAADC driver can be found here.

The ADC driver has a low power mode in SDK 12. Does this disable EasyDMA when possible? (EasyDMA requires around 1.5mA).

The function nrf_drv_saadc_buffer_convert is called twice, once for each buffer. The first time nrf_saadc_buffer_init(p_buffer, size) is called. It sets the m_cb.adc_state state to NRF_SAADC_STATE_BUSY and m_cb.p_secondary_buffer to NULL (note that the latter variable is not set before, e.g. in nrf_drv_saadc_init, minor bug I think). The second time m_cb.p_secondary_buffer is NULL so nrf_saadc_buffer_init(p_buffer, size) is called again.

__STATIC_INLINE void nrf_saadc_buffer_init(nrf_saadc_value_t * buffer, uint32_t num)
{
    NRF_SAADC->RESULT.PTR = (uint32_t)buffer;
    NRF_SAADC->RESULT.MAXCNT = num;
}

Apparently just calling that function twice is enough to use double buffering.

Two differences:

  • In the second call nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED) == 0 is checked before nrf_saadc_event_clear.
  • In the second call nrf_saadc_int_enable is done after nrf_saadc_buffer_init, not before.

It seems very suspect that the order of the channels switches in the buffers. This might happen if we have an odd number of channels, but that is not the case. Is there a timing issue with EasyDMA?

Tests:

  1. Enable 8 channels to see what happens with scan mode in that situation.
  2. Remove all code that handles the buffer so that nrf_drv_saadc_buffer_convert can be called as quickly as possible.
  3. Try to reproduce with a minimal number of files.
  4. Update to SDK12.

Matter of style / consistency w.r.t. hardware presence

There is an IS_CROWNSTONE macro that is used to enable for example modules like switch, pwm etc. There are also fine grained configuration fields such as _boardsConfig.flags.hasLed. It would be best to make it the same. In the future there might be Crownstones without IGBTs for example. Or Crownstones without relays. It's best to use the same manner of configuration. That would be something like this:

  • Switch: _boardsConfig.flags.hasSwitch
  • TemperatureSensor: _boardsConfig.flags.hasTemperatureSensor
  • VoltageSensor: _boardsConfig.flags.hasVoltageSensor
  • CurrentSensor: _boardsConfig.flags.hasCurrentSensor

There are also software modules that we might enable in a similar manner:

  • Watchdog: _boardsConfig.flags.enableWatchdog
  • EnOcean: _boardsConfig.flags.enableEnocean

Samsung S5 "within range" functionality stops working

A Samsung S5 smartphone stops with the functionality that is about getting in and out of range.

  • On (immediately)
  • Off (after 2 minutes)

There might be several reasons:

  • Somehow a certain sleep mode (dozing, app standby) might put the app in such a state that it doesn't perform certain functionality, be it scanning, be it connecting: https://developer.android.com/training/monitoring-device-state/doze-standby.html
  • The service that is running in the background stops.
  • The service that is running in the background stops and restarts, but it doesn't restart the complete app.
  • The Android OS turns off certain BLE functionality if it feels like it.
  • There is some kind of BLE error that is triggered rarely and screws up the connection state in the app.
  • There is a connection set up with a Crownstone that is not disconnected.

Streamline scripts

There are too many scripts in the ./scripts directory. This is very inconvenient for a new user. Some accept flags, some do not. Things that can be done.

  • A script like all.sh is too general. We probably would like to indicate that we want to flash stuff? Hence, a script like flash.sh makes sense. The default flag for flash.sh can be such that indeed everything will be flashed.
  • The script firmware.sh should be placed in /scripts/helper and it should be possible to call it from flash.sh. For example the flag flash.sh -b firmware would be convenient. The current flags of firmware.sh should work as well, such as flash.sh -b firmware -c all -t default.
  • Very small utilities should be put into the CMakeLists.txt and be part of the make system.

Add unit tests for scripts

These unit tests would preferably:

  • Check if all scripts can be called with the described arguments.
  • Check if the binary gets updated (check timestamp).
  • Check if the binary stays below certain size (this means it indirectly checks that the proper flags have been used, no superfluous header files are included, etc.).
  • Check if scripts can be used in multiple shells / platforms.

Multiple advertisement frames

There are multiple beacon standards, iBeacon, Eddystone, and AltBeacon to name a few. Currently there is no buffer within multiple frames can be written in the Nordic SoftDevice (forum question).

The way it should be solved for now is to create a buffer in the bluenet code that does update the advertising (or scan response data) after a Radio Notification Event preferably by rotating over i through a buffer of type p_data in sd_ble_gap_adv_data_set(buffer[i], buffer_length[i], ...).

Two of the Eddystone formats are static (see Google documentation), such as Eddystone-UID, Eddystone-URL. The third, Eddystone-TLM, has status information (such as battery level which will be static in the case of the Crownstone). The fourth, Eddystone-EID, is a time-varying frame.

Hence, not only support for interleaving multiple advertisement frames should be taken into account. The suggested buffer might also be useful for frames of which the content is changing.

updateAdvertisement

The updateAdvertisement function at https://github.com/crownstone/bluenet/blob/sdk_11/src/ble/cs_Stack.cpp#L634-L652 does not respect the fact that the device might NOT be advertising there.

As a workaround I'm not stopping the program if ble_advdata_set returns NRF_ERROR_INVALID_PARAMETER (0x07), but it should just not enter that function if it's not advertising.

The other functions are organized like this:

  • configureX: populate the structs (and allocate if not done before)
  • updateX: perform the sd_ble calls that inform the softdevice of the (updated) configuration (but make sure that a mistake is caught, so check if the device name is present, check if we are actually advertising, check if the softdevice is enabled)
  • startX, stopX: perform sd_ble calls for starting/stopping
  • isX: retrieve local state (the softdevice cannot know if it is advertising, storing this state is the responsibility of the application: https://devzone.nordicsemi.com/question/80959/check-if-currently-advertising/)

Bug: it shouldn't be possible to raise a softdevice error calling updateAdvertisement.

Use user-wide locations for configuration and build results

Allow the user to specify the configuration for bluenet in a general place.

For example $HOME/.ble/config for general configuration options. This can then be subsequently reused for the bootloader code or, if necessary, for the python DFU upload scripts.

And for example $HOME/.ble/binaries for the generated binaries. Also this would allow easy incorporation of e.g. the bootloader generated from another project into another one without copying it around.

Casting error in assembly part in nrf_svc.h

In file included from /opt/softdevices/s110_nrf51822_7.0.0_API/include/ble_gap.h:19:0,
from /home/anne/myworkspace/ble/bluenet/include/BluetoothLE.h:16,
from /home/anne/myworkspace/ble/bluenet/src/BluetoothLE.cpp:5:
/opt/softdevices/s110_nrf51822_7.0.0_API/include/ble_gatts.h: In function 'uint32_t sd_ble_gatts_service_add(uint8_t, const ble_uuid_t_, uint16_t_)':
/opt/softdevices/s110_nrf51822_7.0.0_API/include/nrf_svc.h:20:6: warning: asm operand 0 probably doesn't match constraints [enabled by default]
);
^
/opt/softdevices/s110_nrf51822_7.0.0_API/include/ble_gatts.h:334:1: note: in expansion of macro 'SVCALL'
SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const*const p_uuid, uint16_t *const p_handle));
^
/opt/softdevices/s110_nrf51822_7.0.0_API/include/nrf_svc.h:20:6: error: impossible constraint in 'asm'
);
^

getting assembler messages/errors.. need solution

Hey, this time i am making a fresh build of your repo as it is ( i have only changed the path to bootloader ,etc. etc.) . I have declared a few variables in the CMakeLists.txt ( some were not inherited from Build.config, i don't know why ) , here's a gist : https://gist.github.com/dhruvagarwal/968f5af6d7ff791a49ef

I am attaching a screenshot of the error that i got while running "make". ( i ran "make" on this dir before as well ,therefore it's only 3% ).
screenshot from 2015-02-17 23 35 36

I can update the gist with other files as well if you say.
Thanks in advance .

getting empty CMAKE_OBJCOPY_PAYLOAD

Hey i forked your repo and striped it out to minimal features that i required , now while making the file
The make goes 100% but in one of the last steps
https://github.com/mrquincle/bluenet/blob/master/CMakeLists.txt#L198

I get an empty CMAKE_OBJCOPY_PAYLOAD

Here's my github gist of CMakeLists,CMakeBuild.config and main.cpp ( which in your case is cs_main_crownstone.cpp) . https://gist.github.com/dhruvagarwal/47ef318f872dbb091740

I am using Bootloader from here : https://github.com/mrquincle/nrf51-dfu-bootloader-for-gcc-compiler/tree/master/nrf51822_v6.0.0%20-%20GCC_Bootloader

I have also commented out a few executables which I was not able to "make" successfully (for eg: drivers/*.cpp ) , as you can see here https://gist.github.com/dhruvagarwal/47ef318f872dbb091740#file-cmakelists-txt-L274

Please suggest any suggestions.. i need to resolve it ASAP.

Events are not properly propagated

Regarding fstorage we use the (experimental) file system.

In cs_Storage.cpp we register through fds_register the fds_evt_handler. The fds_evt_handler is defined in cs_Handlers.cpp and forwards the event simply back to the C++ instance, and in particular the function handleFileStorageEvent.

On executing fds_init, we get an FDS_SUCCESS return code, however, we should wait for FDS_EVT_INIT coming through handleFileStorageEvent. It rarely arrives. It's not the case that it NEVER arrives, it just does it SOMETIMES (once in four?). Note that the chip doesn't block. It's just going on without sending these events. What can be the case here?

  • Another listener catches this event and it is removed from the queue. Is this even possible?
  • The iterator over the listeners is not implemented properly. One listener overwrites another or some other bug in the code by Nordic. All those macros are quite compiler dependent, so it's not a complete stretch.
  • The section is "slightly off" with respect to its address. The SoftDevice picks the wrong function as a callback.

Also very awkward and seemingly related to those handlers is when the nrf_sdh_soc.c file is enabled in the CMakeLists.txt file. It's surprising that there is no error if it's not by the way. When it is enabled the code seems to hang in an allocation function in the Balloc module. The code in nrf_sdh_soc.c calls: NRF_SDH_STACK_OBSERVER(..., NRF_SDH_SOC_STACK_OBSERVER_PRIO) = .... This seems to feed the stack events to the SOC observers.

The location of the observers are set in the linker.

/arm-none-eabi-nm crownstone.elf | grep sdh_soc_observers
0004b850 t sdh_soc_observers
0004c530 R __start_sdh_soc_observers
0004c540 R __stop_sdh_soc_observers
0004b540 t sdh_stack_observers
0004c550 R __start_sdh_stack_observers
0004c560 R __stop_sdh_stack_observers

We can check this in gdb:

(gdb) p sdh_soc_observers
Reading 12 bytes @ address 0x0004B850
$1 = {
  section = {
    p_start = 0x4c530 <m_crownstone_soc_observer>,
    p_end = 0x4c540 <m_crownstone_state_handler>
  },
  item_size = 8
}
(gdb) p sdh_stack_observers
Reading 12 bytes @ address 0x0004B540
$4 = {
  section = {
    p_start = 0x4c550 <m_nrf_sdh_soc_evts_poll>,
    p_end = 0x4c560 <m_req_obs>
  },
  item_size = 8
}
(gdb) p sdh_state_observers
Reading 12 bytes @ address 0x0004B564
$2 = {
  section = {
    p_start = 0x4c540 <m_crownstone_state_handler>,
    p_end = 0x4c550 <m_nrf_sdh_soc_evts_poll>
  },
  item_size = 8
}
(gdb) p sdh_ble_observers
Reading 12 bytes @ address 0x0004B824
$5 = {
  section = {
    p_start = 0x4c528 <m_stack>,
    p_end = 0x4c530 <m_crownstone_soc_observer>
  },
  item_size = 8
}
(gdb) p sdh_req_observers
Reading 12 bytes @ address 0x0004B4D8
$7 = {
  section = {
    p_start = 0x4c560 <m_req_obs>,
    p_end = 0x4c568 <m_nrf_log_UART_logs_data_const>
  },
  item_size = 8
}

I'm actually not entire sure how m_nrf_log... gets there. Just grabbing on NRF_SDH_REQUEST_OBSERVER does not reveal much. Perhaps it registers using an internal macro.

Observations:

Apart from fds_register we do not call somewhere an fs_sys_event_handler from a sys_evt_dispatch function. First, I assume that the FDS system is able to do this itself for the underlying fstorage system. Second, this has been changed. There is now a NRF_SDH_SOC_OBSERVER macro with which a similar function, in our case crownstone_soc_evt_handler can be used as callback. However, this does not receive SoC events either...

Does not compile due to flexible array member in union

Error speaks for itself:

In file included from ~/workspace/bluenet/include/mesh/cs_Mesh.h:18:0,
                 from ~/workspace/bluenet/src/drivers/cs_Storage.cpp:27:
~/workspace/bluenet/include/protocol/cs_MeshMessageTypes.h:262:21: error: flexible array member in union
     uint8_t payload[];

Makefile sits on chair of cmake

Currently there is a hack to copy the binary files in the Makefile:

define cross-compile-target-cleanup
        ...
	printf "++ Copy binaries to ${BLUENET_BIN_DIR}\n"
	@mkdir -p "${BLUENET_BIN_DIR}"
	@cp $(BLUENET_BUILD_DIR)/*.hex $(BLUENET_BUILD_DIR)/*.bin $(BLUENET_BUILD_DIR)/*.elf "$(BLUENET_BIN_DIR)"
endef

This should be done by:

  • adding make DESTDIR=$(BLUENET_BIN_DIR) install after make in the target cross-compile-target and only on success (after &&)
  • in conf/cmake/CMakeLists.txt adjust INSTALL(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) to use proper destination.
  • get rid of hardcoding DESTDIR and CMAKE_INSTALL_PREFIX in conf/cmake/arm.toolchain.cmake

Cache is not used on Samsung devices leading to 1.5 seconds delay

The cache is not used on untrusted Samsung devices, e.g. Galaxy S5. This is according to the Bluetooth specification. It might be that if the service_changed characteristic is NOT present, the Samsung S5 WILL use the cache. Good thing to try!

gatts_enable_params.service_changed

There might be other ways to remove this delay, e.g. speeding up the discovery process in certain ways. There are a lot of handles that are tried and that are not present on our devices.

Generic Attribute Service

Smartphone manufacturers choose to cache services/characteristics.

The mere presence of the Generic Attribute Service which has a Service Changed characteristic (0x2A05) influences caching behavior on different smartphones.

In theory, this characteristic should only be used if services are updated while being connected. It can then notify the connected smartphone of the updated handles. For example, in a firmware update procedure, the handles might be changed during the process. On the other hand, it is often stated that this characteristic is used for paired or bonded devices. IMHO the caching of attribute handles has nothing to do with the device being trusted or not, but we rely on the implementation of the vendors here.

Generic Attribute Service

At punchthrough it is stated that:
iOS and OS X do not cache the attribute table of the connected BLE device if the Generic Attribute Service is present in their attribute table.

Apparently if the Generic Attribute Service is absent, it allows iOS to cache the attribute handles!

Note. It might be the case that just the absence of the Service Changed characteristic is sufficient. It might not need to be the absence of the complete Generic Attribute Service.

What is cached?

Of course, the Crownstones actually do change the GATT table during a DFU process. Hence, it is important that the Generic Attribute Service is present at the DFU and setup modes.

Questions:

  • Does removing the Generic Attribute Service speed up the connection process on certain phones?
  • If the Generic Attribute Service is present at DFU, will it be picked up by iPhones? Or do they also "cache" the absence of the Generic Attribute Service itself?

Note. If a Crownstone has an updated GATT table due to another user, it is important that the iPhone does a discovery process manually. This needs to be communicated somehow, either via the cloud or via advertisements / scan responses.

sdk15 - setup

Setup succeeds, but doesn't set the correct keys, ibeacon uuid, and maybe more.
I noticed the last (first) 4 bytes of the ibeacon uuid are set correctly.
Should've been:
55fe 370c - 6cb9 - 43b1 - 9dfe - 00f4 e981 28fa
was:
0001 0003 - 0006 - 6dc0 - 0000 - 0000 e981 28fa

Use flags for all bash/python scripts in /scripts folder

There are a lot of scripts with undocumented arguments.

  • add flags for each script
  • handle these flags with getopt or getopts setup
  • if script is called without arguments display usage
  • print what each flag in this usage description
  • print which flags are optional in this usage description

Example: ./firmware.sh --command cmd --target target

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.