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. // 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) ) { app_invoke(alp->inrec.cmd); // Initialize Ping Task on supplied channel alp_load_retval(alp, 1); // Write back 1 (success) } }
OT_WEAK ot_bool alp_proc_logger(alp_tmpl* alp, id_tmpl* user_id) { /// Logger ALP is like ECHO. The input is copied to the output. // Only root can log directly (this is an important security firewall) if (auth_isroot(user_id)) { alp->OUTREC(FLAGS) = *alp->inq->getcursor++; alp->OUTREC(PLEN) = *alp->inq->getcursor++; alp->inq->getcursor+= 2; if (alp->inq != alp->outq) { q_writestring(alp->outq, alp->inq->getcursor, alp->OUTREC(PLEN)); } } return True; }
ot_bool alp_proc_logger(alp_tmpl* alp, id_tmpl* user_id) { /// Logger ALP is like ECHO. The input is copied to the output. // Only root can log directly (this is an important security firewall) if (auth_isroot(user_id) == False) return False; alp->outrec.flags = alp->inrec.flags; alp->outrec.plength = alp->inrec.plength; if (alp->inq != alp->outq) { q_writestring(alp->outq, alp->inq->getcursor, alp->inrec.plength); } return True; }
ot_bool sub_proc_api_irregular(alp_tmpl* alp, id_tmpl* user_id, otapi_icmd* cmd, ot_u8 cmd_limit) { ot_u16 retval; ot_u8 rec_cmd = alp->inq->getcursor[3]; // record command ot_u8 respond = (rec_cmd & 0x80); ot_u8 lookup_cmd = (rec_cmd & ~0x80) - 1; alp->inq->getcursor += 4; /// Do boundary check, and make sure caller is root if ( (lookup_cmd >= cmd_limit) || (auth_isroot(user_id) == False) ) return False; /// Lookup and process the irregular command, supplying it from input queue retval = cmd[lookup_cmd](alp->inq); /// Write back the twobye retval integer when response is enabled return alp_load_retval(alp, retval); }
OT_WEAK ot_bool alp_proc_api_query(alp_tmpl* alp, id_tmpl* user_id ) { /// The M2QP API calls follow the rules that future extensions to the API shall /// abide, apart from special cases which *must* be cleared by the developer /// community prior to becoming official. /// The form is: ot_u16 otapi_function(ot_u8*, void*) static const ot_u8 argmap[OTAPI_M2QP_FUNCTIONS] = \ { 6, 9, 10, 11, 12, 13, 14, 14, 15, 0, 0 }; //sub_bdtmpl get_tmpl; ot_u8 dt_buf[24]; // 24 bytes is a safe amount, although less might suffice ot_u16 txq_len; ot_u8 status = alp->inq->getcursor[3]; // record cmd ot_u8 lookup_cmd = (status & ~0x80) - 1; ot_bool respond = (ot_bool)(status & 0x80); alp->inq->getcursor += 4; if ((lookup_cmd < OTAPI_M2QP_FUNCTIONS) && auth_isroot(user_id)) { /// Load template from ALP dir cmd into C datatype bdtmpl_cmd[argmap[lookup_cmd]](alp->inq, (void*)dt_buf); /// Run ALP command, using input template txq_len = m2qp_cmd[lookup_cmd](&status, (void*)dt_buf); /// Response to ALP query command includes three bytes: /// byte 1 - status (0 is error) /// bytes 2 & 3 - 16 bit integer, length of TXQ if (respond) { //alp->outrec.flags &= ~ALP_FLAG_CF; //alp->outrec.cmd |= 0x40; //alp->outrec.plength = 3; alp->OUTREC(FLAGS) &= ~ALP_FLAG_CF; alp->OUTREC(PLEN) = 3; alp->OUTREC(CMD) |= 0x40; q_writebyte(alp->outq, status); q_writeshort(alp->outq, txq_len); } } return True; }
/** 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); } }