/** Reaction on incoming UPDATE-DEVICE Issue UPDATE-DEVICE.indication */ void zb_aps_in_update_device(zb_uint8_t param) { /* get source address from the nwk header and convert it to long address */ zb_apsme_update_device_pkt_t *pkt = (zb_apsme_update_device_pkt_t *)ZB_BUF_BEGIN(ZB_BUF_FROM_REF(param)); zb_apsme_update_device_ind_t *ind = ZB_GET_BUF_PARAM(ZB_BUF_FROM_REF(param), zb_apsme_update_device_ind_t); TRACE_MSG(TRACE_SECUR3, ">>zb_aps_in_update_device %d", (FMT__H, param)); { zb_uint16_t src_short_addr = ZB_GET_BUF_PARAM(ZB_BUF_FROM_REF(param), zb_apsde_data_indication_t)->src_addr; zb_address_ieee_by_short(src_short_addr, ind->src_address); } ZB_IEEE_ADDR_COPY(ind->device_address, pkt->device_address); ZB_LETOH16(&ind->device_short_address, &pkt->device_short_address); /* We have short and long addresses of the device UPDATE-DEVICE is * about. Remember it. */ { zb_address_ieee_ref_t ref; (void)zb_address_update(ind->device_address, ind->device_short_address, ZB_FALSE, &ref); } ind->status = pkt->status; ZB_SCHEDULE_CALLBACK(zb_apsme_update_device_indication, param); TRACE_MSG(TRACE_SECUR3, "<<zb_aps_in_update_device", (FMT__0)); }
MAIN() { ARGV_UNUSED; #ifndef KEIL if ( argc < 3 ) { printf("%s <read pipe path> <write pipe path>\n", argv[0]); return 0; } #endif #if defined ZB_NS_BUILD && defined ZB_SECURITY if ( argc > 3 && !strcmp(argv[3], "auth") ) { g_auth = 1; } #endif /* Init device, load IB values from nvram or set it to default */ #ifndef ZB8051 ZB_INIT("zdo_zed", argv[1], argv[2]); #else ZB_INIT("zdo_zed", "2", "2"); #endif /* set ieee addr */ ZB_IEEE_ADDR_COPY(ZB_PIB_EXTENDED_ADDRESS(), &g_ieee_addr); #ifndef ZB_NS_BUILD ZB_UPDATE_LONGMAC(); #endif #ifdef ZB_SECURITY /* turn security */ ZB_NIB_SECURITY_LEVEL() = g_auth ? 1 : 0; #endif /* become an ED */ ZB_NIB_DEVICE_TYPE() = ZB_NWK_DEVICE_TYPE_ED; ZB_PIB_RX_ON_WHEN_IDLE() = ZB_TRUE; if (zdo_dev_start() != RET_OK) { TRACE_MSG(TRACE_ERROR, "zdo_dev_start failed", (FMT__0)); } else { zdo_main_loop(); } TRACE_DEINIT(); MAIN_RETURN(0); }
/* 7.3.6 sends orphan notification command return RET_OK, RET_ERROR */ zb_ret_t zb_orphan_notification_command() { zb_ret_t ret; zb_uint8_t mhr_len; zb_uint8_t *ptr = NULL; zb_mac_mhr_t mhr; /* Orphan notification command 1. Fill MHR fields - set dst pan id = 0xffff - set dst addr = 0xffff 2. Fill FCF - set frame pending = 0, ack req = 0, security enabled = 0 - set dst addr mode to ZB_ADDR_16BIT_DEV_OR_BROADCAST - set src addr mode to ZB_ADDR_64BIT_DEV 3. Set command frame id = 0x07 (Beacon request) */ TRACE_MSG(TRACE_MAC2, ">>orphan_notif_cmd", (FMT__0)); mhr_len = zb_mac_calculate_mhr_length(ZB_ADDR_64BIT_DEV, ZB_ADDR_16BIT_DEV_OR_BROADCAST, 1); { zb_uint8_t packet_length = mhr_len + 1; ZB_BUF_INITIAL_ALLOC(MAC_CTX().operation_buf, packet_length, ptr); ZB_ASSERT(ptr); ZB_BZERO(ptr, packet_length); } /* TODO: optimize FC fill */ ZB_BZERO2(mhr.frame_control); ZB_FCF_SET_FRAME_TYPE(mhr.frame_control, MAC_FRAME_COMMAND); ZB_FCF_SET_DST_ADDRESSING_MODE(mhr.frame_control, ZB_ADDR_16BIT_DEV_OR_BROADCAST); ZB_FCF_SET_SRC_ADDRESSING_MODE(mhr.frame_control, ZB_ADDR_64BIT_DEV); ZB_FCF_SET_PANID_COMPRESSION_BIT(mhr.frame_control, 1); ZB_FCF_SET_FRAME_VERSION(mhr.frame_control, MAC_FRAME_VERSION); /* 7.2.1 General MAC frame format */ mhr.seq_number = ZB_MAC_DSN(); ZB_INC_MAC_DSN(); mhr.dst_pan_id = ZB_BROADCAST_PAN_ID; mhr.dst_addr.addr_short = ZB_MAC_SHORT_ADDR_NO_VALUE; ZB_IEEE_ADDR_COPY(mhr.src_addr.addr_long, ZB_PIB_EXTENDED_ADDRESS()); zb_mac_fill_mhr(ptr, &mhr); *(ptr + mhr_len) = MAC_CMD_ORPHAN_NOTIFICATION; MAC_ADD_FCS(MAC_CTX().operation_buf); ret = ZB_TRANS_SEND_COMMAND(mhr_len, MAC_CTX().operation_buf); TRACE_MSG(TRACE_MAC2, "<<orphan_notif_cmd %hd", (FMT__H, ret)); return ret; }
MAIN() { ARGV_UNUSED; #ifndef KEIL if ( argc < 3 ) { printf("%s <read pipe path> <write pipe path>\n", argv[0]); return 0; } #endif /* Init device, load IB values from nvram or set it to default */ #ifndef ZB8051 ZB_INIT("zdo_zed1_", argv[1], argv[2]); #else ZB_INIT("zdo_zed1_", "2", "2"); #endif /* set ieee addr */ ZB_IEEE_ADDR_COPY(ZB_PIB_EXTENDED_ADDRESS(), &g_ieee_addr); #ifndef ZB_NS_BUILD ZB_UPDATE_LONGMAC(); #endif #ifdef ZB_SECURITY /* turn off security */ ZB_NIB_SECURITY_LEVEL() = 0; #endif MAC_ADD_VISIBLE_LONG(g_zr_ieee_addr); MAC_ADD_INVISIBLE_SHORT(0); /* ignore beacons from ZC */ /* become an ED */ ZB_NIB_DEVICE_TYPE() = ZB_NWK_DEVICE_TYPE_ED; ZB_PIB_RX_ON_WHEN_IDLE() = ZB_FALSE; /* configure poll timer */ ZDO_CTX().conf_attr.nwk_indirect_poll_rate = 2*ZB_TIME_ONE_SECOND; if (zdo_dev_start() != RET_OK) { TRACE_MSG(TRACE_ERROR, "zdo_dev_start failed", (FMT__0)); } else { zdo_main_loop(); } TRACE_DEINIT(); MAIN_RETURN(0); }
MAIN() { ARGV_UNUSED; #ifndef KEIL if ( argc < 3 ) { printf("%s <read pipe path> <write pipe path>\n", argv[0]); return 0; } #endif /* Init device, load IB values from nvram or set it to default */ #ifndef ZB8051 ZB_INIT("zdo_zc", argv[1], argv[2]); #else ZB_INIT("zdo_zc", "1", "1"); #endif /* let's always be coordinator */ ZB_AIB().aps_designated_coordinator = 1; /* set ieee addr */ ZB_IEEE_ADDR_COPY(ZB_PIB_EXTENDED_ADDRESS(), &g_ieee_addr); #ifndef ZB_NS_BUILD ZB_UPDATE_LONGMAC(); #endif #ifdef ZB_SECURITY /* turn off security */ ZB_NIB_SECURITY_LEVEL() = 0; #endif /* accept only one child */ ZB_NWK().max_children = 3; /* configure join duration */ ZDO_CTX().conf_attr.permit_join_duration = 10; if ( zdo_dev_start() != RET_OK ) { TRACE_MSG(TRACE_ERROR, "zdo_dev_start failed", (FMT__0)); } else { zdo_main_loop(); } TRACE_DEINIT(); MAIN_RETURN(0); }
MAIN() { ARGV_UNUSED; #ifndef KEIL if ( argc < 3 ) { printf("%s <read pipe path> <write pipe path>\n", argv[0]); return 0; } #endif /* Init device, load IB values from nvram or set it to default */ #ifndef ZB8051 ZB_INIT("zdo_zr1", argv[1], argv[2]); #else ZB_INIT("zdo_zr1", "2", "2"); #endif /* set ieee addr */ ZB_IEEE_ADDR_COPY(ZB_PIB_EXTENDED_ADDRESS(), &g_ieee_addr); /* join as a router */ ZB_NIB_DEVICE_TYPE() = ZB_NWK_DEVICE_TYPE_ROUTER; ZB_NWK().max_children = 0; #ifndef ZB_NS_BUILD ZB_UPDATE_LONGMAC(); ZB_UPDATE_PAN_ID(); #endif #ifdef ZB_SECURITY /* turn off security */ ZB_NIB_SECURITY_LEVEL() = 0; #endif if (zdo_dev_start() != RET_OK) { TRACE_MSG(TRACE_ERROR, "zdo_dev_start failed", (FMT__0)); } else { zdo_main_loop(); } TRACE_DEINIT(); MAIN_RETURN(0); }
MAIN() { ARGV_UNUSED; #ifndef KEIL if ( argc < 3 ) { printf("%s <read pipe path> <write pipe path>\n", argv[0]); return 0; } #endif /* Init device, load IB values from nvram or set it to default */ #ifndef ZB8051 ZB_INIT("zdo_zc", argv[1], argv[2]); #else ZB_INIT("zdo_zc", "1", "1"); #endif /* let's always be coordinator */ ZB_AIB().aps_designated_coordinator = 1; MAC_PIB().mac_pan_id = 0x1aaa; /* set ieee addr */ ZB_IEEE_ADDR_COPY(ZB_PIB_EXTENDED_ADDRESS(), &g_ieee_addr); #ifndef ZB_NS_BUILD ZB_UPDATE_LONGMAC(); ZB_UPDATE_PAN_ID(); #endif #ifdef ZB_SECURITY /* turn off security */ ZB_NIB_SECURITY_LEVEL() = 0; #endif if ( zdo_dev_start() != RET_OK ) { TRACE_MSG(TRACE_ERROR, "zdo_dev_start failed", (FMT__0)); } else { zdo_main_loop(); } TRACE_DEINIT(); MAIN_RETURN(0); }
void zb_aps_in_remove_device(zb_uint8_t param) { /* get source address from the nwk header and convert it to long address */ zb_apsme_remove_device_pkt_t *pkt = (zb_apsme_remove_device_pkt_t *)ZB_BUF_BEGIN(ZB_BUF_FROM_REF(param)); zb_apsme_remove_device_ind_t *ind = ZB_GET_BUF_PARAM(ZB_BUF_FROM_REF(param), zb_apsme_remove_device_ind_t); TRACE_MSG(TRACE_SECUR3, ">>zb_aps_in_remove_device %d", (FMT__H, param)); { zb_uint16_t src_short_addr = ZB_GET_BUF_PARAM(ZB_BUF_FROM_REF(param), zb_apsde_data_indication_t)->src_addr; zb_address_ieee_by_short(src_short_addr, ind->src_address); } ZB_IEEE_ADDR_COPY(ind->child_address, pkt->child_address); ZB_SCHEDULE_CALLBACK(zb_apsme_remove_device_indication, param); TRACE_MSG(TRACE_SECUR3, "<<zb_aps_in_remove_device", (FMT__0)); }
MAIN() { ARGV_UNUSED; #ifndef KEIL if ( argc < 3 ) { printf("%s <read pipe path> <write pipe path>\n", argv[0]); return 0; } #endif /* Init device, load IB values from nvram or set it to default */ #ifndef ZB8051 ZB_INIT("zdo_zr1", argv[1], argv[2]); #else ZB_INIT("zdo_zr1", "2", "2"); #endif ZB_IEEE_ADDR_COPY(ZB_PIB_EXTENDED_ADDRESS(), &g_ieee_addr); #ifndef ZB_NS_BUILD ZB_UPDATE_LONGMAC(); ZB_UPDATE_PAN_ID(); #endif #ifdef ZB_SECURITY ZG->nwk.nib.security_level = 0; #endif if (zdo_dev_start() != RET_OK) { TRACE_MSG(TRACE_ERROR, "zdo_dev_start failed", (FMT__0)); } else { zdo_main_loop(); } TRACE_DEINIT(); MAIN_RETURN(0); }
/** Reaction on TRANSPORT-KEY APS command */ void zb_aps_in_transport_key(zb_uint8_t param) { zb_transport_key_nwk_key_dsc_pkt_t *dsc = (zb_transport_key_nwk_key_dsc_pkt_t *)ZB_BUF_BEGIN(ZB_BUF_FROM_REF(param)); TRACE_MSG(TRACE_SECUR3, ">>zb_aps_in_transport_key %d", (FMT__H, param)); /* See 4.4.3.3 Upon Receipt of a Transport-Key Command */ switch (dsc->key_type) { case ZB_STANDARD_NETWORK_KEY: if ( /* key is for me */ ZB_IEEE_ADDR_CMP(dsc->dest_address, ZB_PIB_EXTENDED_ADDRESS()) /* key is for all */ || ZB_IEEE_ADDR_IS_ZERO(dsc->dest_address)) { /* This key is for me. Issue APSME-TRANSPORT-KEY.indication. ZDO will * setup keys and remember TC address. */ zb_apsme_transport_key_indication_t *ind = ZB_GET_BUF_PARAM(ZB_BUF_FROM_REF(param), zb_apsme_transport_key_indication_t); TRACE_MSG(TRACE_SECUR3, "in std nwk key #%d for me", (FMT__D, dsc->seq_number)); ind->key_type = dsc->key_type; ZB_IEEE_ADDR_COPY(ind->src_address, dsc->source_address); ind->key.nwk.key_seq_number = dsc->seq_number; ZB_MEMCPY(ind->key.nwk.key, dsc->key, ZB_CCM_KEY_SIZE); ZB_SCHEDULE_CALLBACK(zb_apsme_transport_key_indication, param); /* #ifdef ZB_ROUTER_ROLE */ /* This feature should be processed at request */ #if 0 if (ZB_IEEE_ADDR_IS_ZERO(dsc->dest_address) /* && check for secured transfer at nwk level */ && ZB_IEEE_ADDR_CMP(dsc->source_address, ZB_AIB().trust_center_address)) { /* * Need to pass key to all rx-off-when-idle children. Need another * packet buffer for it. * Do the rest in the calback: this is blocked * buffer alloc. Not need to save current key: it will be aleady * assigned, so can send my own key. */ ZG->aps.tmp.neighbor_table_iterator = zb_nwk_neighbor_next_ze_children_rx_off_i(0); ZG->aps.tmp.key_seq_number = ind->key.nwk.key_seq_number; if (ZG->aps.tmp.neighbor_table_iterator != (zb_ushort_t)~0) { TRACE_MSG(TRACE_SECUR3, "send key #%hd to all ZE", (FMT__H, dsc->seq_number)); zb_get_out_buf_delayed(zb_aps_pass_nwk_key_to_children); } } #endif /* ZB_ROUTER_ROLE */ } #ifdef ZB_ROUTER_ROLE else { zb_address_ieee_ref_t addr_ref; zb_neighbor_tbl_ent_t *nbe; /* Search for child in the Neighbor table, mark child as Authenticated, * send key to it using unsecured NWK transfer */ if (zb_address_by_ieee(dsc->dest_address, ZB_FALSE, ZB_FALSE, &addr_ref) == RET_OK && zb_nwk_neighbor_get(addr_ref, ZB_FALSE, &nbe) == RET_OK && (nbe->relationship == ZB_NWK_RELATIONSHIP_UNAUTHENTICATED_CHILD || nbe->relationship == ZB_NWK_RELATIONSHIP_CHILD)) { zb_uint16_t addr; zb_address_short_by_ref(&addr, addr_ref); TRACE_MSG(TRACE_SECUR3, "send key #%hd to ZE %d, auth ok", (FMT__H_D, dsc->seq_number, addr)); zb_aps_send_command(param, addr, APS_CMD_TRANSPORT_KEY, (nbe->relationship != ZB_NWK_RELATIONSHIP_UNAUTHENTICATED_CHILD)); nbe->relationship = ZB_NWK_RELATIONSHIP_CHILD; } else { TRACE_MSG(TRACE_SECUR1, "child " TRACE_FORMAT_64 " not found", (FMT__A, TRACE_ARG_64(dsc->dest_address))); zb_free_buf(ZB_BUF_FROM_REF(param)); } } #endif /* ZB_ROUTER_ROLE */ break; default: break; } TRACE_MSG(TRACE_SECUR3, "<<zb_aps_in_transport_key", (FMT__0)); }
void zb_aps_secure_frame(zb_buf_t *src, zb_uint_t mac_hdr_size, zb_buf_t *dst) { zb_uint8_t *aps_hdr; zb_uint8_t *payload; zb_secur_ccm_nonce_t nonce; zb_uint8_t *dp; zb_uint8_t *key; zb_ushort_t hdrs_size; zb_aps_nwk_aux_frame_hdr_t *aux; { zb_nwk_hdr_t *nwk_hdr = (zb_nwk_hdr_t *)(ZB_BUF_BEGIN(src) + mac_hdr_size); aps_hdr = (zb_uint8_t *)nwk_hdr + ZB_NWK_HDR_SIZE(nwk_hdr->frame_control); } aux = (zb_aps_nwk_aux_frame_hdr_t *)(aps_hdr + ZB_APS_HDR_SIZE(*aps_hdr)); if (ZB_SECUR_AUX_HDR_GET_KEY_TYPE(aux->secur_control) == ZB_SECUR_DATA_KEY) { payload = (zb_uint8_t *)aux + sizeof(zb_aps_data_aux_frame_hdr_t); /* get src and dst address from APS header, get data key */ key = 0; /* aps data key */ } else { /* nwk key */ payload = (zb_uint8_t *)aux + sizeof(zb_aps_nwk_aux_frame_hdr_t); key = ZG->nwk.nib.secur_material_set[ZG->nwk.nib.active_secur_material_i].key; } /* fill nonce - see 4.5.2.2 */ nonce.frame_counter = aux->frame_counter; nonce.secur_control = aux->secur_control; ZB_IEEE_ADDR_COPY(nonce.source_address, ZB_PIB_EXTENDED_ADDRESS()); hdrs_size = payload - ZB_BUF_BEGIN(src); /* Secure */ (void)zb_ccm_encrypt_n_auth(key, (zb_uint8_t *)&nonce, (zb_uint8_t *)aps_hdr, (payload - aps_hdr), (zb_uint8_t *)payload, (ZB_BUF_LEN(src) - hdrs_size), dst); ZB_BUF_ALLOC_LEFT(dst, (aps_hdr - ZB_BUF_BEGIN(src)), dp); /* copy headers */ ZB_MEMCPY(dp, ZB_BUF_BEGIN(src), (aps_hdr - ZB_BUF_BEGIN(src))); /* clear security level - see 4.4.1.1/11 */ aux = (zb_aps_nwk_aux_frame_hdr_t *)(ZB_BUF_BEGIN(dst) + ((zb_uint8_t*)aux - ZB_BUF_BEGIN(src))); if (ZB_SECUR_AUX_HDR_GET_KEY_TYPE(aux->secur_control) == ZB_SECUR_DATA_KEY) { aux->secur_control = ZB_APS_DATA_STD_SECUR_CONTROL_ZEROED_LEVEL; } else { aux->secur_control = ZB_APS_NWK_STD_SECUR_CONTROL_ZEROED_LEVEL; } TRACE_MSG(TRACE_SECUR3, "secured aps frm %p[%hd] -> %p hdrs_size %hd fcnt %lx", (FMT__P_H_P_H_L, src, ZB_BUF_LEN(src), dst, hdrs_size, aux->frame_counter)); }
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; }