/* * Sets up new route discovery operation. * Call rreq_handler to do a real discovery. */ void zb_nwk_mesh_route_discovery(zb_buf_t *cbuf, zb_uint16_t dest_addr, zb_uint8_t radius) { zb_nwk_hdr_t *nwk_hdr; zb_nwk_cmd_rreq_t *nwk_cmd_rreq; TRACE_MSG(TRACE_NWK1, ">> route_discovery cbuf %p dest_addr %d radius %hd", (FMT__P_D_H, cbuf, dest_addr, radius)); if ( cbuf ) { /* alloc space for nwk header and rreq cmd */ ZB_BUF_INITIAL_ALLOC(cbuf, ZB_NWK_SHORT_HDR_SIZE(0), nwk_hdr); ZB_BUF_ALLOC_RIGHT(cbuf, sizeof(*nwk_cmd_rreq), nwk_cmd_rreq); ZB_ASSERT(nwk_hdr && nwk_cmd_rreq); /* fill meaningful hdr and command parameters for rrreq handler */ nwk_cmd_rreq->opt = 0; nwk_cmd_rreq->rreq_id = ZB_NWK_GET_RREQ_ID(); nwk_cmd_rreq->dest_addr = dest_addr; nwk_cmd_rreq->path_cost = 0; /* default radius = 2 * max depth */ nwk_hdr->radius = radius ? radius : (zb_uint8_t)(ZG->nwk.nib.max_depth << 1); nwk_hdr->src_addr = ZB_NIB_NETWORK_ADDRESS(); zb_nwk_mesh_rreq_handler(cbuf, nwk_hdr, nwk_cmd_rreq); } else { ZB_GET_OUT_BUF_DELAYED(zb_nwk_mesh_initiate_route_discovery); } TRACE_MSG(TRACE_NWK1, "<< route_discovery", (FMT__0)); }
static void send_data() { zb_buf_t *buf = NULL; zb_apsde_data_req_t req; zb_uint8_t *ptr = NULL; zb_short_t i; buf = zb_get_out_buf(); req.dst_addr.addr_short = 0; /* send to ZC */ req.addr_mode = ZB_APS_ADDR_MODE_16_ENDP_PRESENT; req.tx_options = ZB_APSDE_TX_OPT_ACK_TX; req.radius = 1; req.profileid = 2; req.src_endpoint = 10; req.dst_endpoint = 10; buf->u.hdr.handle = 0x11; ZB_BUF_INITIAL_ALLOC(buf, 80, ptr); for (i = 0 ; i < ZB_TEST_DATA_SIZE ; ++i) { ptr[i] = i % 32 + '0'; } ZB_MEMCPY( ZB_GET_BUF_TAIL(buf, sizeof(req)), &req, sizeof(req)); TRACE_MSG(TRACE_APS3, "Sending apsde_data.request", (FMT__0)); ZB_SCHEDULE_CALLBACK(zb_apsde_data_request, ZB_REF_FROM_BUF(buf)); }
/* 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; }
/* This function resend route request */ static void zb_nwk_mesh_resend_rreq(zb_buf_t *cbuf, zb_nwk_rreq_t *rreq) { zb_nwk_hdr_t *nwhdr; zb_nwk_cmd_rreq_t *rreq_cmd; int total; TRACE_MSG(TRACE_NWK1, ">> resend_rreq cbuf %p rreq %p", (FMT__P_P, cbuf, rreq)); rreq->retries++; /* fill nwk header */ ZB_BUF_INITIAL_ALLOC(cbuf, ZB_NWK_SHORT_HDR_SIZE(0), nwhdr); ZB_BZERO2(nwhdr->frame_control); ZB_NWK_FRAMECTL_SET_FRAME_TYPE_N_PROTO_VER(nwhdr->frame_control, ZB_NWK_FRAME_TYPE_COMMAND, ZB_PROTOCOL_VERSION); /*ZB_NWK_FRAMECTL_SET_DISCOVER_ROUTE(nwhdr->frame_control, 0); implied*/ nwhdr->src_addr = rreq->originator; nwhdr->dst_addr = ZB_NWK_BROADCAST_ROUTER_COORDINATOR; nwhdr->radius = rreq->radius; nwhdr->seq_num = ZB_NIB_SEQUENCE_NUMBER(); ZB_NIB_SEQUENCE_NUMBER_INC(); /* fill route request cmd&payload */ ZB_NWK_ALLOC_COMMAND_GET_PAYLOAD_PTR(cbuf, ZB_NWK_CMD_ROUTE_REQUEST, zb_nwk_cmd_rreq_t, rreq_cmd); memcpy(rreq_cmd, &rreq->cmd ,sizeof(*rreq_cmd)); /* transmit route request packet */ ZB_SET_BUF_PARAM(cbuf, ZB_NWK_INTERNAL_NSDU_HANDLE, zb_uint8_t); ZB_SCHEDULE_CALLBACK(zb_nwk_forward, ZB_REF_FROM_BUF(cbuf)); total = ( rreq->originator == ZB_NIB_NETWORK_ADDRESS() ) ? ZB_MWK_INITIAL_RREQ_RETRIES : ZB_MWK_RREQ_RETRIES; TRACE_MSG(TRACE_NWK1, "sent %d times of %d total", (FMT__D_D, rreq->retries, total + 1)); if ( rreq->retries > total ) { NWK_ROUTING_ARRAY_PUT_ENT(ZG->nwk.nib.rreq, rreq, ZG->nwk.nib.rreq_cnt); } TRACE_MSG(TRACE_NWK1, "<< mesh_resend_rreq", (FMT__0)); }