diff --git a/sys/include/net/ieee802154.h b/sys/include/net/ieee802154.h index 86ba001199..7994e839bd 100644 --- a/sys/include/net/ieee802154.h +++ b/sys/include/net/ieee802154.h @@ -396,6 +396,25 @@ int ieee802154_get_src(const uint8_t *mhr, uint8_t *src, le_uint16_t *src_pan); */ int ieee802154_get_dst(const uint8_t *mhr, uint8_t *dst, le_uint16_t *dst_pan); +/** + * @brief Check whether a frame pass the IEEE 802.15.4 frame filter. + * + * A frame passes the frame filter only if: + * - The PAN ID matches the PAN ID of the frame filter or the broadcast PAN ID + * - Either the Short or Extended Address matches the frame filter OR the + * Short Address is the broadcast address. + * + * @param[in] mhr MAC header (PSDU) + * @param[in] pan PAN ID of the frame filter. + * @param[in] short_addr Short Address of the frame filter. + * @param[in] ext_addr Extended Address of the frame filter. + * + * @return 0 if frame passes the frame filter. + * @return 1 if frame doesn't pass the frame filter. + */ +int ieee802154_dst_filter(const uint8_t *mhr, uint16_t pan, + network_uint16_t short_addr, const eui64_t *ext_addr); + /** * @brief Gets sequence number from MAC header. * diff --git a/sys/net/link_layer/ieee802154/ieee802154.c b/sys/net/link_layer/ieee802154/ieee802154.c index ae687703d6..d466ae8dfc 100644 --- a/sys/net/link_layer/ieee802154/ieee802154.c +++ b/sys/net/link_layer/ieee802154/ieee802154.c @@ -241,4 +241,31 @@ int ieee802154_get_dst(const uint8_t *mhr, uint8_t *dst, le_uint16_t *dst_pan) return 0; } +int ieee802154_dst_filter(const uint8_t *mhr, uint16_t pan, + network_uint16_t short_addr, const eui64_t *ext_addr) +{ + uint8_t dst_addr[IEEE802154_LONG_ADDRESS_LEN]; + le_uint16_t dst_pan; + uint8_t pan_bcast[] = IEEE802154_PANID_BCAST; + + int addr_len = ieee802154_get_dst(mhr, dst_addr, &dst_pan); + + /* filter PAN ID */ + if ((memcmp(pan_bcast, dst_pan.u8, 2) != 0) && + (memcmp(&pan, dst_pan.u8, 2) != 0)) { + return 1; + } + + /* check destination address */ + if (((addr_len == IEEE802154_SHORT_ADDRESS_LEN) && + (memcmp(&short_addr.u8, dst_addr, addr_len) == 0 || + memcmp(ieee802154_addr_bcast, dst_addr, addr_len) == 0)) || + ((addr_len == IEEE802154_LONG_ADDRESS_LEN) && + (memcmp(ext_addr->uint8, dst_addr, addr_len) == 0))) { + return 0; + } + + return 1; +} + /** @} */