/*
 * Copyright (c) 2017 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @file
 * @brief IEEE 802.15.4 Management
 */

#ifndef __IEEE802154_UTILS_H__
#define __IEEE802154_UTILS_H__

#include <net/ieee802154_radio.h>

static inline
enum ieee802154_hw_caps ieee802154_get_hw_capabilities(struct net_if *iface)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	return radio->get_capabilities(net_if_get_device(iface));
}

static inline int ieee802154_cca(struct net_if *iface)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	return radio->cca(net_if_get_device(iface));
}

static inline int ieee802154_set_channel(struct net_if *iface, u16_t channel)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	return radio->set_channel(net_if_get_device(iface), channel);
}

static inline int ieee802154_set_tx_power(struct net_if *iface, s16_t dbm)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	return radio->set_txpower(net_if_get_device(iface), dbm);
}

static inline int ieee802154_tx(struct net_if *iface,
				struct net_pkt *pkt, struct net_buf *frag)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	return radio->tx(net_if_get_device(iface), pkt, frag);
}

static inline int ieee802154_start(struct net_if *iface)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	return radio->start(net_if_get_device(iface));
}

static inline int ieee802154_stop(struct net_if *iface)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	return radio->stop(net_if_get_device(iface));
}

static inline void ieee802154_filter_ieee_addr(struct net_if *iface,
					       u8_t *ieee_addr)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	if (radio->get_capabilities(net_if_get_device(iface)) &
	    IEEE802154_HW_FILTER) {
		struct ieee802154_filter filter;

		filter.ieee_addr = ieee_addr;

		if (radio->filter(net_if_get_device(iface), true,
				  IEEE802154_FILTER_TYPE_IEEE_ADDR,
				  &filter) != 0) {
			NET_WARN("Could not apply IEEE address filter");
		}
	}
}

static inline void ieee802154_filter_short_addr(struct net_if *iface,
						u16_t short_addr)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	if (radio->get_capabilities(net_if_get_device(iface)) &
	    IEEE802154_HW_FILTER) {
		struct ieee802154_filter filter;

		filter.short_addr = short_addr;

		if (radio->filter(net_if_get_device(iface), true,
				  IEEE802154_FILTER_TYPE_SHORT_ADDR,
				  &filter) != 0) {
			NET_WARN("Could not apply short address filter");
		}
	}
}

static inline void ieee802154_filter_pan_id(struct net_if *iface,
					    u16_t pan_id)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	if (radio->get_capabilities(net_if_get_device(iface)) &
	    IEEE802154_HW_FILTER) {
		struct ieee802154_filter filter;

		filter.pan_id = pan_id;

		if (radio->filter(net_if_get_device(iface), true,
				  IEEE802154_FILTER_TYPE_PAN_ID,
				  &filter) != 0) {
			NET_WARN("Could not apply PAN ID filter");
		}
	}
}

static inline void ieee802154_filter_src_ieee_addr(struct net_if *iface,
						   u8_t *ieee_addr)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	if (radio->get_capabilities(net_if_get_device(iface)) &
	    IEEE802154_HW_FILTER) {
		struct ieee802154_filter filter;

		filter.ieee_addr = ieee_addr;

		if (radio->filter(net_if_get_device(iface), true,
				  IEEE802154_FILTER_TYPE_SRC_IEEE_ADDR,
				  &filter) != 0) {
			NET_WARN("Could not apply SRC IEEE address filter");
		}
	}
}

static inline void ieee802154_filter_src_short_addr(struct net_if *iface,
						    u16_t short_addr)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	if (radio->get_capabilities(net_if_get_device(iface)) &
	    IEEE802154_HW_FILTER) {
		struct ieee802154_filter filter;

		filter.short_addr = short_addr;

		if (radio->filter(net_if_get_device(iface), true,
				  IEEE802154_FILTER_TYPE_SRC_SHORT_ADDR,
				  &filter) != 0) {
			NET_WARN("Could not apply SRC short address filter");
		}
	}
}

static inline void ieee802154_remove_src_ieee_addr(struct net_if *iface,
						   u8_t *ieee_addr)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	if (radio->get_capabilities(net_if_get_device(iface)) &
	    IEEE802154_HW_FILTER) {
		struct ieee802154_filter filter;

		filter.ieee_addr = ieee_addr;

		if (radio->filter(net_if_get_device(iface), false,
				  IEEE802154_FILTER_TYPE_SRC_IEEE_ADDR,
				  &filter) != 0) {
			NET_WARN("Could not remove SRC IEEE address filter");
		}
	}
}

static inline void ieee802154_remove_src_short_addr(struct net_if *iface,
						    u16_t short_addr)
{
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	if (radio->get_capabilities(net_if_get_device(iface)) &
	    IEEE802154_HW_FILTER) {
		struct ieee802154_filter filter;

		filter.short_addr = short_addr;

		if (radio->filter(net_if_get_device(iface), true,
				  IEEE802154_FILTER_TYPE_SRC_SHORT_ADDR,
				  &filter) != 0) {
			NET_WARN("Could not remove SRC short address filter");
		}
	}
}

static inline bool ieee802154_verify_channel(struct net_if *iface,
					     u16_t channel)
{
	if (channel == IEEE802154_NO_CHANNEL) {
		return false;
	}

#ifdef CONFIG_NET_L2_IEEE802154_SUB_GHZ
	const struct ieee802154_radio_api *radio =
		net_if_get_device(iface)->driver_api;

	if (radio->get_capabilities(net_if_get_device(iface)) &
	    IEEE802154_HW_SUB_GHZ) {
		if (channel >
		    radio->get_subg_channel_count(net_if_get_device(iface))) {
			return false;
		}
	}
#endif /* CONFIG_NET_L2_IEEE802154_SUB_GHZ */

	return true;
}

#endif /* __IEEE802154_UTILS_H__ */
