Esempio n. 1
0
bool zigbee_init(uint64_t ieee_address) {
    /* Set local variables to initial value. */
    ENTER_CRITICAL_REGION();
    bool init_status = false;
    
    ndi = NULL;
    nji = NULL;
    nli = NULL;
    LEAVE_CRITICAL_REGION();
    
    /* Reset internal variables. */
    zigbee_nib_init();
    zigbee_neighbor_table_init();
    
    if(true != ieee802_15_4_init(ieee_address)) {
    } else {
        /* Initialize all necessary callbacks from the IEEE 802.15.4 MAC. */
        ieee802_15_4_set_mcps_data_indication(mac_data_indication_callback);
        ieee802_15_4_set_mlme_associate_indication(mac_associate_indication_callback);
        ieee802_15_4_set_mlme_disassociate_indication(mac_disassociate_indication_callback);
        ieee802_15_4_set_mlme_orphan_indication(mac_orphan_indication_callback);
        ieee802_15_4_set_mlme_comm_status_indication(mac_comm_status_indication_callback);

        ZIGBEE_NWK_SET_STATE(NWK_IDLE);
        init_status = true;
    } // END: if(ieee802_15_4_init(ieee_address)) ...
    
    return init_status;
}
static void mac_associate_confim_callback(mlme_associate_conf_t *mac) {
    /* Build NLME_JOIN.confirm. */
    nlme_join_conf_t *njc = nwk_param.join.njc;
    memcpy((void *)(&(njc->ShortAddress)), (void *)(&(mac->AssocShortAddress)), sizeof(uint16_t));
    memcpy((void *)(&(njc->PANId)), (void *)(&IEEE802_15_4_GET_PAN_ID()), sizeof(uint16_t));
    njc->Status = mac->status;
    
    /* Set state to NWK_JOINED if the association process was successful. */
    if (ASSOCIATION_SUCCESSFUL == (mac->status)) {
        NWK_NIB_SET_NWK_ADDRESS(mac->AssocShortAddress);
        NWK_NIB_SET_ADDRESS_INCREMENT(0);
        
        uint8_t depth = zigbee_neighbor_table_find_depth(IEEE802_15_4_GET_COORD_SHORT_ADDRESS(), \
                                                         IEEE802_15_4_GET_SHORT_ADDRESS());
        
        uint16_t c_skip = zigbee_nib_c_skip(depth - 1);
        NWK_NIB_SET_PARENT_ADDRESS_INCREMENT(c_skip); 
        
        ZIGBEE_NWK_SET_STATE(NWK_JOINED);
        NWK_NIB_SET_NODE_ROLE(ZIGBEE_TYPE_DEVICE);
    } else {
        /* Remove this node from the Neighbor Table. */
        zigbee_neighbor_table_item_t *nb = zigbee_neighbor_table_find(nwk_param.join.parent_address);
        if (NULL != nb) { zigbee_neighbor_table_delete(nb); }
    }
    
    /* Execute callback. */
    nwk_param.join.nlme_callback_join_confirm(njc);
}
void zigbee_network_discovery_confirm_do_callback(void *ndc) {
    /* Cast the ndc to a NLME-NETWORK-DISCOVERY.confirm message. */
    
    ZIGBEE_NWK_SET_STATE(NWK_IDLE);
    
    /* Execute the event handler. */
    nwk_param.discovery.nlme_callback_discovery_confirm((nlme_network_discovery_conf_t *)ndc);
}
bool zigbee_network_discovery_request(nlme_network_discovery_req_t *ndr) {
    /* Verify that the device is in IDLE state. */
    if (NWK_IDLE != ZIGBEE_NWK_GET_STATE()) {
        return false;
    }
    
    /* Perform sanity check on function parameters. */
    if (NULL == ndr) {
        return false;
    }
    
    if (NULL == (ndr->nlme_callback_discovery_confirm)) {
        return false;
    }
    
    /* Store NWK parameters. */
    nwk_param.discovery.nlme_callback_discovery_confirm = ndr->nlme_callback_discovery_confirm;
    nwk_param.discovery.ndc = &(ndr->ndc);
    
    /* Build and send MLME_SCAN.request. */
    mlme_scan_req_t *msr = &(ndr->msr);
    msr->ScanType = MLME_SCAN_TYPE_ACTIVE;
    msr->ScanChannel = ndr->ChannelToScan;
    msr->ScanDuration = ndr->ScanDuration; 
    msr->mlme_scan_confirm = mac_scan_confirm_callback;
    
    /* Set the MLME_BEACON_NOTIFY.indication callback. */
    ieee802_15_4_set_mlme_beacon_notify_indication(mac_beacon_notify_callback);
    
    /* Issue MLME_SCAN.request primitive. */
    bool discovery_status = false;
    if (true != ieee802_15_4_scan_request(msr)) {
    } else {
        ZIGBEE_NWK_SET_STATE(NWK_BUSY_DISCOVERING);
        discovery_status = true;
    }
    
    return discovery_status;
}
bool zigbee_start_router_request(void) {
    /* The device must be joined before it can be started as a router. */
    if (NWK_JOINED != ZIGBEE_NWK_GET_STATE()) { return false; }
    
    /* The device is joined to a coordinator or another router. */
    bool start_router_status = false;
    if (MAC_SUCCESS != ieee802_15_4_start_request(IEEE802_15_4_GET_PAN_ID(), IEEE802_15_4_GET_CHANNEL(), true)) {    
    } else if (MAC_SUCCESS != ieee802_15_4_rx_enable()) {
    } else {
        
        /* Calculate the router's depth in the network and set up the Cskip algorithm. */
        uint8_t depth = zigbee_neighbor_table_find_depth(IEEE802_15_4_GET_COORD_SHORT_ADDRESS(), \
                                                         IEEE802_15_4_GET_SHORT_ADDRESS());
        
        uint16_t c_skip = zigbee_nib_c_skip(depth);
        NWK_NIB_SET_ADDRESS_INCREMENT(c_skip);
         
        ZIGBEE_NWK_SET_STATE(NWK_STARTED);
        NWK_NIB_SET_NODE_ROLE(ZIGBEE_TYPE_COORD);
        start_router_status = true;
    }
    
    return start_router_status; 
}