Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

Bluetooth SDK Forum Discussions

HyCh_4218006
Level 3
Level 3

Hi teams,

I am trying to get response with Generic Location Client model in mesh network.

Three Location Server nodes are already provisioned, and the last Location Client node was also provisioned successfully.

When I tried the following code in some timer callback, p_event returned was always NULL. What was wrong with this code?

wiced_bt_mesh_event_t *p_event = wiced_bt_mesh_create_event(MESH_LOCATION_CLIENT_ELEMENT_INDEX, MESH_COMPANY_ID_BT_SIG, \

                                   WICED_BT_MESH_CORE_MODEL_ID_GENERIC_LOCATION_CLNT, 0, 0);

if (p_event == NULL)

{

     WICED_BT_TRACE("wiced_bt_mesh_create_event error!!!\n");

     return;

}

p_event->reply = WICED_TRUE;

status  = wiced_bt_mesh_model_location_client_send_global_get(p_event);

0 Likes
1 Solution

Self tested answer.

When I used Generic/Set AppKey which is saved in MeshClient in provisioning process, I can successfully communicate with another node.

So I detached this thread and made a new question.

Treaded as answered.

View solution in original post

0 Likes
6 Replies
HyCh_4218006
Level 3
Level 3

I found the following comment in the SDK.

In case dst is 0 the function takes all information from the model's publication or fails if publication is not configured for the specified model.

So, it seems to be failed because I did not set up publication configuration, according to the above comment.

Is there any way to send broadcast request to all nodes? with specific hop/TTL?

With this way, I expect only few nodes which can reach directly by one node, will response to the request, if I limit hop/TTL to small value.

Is this approach reasonable?

0 Likes

I have changed destination and appkey to 0xFFFF, and now can create event.

And wiced_bt_mesh_model_location_client_send_global_get() call was returned 0.

But still no message is received.

According to the sample code, it seems to be received at least WICED_BT_MESH_TX_COMPLETE, but not.

What is wrong with my code?

0 Likes

Hi HyCh_4218006​,

Could you please share your edited full code with me so that I can take a look at it and reproduce the issue at my side.

Thanks,

-Dheeraj

0 Likes

After some trial, the following is my last test code, which is based on mesh_location_client template.

Please see the bold codes. It is my modification from template.

Now this code sent packet and get "tx complete status:2", but no response returned from location server.

Of course, I already provisioned several location servers in networks.

/** @file

*

*

* This file shows how to create a device which can query or set location of the location setup server device.

*/

#include "wiced_bt_ble.h"

#include "wiced_bt_gatt.h"

#include "wiced_bt_mesh_models.h"

#include "wiced_bt_mesh_event.h"

#include "wiced_bt_trace.h"

#include "wiced_bt_mesh_app.h"

#ifdef HCI_CONTROL

#include "wiced_transport.h"

#include "hci_control_api.h"

#endif

#include "wiced_bt_cfg.h"

extern wiced_bt_cfg_settings_t wiced_bt_cfg_settings;

/******************************************************

*          Constants

******************************************************/

#define MESH_PID                0x3013

#define MESH_VID                0x0002

#define MESH_FWID              0x3013000101010001

#define MESH_CACHE_REPLAY_SIZE  0x0008

/******************************************************

*          Structures

******************************************************/

typedef struct

{

    wiced_bt_mesh_location_global_data_t global_data;

    wiced_bt_mesh_location_local_data_t  local_data;

} mesh_location_t;

/******************************************************

*          Function Prototypes

******************************************************/

static void mesh_app_init(wiced_bool_t is_provisioned);

static uint32_t mesh_app_proc_rx_cmd(uint16_t opcode, uint8_t *p_data, uint32_t length);

static void mesh_location_client_message_handler(uint16_t event, wiced_bt_mesh_event_t *p_event, void *p_data);

static void mesh_location_client_global_get(wiced_bt_mesh_event_t *p_event, uint8_t *p_data, uint32_t length);

static void mesh_location_client_local_get(wiced_bt_mesh_event_t *p_event, uint8_t *p_data, uint32_t length);

static void mesh_location_client_global_set(wiced_bt_mesh_event_t *p_event, uint8_t *p_data, uint32_t length);

static void mesh_location_client_local_set(wiced_bt_mesh_event_t *p_event, uint8_t *p_data, uint32_t length);

static void mesh_location_global_hci_event_send(wiced_bt_mesh_hci_event_t *p_hci_event, wiced_bt_mesh_location_global_data_t *p_data);

static void mesh_location_local_hci_event_send(wiced_bt_mesh_hci_event_t *p_hci_event, wiced_bt_mesh_location_local_data_t *p_data);

static void mesh_location_server_restart_timer(mesh_location_t *p_location);

static void mesh_location_publish_timer_callback(TIMER_PARAM_TYPE arg);

/******************************************************

*          Variables Definitions

******************************************************/

uint8_t mesh_mfr_name[WICED_BT_MESH_PROPERTY_LEN_DEVICE_MANUFACTURER_NAME] = { 'C', 'y', 'p', 'r', 'e', 's', 's', 0 };

uint8_t mesh_model_num[WICED_BT_MESH_PROPERTY_LEN_DEVICE_MODEL_NUMBER]    = { '1', '2', '3', '4', 0, 0, 0, 0 };

uint8_t mesh_system_id[8]                                                  = { 0xbb, 0xb8, 0xa1, 0x80, 0x5f, 0x9f, 0x91, 0x71 };

uint32_t      mesh_location_sent_time;                  // time stamp when location was published

uint32_t      mesh_location_publish_period = 60000;    // publish period in msec

wiced_timer_t mesh_location_publish_timer;

wiced_bt_mesh_core_config_model_t  mesh_element1_models[] =

{

    WICED_BT_MESH_DEVICE,

    WICED_BT_MESH_MODEL_LOCATION_CLIENT,

};

#define MESH_APP_NUM_MODELS  (sizeof(mesh_element1_models) / sizeof(wiced_bt_mesh_core_config_model_t))

#define MESH_LOCATION_CLIENT_ELEMENT_INDEX  0

wiced_bt_mesh_core_config_element_t mesh_elements[] =

{

    {

        .location = MESH_ELEM_LOC_MAIN,                                // location description as defined in the GATT Bluetooth Namespace Descriptors section of the Bluetooth SIG Assigned Numbers

        .default_transition_time = MESH_DEFAULT_TRANSITION_TIME_IN_MS,  // Default transition time for models of the element in milliseconds

        .onpowerup_state = WICED_BT_MESH_ON_POWER_UP_STATE_RESTORE,    // Default element behavior on power up

        .default_level = 0,                                            // Default value of the variable controlled on this element (for example power, lightness, temperature, hue...)

        .range_min = 1,                                                // Minimum value of the variable controlled on this element (for example power, lightness, temperature, hue...)

        .range_max = 0xffff,                                            // Maximum value of the variable controlled on this element (for example power, lightness, temperature, hue...)

        .move_rollover = 0,                                            // If true when level gets to range_max during move operation, it switches to min, otherwise move stops.

        .properties_num = 0,                                            // Number of properties in the array models

        .properties = NULL,                                            // Array of properties in the element.

        .sensors_num = 0,                                              // Number of sensors in the sensor array

        .sensors = NULL,                                                // Array of sensors of that element

        .models_num = MESH_APP_NUM_MODELS,                              // Number of models in the array models

        .models = mesh_element1_models,                                // Array of models located in that element. Model data is defined by structure wiced_bt_mesh_core_config_model_t

    },

};

wiced_bt_mesh_core_config_t  mesh_config =

{

    .company_id        = MESH_COMPANY_ID_CYPRESS,                  // Company identifier assigned by the Bluetooth SIG

    .product_id        = MESH_PID,                                // Vendor-assigned product identifier

    .vendor_id          = MESH_VID,                                // Vendor-assigned product version identifier

    .firmware_id        = MESH_FWID,                                // Vendor-assigned firmware version identifier

    .replay_cache_size  = MESH_CACHE_REPLAY_SIZE,                  // Number of replay protection entries, i.e. maximum number of mesh devices that can send application messages to this device.

#if defined(LOW_POWER_NODE) && (LOW_POWER_NODE == 1)

    .features          = WICED_BT_MESH_CORE_FEATURE_BIT_LOW_POWER, // A bit field indicating the device features. In Low Power mode no Relay, no Proxy and no Friend

    .friend_cfg        =                                          // Empty Configuration of the Friend Feature

    {

        .receive_window = 0,                                        // Receive Window value in milliseconds supported by the Friend node.

        .cache_buf_len  = 0,                                        // Length of the buffer for the cache

        .max_lpn_num    = 0                                        // Max number of Low Power Nodes with established friendship. Must be > 0 if Friend feature is supported.

    },

    .low_power          =                                          // Configuration of the Low Power Feature

    {

        .rssi_factor          = 2,                                // contribution of the RSSI measured by the Friend node used in Friend Offer Delay calculations.

        .receive_window_factor = 2,                                // contribution of the supported Receive Window used in Friend Offer Delay calculations.

        .min_cache_size_log    = 3,                                // minimum number of messages that the Friend node can store in its Friend Cache.

        .receive_delay        = 100,                              // Receive delay in 1 ms units to be requested by the Low Power node.

        .poll_timeout          = 36000                              // Poll timeout in 100ms units to be requested by the Low Power node.

    },

#else

    .features = WICED_BT_MESH_CORE_FEATURE_BIT_FRIEND | WICED_BT_MESH_CORE_FEATURE_BIT_RELAY | WICED_BT_MESH_CORE_FEATURE_BIT_GATT_PROXY_SERVER,  // Supports Friend, Relay and GATT Proxy

    .friend_cfg        =                                          // Configuration of the Friend Feature(Receive Window in Ms, messages cache)

    {

        .receive_window        = 200,

        .cache_buf_len        = 300,                              // Length of the buffer for the cache

        .max_lpn_num          = 4                                  // Max number of Low Power Nodes with established friendship. Must be > 0 if Friend feature is supported.

    },

    .low_power          =                                          // Configuration of the Low Power Feature

    {

        .rssi_factor          = 0,                                // contribution of the RSSI measured by the Friend node used in Friend Offer Delay calculations.

        .receive_window_factor = 0,                                // contribution of the supported Receive Window used in Friend Offer Delay calculations.

        .min_cache_size_log    = 0,                                // minimum number of messages that the Friend node can store in its Friend Cache.

        .receive_delay        = 0,                                // Receive delay in 1 ms units to be requested by the Low Power node.

        .poll_timeout          = 0                                  // Poll timeout in 100ms units to be requested by the Low Power node.

    },

#endif

    .gatt_client_only          = WICED_FALSE,                      // Can connect to mesh over GATT or ADV

    .elements_num  = (uint8_t)(sizeof(mesh_elements) / sizeof(mesh_elements[0])),  // number of elements on this device

    .elements      = mesh_elements                                  // Array of elements for this device

};

/*

* Mesh application library will call into application functions if provided by the application.

*/

wiced_bt_mesh_app_func_table_t wiced_bt_mesh_app_func_table =

{

    mesh_app_init,          // application initialization

    NULL,                  // Default SDK platform button processing

    NULL,                  // GATT connection status

    NULL,                  // attention processing

    NULL,                  // notify period set

    mesh_app_proc_rx_cmd,  // WICED HCI command

    NULL,                  // LPN sleep

    NULL                    // factory reset

};

// Application state

mesh_location_t app_state;

/******************************************************

*              Function Definitions

******************************************************/

void mesh_app_init(wiced_bool_t is_provisioned)

{

    // register with the library to receive parsed data

    WICED_BT_TRACE("loc clnt init\n");

    wiced_bt_cfg_settings.device_name = (uint8_t *)"Location Client";

    wiced_bt_cfg_settings.gatt_cfg.appearance = APPEARANCE_GENERIC_TAG;

    // Adv Data is fixed. Spec allows to put URI, Name, Appearance and Tx Power in the Scan Response Data.

    if (!is_provisioned)

    {

        wiced_bt_ble_advert_elem_t  adv_elem[3];

        uint8_t                    buf[2];

        uint8_t                    num_elem = 0;

        adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_NAME_COMPLETE;

        adv_elem[num_elem].len = (uint16_t)strlen((const char*)wiced_bt_cfg_settings.device_name);

        adv_elem[num_elem].p_data = wiced_bt_cfg_settings.device_name;

        num_elem++;

        adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_APPEARANCE;

        adv_elem[num_elem].len = 2;

        buf[0] = (uint8_t)wiced_bt_cfg_settings.gatt_cfg.appearance;

        buf[1] = (uint8_t)(wiced_bt_cfg_settings.gatt_cfg.appearance >> 8);

        adv_elem[num_elem].p_data = buf;

        num_elem++;

        wiced_bt_mesh_set_raw_scan_response_data(num_elem, adv_elem);

    }

    wiced_bt_mesh_model_location_client_init(mesh_location_client_message_handler, is_provisioned);

    if (!is_provisioned)

        return;

    // initialize the periodic timer.

    wiced_init_timer(&mesh_location_publish_timer, &mesh_location_publish_timer_callback, (TIMER_PARAM_TYPE)&app_state, WICED_MILLI_SECONDS_TIMER);

    // If publish period is set, immediately publish current location once.

    if (mesh_location_publish_period != 0)

    mesh_location_publish_timer_callback((TIMER_PARAM_TYPE)&app_state);

}

/*

* Process event received from the Location Server.

*/

void mesh_location_client_message_handler(uint16_t event, wiced_bt_mesh_event_t *p_event, void *p_data)

{

    wiced_bt_mesh_location_global_data_t *p_global;

    wiced_bt_mesh_location_local_data_t *p_local;

#if defined HCI_CONTROL

    wiced_bt_mesh_hci_event_t *p_hci_event;

#endif

    WICED_BT_TRACE("location clt msg:%d\n", event);

    switch (event)

    {

    case WICED_BT_MESH_TX_COMPLETE:

        WICED_BT_TRACE("tx complete status:%d\n", p_event->tx_status);

#if defined HCI_CONTROL

        if ((p_hci_event = wiced_bt_mesh_create_hci_event(p_event)) != NULL)

            wiced_bt_mesh_send_hci_tx_complete(p_hci_event, p_event);

#endif

        break;

    case WICED_BT_MESH_LOCATION_GLOBAL_STATUS:

        p_global = (wiced_bt_mesh_location_global_data_t *)p_data;

        WICED_BT_TRACE("Global lat/long/alt:%d/%d/%d\n",

                p_global->global_latitude, p_global->global_longitude, p_global->global_altitude);

#if defined HCI_CONTROL

        if ((p_hci_event = wiced_bt_mesh_create_hci_event(p_event)) != NULL)

            mesh_location_global_hci_event_send(p_hci_event, p_global);

#endif

        break;

    case WICED_BT_MESH_LOCATION_LOCAL_STATUS:

        p_local = (wiced_bt_mesh_location_local_data_t *)p_data;

        WICED_BT_TRACE("Local north/east/alt %d/%d/%d mobile:%d time:%d precision:%d\n",

                p_local->local_north, p_local->local_east, p_local->local_altitude,

                p_local->is_mobile, p_local->update_time, p_local->precision);

#if defined HCI_CONTROL

        if ((p_hci_event = wiced_bt_mesh_create_hci_event(p_event)) != NULL)

            mesh_location_local_hci_event_send(p_hci_event, p_local);

#endif

        break;

    default:

        WICED_BT_TRACE("unknown\n");

        break;

    }

    wiced_bt_mesh_release_event(p_event);

}

/*

* In 2 chip solutions MCU can send commands from the MCU.

*/

uint32_t mesh_app_proc_rx_cmd(uint16_t opcode, uint8_t *p_data, uint32_t length)

{

    wiced_bt_mesh_event_t *p_event;

    WICED_BT_TRACE("[%s] cmd_opcode 0x%02x\n", __FUNCTION__, opcode);

    switch (opcode)

    {

    case HCI_CONTROL_MESH_COMMAND_LOCATION_GLOBAL_GET:

    case HCI_CONTROL_MESH_COMMAND_LOCATION_LOCAL_GET:

    case HCI_CONTROL_MESH_COMMAND_LOCATION_GLOBAL_SET:

    case HCI_CONTROL_MESH_COMMAND_LOCATION_LOCAL_SET:

        break;

    default:

        WICED_BT_TRACE("unknown\n");

        return WICED_FALSE;

    }

    p_event = wiced_bt_mesh_create_event_from_wiced_hci(opcode, MESH_COMPANY_ID_BT_SIG, WICED_BT_MESH_CORE_MODEL_ID_GENERIC_LOCATION_CLNT, &p_data, &length);

    if (p_event == NULL)

    {

        WICED_BT_TRACE("bad hdr\n");

        return WICED_TRUE;

    }

    switch (opcode)

    {

    case HCI_CONTROL_MESH_COMMAND_LOCATION_GLOBAL_GET:

        mesh_location_client_global_get(p_event, p_data, length);

        break;

    case HCI_CONTROL_MESH_COMMAND_LOCATION_LOCAL_GET:

        mesh_location_client_local_get(p_event, p_data, length);

        break;

    case HCI_CONTROL_MESH_COMMAND_LOCATION_GLOBAL_SET:

        mesh_location_client_global_set(p_event, p_data, length);

        break;

    case HCI_CONTROL_MESH_COMMAND_LOCATION_LOCAL_SET:

        mesh_location_client_local_set(p_event, p_data, length);

        break;

    }

    return WICED_TRUE;

}

/*

* Send Location Get message

*/

void mesh_location_client_global_get(wiced_bt_mesh_event_t *p_event, uint8_t *p_data, uint32_t length)

{

    wiced_bt_mesh_model_location_client_send_global_get(p_event);

}

/*

* Send Location Get message

*/

void mesh_location_client_local_get(wiced_bt_mesh_event_t *p_event, uint8_t *p_data, uint32_t length)

{

    wiced_bt_mesh_model_location_client_send_local_get(p_event);

}

/*

* Send Location Set message

*/

void mesh_location_client_global_set(wiced_bt_mesh_event_t *p_event, uint8_t *p_data, uint32_t length)

{

    wiced_bt_mesh_location_global_data_t data;

    WICED_BT_TRACE("loc clnt global set\n");

    STREAM_TO_UINT32(data.global_latitude, p_data);

    STREAM_TO_UINT32(data.global_longitude, p_data);

    STREAM_TO_UINT16(data.global_altitude, p_data);

    wiced_bt_mesh_model_location_client_send_global_set(p_event, &data);

}

/*

* Send Location Set message

*/

void mesh_location_client_local_set(wiced_bt_mesh_event_t *p_event, uint8_t *p_data, uint32_t length)

{

    wiced_bt_mesh_location_local_data_t data;

    WICED_BT_TRACE("loc clnt local set\n");

    STREAM_TO_UINT16(data.local_north, p_data);

    STREAM_TO_UINT16(data.local_east, p_data);

    STREAM_TO_UINT16(data.local_altitude, p_data);

    STREAM_TO_UINT8(data.floor_number, p_data);

    STREAM_TO_UINT8(data.is_mobile, p_data);

    STREAM_TO_UINT8(data.update_time, p_data);

    STREAM_TO_UINT8(data.precision, p_data);

    wiced_bt_mesh_model_location_client_send_local_set(p_event, &data);

}

#ifdef HCI_CONTROL

/*

* Send Location Status event over transport

*/

void mesh_location_global_hci_event_send(wiced_bt_mesh_hci_event_t *p_hci_event, wiced_bt_mesh_location_global_data_t *p_data)

{

    uint8_t *p = p_hci_event->data;

    UINT32_TO_STREAM(p, p_data->global_latitude);

    UINT32_TO_STREAM(p, p_data->global_longitude);

    UINT16_TO_STREAM(p, p_data->global_altitude);

    mesh_transport_send_data(HCI_CONTROL_MESH_EVENT_LOCATION_GLOBAL_STATUS, (uint8_t *)p_hci_event, (uint16_t)(p - (uint8_t *)p_hci_event));

}

/*

* Send Location Status event over transport

*/

void mesh_location_local_hci_event_send(wiced_bt_mesh_hci_event_t *p_hci_event, wiced_bt_mesh_location_local_data_t *p_data)

{

    uint8_t *p = p_hci_event->data;

    UINT16_TO_STREAM(p, p_data->local_north);

    UINT16_TO_STREAM(p, p_data->local_east);

    UINT16_TO_STREAM(p, p_data->local_altitude);

    UINT8_TO_STREAM(p, p_data->floor_number);

    UINT8_TO_STREAM(p, p_data->is_mobile);

    UINT8_TO_STREAM(p, p_data->update_time);

    UINT8_TO_STREAM(p, p_data->precision);

    mesh_transport_send_data(HCI_CONTROL_MESH_EVENT_LOCATION_LOCAL_STATUS, (uint8_t *)p_hci_event, (uint16_t)(p - (uint8_t *)p_hci_event));

}

#endif

void mesh_location_server_restart_timer(mesh_location_t *p_location)

{

    // If there are no specific cadence settings, publish every publish period.

    uint32_t timeout = mesh_location_publish_period;

    wiced_stop_timer(&mesh_location_publish_timer);

    //TODO: Calculate location & adjust timer interval according to location difference

    WICED_BT_TRACE("location restart timer:%d\n", timeout);

    wiced_start_timer(&mesh_location_publish_timer, timeout);

}

/*

* Publication timer callback.  Need to send data if publish period expired, or

* if value has changed more than specified in the triggers, or if value is in range

* of fast cadence values.

*/

void mesh_location_publish_timer_callback(TIMER_PARAM_TYPE arg)

{

    mesh_location_t *p_location = (mesh_location_t *)arg;

    wiced_bool_t pub_needed = WICED_FALSE;

    uint32_t cur_time = wiced_bt_mesh_core_get_tick_count();

    wiced_result_t status;

    // Calculate location & determine whether publish is required

    WICED_BT_TRACE("Pub needed period\n");

    pub_needed = WICED_TRUE;

    wiced_bt_mesh_event_t *p_event = wiced_bt_mesh_create_event(MESH_LOCATION_CLIENT_ELEMENT_INDEX, MESH_COMPANY_ID_BT_SIG, WICED_BT_MESH_CORE_MODEL_ID_GENERIC_LOCATION_CLNT, 0xFFFF, 0xFFFF);

    if (p_event == NULL)

    {

        WICED_BT_TRACE("wiced_bt_mesh_create_event error!!!\n");

        mesh_location_server_restart_timer(p_location);

    return;

    }

    p_event->reply = WICED_TRUE;

//    p_event->ttl = 1;

    status  = wiced_bt_mesh_model_location_client_send_global_get(p_event);

    WICED_BT_TRACE("wiced_bt_mesh_model_location_client_send_global_get: %d\n", status);

    UNUSED_VARIABLE(status);

}

0 Likes

If you are getting "tx complete status:2" then it means the client gets the ACK as expected.

What are you expecting the server to reply? Did you change anything on the server code?

May I know what is your actual requirement? Can I know the application scenario that you are trying to create? What all data should be communicated between the location_client and location_server?

Also, which is your provisioner device?

0 Likes

Self tested answer.

When I used Generic/Set AppKey which is saved in MeshClient in provisioning process, I can successfully communicate with another node.

So I detached this thread and made a new question.

Treaded as answered.

0 Likes