Skip to content

LG-73 Partial CDD API support #133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions lib/api/wpc.h
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,41 @@ app_res_e WPC_send_data(const uint8_t * bytes,
*/
app_res_e WPC_send_data_with_options(const app_message_t * message_p);

/**
* \brief Set config data item
* \param endpoint
* Endpoint address of the config data item
* \param payload
* Pointer to the new config data payload
* \param size
* Size of the new payload to write (bytes)
* \return Return code of the operation
* \note This call can only be made from a sink node.
* An optional config data item can be removed by setting a zero-size
* payload.
*/
app_res_e WPC_set_config_data_item(const uint16_t endpoint,
const uint8_t *const payload,
const uint8_t size);

/**
* \brief Get config data item
* \param endpoint
* Endpoint address of the config data item to get
* \param payload
* Pointer to read config data item payload into
* \param payload_capacity
* Allocated size of the given payload buffer (bytes). If received
* payload is larger, the function fails.
* \param size
* Size of the payload that was written to the above pointer (bytes)
* \return Return code of the operation
*/
app_res_e WPC_get_config_data_item(const uint16_t endpoint,
uint8_t *const payload,
const size_t payload_capacity,
uint8_t *const size);

/**
* \brief Callback definition to register for received data
* \param bytes
Expand Down Expand Up @@ -1045,4 +1080,33 @@ app_res_e WPC_register_for_stack_status(onStackStatusReceived_cb_f onStackStatus
*/
app_res_e WPC_unregister_from_stack_status();

/**
* \brief Callback definition to register for config data item notification
* \param endpoint
* Endpoint address of the configuration data item
* \param payload
* Pointer to the configuration data
* \param size
* Size of the configuration data (bytes)
*/
typedef void (*onConfigDataItemReceived_cb_f)(const uint16_t endpoint,
const uint8_t *const payload,
const uint8_t size);

/**
* \brief Register for receiving config data item
* \param onConfigDataItemReceived
* The callback to call when config data item is received
* \note All the registered callback share the same thread,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you register to it if you are a sink?
Question is more to know if a CDD can be written by the stack itself so the sink app can also be informed this way that something has changed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, you can register to it if you are a sink. At least earlier this callback was called for example when app config is set via the older API. But now when I tested it with the most recent node build, it wasn't the case. Still, it is invoked when I set some CDD item on the sink.

* so the handling of it must be kept as simple
* as possible or dispatched to another thread for long operations.
*/
app_res_e WPC_register_for_config_data_item(onConfigDataItemReceived_cb_f onConfigDataItemReceived);

/**
* \brief Unregister for receiving config data item
* \return Return code of the operation
*/
app_res_e WPC_unregister_from_config_data_item();

#endif
82 changes: 82 additions & 0 deletions lib/wpc/include/msap.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,33 @@ typedef struct __attribute__((__packed__))
uint8_t bytes[MAXIMUM_SCRATCHPAD_BLOCK_SIZE];
} msap_image_block_read_conf_pl_t;

typedef struct __attribute__((__packed__))
{
uint16_t endpoint;
uint8_t payload_length;
uint8_t payload[MAXIMUM_CDC_ITEM_PAYLOAD_SIZE];
} msap_config_data_item_set_req_pl_t;

typedef struct __attribute__((__packed__))
{
uint16_t endpoint;
} msap_config_data_item_get_req_pl_t;

typedef struct __attribute__((__packed__))
{
uint8_t result;
uint8_t payload_length;
uint8_t payload[MAXIMUM_CDC_ITEM_PAYLOAD_SIZE];
} msap_config_data_item_get_conf_pl_t;

typedef struct __attribute__((__packed__))
{
uint8_t indication_status;
uint16_t endpoint;
uint8_t payload_length;
uint8_t payload[MAXIMUM_CDC_ITEM_PAYLOAD_SIZE];
} msap_config_data_item_rx_ind_pl_t;

static inline void
convert_internal_to_app_scratchpad_status(app_scratchpad_status_t * status_p,
msap_scratchpad_status_conf_pl_t * internal_status_p)
Expand Down Expand Up @@ -448,6 +475,40 @@ static inline int msap_attribute_read_request(uint16_t attribute_id,
return attribute_read_request(MSAP_ATTRIBUTE_READ_REQUEST, attribute_id, attribute_length, attribute_value_p);
}

/**
* \brief Request to set config data item
* \param endpoint
* Endpoint address of the config data item
* \param payload
* Pointer to the new config data payload
* \param payload_size
* Size of the new payload to write (bytes)
* \return Negative value upon internal error, otherwise result code returned
* by the DualMCU API
*/
int msap_config_data_item_set_request(const uint16_t endpoint,
const uint8_t *const payload,
const uint8_t payload_size);

/**
* \brief Request to get config data item
* \param endpoint
* Endpoint address of the config data item to get
* \param payload
* Pointer to the read config data payload
* \param payload_capacity
* Allocated size of the given payload buffer (bytes). If received
* payload is larger, the function fails.
* \param payload_size
* Size of the payload that was read (bytes)
* \return Negative value upon internal error, otherwise result code returned
* by the DualMCU API
*/
int msap_config_data_item_get_request(const uint16_t endpoint,
uint8_t *const payload,
const size_t payload_capacity,
uint8_t *const payload_size);

/**
* \brief Handler for stack state indication
* \param payload
Expand All @@ -469,6 +530,13 @@ void msap_app_config_data_rx_indication_handler(msap_app_config_data_rx_ind_pl_t
*/
void msap_scan_nbors_indication_handler(msap_scan_nbors_ind_pl_t * payload);

/**
* \brief Handler for config data item receive
* \param payload
* pointer to payload
*/
void msap_config_data_item_rx_indication_handler(msap_config_data_item_rx_ind_pl_t * payload);

/**
* \brief Register for app config data
* \param cb
Expand Down Expand Up @@ -511,4 +579,18 @@ bool msap_register_for_stack_status(onStackStatusReceived_cb_f cb);
*/
bool msap_unregister_from_stack_status();

/**
* \brief Register for config data item
* \param cb
* Callback to invoke when config data item is received
* \return True if registered successfully, false otherwise
*/
bool msap_register_for_config_data_item(onConfigDataItemReceived_cb_f cb);

/**
* \brief Unregister for config data item
* \return True if unregistered successfully, false otherwise
*/
bool msap_unregister_from_config_data_item();

#endif /* MSAP_H_ */
8 changes: 8 additions & 0 deletions lib/wpc/include/wpc_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@
#define MSAP_SCRATCH_TARGET_READ_CONFIRM (SAP_CONFIRM_OFFSET + MSAP_SCRATCH_TARGET_READ_REQUEST)
#define MSAP_SCRATCH_BLOCK_READ_REQUEST 0x28
#define MSAP_SCRATCH_BLOCK_READ_CONFIRM (SAP_CONFIRM_OFFSET + MSAP_SCRATCH_BLOCK_READ_REQUEST)
#define MSAP_CONFIG_DATA_ITEM_SET_REQUEST 0x29
#define MSAP_CONFIG_DATA_ITEM_SET_CONFIRM (SAP_CONFIRM_OFFSET + MSAP_CONFIG_DATA_ITEM_SET_REQUEST)
#define MSAP_CONFIG_DATA_ITEM_GET_REQUEST 0x30
#define MSAP_CONFIG_DATA_ITEM_GET_CONFIRM (SAP_CONFIRM_OFFSET + MSAP_CONFIG_DATA_ITEM_GET_REQUEST)
#define MSAP_CONFIG_DATA_ITEM_RX_INDICATION 0x31
#define MSAP_CONFIG_DATA_ITEM_RX_RESPONSE (SAP_RESPONSE_OFFSET + MSAP_CONFIG_DATA_ITEM_RX_INDICATION)

/*
* Configuration Service Access Points
Expand Down Expand Up @@ -118,6 +124,8 @@
/* Maximun Full packet size for all platforms */
#define MAX_FULL_PACKET_SIZE 1500

#define MAXIMUM_CDC_ITEM_PAYLOAD_SIZE 80
#define MAXIMUM_CDC_ITEM_LIST_BYTE_COUNT 32

#endif

Expand Down
8 changes: 8 additions & 0 deletions lib/wpc/include/wpc_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ typedef struct __attribute__((__packed__))
csap_factory_reset_req_pl_t csap_factory_reset_request_payload;
msap_scratchpad_target_write_req_pl_t msap_scratchpad_target_write_request_payload;
msap_image_block_read_req_pl_t msap_image_block_read_request_payload;
msap_config_data_item_set_req_pl_t msap_config_data_item_set_request_payload;
msap_config_data_item_get_req_pl_t msap_config_data_item_get_request_payload;
// Indication
dsap_data_tx_ind_pl_t dsap_data_tx_indication_payload;
dsap_data_rx_ind_pl_t dsap_data_rx_indication_payload;
Expand All @@ -73,6 +75,7 @@ typedef struct __attribute__((__packed__))
msap_app_config_data_rx_ind_pl_t msap_app_config_data_rx_indication_payload;
msap_scan_nbors_ind_pl_t msap_scan_nbors_indication_payload;
generic_ind_pl_t generic_indication_payload;
msap_config_data_item_rx_ind_pl_t msap_config_data_item_rx_indication_payload;
// Confirm
sap_generic_conf_pl_t sap_generic_confirm_payload;
dsap_data_tx_conf_pl_t dsap_data_tx_confirm_payload;
Expand All @@ -84,11 +87,16 @@ typedef struct __attribute__((__packed__))
attribute_read_conf_pl_t attribute_read_confirm_payload;
msap_scratchpad_target_read_conf_pl_t msap_scratchpad_target_read_confirm_payload;
msap_image_block_read_conf_pl_t msap_image_block_read_confirm_payload;
msap_config_data_item_get_conf_pl_t msap_config_data_item_get_confirm_payload;
// Response
sap_resp_pl_t sap_response_payload;
} payload;
} wpc_frame_t;

// Make sure each member of the payload union has a size representable by the
// payload_length field
_Static_assert(sizeof(((wpc_frame_t*)0)->payload) <= UINT8_MAX, "");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good enhancement!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!


// Size of a given frame
#define FRAME_SIZE(__frame_ptr__) ((__frame_ptr__)->payload_length + 3)

Expand Down
108 changes: 108 additions & 0 deletions lib/wpc/msap.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ static onScanNeighborsDone_cb_f m_scan_neighbor_cb = NULL;
*/
static onStackStatusReceived_cb_f m_stack_status_cb = NULL;

/**
* \brief Registered callback for config data item
*/
static onConfigDataItemReceived_cb_f m_config_data_item_cb = NULL;

/**
* \brief Time to wait for scratchpad start request confirm
* It can be long because the start triggers an erase of
Expand Down Expand Up @@ -448,6 +453,85 @@ int msap_scratchpad_block_read_request(uint32_t start_address, uint8_t number_of
return confirm.payload.msap_image_block_read_confirm_payload.result;
}

int msap_config_data_item_set_request(const uint16_t endpoint,
const uint8_t *const payload,
const uint8_t payload_size)
{
if (payload_size > MAXIMUM_CDC_ITEM_PAYLOAD_SIZE)
{
LOGE("Too large payload size (%d) for config data item\n", payload_size);
return WPC_INT_WRONG_PARAM_ERROR;
}

wpc_frame_t request = {
.primitive_id = MSAP_CONFIG_DATA_ITEM_SET_REQUEST,
.payload_length = sizeof(msap_config_data_item_set_req_pl_t),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So even if CDD is 10 bytes, 80 bytes are sent? (padded with 00)
I guess you did it this way as it was the expectation on dualmcu app side.

I guess it is like this to mimic the old implementation of app_config :-)

Copy link
Contributor Author

@sgunes-wirepas sgunes-wirepas Apr 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good find, thanks! I don't remember if I noticed this and checked earlier, but I can optimize this and verify if it works, then add as a separate commit

.payload = {
.msap_config_data_item_set_request_payload = {
.endpoint = endpoint,
.payload_length = payload_size,
.payload = {0}
}
}
};

memcpy(request.payload.msap_config_data_item_set_request_payload.payload,
payload,
payload_size);

wpc_frame_t confirm;
const int res = WPC_Int_send_request(&request, &confirm);
if (res < 0)
{
return res;
}

return confirm.payload.sap_generic_confirm_payload.result;
}

int msap_config_data_item_get_request(const uint16_t endpoint,
uint8_t *const payload,
const size_t payload_capacity,
uint8_t *const payload_size)
{
wpc_frame_t request = {
.primitive_id = MSAP_CONFIG_DATA_ITEM_GET_REQUEST,
.payload_length = sizeof(msap_config_data_item_get_req_pl_t),
.payload = {
.msap_config_data_item_get_request_payload = {
.endpoint = endpoint,
}
}
};

wpc_frame_t confirm;
const int res = WPC_Int_send_request(&request, &confirm);
if (res < 0)
{
return res;
}

if (confirm.payload.sap_generic_confirm_payload.result == 0)
{
const uint8_t payload_length = confirm.payload.msap_config_data_item_get_confirm_payload.payload_length;
if (payload_length > payload_capacity)
{
return WPC_INT_WRONG_BUFFER_SIZE;
}
if (payload_length > sizeof(confirm.payload.msap_config_data_item_get_confirm_payload.payload))
{
return WPC_INT_WRONG_PARAM_ERROR;
}

memcpy(payload,
&confirm.payload.msap_config_data_item_get_confirm_payload.payload,
payload_length);
*payload_size = payload_length;
}

return confirm.payload.sap_generic_confirm_payload.result;
}

void msap_stack_state_indication_handler(msap_stack_state_ind_pl_t * payload)
{
LOGI("Status is 0x%02x\n", payload->status);
Expand Down Expand Up @@ -479,6 +563,20 @@ void msap_scan_nbors_indication_handler(msap_scan_nbors_ind_pl_t * payload)
}
}

void msap_config_data_item_rx_indication_handler(msap_config_data_item_rx_ind_pl_t * payload)
{
LOGD("Received configuration data item indication for endpoint: 0x%04X\n",
payload->endpoint);

if (m_config_data_item_cb != NULL)
{
m_config_data_item_cb(payload->endpoint,
payload->payload,
payload->payload_length);

}
}

// Macro to avoid code duplication
#define REGISTER_CB(cb, internal_cb) \
({ \
Expand Down Expand Up @@ -537,3 +635,13 @@ bool msap_unregister_from_stack_status()
{
return UNREGISTER_CB(m_stack_status_cb);
}

bool msap_register_for_config_data_item(onConfigDataItemReceived_cb_f cb)
{
return REGISTER_CB(cb, m_config_data_item_cb);
}

bool msap_unregister_from_config_data_item()
{
return UNREGISTER_CB(m_config_data_item_cb);
}
Loading