Exemplo n.º 1
0
/*
 * Select the network to join. This function is called after a network discovery
 * and will select the network from the list of scan descriptors. If the
 * use_ext_pan_id flag is set in the APS Info Base, then it will search for that
 * pan ID and join that network.
 *
 * Otherwise, it looks for the following criteria in evaluating a network to join:
 * - The scan descriptor sender is a potential parent
 * - It has capacity
 * - It is permitting joining
 * - The protocol version matches this device's version
 * - The Zigbee stack profile matches this device's profile (ie: Zigbee vs Zigbee Pro)
 */
static bool zdo_nwk_select()
{
	aps_aib_t *aib = aps_aib_get();
	nwk_nib_t *nib = nwk_nib_get();
	zdo_pcb_t *pcb = zdo_pcb_get();
	nwk_join_req_t args;
	mem_ptr_t *mem_ptr;
	bool capacity           = false;
	bool permit_join        = false;
	bool prot_ver_match     = false;
	bool stack_prof_match   = false;

	/*
	 * currently, we will join the first network we find that
	 * fits our join criteria
	 */
	for (mem_ptr = pcb->descr_list; mem_ptr != NULL; mem_ptr = mem_ptr->next)
	{
		/*
		 * if we specify that we need to join a particular pan,
		 * then we need to find a node descr that matches the
		 * ext pan id. otherwise, if there's no such limitation,
		 * then just go on ahead.
		 */
		if ((!aib->use_ext_pan_id) || (aib->use_ext_pan_id == SCAN_ENTRY(mem_ptr)->ext_pan_id))
		{
			if ((aib->use_desig_parent &&
				(aib->desig_parent == SCAN_ENTRY(mem_ptr)->coord_addr.short_addr)) ||
			    !aib->use_desig_parent)
			{
				capacity = (nib->dev_type == NWK_ROUTER) ?
						(SCAN_ENTRY(mem_ptr)->rtr_cap >0) :
						(SCAN_ENTRY(mem_ptr)->end_dev_cap > 0);
				permit_join =
					(SCAN_ENTRY(mem_ptr)->superfrm_spec & MAC_ASSOC_PERMIT_MASK) >>
					       MAC_ASSOC_PERMIT_OFF;
				prot_ver_match =
					(SCAN_ENTRY(mem_ptr)->prot_ver == ZIGBEE_PROTOCOL_VERSION);
				stack_prof_match =
					(SCAN_ENTRY(mem_ptr)->stack_profile == ZIGBEE_STACK_PROFILE);

				if (SCAN_ENTRY(mem_ptr)->pot_parent &&
				    capacity && permit_join &&
				    prot_ver_match &&
				    stack_prof_match)
				{
					args.desc        = pcb->curr_descr = mem_ptr;
					args.ext_pan_id  = SCAN_ENTRY(mem_ptr)->ext_pan_id;
					args.join_as_rtr = (nib->dev_type == NWK_ROUTER);
					args.rejoin_nwk  = (aib->use_ext_pan_id == 0) ?
							   NWK_JOIN_NORMAL :
							   NWK_JOIN_REJOIN;
					nwk_join_req(&args);
					return true;
				}
			}
		}
	}
Exemplo n.º 2
0
void mac_scan_descr_add(address_t *src_addr, U16 src_pan_id, U8 channel, U16 superframe_spec)
{
    mem_ptr_t *mem_ptr;

    if ((mem_ptr = mac_scan_alloc()) != NULL)
    {
        memcpy(&SCAN_ENTRY(mem_ptr)->coord_addr, src_addr, sizeof(address_t));
        SCAN_ENTRY(mem_ptr)->superfrm_spec  = superframe_spec;
        SCAN_ENTRY(mem_ptr)->coord_pan_id   = src_pan_id;
        SCAN_ENTRY(mem_ptr)->channel        = channel;
    }
}
Exemplo n.º 3
0
/*
 * This function indicates that a beacon frame has arrived. We will then need to
 * parse the contents and add it to the pan descriptor. If the protocol ID
 * is incorrect, then we trash the descriptor by removing it from the list and
 * freeing it.
 */
void mac_beacon_notify_ind(buffer_t *buf, mem_ptr_t *mem_ptr)
{
	/* parse the beacon contents and add it to the descriptor */
	nwk_parse_beacon(buf, mem_ptr);

	/*
	 * if the protocol id is not for zigbee, then remove the
	 * descr from the scan list and free the block of memory.
	 */
	if (SCAN_ENTRY(mem_ptr)->prot_id != ZIGBEE_PROTOCOL_ID)
		mac_scan_descr_free(mem_ptr);
}
Exemplo n.º 4
0
mem_ptr_t *mac_scan_descr_find_pan(U16 pan_id)
{
    mem_ptr_t *mem_ptr;

    for (mem_ptr = list_head(scan_list); mem_ptr != NULL; mem_ptr = mem_ptr->next)
    {
        if (SCAN_ENTRY(mem_ptr)->coord_pan_id == pan_id)
        {
            break;
        }
    }
    return mem_ptr;
}
Exemplo n.º 5
0
mem_ptr_t *mac_scan_descr_find_addr(address_t *addr)
{
    mem_ptr_t *mem_ptr;

    for (mem_ptr = list_head(scan_list); mem_ptr != NULL; mem_ptr = mem_ptr->next)
    {
        if (SCAN_ENTRY(mem_ptr)->coord_addr.mode == SHORT_ADDR)
        {
            if (SCAN_ENTRY(mem_ptr)->coord_addr.short_addr == addr->short_addr)
            {
                break;
            }
        }
        else if (SCAN_ENTRY(mem_ptr)->coord_addr.mode == LONG_ADDR)
        {
            if (SCAN_ENTRY(mem_ptr)->coord_addr.long_addr == addr->long_addr)
            {
                break;
            }
        }
    }
    return mem_ptr;
}