[Tinyos-beta-commits] CVS: tinyos-1.x/beta/platform/imote2 BluSH.h, NONE, 1.1 BluSHC.nc, NONE, 1.1 BluSHM.nc, NONE, 1.1 BluSH_AppI.nc, NONE, 1.1 BluSH_types.h, NONE, 1.1 UARTBufferC.nc, NONE, 1.1 UARTBufferM.nc, NONE, 1.1 cmdlinetools.c, NONE, 1.1

Robbie Adler radler at users.sourceforge.net
Tue Mar 8 16:59:27 PST 2005


Update of /cvsroot/tinyos/tinyos-1.x/beta/platform/imote2
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25268

Added Files:
	BluSH.h BluSHC.nc BluSHM.nc BluSH_AppI.nc BluSH_types.h 
	UARTBufferC.nc UARTBufferM.nc cmdlinetools.c 
Log Message:

	Initial IM2 support for UART based shell (BluSH).  At some point in the future, BluSH should probably become it's own entity, but for now...


--- NEW FILE: BluSH.h ---
// Number of interfaces.
#define __BLUSH_APP_COUNT__ uniqueCount("BluSH")
enum
  {
    BLUSH_APP_COUNT = __BLUSH_APP_COUNT__
  };

--- NEW FILE: BluSHC.nc ---
configuration BluSHC {
  provides interface StdControl;
  uses interface BluSH_AppI[uint8_t id];
}

implementation {
    components 
        UARTBufferC as UARTBuffer,
        //DebugUARTBufferC as UARTBuffer,
        BluSHM;
  
    StdControl = BluSHM;
    
    BluSHM.UartControl -> UARTBuffer.Control;
    BluSHM.UartSend -> UARTBuffer.SendVarLenPacket;
    BluSHM.UartReceive -> UARTBuffer.ReceiveData;
    
    BluSH_AppI = BluSHM;
}

--- NEW FILE: BluSHM.nc ---
module BluSHM {
  provides
    {
      interface StdControl;
    }

    uses
      {
        interface StdControl as UartControl;
        interface SendVarLenPacket as UartSend;
        interface ReceiveData as UartReceive;
       
        interface BluSH_AppI[uint8_t id];
      }
}

implementation
{
#include "cmdlinetools.c"
#include "BluSH_types.h"
    //#include <stdio.h>  something is wrong with stdio.h
#include <stdarg.h>

#ifdef __GNUC__
#define __VALIST __gnuc_va_list
#else
#define __VALIST char*
#endif


int vsnprintf(char *, size_t, const char *, __VALIST) __attribute__ ((C, spontaneous));

#define BLUSH_PROMPT_LENGTH 32
  char blush_prompt[ BLUSH_PROMPT_LENGTH ];


  // Index 0 is the current command line.
#define BLUSH_HISTORY_LENGTH 4
#define BLUSH_CMDLINE_LENGTH 80
  char blush_history[ BLUSH_HISTORY_LENGTH ][ BLUSH_CMDLINE_LENGTH ];
  uint16_t blush_cmdline_idx;
  uint16_t blush_history_idx;

  uint8_t funcIdx;
  uint8_t funcIdxInUse;
  char funcCmd[ BLUSH_CMDLINE_LENGTH ];

#define MAX_RETURN_STRING 255


  // Internal commands: help, ls, prompt, readmem, writemem.
#if 0
  void TraceCallback(char *buf, uint16 buflen) __attribute__((C, spontaneous)){
    call UartSend.send(buf,buflen);
  }
#endif

#define MAX_PRINTF_LEN 400
  //void trace(TOS_dbg_mode mode, const char *format, ...) { 
  void trace(const char *format, ...) __attribute ((C, spontaneous)) { 
      // if (trace_active(mode)) 
      {
        char buf[MAX_PRINTF_LEN+1];
        uint16_t buflen;
        va_list args;

        va_start(args, format); 
        //if (!(mode & DBG_SIM)) 
        {
            buflen=vsnprintf(buf,MAX_PRINTF_LEN,format,args);
            //make sure that we're properly terminating our string...
            buflen = (buflen>=MAX_PRINTF_LEN) ? MAX_PRINTF_LEN:buflen;
            buf[MAX_PRINTF_LEN] = 0;
            call UartSend.send(buf,buflen);
        }
    }    
}

  
  command result_t StdControl.init()
    {
      uint16_t i;

      blush_cmdline_idx = 0;
      blush_history_idx = 0;

      funcIdxInUse = 0;

      // Clear history.
      for( i = 0; i < BLUSH_HISTORY_LENGTH; i++ )
        {
          blush_history[i][0] = '\0';
        }

//      trace_set(DBG_USR1|DBG_USR2|DBG_USR3);
      call UartControl.init();
      strncpy( blush_prompt, "BluSH>", BLUSH_PROMPT_LENGTH );
      return SUCCESS;
    }
    
  command result_t StdControl.start()
    {
      call UartControl.start();
      call UartSend.send( "\r\n", strlen("\r\n") );
      call UartSend.send( blush_prompt, strlen(blush_prompt) );
      return SUCCESS;
    }

  command result_t StdControl.stop()
    {
      call UartControl.stop();
      return SUCCESS;
    }

  default command BluSH_result_t BluSH_AppI.getName[uint8_t id](char* buff, uint8_t len )
    {
      buff[0] = '\0';
      return BLUSH_SUCCESS_DONE;
    }

  default command BluSH_result_t BluSH_AppI.callApp[uint8_t id]( char* cmdBuff, uint8_t cmdLen,
                                                                 char* resBuff, uint8_t resLen )
    {
      resBuff[0] = '\0';
      return BLUSH_SUCCESS_DONE;
    }


  task void ls()
    {
      uint8_t i;
      char temp[ BLUSH_CMDLINE_LENGTH ];

      for( i = 0; i < BLUSH_APP_COUNT; i++ )
        {
          call BluSH_AppI.getName[i]( temp, BLUSH_CMDLINE_LENGTH );
          call UartSend.send( temp, strlen(temp) );
          call UartSend.send( "\r\n", 2 );
        }
    } 


  task void help()
    {
      call UartSend.send( "Blue Shell v1.0 (BluSH)\r\n", 
                          strlen("Blue Shell v1.0 (BluSH)\r\n") );
      call UartSend.send( "help - Display this list\r\n", 
                          strlen("help - Display this list\r\n") );
      call UartSend.send( "ls - Display all application commands\r\n", 
                          strlen("ls - Display all application commands\r\n") );
      call UartSend.send( "history - Display the command history\r\n", 
                          strlen("history - Display the command history\r\n") );
      call UartSend.send( "prompt - Allows you to change the prompt\r\n", 
                          strlen("prompt - Allows you to change the prompt\r\n") );
    }


  task void history()
    {
      uint16_t hist_idx;
      for( hist_idx = BLUSH_HISTORY_LENGTH-1; hist_idx > 0; hist_idx-- )
        {
          if( blush_history[ hist_idx ][0] != '\0' )
            {
              call UartSend.send( blush_history[ hist_idx ], 
                                  strlen(blush_history[ hist_idx ]) );
                              
              call UartSend.send( "\r\n", strlen("\r\n") );
            }
        }
    }

  /*
  task void prompt()
    {
      uint16_t frstSpc;
      frstSpc = firstSpace( blush_history[0], 0 );
      if( frstSpc == 0 )
        {
          call UartSend.send( "prompt <new prompt string>\r\n",
                              strlen("prompt <new prompt string>\r\n") );
        }
      else
        {
          strncpy( blush_prompt, &(blush_history[0][frstSpc+1]), BLUSH_PROMPT_LENGTH );
        }
    }
  */


  task void printCmdLine()
    {
      // Print out prompt.
      call UartSend.send( blush_prompt, strlen(blush_prompt) );
      // Last but not least, null terminate the command line.
      blush_history[0][0] = '\0';
      blush_cmdline_idx = 0;
      blush_history_idx = 0;
    }


  task void callFunc()
    {
      char retStr[ MAX_RETURN_STRING ];
      call BluSH_AppI.callApp[funcIdx]( funcCmd, BLUSH_CMDLINE_LENGTH, 
                                        retStr, MAX_RETURN_STRING );

      // Watch out for buffer overflow.
      retStr[ MAX_RETURN_STRING - 1 ] = '\0';
      
      call UartSend.send( retStr, strlen(retStr) );

      funcIdxInUse = 0;
    }

#define UP_ARROW 0x41
#define DOWN_ARROW 0x42
  
  event result_t UartReceive.receive( uint8_t* buff, uint32_t numBytesRead )
    {
      uint16_t i, hist_idx, cmd_idx;
      char temp[ BLUSH_CMDLINE_LENGTH ];

      uint8_t frstSpc;
      static uint8_t uSpecialChar=0;
      
      for( i = 0; i < numBytesRead; i++ )
        {
            // Need to look for special characters:
            
          // ENTER is 0x0d
          if( buff[i] == 0x0d )
            {
              // Append \0
              blush_history[0][ blush_cmdline_idx ] = '\0';

              // Output new line.
              call UartSend.send( "\r\n", 2 );

              // Get rid of whitespace.
              killWhiteSpace( blush_history[0] );

              // check if there is anything meaningful
              if( blush_history[0][ 0 ] == '\0' )
                {
                  // Do nothing.
                  post printCmdLine();
                }
              else
                {              
                  // Copy history
                  for( hist_idx = BLUSH_HISTORY_LENGTH-1; hist_idx > 0; hist_idx-- )
                    {
                      // Rollover to 65535 is intentional.
                      cmd_idx = -1;
                      do
                        {
                          cmd_idx++;
                          blush_history[ hist_idx ][ cmd_idx ] = 
                            blush_history[ hist_idx-1 ][ cmd_idx ];
                        }
                      while( cmd_idx < BLUSH_CMDLINE_LENGTH
                             && blush_history[ hist_idx-1 ][ cmd_idx ] != '\0' );
                    }

                  // Process cmdline.
                  // Look for internal commands first, then blush_app commands.
                  if( 0 == strncmp( "help", blush_history[0], strlen("help") ) )
                    {
                      post help();
                      post printCmdLine();
                      
                      /*
                        call UartSend.send( "Blue Shell v1.0 (BluSH) Native Commands\r\n", 
                        strlen("Blue Shell (BluSH) Native Commands\r\n") );

                        call UartSend.send( "help - Display this list\r\n", 
                        strlen("help - Display this list\r\n") );
                        call UartSend.send( "ls - Display all application commands\r\n", 
                        strlen("ls - Display all application commands\r\n") );
                        call UartSend.send( "history - Display the command history\r\n", 
                        strlen("history - Display the command history\r\n") );
                        call UartSend.send( "prompt - Allows you to change the prompt\r\n", 
                        strlen("prompt - Allows you to change the prompt\r\n") );
                      */
                    }
                  else if( 0 == strncmp( "ls", blush_history[0], strlen("ls") ) )
                    {
                      post ls();
                      post printCmdLine();
                      /*
                        for( i = 0; i < BLUSH_APP_COUNT; i++ )
                        {
                        call BluSH_AppI.getName[i]( temp, BLUSH_CMDLINE_LENGTH );
                        call UartSend.send( temp, strlen(temp) );
                        call UartSend.send( "\r\n", 2 );
                        }
                      */
                    }
                  else if( 0 == strncmp( "prompt", blush_history[0], strlen("prompt") ) )
                    {
                      //post prompt();
                      //post printCmdLine();

                      
                      frstSpc = firstSpace( blush_history[0], 0 );
                      if( frstSpc == 0 )
                        {
                          call UartSend.send( "prompt <new prompt string>\r\n",
                                              strlen("prompt <new prompt string>\r\n") );
                        }
                      else
                        {
                          strncpy( blush_prompt, &(blush_history[0][frstSpc+1]), BLUSH_PROMPT_LENGTH );
                        }

                      post printCmdLine();
                      
                    }
                  else if( 0 == strncmp( "history", blush_history[0], strlen("history") ) )
                    {
                      post history();
                      post printCmdLine();

                      /*
                        for( hist_idx = BLUSH_HISTORY_LENGTH-1; hist_idx > 0; hist_idx-- )
                        {
                        if( blush_history[ hist_idx ][0] != '\0' )
                        {
                        call UartSend.send( blush_history[ hist_idx ], 
                        strlen(blush_history[ hist_idx ]) );
                              
                        sprintf( temp, "%d", strlen(blush_history[ hist_idx ]) );
                              
                        //call UartSend.send( temp,
                        //strlen(temp) );
                              

                        call UartSend.send( "\r\n", strlen("\r\n") );
                        }
                        }
                      */
                    }
                  else
                    {
                      if( funcIdxInUse == 0 )
                        {
                          // Loop through app commands.
                          for( i = 0; i < BLUSH_APP_COUNT; i++ )
                            {
                              call BluSH_AppI.getName[i]( temp, BLUSH_CMDLINE_LENGTH );
                              if( (strncmp( temp,
                                            blush_history[0],
                                            strlen(temp)) == 0)
                                  && ((blush_history[0][strlen(temp)] == ' ')
                                      || (blush_history[0][strlen(temp)] == '\0')) )
                                {
                                  funcIdx = i;
                                  funcIdxInUse = 1;
                                  strcpy( funcCmd, blush_history[0] );
                              
                                  post callFunc();
                                  
                                  /*
                                    call BluSH_AppI.callApp[i]( blush_history[0], BLUSH_CMDLINE_LENGTH, 
                                    temp2, BLUSH_CMDLINE_LENGTH );
                                    call UartSend.send( temp2, strlen(temp2) );
                                  */
                                  break;
                                }
                            }

                          if( i == BLUSH_APP_COUNT )
                            {
                              call UartSend.send( "Bad command\r\n", strlen("Bad command\r\n") );
                            }
                        }
                      else
                        {
                          call UartSend.send( "Shell Busy\r\n",
                                              strlen("Shell Busy\r\n") );
                        }
                      post printCmdLine();
                    }
                }

              /*
              // Print out prompt.
              call UartSend.send( blush_prompt, strlen(blush_prompt) );
              // Last but not least, null terminate the command line.
              blush_history[0][0] = '\0';
              blush_cmdline_idx = 0;
              blush_history_idx = 0;
              */
            }
          // CTRL-C
          else if( buff[i] == 0x03 )
            {
              // Discard history.
              blush_cmdline_idx = 0;
              blush_history_idx = 0;
              blush_history[0][0] = '\0';

              // print out new line and prompt.
              call UartSend.send( "\r\n", 2 );
              call UartSend.send( blush_prompt, strlen(blush_prompt) );

            }
          // TAB is 0x09
          else if( buff[i] == 0x09 )
            {
              // Tab completetion.
              // Search through list of available names.
              // Ouput correct one, or beep.
              for( i = 0; i < BLUSH_APP_COUNT; i++ )
                {
                  call BluSH_AppI.getName[i]( temp, BLUSH_CMDLINE_LENGTH );
                  if( strncmp( blush_history[0],
                               temp,
                               strlen(blush_history[0])) == 0 )
                    {
                      call UartSend.send( temp+strlen(blush_history[0]),
                                          strlen(temp)-strlen(blush_history[0]) );
                      call UartSend.send( " ", 1 );
                      strcat( blush_history[0], temp+strlen(blush_history[0]) );
                      strcat( blush_history[0], " " );
                      blush_cmdline_idx = strlen(temp)+1;

                      // add NULL.
                      blush_history[0][blush_cmdline_idx] = '\0';
                      break;
                    }
                }

              if( i >= BLUSH_APP_COUNT )
                {
                  // No match found.  Send beep.
                  call UartSend.send( "\a", 1 );
                }
            }
          // Arror keys.
          else if( buff[i] == 0x1b  || uSpecialChar!=0 ){
              static int special_i=0;
              //check to see if the current char is part of the escape sequence
              switch(special_i){
              case 0:
                  uSpecialChar=1;
                  special_i++;
                  break;
              case 1:
                  if(buff[i]!=0x5b){
                      uSpecialChar=0;
                      special_i=0;
                      //at this point, we know that our escape sequence was invalid, so we should treat
                      //the current character as a normal character...need to fall through on the outer loop
                      //at the moment, I'm happy with losing a character if the escape key is pressed
                      continue;
                  }
                  
                  special_i++;
                  break;
              case 2:
                  uSpecialChar=buff[i];
              case 3:
              case 4:
              case 5:
                  //pretty much need to assume that these characters are 0's
                  special_i++;
              }
              
              
              
              if( special_i == 6 && uSpecialChar == UP_ARROW ){
                  // Then it is an up arrow.
                  if( blush_history_idx < BLUSH_HISTORY_LENGTH-1 ){
                      blush_history_idx++;
                      
                      // Erase what's currently there.
                      for( i = 0; i < blush_cmdline_idx; i++ ){
                          // send backspace space backspace sequenence
                          call UartSend.send("\b \b", 3 );         
                      }
                      
                      // Copy history index.
                      strcpy( blush_history[0], blush_history[ blush_history_idx ] );
                      call UartSend.send( blush_history[0], strlen(blush_history[0]) );  
                      blush_cmdline_idx = strlen(blush_history[0]);
                  }
                  else{
                      call UartSend.send( "\a", 1 );
                  }
              } // Check for up arrow.
              else if( special_i == 6 && uSpecialChar == DOWN_ARROW ){
                  // Then it is a down arrow.
                  if( blush_history_idx > 0 ){
                      blush_history_idx--;
                      if( blush_history_idx == 0 ){
                          // Erase what's currently there.
                          for( i = 0; i < blush_cmdline_idx; i++ ){
                              // send backspace space backspace sequence
                              call UartSend.send("\b \b", 3 );         
                          }
                          blush_cmdline_idx = 0;
                          blush_history[0][0] = '\0';
                      }
                      else{
                          // Erase what's currently there.
                          for( i = 0; i < blush_cmdline_idx; i++ ){
                              // send backspace space backspace sequence
                              call UartSend.send("\b \b", 3 );         
                          }
                          
                          // Copy history index.
                          strcpy( blush_history[0], blush_history[ blush_history_idx ] );
                          call UartSend.send( blush_history[0], strlen(blush_history[0]) );  
                          blush_cmdline_idx = strlen(blush_history[0]);
                      }
                  }
                  else{
                      call UartSend.send( "\a", 1 );
                  }
              } // check for down arrow.
              if(special_i==6){
                  special_i=0;
                  uSpecialChar=0;
              }
          } // Special char check.
          
          // Backspace
          else if( buff[i] == '\b' )
            {
              if( blush_cmdline_idx > 0 )
                {
                  // Echo the character back.
                  call UartSend.send( &buff[i], 1 );         
                  // Print a space
                  call UartSend.send( " ", 1 );         
                  // Echo the character back.
                  call UartSend.send( &buff[i], 1 );         
                  blush_cmdline_idx--;
                  
                  blush_history[0][blush_cmdline_idx] = '\0';
                }
              else
                {
                  call UartSend.send( "\a", 1 );         
                }
            }
          else // Normal character.
            {
              // By this time we know that it's not a special character.
              // Copy it into our buffer.
              if( blush_cmdline_idx < BLUSH_CMDLINE_LENGTH - 1 )
                {
                  blush_history[0][ blush_cmdline_idx ] = buff[ i ];
                  blush_cmdline_idx++;
                  // Put a \0 on the end for safety.
                  blush_history[0][ blush_cmdline_idx ] = '\0';

                  // Echo the character back.
                  call UartSend.send( &buff[i], 1 );         
                }
              else
                {
                  // Send bell back, avoid buffer overflow.
                  //buff[i] = '\a';
                  call UartSend.send( "\a", 1 );         
                }
            }
        }
      
      return SUCCESS;
    }

  event result_t UartSend.sendDone(uint8_t* packet, result_t success)
    {
      // This function does nothing.
      return SUCCESS;
    }
}

--- NEW FILE: BluSH_AppI.nc ---
/* Blue Shell (BluSH) application (aka module) interface */

includes BluSH_types;
includes BluSH;

interface BluSH_AppI
{
  command BluSH_result_t getName( char* buff, uint8_t len );
  command BluSH_result_t callApp( char* cmdBuff, uint8_t cmdLen,
                                  char* resBuff, uint8_t resLen );
}

--- NEW FILE: BluSH_types.h ---
enum 
  {
    BLUSH_SUCCESS_DONE = 0,
    BLUSH_SUCCESS_NOT_DONE,
    BLUSH_FAIL
  };

typedef uint8_t BluSH_result_t;

--- NEW FILE: UARTBufferC.nc ---
configuration UARTBufferC {
  provides {
    interface StdControl as Control;
    interface SendVarLenPacket;
    interface ReceiveData;
  }
}
implementation {
  components UARTBufferM, UART;

  Control = UARTBufferM;
  SendVarLenPacket = UARTBufferM;
  ReceiveData = UARTBufferM;

  UARTBufferM.ByteComm -> UART;
  UARTBufferM.ByteControl -> UART;
}

--- NEW FILE: UARTBufferM.nc ---
/*									tab:4
 *  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.  By
 *  downloading, copying, installing or using the software you agree to
 *  this license.  If you do not agree to this license, do not download,
 *  install, copy or use the software.
 *
 *  Intel Open Source License
 *
 *  Copyright (c) 2002 Intel Corporation
 *  All rights reserved.
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *
 *	Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *	Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *      Neither the name of the Intel Corporation nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 *  PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE INTEL OR ITS
 *  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 *  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 *  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 */

/*
 * This module maintains a buffer of characters to put on the UART.
 * It copies incoming characters into the buffer and streams them out the
 * UART as each previous character finishes.
 */

module UARTBufferM {
  provides {
    interface StdControl as Control;
    interface SendVarLenPacket;
    interface ReceiveData;

  }
  uses {
    interface ByteComm;
    interface StdControl as ByteControl;
  }
}

implementation
{

  uint32_t Head;               // Next entry in the buffer to fill
  uint32_t Tail;               // Oldest entry in the buffer
  // Head == Tail -> buffer is empty

  #define NEXT_BUFFER(ent, max) (((ent) >= ((max) - 1)) ? 0 : ((ent) + 1))
  #define BUFFER_SIZE 400    // maximum characters buffered in the queue
  char Buffer[BUFFER_SIZE];  // circular buffer of characters

  bool BytePending;          // whether there is a byte sent w/o a
                             // corresponding sendDone


/*
 * Start of StdControl interface
 */

  command result_t Control.init() {
    Head = 0;
    Tail = 0;
    atomic {
       BytePending = FALSE;
    }

    return call ByteControl.init();
  }

  command result_t Control.start() {
    return call ByteControl.start();
  }

  command result_t Control.stop() {
    return call ByteControl.stop();
  }

/*
 * End of StdControl interface
 */



   result_t SendNextByte() {
     bool busy;
     atomic {
        busy = (BytePending == TRUE);
     }
     if (busy) {
        return FAIL;
     }

     if (Head == Tail) return SUCCESS; // buffer is empty

     atomic {
        BytePending = TRUE;
     }

     call ByteComm.txByte(Buffer[Tail]);
//     if (call ByteComm.txByte(Buffer[Tail]) == FAIL) {
//       // UART not enabled
//       Tail = Head;
//       BytePending = FALSE;
//     }

     return SUCCESS;
   }

/*
 * Start of SendVarLenPacket interface
 */

  command result_t SendVarLenPacket.send(uint8_t* data, uint8_t length) {
    int     i, size;
    bool    not_busy;

    // see if there's enough room for this packet
    size = (Head < Tail) ? Head + BUFFER_SIZE - Tail : Head - Tail;
    if (size + length >= BUFFER_SIZE) return FAIL; // not enough room

    // copy incoming bytes to the buffer
    for (i = 0; i < length; i++) {
      Buffer[Head] = data[i];
      Head = NEXT_BUFFER(Head, BUFFER_SIZE);
    }

    atomic {
       not_busy = (BytePending == FALSE);
    }

    if (not_busy) SendNextByte();

    return SUCCESS;
  }

  default event result_t SendVarLenPacket.sendDone(uint8_t* data, result_t suc) {
    return suc;
  }

/*
 * End of SendVarLenPacket interface
 */



/*
 * Start of ByteComm interface
 */

  async event result_t ByteComm.txByteReady(bool success) {

    atomic {
       BytePending = FALSE;
    }
if (Head == Tail) return SUCCESS;
    Tail = NEXT_BUFFER(Tail, BUFFER_SIZE);
    SendNextByte();

    return SUCCESS;
  }

  // this appears to be redundant in the interface with txByteReady
  async event result_t ByteComm.txDone() { return SUCCESS; }

  async event result_t ByteComm.rxByteReady(uint8_t data, bool error, uint16_t str) {
    signal ReceiveData.receive(&data, 1);
    return SUCCESS;
  }

/*
 * End of ByteComm interface
 */



/*
 * Start of ReceiveData interface
 */

  default event result_t ReceiveData.receive(uint8_t* Data, uint32_t Length) {
    return SUCCESS;
  }

/*
 * End of ReceiveData interface
 */

}


--- NEW FILE: cmdlinetools.c ---
#include <inttypes.h>
// Command line tools.

// Get rid of extra whitespace.
void killWhiteSpace( char* str );

void killWhiteSpace( char* str )
{
  uint16_t i, j;
  uint16_t startIdx;
  
  // Find first character or line end.
  for( i = 0; str[i] != '\0'; i++ )
    {
      if( str[i] != ' ' )
        {
          break;
        }
    }

  // Check for end of line.
  if( str[i] == '\0' )
    {
      // Empty string.
      str[0] = '\0';
      return;
    }


  startIdx = 0;
  while( 1 )
    {
      // i is the first character of the next word.
      // startIdx is where it needs to be copied to.

      // Copy line back.
      j = startIdx;
      while( str[i] != '\0' )
        {
          str[j] = str[i];
          i++;
          j++;
        }
      // Append '\0';
      str[j] = '\0';

      // Move startIdx to end of word.          
      for( ; str[startIdx] != ' ' && str[startIdx] != '\0'; startIdx++ )
        {}

      // See if next word exists;
      // Looking for a isalpha.
      for( j = startIdx; str[j] != '\0'; j++ )
        {
          if( str[j] != ' ' )
            {
              break;
            }
        }

      // See if we fell off the end.
      if( str[j] == '\0' )
        {
          // We're done.
          // Copy the \0.
          str[startIdx] = '\0';
          return;
        }

      // Copy a space.
      str[startIdx] = ' ';
      startIdx++;

      // j is the start of the next word.
      i = j;
    }
}


uint16_t firstSpace( char* str, uint16_t start )
{
  uint16_t i;
  for( i = start; str[i] != '\0'; i++ )
    {
      if( str[i] == ' ' )
        {
          return i;
        }
    }
  return start;
}

uint16_t cntArgs( char* str, uint16_t start )
{
  uint16_t count, i;
  count = i = 0;

  // Rollover of i is intentional.
  i--;
  
  do
    {
      i++;
      if( str[i] == ' ' || str[i] == '\0' )
        {
          count++;
        }
    }
  while( str[i] != '\0' );

  return count;
}



More information about the Tinyos-beta-commits mailing list