lorawan: services: add Class C session handling
The new functions are required for Multicast Class C session setup. Signed-off-by: Martin Jäger <martin@libre.solar>
This commit is contained in:
parent
1f25531d7c
commit
a4c13fc584
3 changed files with 92 additions and 0 deletions
|
|
@ -174,6 +174,12 @@ static int clock_sync_app_time_req(void)
|
|||
uint8_t tx_pos = 0;
|
||||
uint8_t tx_buf[6];
|
||||
|
||||
if (lorawan_services_class_c_active() > 0) {
|
||||
/* avoid disturbing the session and causing potential package loss */
|
||||
LOG_DBG("AppTimeReq not sent because of active class C session");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
tx_buf[tx_pos++] = CLOCK_SYNC_CMD_APP_TIME;
|
||||
tx_pos += clock_sync_serialize_device_time(tx_buf + tx_pos,
|
||||
sizeof(tx_buf) - tx_pos);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ static struct k_work_q services_workq;
|
|||
|
||||
static struct k_work_delayable uplink_work;
|
||||
|
||||
/* Number of active class C sessions and mutex to protect access to session info */
|
||||
static uint8_t active_class_c_sessions;
|
||||
static struct k_mutex session_mutex;
|
||||
|
||||
/* single-linked list (with pointers) and array for implementation of priority queue */
|
||||
static struct service_uplink_msg messages[10];
|
||||
static sys_slist_t msg_list;
|
||||
|
|
@ -160,6 +164,56 @@ int lorawan_services_reschedule_work(struct k_work_delayable *dwork, k_timeout_t
|
|||
return k_work_reschedule_for_queue(&services_workq, dwork, delay);
|
||||
}
|
||||
|
||||
int lorawan_services_class_c_start(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
k_mutex_lock(&session_mutex, K_FOREVER);
|
||||
|
||||
if (active_class_c_sessions == 0) {
|
||||
ret = lorawan_set_class(LORAWAN_CLASS_C);
|
||||
if (ret == 0) {
|
||||
LOG_DBG("Switched to class C");
|
||||
active_class_c_sessions++;
|
||||
ret = active_class_c_sessions;
|
||||
}
|
||||
} else {
|
||||
active_class_c_sessions++;
|
||||
ret = active_class_c_sessions;
|
||||
}
|
||||
|
||||
k_mutex_unlock(&session_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lorawan_services_class_c_stop(void)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
k_mutex_lock(&session_mutex, K_FOREVER);
|
||||
|
||||
if (active_class_c_sessions == 1) {
|
||||
ret = lorawan_set_class(LORAWAN_CLASS_A);
|
||||
if (ret == 0) {
|
||||
LOG_DBG("Reverted to class A");
|
||||
active_class_c_sessions--;
|
||||
}
|
||||
} else if (active_class_c_sessions > 1) {
|
||||
active_class_c_sessions--;
|
||||
ret = active_class_c_sessions;
|
||||
}
|
||||
|
||||
k_mutex_unlock(&session_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lorawan_services_class_c_active(void)
|
||||
{
|
||||
return active_class_c_sessions;
|
||||
}
|
||||
|
||||
static int lorawan_services_init(void)
|
||||
{
|
||||
|
||||
|
|
@ -173,6 +227,8 @@ static int lorawan_services_init(void)
|
|||
|
||||
k_work_init_delayable(&uplink_work, uplink_handler);
|
||||
|
||||
k_mutex_init(&session_mutex);
|
||||
|
||||
k_thread_name_set(&services_workq.thread, "lorawan_services");
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -58,4 +58,34 @@ int lorawan_services_schedule_uplink(uint8_t port, uint8_t *data, uint8_t len, u
|
|||
int lorawan_services_reschedule_work(struct k_work_delayable *dwork, k_timeout_t delay);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Start a class C session
|
||||
*
|
||||
* If there is already an ongoing class C session, only the internal counter of
|
||||
* active sessions is incremented.
|
||||
*
|
||||
* @returns Number of active sessions if successful or negative errno otherwise.
|
||||
*/
|
||||
int lorawan_services_class_c_start(void);
|
||||
|
||||
/**
|
||||
* @brief Stop class C session and revert to class A
|
||||
*
|
||||
* If there is more than one class C session ongoing, only the internal counter
|
||||
* of active sessions is decremented.
|
||||
*
|
||||
* @returns Number of active sessions if successful or negative errno otherwise.
|
||||
*/
|
||||
int lorawan_services_class_c_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Retrieve number of active sessions
|
||||
*
|
||||
* Can be used to determine if sessions are ongoing and avoid disturbing an
|
||||
* ongoing session by sending out unnecessary messages.
|
||||
*
|
||||
* @returns Number of active class C sessions.
|
||||
*/
|
||||
int lorawan_services_class_c_active(void);
|
||||
|
||||
#endif /* ZEPHYR_SUBSYS_LORAWAN_SERVICES_LORAWAN_SERVICES_H_ */
|
||||
|
|
|
|||
Loading…
Reference in a new issue