Skip to content
This repository has been archived by the owner on Nov 11, 2024. It is now read-only.

Commit

Permalink
Add support for u-Connect 2nd generation (#1079)
Browse files Browse the repository at this point in the history
This commit adds functionality for the 2nd generation of
u-Connect for short range modules. Some refactoring
of the directory structure has been made. All short
range source files which contain AT commands have
been given duplicates to be used when the new u-Connect
is to be used. These files have the same name but are
stored in sub directories named "gen2". To handle this
a new ubxlib feature named "short_range_gen2" has been
added. When present the build will automatically use
the gen2 files instead.

A new git submodule which encapsulates much of the
AT-command handling is used in this case.

The only available module for this right now is Nora W36.
The current firmware for this has some limitations which
means that some tests have been disabled for this module.
  • Loading branch information
plerup authored Jan 24, 2024
1 parent bb93cdb commit 95f8347
Show file tree
Hide file tree
Showing 69 changed files with 4,589 additions and 118 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
path = common/geofence/geographiclib
branch = devel
url = https://github.com/geographiclib/geographiclib
[submodule "common/short_range/src/gen2/ucxclient"]
path = common/short_range/src/gen2/ucxclient
url = https://github.com/u-blox/ucxclient.git
12 changes: 11 additions & 1 deletion .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
{
"configurations": [
{
"name": "Linux UCX2",
"includePath": [
"${workspaceFolder}/**"
],
"defines": ["U_UCONNECT_GEN2=1"],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "gnu++14",
"intelliSenseMode": "linux-gcc-x64",
},
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu17",
"cppStandard": "gnu++14",
Expand Down
1 change: 1 addition & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
},
{
"name": "Linux runner: Run",
"cwd": "${input:getBuildDir}",
"type": "cppdbg",
"request": "launch",
"program": "${input:getBuildDir}/runner_linux/ubxlib_test_main",
Expand Down
3 changes: 2 additions & 1 deletion Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,8 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.

EXCLUDE = port/platform common/geofence/geographiclib
EXCLUDE = port/platform common/geofence/geographiclib \
common/short_range/src/gen2/ucxclient

# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
Expand Down
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,24 @@ If your MCU is not on the list:

|`ubxlib` hosts |NINA-W10|NINA-B40 series<br />NINA-B30 series<br />NINA-B1 series<br />ANNA-B1 series<br />|NORA-B1 series|C030 board|PC|PC|
|-----------|-----------|--------------|-----|-----|------|------|
|**MCU**|Espressif ESP32|Nordic nRF52|Nordic nRF53|ST-Micro STM32F4|x86/64 (Linux)|x86 (Win32)<sup>*</sup>|
|**MCU**|Espressif ESP32|Nordic nRF52|Nordic nRF53|ST-Micro STM32F4|x86/64 (Linux)|x86 (Win32)<sup>1</sup>|
|**Toolchain**|ESP-IDF<br />Arduino-ESP32|GCC<br />nRF Connect|nRF Connect|Cube|GCC|MSVC|
|**RTOS/SDK**|FreeRTOS|FreeRTOS<br />Zephyr|Zephyr|FreeRTOS|Posix|Windows|
|**APIs provided by host with peripheral attached<sup>**</sup>**|[wifi](/wifi)<br />[ble](/ble "ble API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")|[ble](/ble "ble API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")|[ble](/ble "ble API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />| [cell](/cell "cell API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")<br />[location<sup>***</sup>](/common/location "location API")<br />[TLS&nbsp;security](/common/security "security API")<br>| N/A | N/A |
|**APIs provided by host with peripheral attached<sup>2</sup>**|[wifi](/wifi)<br />[ble](/ble "ble API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")|[ble](/ble "ble API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")|[ble](/ble "ble API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />| [cell](/cell "cell API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")<br />[location<sup>3</sup>](/common/location "location API")<br />[TLS&nbsp;security](/common/security "security API")<br>| N/A | N/A |

<sup>* For development/test purposes only.</sup></br>
<sup>** Only SPS API provided for native (on-chip) BLE interface, other APIs for native (on-chip) access, e.g. WiFi support, are a work in progress.</sup>
<sup>1: For development/test purposes only.</sup></br>
<sup>2: Only SPS API provided for native (on-chip) BLE interface, other APIs for native (on-chip) access, e.g. WiFi support, are a work in progress.</sup>

# Supported modules as `ubxlib` peripherals and APIs
Peripherals are u-blox modules which accept commands (e.g. AT-commands) over a serial interface and have no open MCU environment. To run the APIs they need to be attached to a host which runs `ubxlib`. For example in the [test farm](/port/platform/common/automation/DATABASE.md) combinations of hosts and peripherals are listed.

|`ubxlib` peripherals |NINA-B41 series<br />NINA-B31 series<br />NINA-B1 series<br />ANNA-B1|NINA-W13|NINA-W15|SARA-U2 series|LENA-R8 series|SARA-R4 series<br />SARA-R5 series<br />LARA-R6 series<br />|SARA-R510M8S<br />SARA-R422M8S|M8/M9/M10 series|
|`ubxlib` peripherals |NINA-B41 series<br />NINA-B31 series<br />NINA-B1 series<br />ANNA-B1|NINA-W13|NINA-W15<br /><nobr>NORA-W36<sup>4</sup></nobr>|SARA-U2 series|LENA-R8 series|SARA-R4 series<br />SARA-R5 series<br />LARA-R6 series<br />|SARA-R510M8S<br />SARA-R422M8S|M8/M9/M10 series|
|-----------|-----------|--------------|-----|-----|-----|------|------|------|
|**APIs provided by host with peripheral attached**|[ble](/ble "ble API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")|[wifi](/wifi)<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")<br />[TLS&nbsp;security](/common/security "security API")<br />[mqtt_client](/common/mqtt_client "MQTT client API")|[wifi](/wifi)<br />[ble](/ble "ble API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")<br />[TLS&nbsp;security](/common/security "security API")<br />[mqtt_client](/common/mqtt_client "MQTT client API")|[cell](/cell "cell API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")<br />[location<sup>***</sup>](/common/location "location API")<br />[TLS&nbsp;security](/common/security "security API")<br />[http_client](/common/http_client "HTTP client API")|[cell](/cell "cell API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")<br />[location<sup>***</sup>](/common/location "location API")<br />[TLS&nbsp;security](/common/security "security API")<br />[mqtt_client](/common/mqtt_client "MQTT client API")|[cell](/cell "cell API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")<br />[location<sup>***</sup>](/common/location "location API")<br />[security](/common/security "security API")<br />[mqtt_client](/common/mqtt_client "MQTT client API")<br />[http_client](/common/httpt_client "HTTP client API")|All APIs of<br />SARA-R4,<br />SARA-R5 series&nbsp;+<br />[gnss](/gnss "GNSS API")<br />[location](/common/location "location API")|[gnss](/gnss "GNSS API")<br />[location](/common/location "location API")|
|**APIs provided by host with peripheral attached**|[ble](/ble "ble API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")|[wifi](/wifi)<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")<br />[TLS&nbsp;security](/common/security "security API")<br />[mqtt_client](/common/mqtt_client "MQTT client API")<br />[http_client](/common/http_client "HTTP client API")|[wifi](/wifi)<br />[ble](/ble "ble API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")<br />[TLS&nbsp;security](/common/security "security API")<br />[mqtt_client](/common/mqtt_client "MQTT client API")<br />[http_client](/common/http_client "HTTP client API")|[cell](/cell "cell API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")<br />[location<sup>3</sup>](/common/location "location API")<br />[TLS&nbsp;security](/common/security "security API")<br />[http_client](/common/http_client "HTTP client API")|[cell](/cell "cell API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")<br />[location<sup>3</sup>](/common/location "location API")<br />[TLS&nbsp;security](/common/security "security API")<br />[mqtt_client](/common/mqtt_client "MQTT client API")|[cell](/cell "cell API")<br />[device](/common/device "device API")<br />[network](/common/network "network API")<br />[sock](/common/sock "sock API")<br />[location<sup>3</sup>](/common/location "location API")<br />[security](/common/security "security API")<br />[mqtt_client](/common/mqtt_client "MQTT client API")<br />[http_client](/common/httpt_client "HTTP client API")|All APIs of<br />SARA-R4,<br />SARA-R5 series&nbsp;+<br />[gnss](/gnss "GNSS API")<br />[location](/common/location "location API")|[gnss](/gnss "GNSS API")<br />[location](/common/location "location API")|


<sup>*** Through the u-blox [CellLocate](https://www.u-blox.com/en/product/celllocate) mobile network-based location service.</sup>
<sup>3: Through the u-blox [CellLocate](https://www.u-blox.com/en/product/celllocate) mobile network-based location service.</sup><br />
<sup>4: Beta support: please **add** `short_range_gen2` to the `UBXLIB_FEATURES` variable in your `make` or `CMake` file when building `ubxlib` for NORA-W36; NORA-W36 comes with a second generation uConnectExpress, please see the release notes for NORA-W36 for the supported features.</sup>

# Structure of `ubxlib`
The APIs for each type of u-blox module can be found in the relevant directory (e.g. [cell](/cell) for cellular modules and [ble](/ble)/[wifi](/wifi) for BLE/Wi-Fi modules). The [common](/common) directory contains APIs and 'helper' modules that are shared by u-blox modules, most importantly the [device](/common/device) API, the [network](/common/network) API and the [sockets](/common/sockets) API. All APIs are documented in the API header files.
Expand Down
3 changes: 2 additions & 1 deletion astyle.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@
--exclude='_build'
--exclude='gnss/src/lib_mga'
--exclude='common/geofence/geographiclib'
--exclude='Unity'
--exclude='Unity'
--exclude='common/short_range/src/gen2/ucxclient'
17 changes: 12 additions & 5 deletions ble/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,18 @@ This API can safely be used simultaneously with the [wifi](/wifi) API using the

This API relies on the [common/at_client](/common/at_client) component to send commands to and parse responses received from a short range module.

Communication with an external module uses the binary EDM protocol. The app can ignore this, it will be handled by lower layers.

It is not in the scope of this API to support the full range short range module (AT) API. However, using the BLE `cfg` API as a prototype it is easy to add additional commands to your application. Make sure your code locks the short range mutex.

The operation of `ubxlib` does not rely on a particular version of uConnectExpress; the versions that we test with are listed in the short-range [test](/common/short_range/test) directory.

# Usage
The [api](api) directory contains the files that define the BLE APIs, each API function documented in its header file. In the [src](src) directory you will find the implementation of the APIs and in the [test](test) directory the tests for the APIs that can be run on any platform.
The [api](api) directory contains the files that define the BLE APIs, each API function documented in its header file. In the [src](src) and [src/gen2](src/gen2) directories you will find the implementation of the APIs and in the [test](test) directory the tests for the APIs that can be run on any platform.

# uConnectExpress For NORA-W36 And Beyond
`ubxlib` relies on uConnectExpress, running on the short-range module and providing the AT interface to this MCU. While `ubxlib` does not rely on a particular version of uConnectExpress, NORA-W3 and later modules are provided with a second generation of uConnectExpress which requires the `ubxlib` code in the [src/gen2](src/gen2) directory rather that in the [src](src) directory.

To use the [src/gen2](src/gen2) code, please **add** `short_range_gen2` to the `UBXLIB_FEATURES` variable in your `make` or `CMake` file, e.g.:

```
UBXLIB_FEATURES=cell gnss short_range short_range_gen2
```

The versions of uConnectExpress that we test with are listed in the short-range [test](/common/short_range/test) directory.
20 changes: 16 additions & 4 deletions ble/api/u_ble_gatt.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,16 +134,18 @@ int32_t uBleGattSetWriteCallback(uDeviceHandle_t devHandle,

/* Peripheral (server) role GATT functions */

/** Add a server service when in peripheral mode
*
/** Start adding a server service when in peripheral mode.
* Should be followed by uBleGattAddCharacteristic for the server
* characteristics and then uBleGattEndAddService to complete
* and activate the service.
* Note: not all modules support this (e.g. ODIN-W2 does not).
*
* @param[in] devHandle the handle of the u-blox BLE device.
* @param[in] pUuid pointer to a string with the service UUID.
* @return zero on success, on failure negative error code.
*/
int32_t uBleGattAddService(uDeviceHandle_t devHandle,
const char *pUuid);
int32_t uBleGattBeginAddService(uDeviceHandle_t devHandle,
const char *pUuid);

/** Add a server characteristic when in peripheral mode
*
Expand All @@ -160,6 +162,16 @@ int32_t uBleGattAddCharacteristic(uDeviceHandle_t devHandle,
const char *pUuid, uint8_t properties,
uint16_t *pValueHandle);

/** Complete and activate a service definition initiated by uBleGattBeginAddService
* when in peripheral mode. The service will be activated after this call.
*
* Note: not all modules support this (e.g. ODIN-W2 does not).
*
* @param[in] devHandle the handle of the u-blox BLE device.
* @return zero on success, on failure negative error code.
*/
int32_t uBleGattEndAddService(uDeviceHandle_t devHandle);

/** Set callback for peer notification writes when in peripheral mode.
*
* Note: not all modules support this (e.g. ODIN-W2 does not).
Expand Down
7 changes: 7 additions & 0 deletions ble/api/u_ble_module_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@
_BLE(_TYPE_NAME)

/** The possible types of BLE module.
*
* IMPORTANT: if you are using U_BLE_MODULE_TYPE_NORA_W36, which comes
* with a second generation of uConnectExpress, you MUST add
* short_range_gen2 to the UBXLIB_FEATURES variable in your make or CMake
* file when building ubxlib. For instance:
*
* UBXLIB_FEATURES=cell gnss short_range short_range_gen2
*/
typedef enum {
// X macro is used to generate this enum from #U_SHORT_RANGE_MODULE_LIST
Expand Down
4 changes: 4 additions & 0 deletions ble/src/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# IMPORTANT
When `short_range_gen2` is added to the `UBXLIB_FEATURES` variable in your `make` or `CMake` file (e.g. for the next generation uConnectExpress used by NORA-W36), NONE OF THE SOURCE FILES IN THIS DIRECTORY are used.

Please see the files in the [gen2](gen2) sub-directory instead.
126 changes: 126 additions & 0 deletions ble/src/gen2/u_ble_cfg_extmod.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Copyright 2019-2024 u-blox
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/* Only #includes of u_* and the C standard library are allowed here,
* no platform stuff and no OS stuff. Anything required from
* the platform/OS must be brought in through u_port* to maintain
* portability.
*/

/** @file
* @brief Implementation of the cfg API for ble.
*/

#ifndef U_CFG_BLE_MODULE_INTERNAL

#ifdef U_CFG_OVERRIDE
# include "u_cfg_override.h" // For a customer's configuration override
#endif

#include "stdlib.h" // strol(), atoi(), strol(), strtof()
#include "stddef.h" // NULL, size_t etc.
#include "stdint.h" // int32_t etc.
#include "stdbool.h"

#include "u_error_common.h"

#include "u_cfg_sw.h"
#include "u_port_os.h"

#include "u_at_client.h"

#include "u_short_range_module_type.h"
#include "u_short_range.h"
#include "u_short_range_private.h"
#include "u_ble_cfg.h"

#include "u_cx_system.h"
#include "u_cx_bluetooth.h"
#include "u_cx_sps.h"

/* ----------------------------------------------------------------
* COMPILE-TIME MACROS
* -------------------------------------------------------------- */

/* ----------------------------------------------------------------
* TYPES
* -------------------------------------------------------------- */

/* ----------------------------------------------------------------
* VARIABLES
* -------------------------------------------------------------- */

/* ----------------------------------------------------------------
* STATIC FUNCTIONS
* -------------------------------------------------------------- */

/* ----------------------------------------------------------------
* PUBLIC FUNCTIONS THAT ARE PRIVATE TO BLE EXTMOD
* -------------------------------------------------------------- */

int32_t uBlePrivateGetRole(uDeviceHandle_t devHandle)
{
int32_t mode = 0;
uCxHandle_t *pUcxHandle = pShortRangePrivateGetUcxHandle(devHandle);
if (pUcxHandle != NULL) {
uCxBluetoothGetMode(pUcxHandle, (uBtMode_t *)&mode);
}
return mode;
}

/* ----------------------------------------------------------------
* PUBLIC FUNCTIONS
* -------------------------------------------------------------- */

int32_t uBleCfgConfigure(uDeviceHandle_t devHandle,
const uBleCfg_t *pCfg)
{
int32_t errorCode = (int32_t)U_ERROR_COMMON_INVALID_PARAMETER;
uCxHandle_t *pUcxHandle = pShortRangePrivateGetUcxHandle(devHandle);
uBtMode_t mode = (uBtMode_t)pCfg->role;
if ((mode == U_BT_MODE_CENTRAL) && pCfg->spsServer) {
mode = U_BT_MODE_CENTRAL_PERIPHERAL;
}
if (pUcxHandle != NULL) {
errorCode = (int32_t)U_ERROR_COMMON_SUCCESS;
int32_t currMode = uBlePrivateGetRole(devHandle);
if (currMode != mode) {
errorCode = uCxBluetoothSetMode(pUcxHandle, mode);
// Restart needed to change mode
errorCode = uShortrangePrivateRestartDevice(devHandle, true);
}
bool isActive = false;
if (errorCode == 0) {
uSpsServiceOption_t opt;
errorCode = uCxSpsGetServiceEnable(pUcxHandle, &opt);
isActive = opt == U_SPS_SERVICE_OPTION_ENABLE_SPS_SERVICE;
}
if ((errorCode == 0) && (isActive != pCfg->spsServer)) {
errorCode = uCxSpsSetServiceEnable(pUcxHandle,
pCfg->spsServer ?
U_SPS_SERVICE_OPTION_ENABLE_SPS_SERVICE :
U_SPS_SERVICE_OPTION_DISABLE_SPS_SERVICE);
// *** UCX WORKAROUND FIX ***
// Need to restart
errorCode = uShortrangePrivateRestartDevice(devHandle, true);
}
}
return errorCode;
}

#endif

// End of file
Loading

0 comments on commit 95f8347

Please sign in to comment.