Esempio n. 1
0
OT_WEAK void dll_activate(void) {
/// Do session creation
/// 1. Block DLL Idle-time tasks: they get reactivated by dll_idle()
/// 2. Get top session
/// 3. Associated Applet can construct packet, or control parameters
/// 4. Session is terminated if "SCRAP" bit is 1
/// 5. Session is processed otherwise
    m2session*  s_active;
    ot_app      s_applet;

    dll_block_idletasks();

  //dll.idle_state      = sub_default_idle();
    s_active            = session_top();
    s_applet            = (s_active->applet == NULL) ? \
                            &dll_response_applet : s_active->applet;
    s_active->applet    = NULL;
    s_applet(s_active);

    if (s_active->netstate & M2_NETSTATE_SCRAP) {
        session_pop();
        dll_idle();
    }
    else if (s_active->netstate & M2_NETSTATE_RX) {
        dll_init_rx(s_active);
    }
    else {
        dll_init_tx(s_active->netstate & (M2_NETFLAG_BG | M2_NETFLAG_STREAM));
    }
}
Esempio n. 2
0
m2session* otapi_task_advertise(advert_tmpl* adv_tmpl, session_tmpl* s_tmpl, ot_app applet) {
/// This is a more complicated process than the others, because it actually 
/// creates two sessions: one for the flood and one for the request.
#   define _FLOOD_NETSTATE  (M2_NETFLAG_FLOOD | M2_NETSTATE_INIT | M2_NETSTATE_REQTX)
    ot_u8 scratch;
    m2session* session;
    
    /// 1.  Clear any sessions between now and the request, and push the 
    ///     request session onto the stack.  If the push failed, exit.  If the
    ///     advertising is 0, also exit and do this session without flood.
    session_crop(adv_tmpl->duration);
    session = sub_newtask(s_tmpl, applet, adv_tmpl->duration);
    if ((session == NULL) || (adv_tmpl->duration == 0))
        return NULL;
    
    /// 2.  Flood duty cycling is not supported at this time.  All floods 
    ///     are implemented as 100% duty cycle.
    
    /// 3.  Push the Advertising session onto the stack, for immediate running.
    ///     <LI> Use the same subnet for the advertising as for the request. </LI>
    ///     <LI> For basic flooding, the applet can be empty </LI>
    scratch = session->subnet;
    session = session_new(&otutils_applet_null, 0, _FLOOD_NETSTATE, adv_tmpl->channel);
    if (session == NULL) {
        session_pop();  //pop the request session from above
        return NULL;
    }
    session->subnet = scratch;
    
    return session;
}
Esempio n. 3
0
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();
}
Esempio n. 4
0
void dll_processing(void) {
/// This is the task for processing a DASH7 packet which has been received.
/// If the packet is a valid request, this task will put the DLL into HOLD.
/// If the listen bit is high, additionally, this task will clone the session
/// to be re-visited at a later time.
    m2session* active;
    ot_int proc_score;
    sys.task_RFA.event  = 0;                // Only run processing once
    active              = session_top();
    active->counter     = 0;
    proc_score          = network_route_ff(active);

    /// Response is prepared already, so setup holdstate and flow control.
    /// proc_score is always negative after parsing a response.
    if (proc_score >= 0) {
        sub_fceval(proc_score);
        sys.task_HSS.cursor = 0;
        dll.counter         = dll.netconf.hold_limit;
        dll.idle_state      = M2_DLLIDLE_HOLD;

        /// If the Listen flag is high, clone the session to a time in the
        /// future, when it will listen again.
        /// <LI> dll.comm.tc has just been assigned by the request.  It is the
        ///      response contention period (Tc). </LI>
        /// <LI> This device should listen again after Tc ends, so the session
        ///      is cloned & scheduled for Tc </LI>
        /// <LI> The current session is popped after response, or on next kernel
        ///      loop (immediately) if no response </LI>
        if (active->flags & M2_FLAG_LISTEN) {
            network_cont_session(active->applet, M2_NETSTATE_REQRX, 0);
        }
    }

    /// Bad score, plus session indicates no listening or sending response.
    /// Scrap the session.
    else if ((active->netstate & M2_NETSTATE_RESP) == 0) {
        goto dll_processing_SCRAP;
    }

    /// A protocol parser has scrapped the session, or possibly the above
    /// condition branched here directly.
    if (active->netstate & M2_NETSTATE_SCRAP) {
        dll_processing_SCRAP:
        session_pop();
        dll_idle();
    }
}