bluerange-io / bluerange-mesh

BlueRange Mesh (formerly FruityMesh) - The first completely connection-based open source mesh on top of Bluetooth Low Energy (4.1/5.0 or higher)
https://bluerange.io/
Other
287 stars 109 forks source link

gateway possibilities #144

Closed viveknath93 closed 3 years ago

viveknath93 commented 4 years ago

Hi,

Is it possible that we can modify the existing fruitymesh firmware to create a gateway node?

It does not need to connect to the internet but only needs to be connected with mobile applications and should be able to process the BLE messages ( Beacons that broadcast data ).

In other words, can that particular node be a part of mesh be switching between connection-based( for maintaining fruitymesh and Mobile application ) and beaconing mode ( as receivers listening to external beacons )?

Viveknath Thulasi

mariusheil commented 4 years ago

Hello,

yes, this is certainly possible. By default, you can achieve the requested behaviour with all mesh nodes, if you wish. But you can also disable it if you only want this functionality on a gateway node. Take a look at the Scanning module for an example on how to process received advertising messages of any kind. This can be done in parallel to having mesh connections. Next, the Mesh access module allows you to connect to a node using a mobile phone. This can also be done in parallel to mesh connections. You can create your custom featureset for a gateway in which you can enable this functionality and another featureset for your mesh, that has this disabled if you wish.

Marius

viveknath93 commented 4 years ago

Hi @mariusheil

Thanks for the support! I will analyze in this direction.

Viveknath

viveknath93 commented 4 years ago

Hi,

How to establish a connection between ble app and one of the mesh node?

Looks like an android app was used for Enrolling and Unenrolling the devices from the mesh devices.

Is it necessary that in the firmware of the node that we are trying to establish a connection with, should be configured as DeviceType::SINK ?

With my app, I could scan( as central ) and trying to establish a connection with one of the nodes(access using BLE address ) in Mesh. When I initiate this from the Application, I get UART log data like as below:

[GAPController.cpp@125 C]: Connected device [MeshAccessModule.cpp@326 MAMOD]: Broadcasting mesh access 02:01:06:03:03:12:FE:0F:16:12:FE:03:00:0B:00:09:75:15:03:01:00:00:00, len 23 [ResolverConnection.cpp@47 RCONN]: New Resolver Connection [BaseConnection.cpp@604 CONN]: Incoming connection 0 connected [MeshAccessModule.cpp@326 MAMOD]: Broadcasting mesh access 02:01:06:03:03:12:FE:0F:16:12:FE:03:00:0B:00:09:75:15:03:01:00:00:00, len 23 {"type":"update_joinme","clusterId":3962372312,"clusterSize":1} [GAPController.cpp@119 C]: Disconnected device 22 {"type":"live_report","nodeId":216,"module":3,"code":52,"extra":0,"extra2":22}

02:01:06:03:03:12:FE:0F:16:12:FE:03:00:0B:00:09:75:15:03:01:00:00:00 if I am not wrong, this is the 23 byte meshAccessServiceAdvMessage But how do I respond to it ?

and it is getting disconnected due to Disconnected device 22 => LOCAL_HOST_TERMINATED_CONNECTION what does this imply?

The device is broadcasting data in order to be responded.

How exactly should the request-response be used dealt in order to establish a successful hand shake ?

mariusheil commented 4 years ago

Hi,

we currently do not have an open source version of an App that can connect to the mesh. We are working on this, but it will take some time. Take a look here: https://github.com/mwaylabs/fruitymesh/issues/139 Maybe you can cooperate on this.

If you want to build a connection to a FruityMesh node, it does not have to be of DeviceType::SINK, it can be any device type as long as the MeshAccessModule is enabled and the broadcast message is being sent.

FruityMesh nodes will disconnect a connection to another Bluetooth device if no encrypted connection is being made within a few seconds. This protects the nodes from running out of connections to partners that should not have access to the mesh. The connection will be connected forever if it is either another mesh node that implements the connection encryption, or if a handshake is done with the MeshAccessModule. Doing the proper handshake and connection encryption using our MeshAccessModule is the correct way of handling connections. Read the documentation on this here: https://www.bluerange.io/docs/fruitymesh/MeshAccessModule.html and make sure to read the information in the issue that I mentioned.

Marius

viveknath93 commented 4 years ago

Hi,

Thanks a lot for your response.

I am also around the same state (as mentioned in issue #139 ) in establishing a connection between the application and the BLE device. But I am using nrf device as peripheral and Mobile application as central. I will try to establish the connection

Viveknath

viveknath93 commented 4 years ago

Hi,

I followed the instructions that are given in #139 . So I m currentlyhaving 1 nrf device and mobile App to interact with.

I get data something like this. . .

mhTerm: [GAPController.cpp@125 C]: Connected device [MeshAccessModule.cpp@326 MAMOD]: Broadcasting mesh access 02:01:06:03:03:12:FE:0F:16:12:FE:03:00:0B:00:09:75:15:03:01:00:00:00, len 23 [ResolverConnection.cpp@47 RCONN]: New Resolver Connection [BaseConnection.cpp@604 CONN]: Incoming connection 0 connected [ResolverConnection.cpp@61 RCONN]: Resolving Connection with received data [ConnectionManager.cpp@227 RCONN]: numConnTypeResolvers 2

[MeshAccessModule.cpp@326 MAMOD]: Broadcasting mesh access 02:01:06:03:03:12:FE:0F:16:12:FE:03:00:0B:00:09:75:15:03:01:00:00:00, len 23 [MeshAccessConnection.cpp@74 MACONN]: New MeshAccessConnection [BaseConnection.cpp@604 CONN]: Incoming connection 0 connected [MeshAccessModule.cpp@326 MAMOD]: Broadcasting mesh access 02:01:06:03:03:12:FE:0F:16:12:FE:03:00:0B:00:09:75:15:03:01:00:00:00, len 23 [MeshAccessConnection.cpp@265 MACONN]: -- TX ANonce, fmKeyId 1234 [MeshAccessConnection.cpp@512 MACONN]: Using derived user key 1234 [MeshAccessConnection.cpp@824 MACONN]: MA SendData from 216 to 2216 [MeshAccessModule.cpp@618 MACONN]: Message auth is 1 [GATTController.cpp@118 CONN_DATA]: hvx Data size is: 13, handles(3, 22)

[ConnectionManager.cpp@484 CONN_DATA]: write_CMD complete (n=1) mhTerm: advjobs

I need to use a network key instead of a derived user key as in the log. But where can I configure this to network key as you instructed?

"This generates this bit array in little endian : 25,0,125,0,0,1,210,4,0,0,4" => 0x 19 00 7D 00 00 01 D2 04 00 00 04

How is this calculated?

Thank you!

Viveknath

mariusheil commented 4 years ago

Hi, in the log you can see the line: -- TX ANonce, fmKeyId 1234

this suggests that you were sending the keyId as 1234 in the Start Handshake message. You have to change this to the network key id as mentioned in the specification documentation.

I did not understand you second question ,sorry.

viveknath93 commented 4 years ago

Hi @mariusheil Thanks a lot for your quick response! Amazing!

Yes. I will update the post after changing the network key.

I just went through the document and got to know about the second question. (Y)

So, I am able to get data untill ANonce from the peripheral to central (app) Are there a specific set of operations with examples that are mentioned in the meshaccessmodule Doc page?

The idea is to implement MeshAccessConnection::HandshakeSNonce , Utility::GetRandomInteger() , GenerateSessionKey,Utility::Aes128BlockEncrypt - All these needs to be implemented on Android application perpective right?

Or let me know if we have any library in AndroidStudio that could use the same encryption algorithm

viveknath93 commented 4 years ago

Hi,

I am just trying to implement the complete module of mesh Access connection in the Android App as well - In order to create a handshake between the App and the Fruity mesh firmware.

In order to understand I just want to get the flow of complete encryption sequence using the log data. To do this I just tried to Connection Establishment via BLE Address https://www.bluerange.io/docs/fruitymesh/MeshAccessModule.html#_connection_establishment_via_ble_address

But it somehow doesn't seem to get connected at all.

action [nodeId] ma connect [bleAddress] {keyId=FM_NODE_KEY} {keyHex=} {tunnelType=PEER_TO_PEER} {requestHandle=0} How can I get the KeyHex ? Is it a random value?

On device 1 :

`mhTerm: action this ma connect e2:f0:ee:1b:44:33 1 11:22:33:44:11:22:33:44:11:22:33:44:11:22:33:44 0 0 [MeshAccessModule.cpp@463 MAMOD]: Received connect task [MeshAccessModule.cpp@326 MAMOD]: Broadcasting mesh access 02:01:06:03:03:12:FE:0F:16:12:FE:03:00:0B:00:09:75:15:03:01:00:00:00, len 23 [MeshAccessConnection.cpp@74 MACONN]: New MeshAccessConnection

[MeshAccessConnection.cpp@199 MACONN]: Trying to connect [ConnectionManager.cpp@1217 ERROR]: Fatal: Pending timeout [MeshAccessConnection.cpp@123 MACONN]: Deleted MeshAccessConnection, discR: 0, appDiscR: 16 [MeshAccessModule.cpp@326 MAMOD]: Broadcasting mesh access 02:01:06:03:03:12:FE:0F:16:12:FE:03:00:0B:00:09:75:15:03:01:00:00:00, len 23 {"type":"update_joinme","clusterId":1863450840,"clusterSize":2} [GAPController.cpp@125 C]: Connected device [ConnectionManager.cpp@808 ERROR]: No pending Connection [GAPController.cpp@119 C]: Disconnected device 22 {"type":"live_report","nodeId":216,"module":3,"code":52,"extra":0,"extra2":22}

[GATTController.cpp@79 CONN_DATA]: TX Data size is: 17, handles(0, 16), reliable 0

[MeshConnection.cpp@467 CONN_DATA]: Mesh RX 53,length:17,deliv:1,data:35:7C:20:00:00:03:00:01:34:00:00:00:00:13:00:00:00 [MeshConnection.cpp@499 CONN_DATA]: Received type 53,length:17,deliv:1,data:35:7C:20:00:00:03:00:01:34:00:00:00:00:13:00:00:00 {"type":"live_report","nodeId":8316,"module":3,"code":52,"extra":0,"extra2":19} [ConnectionManager.cpp@484 CONN_DATA]: write_CMD complete (n=1)`

On Device 2: [GAPController.cpp@125 C]: Connected device [MeshAccessModule.cpp@326 MAMOD]: Broadcasting mesh access 02:01:06:03:03:12:FE:0F:16:12:FE:03:00:0B:00:09:38:A2:51:01:00:00:00, len 23 [ResolverConnection.cpp@47 RCONN]: New Resolver Connection [BaseConnection.cpp@604 CONN]: Incoming connection 1 connected [GAPController.cpp@119 C]: Disconnected device 19 {"type":"live_report","nodeId":8316,"module":3,"code":52,"extra":0,"extra2":19} [BaseConnection.cpp@641 CONN]: Disconnected 0 from connId:1, HCI:19 Remote User Terminated Connection [ConnectionManager.cpp@924 WARNING]: Final Disconnect [MeshAccessModule.cpp@326 MAMOD]: Broadcasting mesh access 02:01:06:03:03:12:FE:0F:16:12:FE:03:00:0B:00:09:38:A2:51:01:00:00:00, len 23 {"type":"update_joinme","clusterId":1863450840,"clusterSize":2} {"type":"live_report","nodeId":216,"module":3,"code":52,"extra":0,"extra2":22} mhTerm:

What is that I am doing wrong?

Is it necessary that the 2 devices should not be connected already in Automesh for 2 devices to establish a meshaccessconnection?

Any info could be helpful thanks in advance!

mariusheil commented 4 years ago

Hi,

the easiest way is probably to use the network key to connect. I think it is mandatory that the devices are not already connected to each other as the ConnectionManager will enforce that by checking the BLE Address. I do not remember for certain and the error message could be more descriptive here, but I think the part "No pending Connection" suggests that it did not create a connection objecton purpose.

For testing, enroll both devices in a different networkId but with the same networkkey, e.g.:

//First device action this enroll basic ABCDE 1 2 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11

//Second device action this enroll basic ABCDE 2 3 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11

Afterwards, you can use the connect command with the networkkey (keyId 2): action this ma connect 00:11:22:33:44:55 2 11:11:11:11:11:11:11:11:11:11:11:11:11:11:11:11

Take a look at the github_nrf52.cpp where we set a default enrollment for the node so that it is easier to work with the github code example for beginners:

    c->enrollmentState = EnrollmentState::ENROLLED;
    c->networkId = 11;
    CheckedMemset(c->networkKey, 0x00, 16);

So by default all nodes are in network id 11 with networkkey 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00

PS: I added more information to #139, for implementing the encryption, the Simulator will be a great help as you can rerun the exact same simulation multiple times and debug everything on the way.

viveknath93 commented 4 years ago

Hi @mariusheil

Thanks for the information. I am following it up with #139 too. 👍

viveknath93 commented 4 years ago

Hi @mariusheil ,

I have a couple of questions

  1. For compiling cherry sim, is the Vstudio community edition sufficient?

I am getting this below error.

`C:\fruitymesh_>cd fruitymesh_cherrysim_build

C:\fruitymesh_\fruitymesh_cherrysim_build>cmake ../fruitymesh -- Building for: Visual Studio 15 2017 -- Selecting Windows SDK version 10.0.17763.0 to target Windows 10.0.18362. -- The C compiler identification is MSVC 19.16.27032.1 -- The CXX compiler identification is MSVC 19.16.27032.1 -- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe -- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe - works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe -- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x86/cl.exe - works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done -- Could not find cppcheck! Install it for additional useful warnings! Microsoft (R) Build Engine version 15.9.21+g9802d43bc3 for .NET Framework Copyright (C) Microsoft Corporation. All rights reserved.

Checking Build System Performing update step for 'libevent-populate' fatal: not a git repository (or any of the parent directories): .git CMake Error at C:/fruitymesh_/fruitymesh_cherrysim_build/_deps/libevent-subbuild/libevent-populate-prefix/tmp/libevent-populate-gitupdate.cmake:10 (message): Failed to get the hash for HEAD

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(209,5): error MSB6006: "cmd.exe" exited with code 1. [C:\fruitymesh_\fruitymesh_cherrysim_build_deps\libevent-subbuild\libevent-populate.vcxproj]

CMake Error at C:/cmake-3.17.1-win64-x64/share/cmake-3.17/Modules/FetchContent.cmake:912 (message): Build step for libevent failed: 1 Call Stack (most recent call first): C:/cmake-3.17.1-win64-x64/share/cmake-3.17/Modules/FetchContent.cmake:1003 (__FetchContent_directPopulate) CMake/FindLibEvent.cmake:14 (FetchContent_Populate) cherrysim/CMakeLists.txt:1 (include)

-- Configuring incomplete, errors occurred! See also "C:/fruitymesh_/fruitymesh_cherrysim_build/CMakeFiles/CMakeOutput.log".`

What configuration I am missing? It is trying to access a git repository inside the build folder.. ..\fruitymesh_cherrysim_build_deps\libevent-subbuild\CMakeFiles\5cacf8d982680cfa5395fa2931cdaba4\libevent-populate-update.rule

  1. I just tried to port the code from mesh access connection and Mesh access module for implementing functionalities(OnANonceReceived) in Android App. And most of the inbuilt function it leads to sd** Which are part of the soft device! Do you know any library in Java that has similar encryption functionalities?
mariusheil commented 4 years ago

Hi,

  1. the community edition is fine. I have asked a colleague if he knows the cmake error.

  2. If you mean the sd_ function for AES encryption, you can use every standard AES library, maybe even inbuilt in android to do an ECB AES 128 bit encryption. The other as functions are if course used to sending packets and stuff which you have to replace by the appropriate functionality from android.

Marius

Brotcrunsher commented 4 years ago

Hi,

the reported error starts here:

Performing update step for 'libevent-populate'
fatal: not a git repository (or any of the parent directories): .git
CMake Error at C:/fruitymesh_/fruitymesh_cherrysim_build/_deps/libevent-subbuild/libevent-populate-prefix/tmp/libevent-populate-gitupdate.cmake:10 (message):
Failed to get the hash for HEAD

For some reason your installation has problems to get libevent. Are you sure your git client is set up correctly? Did you clone our repository or download it as a .zip file? Another possibility could be that github had some temporary issues. I just tried it and could not reproduce the error. Please retry it as well.

Jakob

viveknath93 commented 4 years ago

Hi,

Thanks a lot for your response!

Yes. I have cloned the git repo( Did not zip and use it! ). The git repo is here : C:\fruitymesh_\fruitymesh

Because as mentioned in the doc, I used an external folder for fruitymesh build with the same repo and it works fine. C:/fruitymesh_/fruitymesh_build_tmp/ - Comiples and I could build it.

Similarly, I used out of repo build folder for cherry sim. C:/fruitymesh_/fruitymesh_cherrysim_build/

Yes. I will retry it!

viveknath93 commented 4 years ago

Hi,

I just tried with implementing the encryption-decryption as a separate java entity using the Android studio with the Cypher, Random modules and it is working. Log as separate module :

Task :libaesccm:BleAESEncryption.main() Input : sample cleartext 01 00 0E 75 87 87 86 F8 76 04 00 00 00 00 00 00 Input : sample longterm Key 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 Encrypted op : 97 FF E3 D6 D4 AF 38 CC 80 27 3E DD C2 4F F3 1F 97ffe3d6d4af38cc80273eddc24ff31f decrypted op : Encryption op is given as input with same key: 01 00 0E 75 87 87 86 F8 76 04 00 00 00 00 00 00

BUILD SUCCESSFUL in 2s 2 actionable tasks: 1 executed, 1 up-to-date

Images of Application :

2020_08_14_10 44 39_FM0 2020_08_14_10 45 57_FM1

Error on application debug: 2020-08-28 16:36:16.385 27328-27328/com.Myapp.vewapp I/MyappBleManagerImpl: Successfully subscribed to characteristics: 00000003-acce-423c-93fd-0c07a0051858 2020-08-28 16:36:16.403 27328-27328/com.Myapp.vewapp E/MyappBleManagerImpl: Could not read characteristic: null uuid: 00000002-acce-423c-93fd-0c07a0051858 2020-08-28 16:36:20.586 27328-27328/com.Myapp.vewapp I/LiveDataListAdapter: Clicked on Encrypt button for characteristic null 2020-08-28 16:36:20.587 27328-27328/com.Myapp.vewapp I/BLE Abstraction: write requested for 00000002-acce-423c-93fd-0c07a0051858 value: 19 00 7D 00 00 01 D2 04 00 00 02 2020-08-28 16:36:20.722 27328-27328/com.Myapp.vewapp E/MyappBleEncr: OnANonceReceived 2020-08-28 16:36:20.723 27328-27328/com.Myapp.vewapp E/MyappBleEncr ANONCE: 1A D8 00 00 7D FE BD EE 92 B9 CA BD 87 2020-08-28 16:36:20.738 27328-27328/com.Myapp.vewapp E/MyappBleEncr SNONCE: 1B007DD800F790D5F2969C269C 2020-08-28 16:36:20.753 27328-27328/com.Myapp.vewapp E/MyappBleEncr Encr: 4C F9 E1 80 3C 1F 76 BE 6A BB 85 EE 48 57 DB F7 2020-08-28 16:36:20.754 27328-27328/com.Myapp.vewapp E/MyappBleEncr Decr: A0 61 B7 6A 59 95 F6 66 7B FE 69 1F E5 07 F0 31 2020-08-28 16:36:20.755 27328-27328/com.Myapp.vewapp D/AndroidRuntime: Shutting down VM 2020-08-28 16:36:20.763 27328-27328/com.Myapp.vewapp E/AndroidRuntime: FATAL EXCEPTION: main Process: com.Myapp.vewapp, PID: 27328 java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.util.UUID.toString()' on a null object reference

Fruity mesh Log :

Mesh clusterSize:1, clusterId:2646343896 Enrolled 1: networkId:11, deviceType:1, NetKey 11:11:....:11:11, UserBaseKey FF:FF:....:FF:FF Addr:E9:99:EF:E3:7B:A0, ConnLossCounter:0, AckField:0, State: 1

CONNECTIONS 1 (freeIn:2, freeOut:3, pendingPackets:0 IN MA state:2, Queue:0-0(0), hnd:3, partnerId/virtual:0/2216, tunnel 255

[MeshAccessConnection.cpp@265 MACONN]: -- TX ANonce, fmKeyId 1234 [MeshAccessConnection.cpp@512 MACONN]: Using derived user key 1234 [MeshAccessConnection.cpp@824 MACONN]: MA SendData from 216 to 2216 [MeshAccessModule.cpp@618 MACONN]: Message auth is 1 [GATTController.cpp@118 CONN_DATA]: hvx Data size is: 13, handles(3, 22)

[ConnectionManager.cpp@484 CONN_DATA]: write_CMD complete (n=1) [GAPController.cpp@119 C]: Disconnected device 19 {"type":"live_report","nodeId":216,"module":3,"code":52,"extra":32000,"extra2":19} [MeshAccessConnection.cpp@824 MACONN]: MA SendData from 216 to 0 [MeshAccessModule.cpp@618 MACONN]: Message auth is 0 [BaseConnection.cpp@641 CONN]: Disconnected 32000 from connId:0, HCI:19 Remote User Terminated Connection [ConnectionManager.cpp@926 WARNING]: Final Disconnect [MeshAccessConnection.cpp@123 MACONN]: Deleted MeshAccessConnection, discR: 19,appDiscR: 3 [MeshAccessModule.cpp@326 MAMOD]: Broadcasting mesh access 02:01:06:03:03:12:FE:0F:16:12:FE:03:00:0B:00:09:75:15:03:01:00:00:00, len 23 {"type":"update_joinme","clusterId":2646343896,"clusterSize":1}

I am able to see the characteristics(image screenshots) as mentioned in the Fruity mesh code.

When I try to write the data in the write characteristics the second time, the whole App hangs ie. Starthandshake is read and responded, I could see the nonce value, (screenshot) The incoming message comes in reading characteristics and I write the calculated Snonce to write characteristic.

when I try to respond "OnSubscribed to notification" it hangs . Any hints on why this could happen? Any idea where I could be doing wrong?

Thanks in Advance!

MichalBiolik commented 4 years ago

Hi,

Only suspicious part I can see is log from application debug:

2020-08-28 16:36:16.403 27328-27328/com.Myapp.vewapp E/MyappBleManagerImpl: Could not read characteristic: null uuid: 00000002-acce-423c-93fd-0c07a0051858

Mentioned UUID has only write access and no read or notification access so you shouldn't be doing any read operations on that UUID. In fruitymesh logs you can see:

[BaseConnection.cpp@641 CONN]: Disconnected 32000 from connId:0, HCI:19 Remote User Terminated Connection

it indicates that it was mobile to break up connection. It looks like a bug of null reference in your code which causes crash of application and in the end connection break up. I would check object on which you are trying to execute java.lang.String java.util.UUID.toString() .

Michal

viveknath93 commented 4 years ago

Hi,

Thanks a lot for your hints. I will check in this direction

Viveknath