コード例 #1
0
ファイル: main.c プロジェクト: KennyRIM/OpenTag
void applet_send_beacon(m2session* session) {
    { //open request for broadcast
        otapi_open_request(ADDR_broadcast, NULL);
    }
    { //use a command template for collection of single file from single file search
        ot_u8 status;
        command_tmpl command;
        command.opcode      = (ot_u8)CMD_announce_file;
        command.type        = (ot_u8)CMDTYPE_na2p_request;
        command.extension   = (ot_u8)CMDEXT_no_response;
        otapi_put_command_tmpl(&status, &command);
    }
    { //write the dialog information (timeout, channels to use)
        ot_u8 status;
        dialog_tmpl dialog;
        dialog.channels = 0;    //use same channel as request for response
        dialog.timeout  = 0;    //0 tick response timeout (1 tick = 0,977 ms)
        otapi_put_dialog_tmpl(&status, &dialog);
    }
    { //write the ISF return data (note: use isfcall template)
        ot_u8 status;
        isfcall_tmpl isfcall;
        isfcall.is_series   = False;
        isfcall.isf_id      = ISF_ID(network_settings);
        isfcall.max_return  = ISF_LEN(network_settings);
        isfcall.offset      = 0;
        otapi_put_isf_return(&status, &isfcall);
    }

    //Done building command, close the request and send the dialog
    otapi_close_request();
}
コード例 #2
0
ファイル: radio_task.c プロジェクト: kaalabs/OpenTag
OT_WEAK void rm2_init(void) {
    vlFILE* fp;
    
    /// Set universal Radio module initialization defaults
    radio.state     = RADIO_Idle;
    radio.evtdone   = &otutils_sig2_null;

    /// These Radio Link features are available on the SPIRIT1
    ///@todo see if this and the "Set startup channel" part of the init can
    ///      get bundled into a common initialization function in radio_task.c
#   if (OT_FEATURE(RF_LINKINFO))
#       if (M2_FEATURE(RSCODE))
#           define _CORRECTIONS RADIO_LINK_CORRECTIONS
#       else
#           define _CORRECTIONS 0
#       endif
    radio.link.flags        = _CORRECTIONS | RADIO_LINK_PQI | RADIO_LINK_SQI \
                            | RADIO_LINK_LQI | RADIO_LINK_AGC;
#   endif
    radio.link.offset_thr   = 0;
    radio.link.raw_thr      = 0;
    
    /// Set startup channel to an always invalid channel ID (0xF0), and run 
    /// lookup on the default channel (0x18) to kick things off.  Since the 
    /// startup channel will always be different than a real channel, the 
    /// necessary settings and calibration will always occur. 
    phymac[0].channel   = 0xF0;
    phymac[0].tx_eirp   = 0x7F;
    fp                  = ISF_open_su( ISF_ID(channel_configuration) );
    rm2_channel_lookup(0x18, fp);
    vl_close(fp);
}
コード例 #3
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();
}
コード例 #4
0
ファイル: ht_protocol.c プロジェクト: kaalabs/OpenTag
void applet_send_query(m2session* session) {
/// The C-API for building commands can be bypassed in favor of directly
/// putting data to the queue.  That way is more efficient, but it also requires
/// you to know more about DASH7 than just what order the templates should be.
///
/// The query that we build will collect sensor configuration data back from
/// all devices that support the sensor protocol.  Much more interesting queries
/// are possible.
    ot_u8 status;

    { //open request for single hop anycast query
        routing_tmpl routing;
        routing.hop_code = 0;
        otapi_open_request(ADDR_anycast, &routing);
    }
    { //use a command template for collection of single file from single file search
        command_tmpl command;
        command.opcode      = (ot_u8)CMD_udp_on_file;
        command.type        = (ot_u8)CMDTYPE_na2p_request;
        command.extension   = (ot_u8)CMDEXT_none;
        otapi_put_command_tmpl(&status, &command);
    }
    { //write the dialog information (timeout, channels to use)
        dialog_tmpl dialog;
        dialog.channels = 0;    //use same channel as request for response
        dialog.timeout  = 0x41; //same as otutils_encode_timeout(512) -- 512 tick response slot
        otapi_put_dialog_tmpl(&status, &dialog);
    }
    { //write the query to search for the sensor protocol id
        static const ot_u8 query_str[10] = "APP=PongLT";
        query_tmpl query;
        query.code      = M2QC_COR_SEARCH + 10; // do a 100% length=10 correlation search
        query.mask      = NULL;                 // don't do any masking (no partial matching)
        query.length    = 10;                   // query_str is 10 bytes
        query.value     = (ot_u8*)query_str;
        otapi_put_query_tmpl(&status, &query);
    }
    { //put in the information of the file to search (the user id)
        isfcomp_tmpl isfcomp;
        isfcomp.is_series   = False;
        isfcomp.isf_id      = ISF_ID(user_id);
        isfcomp.offset      = 0;
        otapi_put_isf_comp(&status, &isfcomp);
    }
    { //put in UDP ports (from 254 to 255) and Ping ID
        q_writebyte(&txq, 254);
        q_writebyte(&txq, 255);
        q_writeshort(&txq, app.pingval);
    }

    //Done building command, close the request and send the dialog
    otapi_close_request();
}
コード例 #5
0
ファイル: main.c プロジェクト: KennyRIM/OpenTag
/** ALP Processor Callback for Starting a Ping <BR>
  * ========================================================================<BR>
  * "ALP" is the NDEF-based set of low-level API protocols that OpenTag uses.
  * ALP messages can come-in over any communication method: wire, wireless, 
  * telepathy... anything that can transfer a packet payload.
  *
  * Some ALPs are standardized. Those get handled by OTlib automatically.  ALPs
  * that are not recognized are sent to this function to be handled.  In this
  * demo, we are using a very simple ALP, shown below:
  *
  * ALP Payload Length:         0
  * ALP Protocol ID:            255 (FF)
  * ALP Protocol Commands:      0-127 (00-7F) corresponding to channel to sniff
  *
  * The "user_id" parameter corresponds to the Device ID that sent this ALP.
  * 
  * A quickstart guide to the ALP API is available on the Indigresso Wiki.
  * http://www.indigresso.com/wiki/doku.php?id=opentag:api:quickstart
  */ 
void otapi_alpext_proc(alp_tmpl* alp, id_tmpl* user_id) {
/// The function app_invoke() will cause the kernel to call ext_systask() as
/// soon as resources are available.
    vlFILE*     fp;
    ot_uni16    scratch;
    ot_u8       channel;
    ot_u8       retval;

    // Start the task only if: Caller is ROOT, ALP Call is Protocol-255, Task is idle
    if (    auth_isroot(user_id)    \
        &&  (alp->inrec.id == 0xFF) \
        &&  (APP_TASK.event == 0)   )   {
        
        /// Make sure channel is spec-legal.  If so, set the channel of the 
        /// first (and only) in the channel list to the specified one, and also
        /// set the channel of the hold scan accordingly.  By default, the scan
        /// is updated every second.  The next scan will have these settings.
        retval  = 0;
        channel = alp->inrec.cmd & 0x7F;
        if (((channel & 0xF0) <= 0x20) && ((channel & 0x0F) <= 0x0E)) {
            fp                  = ISF_open_su(ISF_ID(channel_configuration));
            scratch.ushort      = vl_read(fp, 0);
            scratch.ubyte[0]    = channel;
            vl_write(fp, 0, scratch.ushort);
            vl_close(fp);
            
            fp                  = ISF_open_su(ISF_ID(hold_scan_sequence));
            scratch.ushort      = vl_read(fp, 0);
            scratch.ubyte[0]    = channel;
            vl_write(fp, 0, scratch.ushort);
            vl_close(fp);
            
            retval = 1; //success
        }
        
        alp_load_retval(alp, retval);
    }
}
コード例 #6
0
ot_bool applet_beacon_discovery() {
    { //create a new session (it will get copied to session stack)
        session_tmpl session;
        session.channel     = 0x00;
        session.flagmask    = 0;
        session.flags       = 0;
        session.subnet      = 0;
        session.subnetmask  = 0;
        session.timeout     = 16;
        otapi_new_session(&session, NULL);
    }
    { //open request for broadcast
        otapi_open_request(ADDR_broadcast, NULL);
    }
    { //use a command template for collection of single file from single file search
        ot_u8 status;
        command_tmpl command;
        command.opcode      = (ot_u8)CMD_announce_file;
        command.type        = (ot_u8)CMDTYPE_na2p_request;
        command.extension   = (ot_u8)CMDEXT_no_response;
        otapi_put_command_tmpl(&status, &command);
    }
    { //write the dialog information (timeout, channels to use)
        ot_u8 status;
        dialog_tmpl dialog;
        dialog.channels = 0;    //use same channel as request for response
        dialog.timeout  = 0;    //0 tick response timeout (1 tick = 0,977 ms)
        otapi_put_dialog_tmpl(&status, &dialog);
    }
    { //write the ISF return data (note: use isfcall template)
        ot_u8 status;
        isfcall_tmpl isfcall;
        isfcall.is_series   = False;
        isfcall.isf_id      = ISF_ID(network_settings);
        isfcall.max_return  = ISF_LEN(network_settings);
        isfcall.offset      = 0;
        otapi_put_isf_return(&status, &isfcall);
    }

    //Done building command, close the request and send the dialog
    otapi_close_request();
    //otapi_start_dialog();

    return True;
}
コード例 #7
0
ファイル: data_default.c プロジェクト: jpnorair/OpenTag
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,

    /* Mode 2 ISFs, written as little endian */
    ISF_LEN(network_settings), 0x00,                /* Length, little endian */
    SPLIT_SHORT_LE(ISF_ALLOC(network_settings)),    /* Alloc, little endian */
    ISF_ID(network_settings),                       /* ID */
    ISF_MOD(network_settings),                      /* Perms */
    SPLIT_SHORT_LE(ISF_BASE(network_settings)),
    SPLIT_SHORT_LE(ISF_MIRROR(network_settings)),

    ISF_LEN(device_features), 0x00,
    SPLIT_SHORT_LE(ISF_ALLOC(device_features)),
    ISF_ID(device_features),
    ISF_MOD(device_features),
    SPLIT_SHORT_LE(ISF_BASE(device_features)),
    SPLIT_SHORT_LE(ISF_MIRROR(device_features)),

    ISF_LEN(channel_configuration), 0x00,
    SPLIT_SHORT_LE(ISF_ALLOC(channel_configuration)),
    ISF_ID(channel_configuration),
    ISF_MOD(channel_configuration),
コード例 #8
0
ファイル: main.c プロジェクト: KennyRIM/OpenTag
void applet_send_query(m2session* session) {
/// The C-API for building commands can be bypassed in favor of directly
/// putting data to the queue.  That way is more efficient, but it also requires
/// you to know more about DASH7 than just what order the templates should be.
///
/// The query that we build will collect sensor configuration data back from
/// all devices that support the sensor protocol.  Much more interesting queries
/// are possible.

    { //open request for single hop anycast query
        routing_tmpl routing;
        routing.hop_code = 0;
        otapi_open_request(ADDR_anycast, &routing);
    }
    { //use a command template for collection of single file from single file search
        ot_u8 status;
        command_tmpl command;
        command.opcode      = (ot_u8)CMD_collect_file_on_file;
        command.type        = (ot_u8)CMDTYPE_na2p_request;
        command.extension   = (ot_u8)CMDEXT_none;
        otapi_put_command_tmpl(&status, &command);
    }
    { //write the dialog information (timeout, channels to use)
        ot_u8 status;
        dialog_tmpl dialog;
        dialog.channels = 0;    //use same channel as request for response
        dialog.timeout  = 512;  //512 tick response timeout (1 tick = 0,977 ms)
        otapi_put_dialog_tmpl(&status, &dialog);
    }
    { //write the query to search for the sensor protocol id
        query_tmpl query;
        ot_u8 status;
        ot_u8 protocol_id;
        protocol_id     = 0x02;                 // sensor protocol id = 0x02
        query.code      = M2QC_COR_SEARCH | 1;  // do a 100% length=1 correlation search
        query.mask      = NULL;                 // don't do any masking (no partial matching)
        query.length    = 1;                    // look for one byte (0x02)
        query.value     = &protocol_id;         // (query.value is a string)
        otapi_put_query_tmpl(&status, &query);
    }
    { //put in the information of the file to search (the protocol list)
        ot_u8 status;
        isfcomp_tmpl isfcomp;
        isfcomp.is_series   = False;
        isfcomp.isf_id      = ISF_ID(protocol_list);
        isfcomp.offset      = 0;
        otapi_put_isf_comp(&status, &isfcomp);
    }
    { //put in the information of the file to return (the sensor list)
        ot_u8 status;
        isfcall_tmpl isfcall;
        isfcall.is_series   = False;
        isfcall.isf_id      = ISF_ID(sensor_list);
        isfcall.max_return  = 32;
        isfcall.offset      = 0;
        otapi_put_isf_call(&status, &isfcall);
    }

    //Done building command, close the request and send the dialog
    otapi_close_request();
}
コード例 #9
0
ファイル: m2_network.c プロジェクト: Chloe880810/OpenTag
ot_int network_route_ff(m2session* session) {
    ot_int route_val;

    /// Strip CRC (-2 bytes)
    rxq.front[0] -= 2;
    
    /// Acquire Flags and Protocol from the Frame Info Field
    rxq.getcursor       = &rxq.front[3];
    session->protocol   = (*rxq.getcursor & M2FI_FRTYPEMASK);
    session->flags      = *rxq.getcursor & 0xC0;
    m2np.header.fr_info = *rxq.getcursor++;
    
    /// Treat Non-Mode-2 Protocols
    /// @note Non-Mode-2 protocols not supported at this time
    if (m2np.header.fr_info & M2FI_NM2) {
        return -1;
    }
    
    /// Data Link Layer Security
    if (m2np.header.fr_info & M2FI_DLLS) {
#   if (OT_FEATURE(DLL_SECURITY))
        ///@todo experimental
        AES_load_static_key(ISF_ID(user_authentication_key), (ot_u32*)txq.front);
        AES_keyschedule_dec((ot_u32*)txq.front, (ot_u32*)(txq.front+16));
        AES_decrypt(rxq.getcursor, rxq.getcursor, (ot_u32*)(txq.front+16));
#   else
        return -1;
#   endif
    }
    
    /// Address Control Header (Present in M2NP)
    /// Session Connection and Dialog Filtering:
    /// - if unassociated, connect now
    /// - if already connected, make sure the dialog IDs are equal
    if (m2np.header.fr_info & M2FI_ENADDR) {
        if (session->netstate & M2_NETSTATE_CONNECTED) {
            if (session->dialog_id != q_readbyte(&rxq)) {
                return -1;
            }
        }
        else {
            session->netstate  |= M2_NETSTATE_CONNECTED;
            session->subnet     = rxq.front[2];
            session->dialog_id  = q_readbyte(&rxq);
        }
        
        /// Grab global flags from Address Control
        m2np.header.addr_ctl    = q_readbyte(&rxq);
        session->flags         |= m2np.header.addr_ctl & 0x3F;
        
        /// Grab Source Address from this packet (dialog address), which is 
        /// converted to the target address in the response.
        m2np.rt.dlog.length = (m2np.header.addr_ctl & M2_FLAG_VID) ? 2 : 8;
        m2np.rt.dlog.value  = q_markbyte(&rxq, m2np.rt.dlog.length);
        
        /// Network Layer Security
        /// @note Network Layer Security not supported at this time
        if (m2np.header.addr_ctl & M2_FLAG_NLS) {
#       if (OT_FEATURE(NL_SECURITY))
#       else
            return -1;
#       endif
        }
        
        /// If unicasting, the next data is the target address, which will have
        /// the same length as the source address, and it needs to match this
        /// device's device ID (VID or UID)
        if ((m2np.header.addr_ctl & 0xC0) == 0) {
            session->netstate |= M2_NETFLAG_FIRSTRX;
            if ( !m2np_idcmp(m2np.rt.dlog.length, q_markbyte(&rxq, m2np.rt.dlog.length)) ) {
                return -1;
            }
        }
    }

    /// Vector to the appropriate Network Layer Protocol Parser
    /// Most network protocols don't do anything except broadcast.  M2NP is the
    /// exception, and it manages various types of routing at the network layer.
    route_val = -1;
    switch (session->protocol & M2FI_FRTYPEMASK) {
    	case M2FI_FRDIALOG:
        case M2FI_FRNACK: {
            // Reset routing template
            m2np.rt.hop_code    = 0;
            m2np.rt.hop_ext     = 0;
            m2np.rt.orig.value  = NULL;
            m2np.rt.dest.value  = NULL;
            
            /// Unicast and Anycast Requests have a routing template
            /// (Not currently supported, so just move the cursor ahead)
            if ((m2np.header.addr_ctl & 0x40) == 0) {
                m2np.rt.hop_code    = q_readbyte(&rxq);
                m2np.rt.orig.length = ((m2np.rt.hop_code & M2HC_VID) != 0) ? 2 : 8;                       
                m2np.rt.dest.length = m2np.rt.orig.length;
                
                if ((m2np.rt.hop_code & M2HC_EXT) != 0) {
                    m2np.rt.hop_ext = q_readbyte(&rxq);
                }
                if ((m2np.rt.hop_code & M2HC_ORIG) != 0) {
                    m2np.rt.orig.value = q_markbyte(&rxq, m2np.rt.orig.length);
                }
                if ((m2np.rt.hop_code & M2HC_DEST) != 0) {
                    m2np.rt.dest.value = q_markbyte(&rxq, m2np.rt.dest.length);
                }
            }
        } // Note case fall-through
    
        case M2FI_STREAM: {
            /// M2DP gets parsed just like M2NP, but it uses the Network data
        	/// stored from the last M2NP frame
            route_val = m2qp_parse_frame(session);
            break;
        }
        
        case M2FI_RFU: break;
    }
    
    /// Attach footer to response, if necessary
    if (route_val >= 0) {
        m2np_footer(session);
    }

#   if (OT_FEATURE(M2NP_CALLBACKS) == ENABLED) && \
        !defined(EXTF_network_sig_route)
        m2np.signal.route(route_val, session->protocol);
#   elif defined(EXTF_network_sig_route)
        network_sig_route(route_val, session->protocol);
#   endif
    
    return route_val;
}