static int _init(netdev2_t *netdev) { cc2538_rf_t *dev = (cc2538_rf_t *) netdev; _dev = netdev; uint16_t pan = cc2538_get_pan(); uint16_t chan = cc2538_get_chan(); uint16_t addr_short = cc2538_get_addr_short(); uint64_t addr_long = cc2538_get_addr_long(); /* Initialise netdev2_ieee802154_t struct */ netdev2_ieee802154_set((netdev2_ieee802154_t *)netdev, NETOPT_NID, &pan, sizeof(pan)); netdev2_ieee802154_set((netdev2_ieee802154_t *)netdev, NETOPT_CHANNEL, &chan, sizeof(chan)); netdev2_ieee802154_set((netdev2_ieee802154_t *)netdev, NETOPT_ADDRESS, &addr_short, sizeof(addr_short)); netdev2_ieee802154_set((netdev2_ieee802154_t *)netdev, NETOPT_ADDRESS_LONG, &addr_long, sizeof(addr_long)); cc2538_set_state(dev, NETOPT_STATE_IDLE); /* set default protocol */ #ifdef MODULE_GNRC_SIXLOWPAN dev->netdev.proto = GNRC_NETTYPE_SIXLOWPAN; #elif MODULE_GNRC dev->netdev.proto = GNRC_NETTYPE_UNDEF; #endif #ifdef MODULE_NETSTATS_L2 memset(&netdev->stats, 0, sizeof(netstats_t)); #endif return 0; }
static int _set(netdev2_t *netdev, netopt_t opt, void *val, size_t len) { at86rf2xx_t *dev = (at86rf2xx_t *) netdev; uint8_t old_state = at86rf2xx_get_status(dev); int res = -ENOTSUP; if (dev == NULL) { return -ENODEV; } /* temporarily wake up if sleeping */ if (old_state == AT86RF2XX_STATE_SLEEP) { at86rf2xx_assert_awake(dev); } switch (opt) { case NETOPT_ADDRESS: if (len > sizeof(uint16_t)) { res = -EOVERFLOW; } else { at86rf2xx_set_addr_short(dev, *((uint16_t *)val)); /* don't set res to set netdev2_ieee802154_t::short_addr */ } break; case NETOPT_ADDRESS_LONG: if (len > sizeof(uint64_t)) { res = -EOVERFLOW; } else { at86rf2xx_set_addr_long(dev, *((uint64_t *)val)); /* don't set res to set netdev2_ieee802154_t::long_addr */ } break; case NETOPT_NID: if (len > sizeof(uint16_t)) { res = -EOVERFLOW; } else { at86rf2xx_set_pan(dev, *((uint16_t *)val)); /* don't set res to set netdev2_ieee802154_t::pan */ } break; case NETOPT_CHANNEL: if (len != sizeof(uint16_t)) { res = -EINVAL; } else { uint8_t chan = ((uint8_t *)val)[0]; if (chan < AT86RF2XX_MIN_CHANNEL || chan > AT86RF2XX_MAX_CHANNEL) { res = -EINVAL; break; } at86rf2xx_set_chan(dev, chan); /* don't set res to set netdev2_ieee802154_t::chan */ } break; case NETOPT_CHANNEL_PAGE: if (len != sizeof(uint16_t)) { res = -EINVAL; } else { uint8_t page = ((uint8_t *)val)[0]; #ifdef MODULE_AT86RF212B if ((page != 0) && (page != 2)) { res = -EINVAL; } else { at86rf2xx_set_page(dev, page); res = sizeof(uint16_t); } #else /* rf23x only supports page 0, no need to configure anything in the driver. */ if (page != 0) { res = -EINVAL; } else { res = sizeof(uint16_t); } #endif } break; case NETOPT_TX_POWER: if (len > sizeof(int16_t)) { res = -EOVERFLOW; } else { at86rf2xx_set_txpower(dev, *((int16_t *)val)); res = sizeof(uint16_t); } break; case NETOPT_STATE: if (len > sizeof(netopt_state_t)) { res = -EOVERFLOW; } else { res = _set_state(dev, *((netopt_state_t *)val)); } break; case NETOPT_AUTOACK: at86rf2xx_set_option(dev, AT86RF2XX_OPT_AUTOACK, ((bool *)val)[0]); /* don't set res to set netdev2_ieee802154_t::flags */ break; case NETOPT_RETRANS: if (len > sizeof(uint8_t)) { res = -EOVERFLOW; } else { at86rf2xx_set_max_retries(dev, *((uint8_t *)val)); res = sizeof(uint8_t); } break; case NETOPT_PRELOADING: at86rf2xx_set_option(dev, AT86RF2XX_OPT_PRELOADING, ((bool *)val)[0]); res = sizeof(netopt_enable_t); break; case NETOPT_PROMISCUOUSMODE: at86rf2xx_set_option(dev, AT86RF2XX_OPT_PROMISCUOUS, ((bool *)val)[0]); res = sizeof(netopt_enable_t); break; case NETOPT_RX_START_IRQ: at86rf2xx_set_option(dev, AT86RF2XX_OPT_TELL_RX_START, ((bool *)val)[0]); res = sizeof(netopt_enable_t); break; case NETOPT_RX_END_IRQ: at86rf2xx_set_option(dev, AT86RF2XX_OPT_TELL_RX_END, ((bool *)val)[0]); res = sizeof(netopt_enable_t); break; case NETOPT_TX_START_IRQ: at86rf2xx_set_option(dev, AT86RF2XX_OPT_TELL_TX_START, ((bool *)val)[0]); res = sizeof(netopt_enable_t); break; case NETOPT_TX_END_IRQ: at86rf2xx_set_option(dev, AT86RF2XX_OPT_TELL_TX_END, ((bool *)val)[0]); res = sizeof(netopt_enable_t); break; case NETOPT_CSMA: at86rf2xx_set_option(dev, AT86RF2XX_OPT_CSMA, ((bool *)val)[0]); res = sizeof(netopt_enable_t); break; case NETOPT_CSMA_RETRIES: if ((len > sizeof(uint8_t)) || (*((uint8_t *)val) > 5)) { res = -EOVERFLOW; } else if (dev->netdev.flags & AT86RF2XX_OPT_CSMA) { /* only set if CSMA is enabled */ at86rf2xx_set_csma_max_retries(dev, *((uint8_t *)val)); res = sizeof(uint8_t); } break; case NETOPT_CCA_THRESHOLD: if (len > sizeof(int8_t)) { res = -EOVERFLOW; } else { at86rf2xx_set_cca_threshold(dev, *((int8_t *)val)); res = sizeof(int8_t); } break; default: break; } /* go back to sleep if were sleeping and state hasn't been changed */ if ((old_state == AT86RF2XX_STATE_SLEEP) && (opt != NETOPT_STATE)) { at86rf2xx_set_state(dev, AT86RF2XX_STATE_SLEEP); } if (res == -ENOTSUP) { res = netdev2_ieee802154_set((netdev2_ieee802154_t *)netdev, opt, val, len); } return res; }
static int _set(netdev2_t *netdev, netopt_t opt, void *value, size_t value_len) { cc2538_rf_t *dev = (cc2538_rf_t *)netdev; int res = -ENOTSUP; if (dev == NULL) { return -ENODEV; } switch (opt) { case NETOPT_ADDRESS: if (value_len > sizeof(uint16_t)) { res = -EOVERFLOW; } else { cc2538_set_addr_short(*((uint16_t*)value)); } break; case NETOPT_ADDRESS_LONG: if (value_len > sizeof(uint64_t)) { res = -EOVERFLOW; } else { cc2538_set_addr_long(*((uint64_t*)value)); } break; case NETOPT_AUTOACK: RFCORE->XREG_FRMCTRL0bits.AUTOACK = ((bool *)value)[0]; res = sizeof(netopt_enable_t); break; case NETOPT_CHANNEL: if (value_len != sizeof(uint16_t)) { res = -EINVAL; } else { uint8_t chan = ((uint8_t *)value)[0]; if (chan < IEEE802154_CHANNEL_MIN || chan > IEEE802154_CHANNEL_MAX) { res = -EINVAL; } else { cc2538_set_chan(chan); } } break; case NETOPT_CHANNEL_PAGE: /* This tranceiver only supports page 0 */ if (value_len != sizeof(uint16_t) || *((uint16_t *)value) != 0 ) { res = -EINVAL; } else { res = sizeof(uint16_t); } break; case NETOPT_IS_WIRED: return -ENOTSUP; case NETOPT_NID: if (value_len > sizeof(uint16_t)) { res = -EOVERFLOW; } else { cc2538_set_pan(*((uint16_t *)value)); } break; case NETOPT_PROMISCUOUSMODE: cc2538_set_monitor(((bool *)value)[0]); res = sizeof(netopt_enable_t); break; case NETOPT_STATE: if (value_len > sizeof(netopt_state_t)) { return -EOVERFLOW; } cc2538_set_state(dev, *((netopt_state_t *)value)); res = sizeof(netopt_state_t); break; case NETOPT_TX_POWER: if (value_len > sizeof(int16_t)) { return -EOVERFLOW; } cc2538_set_tx_power(*((int16_t *)value)); res = sizeof(uint16_t); break; default: break; } if (res == -ENOTSUP) { res = netdev2_ieee802154_set((netdev2_ieee802154_t *)netdev, opt, value, value_len); } return res; }
static int _set(netdev2_t *netdev, netopt_t opt, void *val, size_t val_len) { if (netdev == NULL) { return -ENODEV; } cc2420_t *dev = (cc2420_t *)netdev; int ext = netdev2_ieee802154_set(&dev->netdev, opt, val, val_len); switch (opt) { case NETOPT_ADDRESS: assert(val_len == 2); cc2420_set_addr_short(dev, (uint8_t *)val); return 2; case NETOPT_ADDRESS_LONG: assert(val_len == 8); cc2420_set_addr_long(dev, (uint8_t *)val); return 8; case NETOPT_NID: assert(val_len == sizeof(uint16_t)); cc2420_set_pan(dev, to_u16(val)); return sizeof(uint16_t); case NETOPT_CHANNEL: assert(val_len == sizeof(uint16_t)); return cc2420_set_chan(dev, to_u16(val)); case NETOPT_TX_POWER: assert(val_len == sizeof(int16_t)); cc2420_set_txpower(dev, to_i16(val)); return sizeof(int16_t); case NETOPT_STATE: assert(val_len == sizeof(netopt_state_t)); return cc2420_set_state(dev, *((netopt_state_t *)val)); case NETOPT_AUTOACK: return cc2420_set_option(dev, CC2420_OPT_AUTOACK, to_bool(val)); case NETOPT_CSMA: return cc2420_set_option(dev, CC2420_OPT_CSMA, to_bool(val)); case NETOPT_PRELOADING: return cc2420_set_option(dev, CC2420_OPT_PRELOADING, to_bool(val)); case NETOPT_PROMISCUOUSMODE: return cc2420_set_option(dev, CC2420_OPT_PROMISCUOUS, to_bool(val)); case NETOPT_RX_START_IRQ: return cc2420_set_option(dev, CC2420_OPT_TELL_RX_START, to_bool(val)); case NETOPT_RX_END_IRQ: return cc2420_set_option(dev, CC2420_OPT_TELL_RX_END, to_bool(val)); case NETOPT_TX_START_IRQ: return cc2420_set_option(dev, CC2420_OPT_TELL_TX_START, to_bool(val)); case NETOPT_TX_END_IRQ: return cc2420_set_option(dev, CC2420_OPT_TELL_TX_END, to_bool(val)); default: return ext; } return 0; }