blob: 3d1d47883d8e8e77a2fba07f0913928f32809905 [file] [edit]
/*
* This file is part of the UWB stack for linux.
*
* Copyright (c) 2022 Qorvo US, Inc.
*
* This software is provided under the GNU General Public License, version 2
* (GPLv2), as well as under a Qorvo commercial license.
*
* You may choose to use this software under the terms of the GPLv2 License,
* version 2 ("GPLv2"), as published by the Free Software Foundation.
* You should have received a copy of the GPLv2 along with this program. If
* not, see <http://www.gnu.org/licenses/>.
*
* This program is distributed under the GPLv2 in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GPLv2 for more
* details.
*
* If you cannot meet the requirements of the GPLv2, you may not use this
* software for any purpose without first obtaining a commercial license from
* Qorvo. Please contact Qorvo to inquire about licensing terms.
*/
#include <linux/errno.h>
#include "fira_session_fsm_init.h"
#include "fira_session_fsm_idle.h"
#include "fira_session_fsm_active.h"
#include "fira_session.h"
#include "fira_access.h"
#include "fira_trace.h"
void fira_session_fsm_initialise(struct fira_local *local,
struct fira_session *session)
{
list_add(&session->entry, &local->inactive_sessions);
session->state = &fira_session_fsm_init;
WARN_ON(!session->state->enter);
session->state->enter(local, session);
}
void fira_session_fsm_uninit(struct fira_local *local,
struct fira_session *session)
{
if (session->state->leave)
session->state->leave(local, session);
trace_region_fira_session_fsm_change_state(
session, FIRA_SESSION_STATE_ID_DEINIT);
list_del(&session->entry);
}
void fira_session_fsm_change_state(
struct fira_local *local, struct fira_session *session,
const struct fira_session_fsm_state *new_state)
{
if (session->state->leave)
session->state->leave(local, session);
trace_region_fira_session_fsm_change_state(session, new_state->id);
session->state = new_state;
if (session->state->enter)
session->state->enter(local, session);
}
bool fira_session_is_active(const struct fira_session *session)
{
return session->state == &fira_session_fsm_active;
}
enum fira_session_state_id
fira_session_get_state_id(const struct fira_session *session)
{
return session->state->id;
}
int fira_session_fsm_check_parameters(const struct fira_session *session,
struct nlattr **attrs)
{
WARN_ON(!session->state->check_parameters);
return session->state->check_parameters(session, attrs);
}
void fira_session_fsm_parameters_updated(struct fira_local *local,
struct fira_session *session)
{
/* The handler is defined for all states. */
WARN_ON(!session->state->parameters_updated);
session->state->parameters_updated(local, session);
}
void fira_session_fsm_controlee_list_updated(struct fira_local *local,
struct fira_session *session)
{
if (session->state->controlee_list_updated)
session->state->controlee_list_updated(local, session);
}
int fira_session_fsm_start(struct fira_local *local,
struct fira_session *session,
const struct genl_info *info)
{
if (session->state->start)
return session->state->start(local, session, info);
return -EINVAL;
}
int fira_session_fsm_stop(struct fira_local *local,
struct fira_session *session)
{
if (session->state->stop)
return session->state->stop(local, session);
return 0;
}
int fira_session_fsm_get_demand(const struct fira_local *local,
const struct fira_session *session,
u32 next_timestamp_dtu, int max_duration_dtu,
struct fira_session_demand *session_demand)
{
/*
* fira_get_demand will not call this function without an
* active session.
*/
WARN_ON(!session->state->get_demand);
return session->state->get_demand(local, session, next_timestamp_dtu,
max_duration_dtu, session_demand);
}
struct mcps802154_access *
fira_session_fsm_get_access(struct fira_local *local,
struct fira_session *session,
const struct fira_session_demand *session_demand)
{
/*
* fira_get_access will not call this function without an
* active session.
*/
WARN_ON(!session->state->get_access);
return session->state->get_access(local, session, session_demand);
}
void fira_session_fsm_access_done(struct fira_local *local,
struct fira_session *session, bool error)
{
WARN_ON(!session->state->access_done);
return session->state->access_done(local, session, error);
}
void fira_session_fsm_check_missed_ranging(struct fira_local *local,
struct fira_session *session,
u32 timestamp_dtu)
{
WARN_ON(!session->state->check_missed_ranging);
return session->state->check_missed_ranging(local, session,
timestamp_dtu);
}