Example #1
0
OT_WEAK void dll_systask_beacon(ot_task task) {
/// The beacon rountine runs as an idependent systask.
    m2session*  b_session;

    if ((task->event == 0) || (dll.netconf.b_attempts == 0)) {
        dll_idle();
        return;
    }

    /// Load file-based beacon:
    /// Open BTS ISF Element and read the beacon sequence.  Make sure there is
    /// a beacon file of non-zero length and that beacons are presently enabled.
    if (dll.netconf.dd_flags == 0) {
        ot_u16  scratch;
        vlFILE* fp;

        fp = ISF_open_su( ISF_ID(beacon_transmit_sequence) );
        if (fp == NULL) {
            return; //goto dll_systask_beacon_STOP;
        }
        if (fp->length == 0)    {
            vl_close(fp);
            return; //goto dll_systask_beacon_STOP;
        }

        // a little hack
        scratch     = fp->start;
        fp->start  += task->cursor;

        /// Beacon List Management:
        /// <LI> Move cursor onto next beacon period (above, +8)</LI>
        /// <LI> Loop cursor if it is past the length of the list </LI>
        /// <LI> In special case where cursor = 254, everything still works! </LI>
        task->cursor   += 8;
        task->cursor    = (task->cursor >= fp->length) ? 0 : task->cursor;

        // Load next beacon into btemp, then undo the start hack, then close
        vl_load(fp, 8, dll.netconf.btemp);
        fp->start = scratch;
        vl_close(fp);
    }

    // First 2 bytes: Chan ID, Cmd Code
    // - Setup beacon ad-hoc session, on specified channel (ad hoc sessions never return NULL)
    // - Assure cmd code is always Broadcast & Announcement
    b_session           = session_new(  &dll_beacon_applet, 0, dll.netconf.btemp[0],
                                        (M2_NETSTATE_INIT | M2_NETSTATE_REQTX | M2_NETFLAG_FIRSTRX)  );
    b_session->subnet   = dll.netconf.b_subnet;
    b_session->extra    = dll.netconf.btemp[1];
    b_session->flags    = dll.netconf.btemp[1] & 0x78;
    //b_session->flags   |= (b_session->extra & 0x30);

    // Last 2 bytes: Next Scan ticks
    sys_task_setnext(task, TI2CLK( PLATFORM_ENDIAN16(*(ot_u16*)&dll.netconf.btemp[6]) ));

    ///@note this might not be necessary or wise!
    //return;
    //dll_systask_beacon_STOP:
    //dll_idle();
}
Example #2
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();
}
Example #3
0
OT_WEAK void dll_response_applet(m2session* active) {
/// If this is a response transmission of a session with "Listen" active, it
/// means the contention period (Tc) is followed immediately with a subsequent
/// request.  We must not overlap that request with the tail-end of our own
/// response.  Therefore, we subtract from Tc the duration of this response.
    if (active->flags & M2_FLAG_LISTEN) {
        ot_u8 substate = active->netstate & M2_NETSTATE_TMASK;

        if (substate == M2_NETSTATE_RESPTX) {
            dll.comm.tc -= TI2CLK(rm2_pkt_duration(&txq));
        }
        else if (substate == M2_NETSTATE_REQRX) {
            sys.task_HSS.cursor     = 0;
            sys.task_HSS.nextevent  = dll.comm.rx_timeout;
            dll.comm.rx_timeout     = rm2_default_tgd(active->channel);
        }
    }
}
Example #4
0
OT_WEAK ot_u16 otapi_start_dialog(ot_u16 timeout) {
/// Stop any ongoing processes and seed the event for the event manager.  The
/// radio killer will work in all cases, but it is bad form to kill sessions
/// that are moving data.
    if (timeout != 0) {
        dll.comm.tc = TI2CLK(timeout);
    }
    
    ///@todo update null radio driver to modern interface
#   ifndef __KERNEL_NONE__
    if (radio.state != RADIO_Idle) {
    	rm2_kill();
    }
#   endif

#   ifndef __KERNEL_NONE__
    sys.task_RFA.event = 0;
    sys_preempt(&sys.task_RFA, 0);
#   endif
    return 1;
}