void zb_start_sniffer(zb_uint8_t channel) { /* Received channel is in range of supported ZB channels*/ if (channel >= ZB_TRANSCEIVER_START_CHANNEL_NUMBER && channel <= ZB_TRANSCEIVER_MAX_CHANNEL_NUMBER) { /* Flush output buffer to prevent old chanel's packets appearance in the output of a new capture */ bufFlush(&rbTxBuf); ZB_TRANSCEIVER_SET_CHANNEL(channel); ISFLUSHRX(); ISRXON(); #ifndef ZB_SNIFFER_USB_TRACE ZB_SET_SERIAL_TRANSMIT_FLAG(); ZB_ENABLE_SERIAL_INTER(); #endif } }
/* this is a universal routine for ed/active/orphan scans */ void zb_mlme_scan_step(zb_uint8_t param) { zb_uint8_t channel_number; zb_mlme_scan_params_t *scan_params; zb_ret_t ret = RET_OK; zb_uint16_t timeout; zb_uint32_t *unscanned_channels; TRACE_MSG(TRACE_MAC1, ">> zb_mlme_scan_step", (FMT__0)); ZVUNUSED(param); channel_number = ZB_MAC_START_CHANNEL_NUMBER; scan_params = ZB_GET_BUF_PARAM(MAC_CTX().pending_buf, zb_mlme_scan_params_t); /* Table 2.80 Fields of the Mgmt_NWK_Disc_req Command (the other scans requests are using the same parameters A value used to calculate the length of time to spend scanning each channel. The time spent scanning each channel is (aBaseSuperframeDuration * (2^n + 1)) symbols, where n is the value of the ScanDuration parameter. */ timeout = (1l << scan_params->scan_duration) + 1; MAC_CTX().mlme_scan_in_progress = 1; unscanned_channels = &MAC_CTX().unscanned_channels; for (;channel_number < ZB_MAC_START_CHANNEL_NUMBER + ZB_MAC_MAX_CHANNEL_NUMBER;channel_number++) { if (*unscanned_channels & 1l<<channel_number) { TRACE_MSG(TRACE_MAC2, "set channel %hd", (FMT__H, channel_number)); ZB_TRANSCEIVER_SET_CHANNEL(channel_number); *unscanned_channels &=~(1l<<channel_number); if (scan_params->scan_type == ACTIVE_SCAN) { ret = zb_beacon_request_command(); if (ret == RET_OK) { /* check beacon request TX status */ /* There's nothing to do during active scan, so, synchronous */ ret = zb_check_cmd_tx_status(); } } ZB_SCHEDULE_ALARM_CANCEL(zb_mlme_scan_step, 0); ret = ZB_SCHEDULE_ALARM(zb_mlme_scan_step, 0, timeout); break; } } if (channel_number == (ZB_MAC_START_CHANNEL_NUMBER + ZB_MAC_MAX_CHANNEL_NUMBER)) { zb_mac_scan_confirm_t *scan_confirm; /* There's no need to restore channel after active or orphan scan, because we will choose new channel, according to scan results. */ /* ZB_TRANSCEIVER_SET_CHANNEL(MAC_CTX().rt_ctx.ed_scan.save_channel);*/ scan_confirm = ZB_GET_BUF_PARAM(MAC_CTX().pending_buf, zb_mac_scan_confirm_t); TRACE_MSG(TRACE_MAC3, "beacon found %hd", (FMT__H, MAC_CTX().rt_ctx.active_scan.beacon_found)); if (scan_params->scan_type == ED_SCAN || MAC_CTX().rt_ctx.active_scan.beacon_found || MAC_CTX().rt_ctx.orphan_scan.got_realignment) { scan_confirm->status = MAC_SUCCESS; /* Q: do we really need to zero here? What about got_realignment? * * A: I think yes, because it is the only indication * for NO_BEACON status, that will not affect ED or ORPHAN scans. ED just * doesn't need any packets, and ORPHAN needs a realignment command that * is processed in appropriate function */ MAC_CTX().rt_ctx.active_scan.beacon_found = 0; } else { scan_confirm->status = MAC_NO_BEACON; } #ifdef ZB_MAC_TESTING_MODE { scan_confirm->result_list_size = desc_count; } #endif scan_confirm->scan_type = scan_params->scan_type; MAC_CTX().mlme_scan_in_progress = 0; ZB_SCHEDULE_CALLBACK(zb_mlme_scan_confirm, ZB_REF_FROM_BUF(MAC_CTX().pending_buf)); } TRACE_MSG(TRACE_MAC1, "<< zb_mlme_scan_step", (FMT__0)); }
zb_ret_t zb_read_formdesc_data() { zb_uint8_t read_bytes = 0; zb_uint8_t buf[8]; zb_ieee_addr_t parent_addr; zb_uint16_t s_parent_addr; read_bytes = ZB_CONFIG_SIZE; /* Stack profile */ read_bytes+=zb_read_nvram(ZB_CONFIG_PAGE + read_bytes, buf, sizeof(zb_uint8_t)); /* Parent's long addr */ read_bytes+=zb_read_nvram(ZB_CONFIG_PAGE + read_bytes, buf, sizeof(zb_ieee_addr_t)); /* this can be replaced by memcmp, but it will cost more code space*/ if ((buf[0]&buf[1]&buf[2]&buf[3]&buf[4]&buf[5]&buf[6]&buf[7])!=0xFF) { zb_neighbor_tbl_ent_t *nbt; ZB_IEEE_ADDR_COPY(parent_addr, buf); /* channel mask */ read_bytes+=zb_read_nvram(ZB_CONFIG_PAGE + read_bytes, buf, sizeof(zb_uint32_t)); ZB_AIB().aps_channel_mask = *(zb_uint32_t*)buf; /* Parent's short address */ read_bytes+=zb_read_nvram(ZB_CONFIG_PAGE + read_bytes, buf, sizeof(zb_uint16_t)); s_parent_addr = *(zb_uint16_t*)buf; /*we have long and short parent's address, so we can update neighbour table now */ zb_address_update(parent_addr, s_parent_addr,ZB_FALSE, &ZG->nwk.handle.parent); zb_nwk_neighbor_get(ZG->nwk.handle.parent, ZB_TRUE, &nbt); nbt->relationship = ZB_NWK_RELATIONSHIP_PARENT; nbt->device_type = ZB_NWK_DEVICE_TYPE_COORDINATOR; nbt->rx_on_when_idle = ZB_TRUE; nbt->addr_ref = ZG->nwk.handle.parent; /* Device depth */ read_bytes+=zb_read_nvram(ZB_CONFIG_PAGE + read_bytes, buf, sizeof(zb_uint8_t)); ZB_NIB_DEPTH() = buf[0]; /* Short PanID */ read_bytes+=zb_read_nvram(ZB_CONFIG_PAGE + read_bytes, buf, sizeof(zb_uint16_t)); MAC_PIB().mac_pan_id = *(zb_uint16_t*)buf; ZB_UPDATE_PAN_ID(); /* Extended PanID */ read_bytes+=zb_read_nvram(ZB_CONFIG_PAGE + read_bytes, buf, sizeof(zb_ext_pan_id_t)); ZB_IEEE_ADDR_COPY(ZG->nwk.nib.extended_pan_id, buf); /* Short address */ read_bytes+=zb_read_nvram(ZB_CONFIG_PAGE + read_bytes, buf, sizeof(zb_uint16_t)); MAC_PIB().mac_short_address = *(zb_uint16_t *)buf; ZB_UPDATE_SHORT_ADDR(); /* define to pass bv-31, it contradicts specification, so this hack only for test*/ #ifdef TP_PRO_BV_31 { zb_uint8_t channel_number; /*We're joined already */ ZG->nwk.handle.joined = 1; for(channel_number = ZB_MAC_START_CHANNEL_NUMBER; channel_number <= ZB_MAC_MAX_CHANNEL_NUMBER; channel_number++) { /* check channel mask */ if (ZB_DEFAULT_APS_CHANNEL_MASK & (1l << channel_number)) { ZB_TRANSCEIVER_SET_CHANNEL(channel_number); break; } } ZB_AIB_APS_COUNTER() = 0xF0; } #endif } return RET_OK; }