- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);
}
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.