コード例 #1
0
ファイル: alp_tmpl.c プロジェクト: jpnorair/OpenTag
OT_WEAK void alp_breakdown_udp_tmpl(ot_queue* in_q, void* data_type) {
    ot_int udp_data_length;
    udp_data_length                       = q_readshort(in_q);
    ((udp_tmpl*)data_type)->data_length   = udp_data_length;
    ((udp_tmpl*)data_type)->dst_port      = q_readbyte(in_q);
    ((udp_tmpl*)data_type)->src_port      = q_readbyte(in_q);
    ((udp_tmpl*)data_type)->data          = q_markbyte(in_q, udp_data_length);
}
コード例 #2
0
ファイル: alp_tmpl.c プロジェクト: jpnorair/OpenTag
OT_WEAK void alp_breakdown_ack_tmpl(ot_queue* in_q, void* data_type) {
    ot_int ack_id_count;
    ot_int ack_id_length;
    ack_id_count                    = q_readbyte(in_q);
    ack_id_length                   = q_readbyte(in_q);
    ((ack_tmpl*)data_type)->count   = (ot_u8)ack_id_count;
    ((ack_tmpl*)data_type)->length  = (ot_u8)ack_id_length;
    ((ack_tmpl*)data_type)->list    = q_markbyte(in_q, ack_id_count*ack_id_length);
}
コード例 #3
0
ファイル: alp_tmpl.c プロジェクト: jpnorair/OpenTag
OT_WEAK void alp_breakdown_query_tmpl(ot_queue* in_q, void* data_type) {
    ot_u8   query_length;
    ot_u8   query_code;
    ot_u8*  query_mask;
    
    query_code      = q_readbyte(in_q);
    query_length    = q_readbyte(in_q);
    query_mask      = NULL;
    
    if (query_code & 0x80) {
        query_mask  = q_markbyte(in_q, query_length);
    }
    
    ((query_tmpl*)data_type)->code      = query_code;
    ((query_tmpl*)data_type)->length    = query_length;
    ((query_tmpl*)data_type)->mask      = query_mask;
    ((query_tmpl*)data_type)->value     = q_markbyte(in_q, query_length);
}
コード例 #4
0
ファイル: alp_tmpl.c プロジェクト: jpnorair/OpenTag
OT_WEAK void alp_breakdown_dialog_tmpl(ot_queue* in_q, void* data_type) {
    ((dialog_tmpl*)data_type)->timeout = q_readbyte(in_q);
    
    if (((dialog_tmpl*)data_type)->timeout & 0x80) {
        ((dialog_tmpl*)data_type)->channels = q_readbyte(in_q);
        ((dialog_tmpl*)data_type)->chanlist = \
            q_markbyte(in_q, ((dialog_tmpl*)data_type)->channels);
    }
}
コード例 #5
0
ファイル: alp_tmpl.c プロジェクト: jpnorair/OpenTag
OT_WEAK void alp_breakdown_queue(ot_queue* in_q, void* data_type) {
    ot_u16 queue_length;
    ot_u8* queue_front;
    queue_length                    = q_readshort(in_q);
    ((ot_queue*)data_type)->alloc      = queue_length;
    ((ot_queue*)data_type)->options    = in_q->options;
    queue_front                     = q_markbyte(in_q, queue_length);
    ((ot_queue*)data_type)->front      = queue_front;
    ((ot_queue*)data_type)->back       = queue_front+queue_length;
    ((ot_queue*)data_type)->getcursor  = queue_front;
    ((ot_queue*)data_type)->putcursor  = queue_front;
}
コード例 #6
0
ファイル: alp_tmpl.c プロジェクト: jpnorair/OpenTag
OT_WEAK void alp_breakdown_routing_tmpl(ot_queue* in_q, void* data_type) {
    ot_u8 id_length;
    ot_u8 code_mask;
    ((routing_tmpl*)data_type)->hop_code    = q_readbyte(in_q);
    ((routing_tmpl*)data_type)->hop_ext     = q_readbyte(in_q);
    
    alp_breakdown_id_tmpl(in_q, (void*)&((routing_tmpl*)data_type)->dlog);
    
    if (((routing_tmpl*)data_type)->hop_code > 1) {
        code_mask                               = (((routing_tmpl*)data_type)->hop_ext != 0) << 7;
        id_length                               = q_readbyte(in_q);
        ((routing_tmpl*)data_type)->orig.length = id_length;
        code_mask                              |= (id_length != 0) << 6;
        code_mask                              |= (id_length == 2) << 4;
        ((routing_tmpl*)data_type)->orig.value  = q_markbyte(in_q, id_length);
        id_length                               = q_readbyte(in_q);
        ((routing_tmpl*)data_type)->dest.length = id_length;
        code_mask                              |= (id_length != 0) << 5;
        code_mask                              |= (id_length == 2) << 4;
        ((routing_tmpl*)data_type)->dest.value  = q_markbyte(in_q, id_length);
        ((routing_tmpl*)data_type)->hop_code   |= code_mask;
    }
}
コード例 #7
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;
}
コード例 #8
0
ファイル: alp_filedata.c プロジェクト: kaalabs/OpenTag
ot_int sub_filedata( alp_tmpl* alp, id_tmpl* user_id, ot_u8 respond, ot_u8 cmd_in, ot_int data_in ) {
    vlFILE* fp;
    ot_u16  offset;
    ot_u16  span;
    ot_int  data_out    = 0;
    ot_bool inc_header  = (ot_bool)((cmd_in & 0x0F) == 0x0C);
    vlBLOCK file_block  = (vlBLOCK)((cmd_in >> 4) & 0x07);
    ot_u8   file_mod    = ((cmd_in & 0x02) ? VL_ACCESS_W : VL_ACCESS_R);
    ot_queue*  inq      = alp->inq;
    ot_queue*  outq     = alp->outq;
    
    sub_filedata_TOP:
    
    while (data_in > 0) {
        vaddr   header;
        ot_u8   err_code;
        ot_u8   file_id;
        ot_u16  limit;
        
        //alp->BOOKMARK_IN    = inq->getcursor;
        //alp->BOOKMARK_OUT   = NULL;
        
        file_id     = q_readbyte(inq);
        offset      = q_readshort(inq);
        span        = q_readshort(inq);
        limit       = offset + span;
        err_code    = vl_getheader_vaddr(&header, file_block, file_id, file_mod, user_id);
        file_mod    = ((file_mod & VL_ACCESS_W) != 0);
        //fp          = NULL;
        
        // A. File error catcher Stage
        // (In this case, gotos make it more readable)
        
        /// Make sure file header was retrieved properly, or goto error
        if (err_code != 0) {
            goto sub_filedata_senderror;
        }
        
        /// Make sure file opens properly, or goto error
        fp = vl_open_file(header);
        if (fp == NULL) {
            err_code = 0xFF;
            goto sub_filedata_senderror;
        }
        
        /// Make sure offset is within file bounds, or goto error
        if (offset >= fp->alloc) {
            err_code = 0x07;
            goto sub_filedata_senderror;
        }
        
        if (limit > fp->alloc) {
            limit       = fp->alloc;
            err_code    = 0x08;
        }

        // B. File Writing or Reading Stage
        // Write to file
        // 1. Process error on bad ALP parameters, but still do partial write
        // 2. offset, span are adjusted to convey leftover data
        // 3. miscellaneous write error occurs when vl_write fails
        if (file_mod) {
            for (; offset<limit; offset+=2, span-=2, data_in-=2) {
                if (inq->getcursor >= inq->back) {
                    goto sub_filedata_overrun;      
                }
                err_code |= vl_write(fp, offset, q_readshort_be(inq));
            }
        }
        
        // Read from File
        // 1. No error for bad read parameter, just fix the limit
        // 2. If inc_header param is set, include the file header in output
        // 3. Read out file data
        else {
            ot_u8 overhead;
            //limit       = (limit > fp->length) ? fp->length : limit;
            overhead    = 6;
            overhead   += (inc_header != 0) << 2; 
            
            if ((outq->putcursor+overhead) >= outq->back) {
                goto sub_filedata_overrun;
            }
            
            q_writeshort_be(outq, vworm_read(header + 4)); // id & mod
            if (inc_header) {
                q_writeshort(outq, vworm_read(header + 0));    // length
                q_writeshort(outq, vworm_read(header + 2));    // alloc
                data_out += 4;
            }
            q_writeshort(outq, offset);
            q_writeshort(outq, span);
            data_out += 6;
            
            for (; offset<limit; offset+=2, span-=2, data_out+=2) {
                if ((outq->putcursor+2) >= outq->back) {
                    goto sub_filedata_overrun;
                }
                q_writeshort_be(outq, vl_read(fp, offset));
            }
        }
        
        // C. Error Sending Stage
        sub_filedata_senderror:
        if ((respond != 0) && (err_code | file_mod)) {
            if ((outq->putcursor+2) >= outq->back) {
                goto sub_filedata_overrun;
            }
            q_writebyte(outq, file_id);
            q_writebyte(outq, err_code);
            q_markbyte(inq, span);         // go past any leftover input data
            data_out += 2;
        }
        
        data_in -= 5;   // 5 bytes input header
        vl_close(fp);
    }
    
    
    // Total Completion:
    // Set bookmark to NULL, because the record was completely processed
    //alp->BOOKMARK_IN = NULL;
    return data_out;
    
    
    // Partial or Non Completion:
    // Reconfigure last ALP operation, because it was not completely processed
    
    ///@todo Bookmarking is obsolete, because the way Chunking is done has
    /// been revised.  Chunked records must be contiguous.  ALP-Main will not
    /// call this app, and thus not call this function, until the message-end
    /// bit is detected, therefore meaning that all data is received and
    /// contiguous.  This overrun block, thus, should only check the flags for
    /// chunking, bypass them, and loop back to the top of this function.
    sub_filedata_overrun:
    vl_close(fp);
    
    ///@todo alp_next_chunk(alp);
    
//    {
//        ot_u8* scratch;
//        inq->getcursor  = (ot_u8*)alp->BOOKMARK_IN;
//        scratch         = inq->getcursor + 1;
//        *scratch++      = ((ot_u8*)&offset)[UPPER];
//        *scratch++      = ((ot_u8*)&offset)[LOWER];
//        *scratch++      = ((ot_u8*)&span)[UPPER];
//        *scratch        = ((ot_u8*)&span)[LOWER];
//    }
    
    return data_out;
}
コード例 #9
0
ファイル: m2_transport.c プロジェクト: petertettelaar/OpenTag
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;
        }
    }
コード例 #10
0
ファイル: alp_tmpl.c プロジェクト: jpnorair/OpenTag
OT_WEAK void alp_breakdown_id_tmpl(ot_queue* in_q, void* data_type) {
    ot_int id_length;
    id_length                       = q_readbyte(in_q);
    ((id_tmpl*)data_type)->length   = id_length;
    ((id_tmpl*)data_type)->value    = (id_length==0) ? NULL : q_markbyte(in_q, id_length);
}