mirror of
https://github.com/zephyrproject-rtos/zephyr
synced 2025-09-16 05:31:57 +00:00
It is possible that the device driver API pointer is null. For example if the device driver returns an error, the device code will make the API pointer NULL so that the API would not be used. This can cause errors in networking code where we typically do not check the NULL value. Fixes #15003 Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
271 lines
6.2 KiB
C
271 lines
6.2 KiB
C
/*
|
|
* 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;
|
|
|
|
if (!radio) {
|
|
return 0;
|
|
}
|
|
|
|
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;
|
|
|
|
if (!radio) {
|
|
return -ENOENT;
|
|
}
|
|
|
|
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;
|
|
|
|
if (!radio) {
|
|
return -ENOENT;
|
|
}
|
|
|
|
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;
|
|
|
|
if (!radio) {
|
|
return -ENOENT;
|
|
}
|
|
|
|
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 *buf)
|
|
{
|
|
const struct ieee802154_radio_api *radio =
|
|
net_if_get_device(iface)->driver_api;
|
|
|
|
if (!radio) {
|
|
return -ENOENT;
|
|
}
|
|
|
|
return radio->tx(net_if_get_device(iface), pkt, buf);
|
|
}
|
|
|
|
static inline int ieee802154_start(struct net_if *iface)
|
|
{
|
|
const struct ieee802154_radio_api *radio =
|
|
net_if_get_device(iface)->driver_api;
|
|
|
|
if (!radio) {
|
|
return -ENOENT;
|
|
}
|
|
|
|
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;
|
|
|
|
if (!radio) {
|
|
return -ENOENT;
|
|
}
|
|
|
|
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 && (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 && (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 && (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 && (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 && (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 && (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 && (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) {
|
|
return false;
|
|
}
|
|
|
|
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__ */
|