OT_WEAK void dll_beacon_applet(m2session* active) { /// Beaconing is a Request-TX operation, and the value for Tc is the amount of /// time to spend in CSMA before quitting the beacon. ot_queue beacon_queue; ot_u8 b_params; ot_u8 cmd_ext; ot_u8 cmd_code; b_params = active->extra; active->extra = 0; /// Start building the beacon packet: /// <LI> Calling m2np_header() will write most of the front of the frame </LI> /// <LI> Add the command byte and optional command-extension byte </LI> m2np_header(active, M2RT_BROADCAST, M2FI_FRDIALOG); cmd_ext = (b_params & 0x06); // Normal extension bits cmd_ext |= (dll.netconf.btemp[2] == 0) << 6; // Announcement No-File bit cmd_code = 0x20 | (b_params & 1) | ((cmd_ext!=0) << 7); q_writebyte(&txq, cmd_code); if (cmd_code) { q_writebyte(&txq, cmd_ext); } /// Setup the comm parameters, if the channel is available: /// <LI> dll.comm values tx_eirp, cs_rssi, and cca_rssi must be set by the /// radio module during the CSMA-CA process -- don't set them here. /// The DASH7 spec requires it to happen in this order. </LI> /// <LI> Set CSMA-CA parameters, which are used by the radio module </LI> /// <LI> Set number of redundant TX's we would like to transmit </LI> /// <LI> Set rx_timeout for Default-Tg or 0, if beacon has no response </LI> dll_set_defaults(active); dll.comm.tc = TI2CLK(M2_PARAM_BEACON_TCA); dll.comm.rx_timeout = (b_params & 0x02) ? \ 0 : rm2_default_tgd(active->channel); dll.comm.csmaca_params |= (b_params & 0x04) | M2_CSMACA_NA2P | M2_CSMACA_MACCA; dll.comm.redundants = dll.netconf.b_attempts; q_writebyte(&txq, (ot_u8)dll.comm.rx_timeout); /// Add the announcement file data if the specified return data != 0 bytes. /// If the beacon data is missing or otherwise not accessible by the GUEST /// user, dump the session (thus killing the beacon) and go back to idle. if (dll.netconf.btemp[2] != 0) { q_init(&beacon_queue, &dll.netconf.btemp[2], 4); if (m2qp_isf_call((b_params & 1), &beacon_queue, AUTH_GUEST) < 0) { session_pop(); dll_idle(); return; } } /// Final step to any packet generation: add footer m2np_footer(); }
OT_WEAK ot_u16 otapi_open_request(addr_type addr, routing_tmpl* routing) { /// Set the header if the session is valid. Also conditionally write the header /// depending on the address type (a parameter). if (session_notempty()) { m2session* s_active; s_active = session_top(); // Set the dll parameters to a safe setting; can be changed later dll_set_defaults(s_active); // Unicast/Anycast support routing, so copy the supplied template if ((addr & M2QUERY_GLOBAL) == 0) { platform_memcpy((ot_u8*)&m2np.rt, (ot_u8*)routing, sizeof(routing_tmpl)); } // Load the header m2np_header(s_active, (ot_u8)addr, M2FI_FRDIALOG); return 1; } return 0; }
ot_int sub_parse_request(m2session* session) { ot_int score = 0; ot_u8 cmd_opcode; //ot_u8 nack = 0; /// 1. Universal Comm Processing <BR> /// - Load CCA type & CSMA disable from command extension <BR> /// - Load NA2P or A2P dialog type from command code m2qp.cmd.code = q_readbyte(&rxq); m2qp.cmd.ext = (m2qp.cmd.code & 0x80) ? q_readbyte(&rxq) : 0; dll.comm.csmaca_params = m2qp.cmd.ext & (M2_CSMACA_CAMASK | M2_CSMACA_NOCSMA); dll.comm.csmaca_params |= m2qp.cmd.code & M2_CSMACA_ARBMASK; cmd_opcode = m2qp.cmd.code & M2OP_MASK; /// 2. All Requests contain the dialog template, so load it. <BR> /// - [ num resp channels ] [ list of resp channels] <BR> /// - if number of resp channels is 0, use the current channel { ot_u8 timeout_code = q_readbyte(&rxq); dll.comm.rx_timeout = otutils_calc_timeout(timeout_code); // original contention period dll.comm.tc = dll.comm.rx_timeout; // contention period counter if (timeout_code & 0x80) { dll.comm.tx_channels = q_readbyte(&rxq); dll.comm.tx_chanlist = q_markbyte(&rxq, dll.comm.tx_channels); } else { dll.comm.tx_channels = 1; dll.comm.tx_chanlist = &dll.comm.scratch[0]; dll.comm.scratch[0] = session->channel; } } /// 3. Handle Command Queries (filtering) <BR> /// Multicast and anycast addressed requests include queries if (m2np.header.addr_ctl & 0x80) { score = sub_process_query(session); } /// 4. If the query is good (sometimes this is trivial): <BR> /// - Prepare the response header (same for all responses) <BR> /// - Run command-specific dialog data processing if (score >= 0) { q_empty(&txq); // Flush TX Queue if (m2qp.cmd.ext & M2CE_NORESP) { session->netstate |= M2_NETFLAG_SCRAP; } else { ot_u8 addressing; session->netstate &= ~M2_NETSTATE_TMASK; session->netstate |= M2_NETSTATE_RESPTX; addressing = ext_get_m2appflags(); addressing |= m2np.header.addr_ctl & 0x30; // make unicast, retain VID & NLS m2np_header(session, addressing, 0); // Create M2QP header q_writebyte(&txq, (M2TT_RESPONSE | cmd_opcode)); // Write Cmd code byte } switch ((cmd_opcode>>1) & 7) { case 0: case 1: break; case 2: sub_opgroup_shell(); break; case 3: case 4: sub_opgroup_collection(); break; case 5: break; case 6: sub_opgroup_datastream(); break; case 7: sub_ack_datastream(); break; } }