=====

/* handle control messages */
// op codes:
//   set:
//	<delay	set delay to x msec (e.g., "<delay 50")
//   get:
//	>ninq	get ninq (#pkts in queue)
//	>npkts	get npkts seen by plugin (stored in plugin counter 0)
//	>delay	get delay (msec)
//   miscellaneous:
//	reset	reset npkts and clear queue
//
void handle_msg()
{
    // assume messages are at most 8 words for now
    __declspec(gp_reg) unsigned int i;
    __declspec(gp_reg) unsigned int message[8];
    __declspec(gp_reg) onl_api_ctrl_msg_hdr hdr;
    __declspec(gp_reg) char *valptr;
    __declspec(local_mem) char inmsgstr[28];			// inbound
    __declspec(local_mem) char outmsgstr[28] = "";		// outbound
    __declspec(local_mem) char tmpstr[20];

    __declspec(local_mem) char SET_delay[7] = "<delay";		// request msgs
    __declspec(local_mem) char GET_ninq[6] = ">ninq";
    __declspec(local_mem) char GET_npkts[7] = ">npkts";
    __declspec(local_mem) char GET_delay[7] = ">delay";
    __declspec(local_mem) char RESET[6] = "reset";
    __declspec(local_mem) char BAD_op[7] = "BAD OP";		// error msgs
    __declspec(local_mem) char NO_arg[7] = "NO ARG";
    __declspec(local_mem) char NOT_impl[9] = "NOT IMPL";

    for(i=0; i<8; ++i) { message[i] = 0; }

    dl_source_message(msgFromBlock, message);

    hdr.value = message[0];
    if( hdr.type != CM_CONTROLMSG )	return;
    if( hdr.response_requested != 1 )	return;

    onl_api_intarr2str( &message[1], inmsgstr );

    if( strncmp_lmem(inmsgstr, SET_delay, 6) == 0 ) {
	valptr = nxt_token( &message[2], 20 ); 
	if( valptr == 0 ) {
	    strcat_lmem( outmsgstr, NO_arg );
	} else {
	    delay = onl_api_atoi( valptr );
	    onl_api_itoa( delay, &message[1], 24 );
	    strcat_lmem( outmsgstr, &message[1] );
	}
    elseif( strncmp_lmem(inmsgstr, GET_ninq, 5) == 0 ) {
	onl_api_itoa( ninq, &message[1], 24 );
    	strcat_lmem( outmsgstr, &message[1] );
    elseif( strncmp_lmem(inmsgstr, GET_npkts, 6) == 0 ) {
	onl_api_itoa( npkts, &message[1], 24 );
    	strcat_lmem( outmsgstr, &message[1] );
    elseif( strncmp_lmem(inmsgstr, GET_delay, 6) == 0 ) {
	onl_api_itoa( delay, &message[1], 24 );
    	strcat_lmem( outmsgstr, &message[1] );
    elseif( strncmp_lmem(inmsgstr, RESET, 5) == 0 ) {
    	strcat_lmem( outmsgstr, NOT_impl );
    } else {
    	strcat_lmem( outmsgstr, BAD_op );
    }

    if( onl_api_str2intarr(outmsgstr, &message[1]) < 0 )	return;

    hdr.type = CM_CONTROLMSGRSP;
    hdr.response_requested = 0;
    hdr.num_words = 7;
    message[0] = hdr.value;

    dl_sink_message(msgNextBlock, message);
}

<< nxt_token( char_ptr, nchars ) >>
	find spaces;
	p = move across spaces;
	return p;

static __forceinline char *
nxt_token( __declspec(gp_reg) char *p, __declspec(gp_reg) int n ) {
    __declspec(gp_reg) char *pend;

    pend = p + n;

    while( p<pend ) {		// find SP char
    	if( *p == ' ' )	break;
	p++;
    }
    if( p >= pend )	return 0;
    ++p;

    while( p<pend ) {		// scan past SP characters
    	if( *p == ' ' )	++p;
	else		break;
    }

    if( p >= pend )	return 0;
    else		return p;
}


<< onl_api_itoa( int, char_ptr, nchars ) >>

static __forceinline char *
onl_api_utoa(	__declspec(gp_reg) unsigned long x,
		__declspec(gp_reg) char *p,
		__declspec(gp_reg) int n ) {
    __declspec(gp_reg) int k;
    __declspec(gp_reg) int r;
    __declspec(gp_reg) char *pend;

    pend = p + n - 1;
    *pend = '\0';
    --pend;

    while( pend >= p ) {
    	if( x > 0 ) {
    	    r = x%10;
	    *pend = '0' + r;
	} else {
	    *pend = ' ';
	}
	x = x/10;
    	--pend;
    }
}

=====
