Example #1
0
void m2np_put_deviceid(ot_bool use_vid) {
    vlFILE* fp;
    
    //file 0=network_settings, 1=device_features
    fp = ISF_open_su( (ot_u8)(use_vid == False) );
    ///@todo assert fp

    q_writeshort_be( &txq, vl_read(fp, 0) );
    if (use_vid == False) {
    	q_writeshort_be( &txq, vl_read(fp, 2) );
    	q_writeshort_be( &txq, vl_read(fp, 4) );
    	q_writeshort_be( &txq, vl_read(fp, 6) );
    }
    
    vl_close(fp);
}
Example #2
0
ot_bool m2np_idcmp(ot_int length, void* id) {
    ot_bool check   = True;
    ot_u8   use_uid = (length == 8);
    vlFILE* fp;
    
    //file 0=network_settings, 1=device_features
    fp      = ISF_open_su( use_uid );
    check  &= ( ((ot_u16*)id)[0] == vl_read(fp, 0));

    if (use_uid) {
        check &= ( ((ot_u16*)id)[1] == vl_read(fp, 2) );
        check &= ( ((ot_u16*)id)[2] == vl_read(fp, 4) );
        check &= ( ((ot_u16*)id)[3] == vl_read(fp, 6) );
    }
    
    vl_close(fp);
    return check;
}
Example #3
0
OT_WEAK void dll_systask_sleepscan(ot_task task) {
/// The Sleep Scan process runs as an independent task.  It is very similar
/// to the Hold Scan process, which actually calls this same routine.  They
/// use independent task markers, however, so they behave differently.
    ot_u8       s_channel;
    ot_u8       s_code;
    ot_uni16    scratch;
    vlFILE*     fp;
    m2session*  s_new;

    /// event = 0 is the initializer, but there is no state-based operation
    /// or any heap-stored data for this task, so it does nothing
    if (task->event == 0) {
        return;
    }

    fp = ISF_open_su( task->event );
    ///@note fp doesn't really need to be asserted unless you are mucking
    ///      with things in test builds.

    /// Pull channel ID and Scan flags
    scratch.ushort  = vl_read(fp, task->cursor);
    s_channel       = scratch.ubyte[0];
    s_code          = scratch.ubyte[1];

    /// Set the next idle event from the two-byte Next Scan field.
    /// The DASH7 registry is big-endian.
    scratch.ushort  = PLATFORM_ENDIAN16( vl_read(fp, (task->cursor)+=2 ) );
    sys_task_setnext(task, scratch.ushort);

    /// Advance cursor to next datum, go back to 0 if end of sequence
    /// (still works in special case where cursor = 254)
    task->cursor   += 2;
    task->cursor    = (task->cursor >= fp->length) ? 0 : task->cursor;
    vl_close(fp);

    /// Choosing Background-Scan or Foreground-Scan is based on scan-code.
    /// If b7 is set, do a Background-Scan.  At the session level, the "Flood"
    /// select uses b6, which is why there is a >> 1.
    s_new           = session_new(&dll_scan_applet, 0, s_channel,
                                    ((M2_NETSTATE_REQRX | M2_NETSTATE_INIT) | (s_code & 0x80) >> 1)  );
    s_new->extra    = s_code;
}
Example #4
0
void AES_load_static_key(ot_u8 key_id, ot_u32* key) {
    ot_int i;
    vlFILE* fp;
    
    fp = ISF_open_su(key_id);
    for (i=0; i<16; i+=2) {
        *(ot_u16*)((ot_u8*)key+i) = vl_read(fp, i);
    }
    vl_close(fp);
}
Example #5
0
OT_WEAK void dll_refresh_rts(void) {
#if (OT_FEATURE(CRON) && M2_FEATURE(RTC_SCHEDULER))
///@todo need to update this implementation to also delete the old tasks.

    vlFILE* fp;

    // Early exit if RTS is not active
    if (dll.netconf.active_settings & M2_SET_SCHEDMASK) == 0)
        return;

    // - open the real-time-schedule ISF
    // - make sure the file is there
    // - make sure the file has at least 12 bytes (this is how much DLL uses)
    fp = ISF_open_su(ISF_ID_real_time_scheduler);
    if (fp != NULL) {
        if (fp->length < 12) {
            static const ot_task task_fn[3] = { &dll_systask_holdscan,
                                                &dll_systask_sleepscan,
                                                &dll_systask_beacon };

            ot_u16  sched_enable    = dll.netconf.active_settings & M2_SET_SCHEDMASK;
            ot_u16  cursor          = 0;
            ot_sigv* fn             = task_fn;

            // Apply Hold, Sleep, and Beacon RTS as specified in enabler bitmask
            while (sched_enable != 0) {
                if (sched_enable & M2_SET_HOLDSCHED) {
                    ot_u32 time_evt;
                    ot_u32 time_mask;
                    time_evt    = vl_read(fp, cursor);
                    time_mask   = 0xFFFF0000 | vl_read(fp, cursor+2);
                    otcron_add(*fn, CRONTIME_absolute, time_evt, time_mask);
                }
                fn++;
                cursor         += 4;
                sched_enable  <<= 1;
            }
        }
        vl_close(fp);
    }
#endif
}
Example #6
0
/** 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);
    }
}
Example #7
0
OT_WEAK void dll_change_settings(ot_u16 new_mask, ot_u16 new_settings) {
    vlFILE* fp_active;
    vlFILE* fp_supported;

    // Get Active Settings, Get Supported Settings,
    // Mask-out unsupported settings, apply to new active settings
    ///@todo assert fp
    fp_active           = ISF_open_su( 0x00 );
    fp_supported        = ISF_open_su( 0x01 );
    new_mask           &= vl_read(fp_supported, 8);
    dll.netconf.active  = vl_read(fp_active, 4);
    new_settings       &= new_mask;
    dll.netconf.active &= ~new_mask;
    dll.netconf.active |= new_settings;

    // Write the new settings to the ISF 0
    vl_write(fp_active, 4, dll.netconf.active);
    vl_close(fp_active);
    vl_close(fp_supported);

    // Flush the System of all Sessions and Events, and restart it
    sub_dll_flush();
}
Example #8
0
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;
}