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); }
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; }
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; }
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); }
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 }
/** 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); } }
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(); }
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; }