This is a console for interacting with Vodafone dongles.

Dependencies:   mbed-rtos VodafoneUSBModem mbed

This is a bridge between a serial driven console and a serial driven cellular modem or modem interface. This was written to complement our collaboration with mbed: See https://mbed.org/users/mbed_official/code/VodafoneUSBModem/ for further information.

For example, one can use GNU screen or PuTTY (two popular consoles) to interact with a Vodafone K3770 USB dongle. In the image below I used the UNIX version of PuTTY:

/media/uploads/ashleymills/atcons.png

Support is provided for line-based consoles, which send one line at a time, and for character based consoles.

For character based consoles, the following line-editing features are provided:

  • In-line editing (deletion, left/right arrow keys, insertion)
  • Command history (via up/down arrow keys)

Line buffer length, and command history depth, are compile-time options.

--

How to use:

Compile and save to mbed.

Connect PuTTY or GNU screen to serial port.

If you use GNU screen you probably already know what you are doing.

If you use PuTTY, you need to set the options to specify the serial device and, set the baud rate, and set the "Connection Type" to "Serial":

/media/uploads/ashleymills/putty0.png

You need to set the keyboard to send Control-H for backspace, and use "Linux" function keys and keypad:

/media/uploads/ashleymills/putty1.png

Revision:
0:6c831cc49d22
Child:
4:6971bded3ebd
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Console.cpp	Tue Aug 14 16:03:35 2012 +0000
@@ -0,0 +1,276 @@
+#include "Console.h"
+//#define DEBUG
+
+Console::Console(Serial *terminal, int lineLength, int numLines)
+    : _terminal(terminal), _lineLength(lineLength), _numLines(numLines) {
+    
+    _terminal->printf("Console ready!\r\n");
+    
+    // set the buffer timeout
+    _bufferWaitTimeout = BUFFER_WAIT_TIMEOUT;
+    
+    // allocate space for current line
+    _lineBuffer = (char*)malloc((_lineLength+1)*sizeof(char));
+    _lines = (char**)malloc(_numLines*sizeof(char*));
+    for(int i=0; i<_numLines; i++) {
+        _lines[i] = (char*)malloc((_lineLength+1)*sizeof(char));
+    }
+    
+    // blank out current line with NULLs
+    for(int i=0; i<=_lineLength; i++)
+        _lineBuffer[i] = 0x00;
+    
+    // set line position, number of used lines, and line buffer pointer to 0    
+    _linePos = 0;
+    _prevLinePos = 0;
+    _usedLines = 0;
+    _currentLine = 0;
+}
+
+// destructor
+Console::~Console() {
+    free(_lineBuffer);
+}
+
+// store the current lineBuffer in the history
+void Console::storeBuffer() {
+    // only do so if history specified
+    if(_numLines==0)
+        return;
+    
+    // imagine the command history as a FILO buffer
+    // here we rightshift the command history    
+    if(_usedLines==_numLines-1) {
+        char* p = _lines[0];
+        for(int i=0; i<_numLines-1; i++) {
+            _lines[i] = _lines[i+1];
+        }
+        _lines[_numLines-1] = p;
+    }
+    
+    // and insert the current line in the newest position
+    strncpy(_lines[_usedLines],_lineBuffer,_lineLength+1);
+    
+    // this just deals with the filling up stage
+    if(_usedLines<_numLines-1) {
+        _usedLines++;
+        if(_currentLine<_usedLines)
+            _currentLine = _usedLines;
+    } else {
+        _currentLine = _usedLines+1;
+    }
+}
+
+// clear the current-line buffer
+void Console::clearBuffer() {
+    _linePos=0;
+    for(int i=0; i<=_lineLength; i++)
+        _lineBuffer[i] = 0x00;
+}
+
+// load the next buffer in the line history (activated by DOWN key)
+void Console::loadNextBuffer() {
+    if(_currentLine<_usedLines) {
+        _currentLine++;
+    } else {
+        _linePos=0;
+        for(int i=0; i<=_lineLength; i++)
+            _lineBuffer[i] = 0x00;
+        return;
+    }
+    strncpy(_lineBuffer,_lines[_currentLine],_lineLength+1);
+    _prevLinePos = _linePos;
+    _linePos=0;
+    while(_lineBuffer[_linePos]!=0x00)
+        _linePos++;
+}
+
+// load the previous buffer in the line history (activated by UP key)
+void Console::loadPreviousBuffer() {
+    if(_currentLine>0) {
+        _currentLine--;
+    }
+    strncpy(_lineBuffer,_lines[_currentLine],_lineLength+1);
+    _prevLinePos = _linePos;
+    _linePos=0;
+    while(_lineBuffer[_linePos]!=0x00)
+        _linePos++;
+}
+
+// process a command entered (received by CRLF)
+void Console::processCommand() {
+    _terminal->printf("Command: \"%s\"\r\n",_lineBuffer);
+}
+
+// wait on the console for input, returns false on timeout
+// this is useful for processing escape chars
+bool Console::waitForInput() {
+    long timer = 0;
+    while(!_terminal->readable()&&timer++<_bufferWaitTimeout);
+    return _terminal->readable();
+}
+
+// print the entire command history
+void Console::printHistory() {
+    for(int i=0; i<_numLines; i++)
+        printBuffer(i);
+}
+
+// print the command at index in the history
+void Console::printBuffer(int index) {
+    if(index==_currentLine)
+        _terminal->printf("> ");
+    else
+        _terminal->printf("  ");
+    _terminal->printf("%d) \"%s\"\r\n",index,_lines[index]);
+}
+
+void Console::reprintBuffer() {
+    //printf("plp: %d, lB: %d\r\n",_prevLinePos,_lineLength);
+    _terminal->putc('\r');
+    for(int i=0; i<_lineLength; i++) {;
+        _terminal->putc(' ');
+    }
+    _terminal->putc('\r');
+    if(_linePos>0) {
+       _terminal->printf("%s",_lineBuffer);
+       _terminal->putc('\r');
+       for(int i=0; i<_linePos; i++) {;
+            _terminal->putc(0x1b);
+            _terminal->putc('[');
+            _terminal->putc('C');
+       }
+    }
+}
+
+// print the current-line buffer including debugging stuff
+void Console::printLineBuffer() {
+    printHistory();
+    _terminal->printf("C) \"%s\"\r\n",_lineBuffer);
+    _terminal->printf("   \"");
+    for(int i=0; i<_linePos; i++) {
+        _terminal->printf(" ");
+    }
+    _terminal->printf("^");
+    for(int i=_linePos+1; i<_lineLength; i++) {
+        _terminal->printf(" ");
+    }
+    _terminal->printf("\"\r\n");
+    for(int i=0; i<=_lineLength; i++) {
+        _terminal->printf("%x ",_lineBuffer[i]);
+    }
+    _terminal->printf("\r\n");
+}
+
+// process the console
+void Console::update() {
+    // process console input
+    while(_terminal->readable()) {
+        int c = _terminal->getc();
+        switch(c) {
+            // backspace
+            case 0x08:
+                if(_linePos>0) {
+                    // case where pointer is at end of line
+                    if(_lineBuffer[_linePos]==0x00) {
+                        _lineBuffer[--_linePos] = 0x00;
+                    } else {
+                        // case where pointer is somewhere in the middle of the line
+                        int copyPointer = --_linePos;
+                        while(_lineBuffer[copyPointer]!=0x00) {
+                            _lineBuffer[copyPointer] = _lineBuffer[copyPointer+1];
+                            copyPointer++;
+                        }
+                    }
+                    reprintBuffer();
+                }           
+            break;
+                
+            // escape sequence 0x1b 0x5b
+            case 0x1b:
+                // check that escape sequence exists
+                if(waitForInput()&&_terminal->getc()==0x5b) {
+                        
+                    // process escape characters
+                    if(waitForInput()) {
+                        c = _terminal->getc();
+                        switch(c) {
+                            // up
+                            case 0x41:
+                                loadPreviousBuffer();
+                                reprintBuffer();
+                            break;
+                                
+                            // down
+                            case 0x42:
+                                loadNextBuffer();
+                                reprintBuffer();
+                            break;
+                                
+                            // left
+                            case 0x44:
+                                if(_linePos>0) {
+                                    _linePos--;
+                                    _terminal->putc('\b');
+                                }
+                            break;
+                                
+                            // right
+                            case 0x43:
+                                // only move right within a string upto its end
+                                if(_lineBuffer[_linePos]!=0x00) {
+                                    _linePos++;
+                                    _terminal->putc(0x1b);
+                                    _terminal->putc('[');
+                                    _terminal->putc('C');
+                                }
+                            break;
+                        }
+                    }
+                }
+            break;
+                
+            // carriage return
+            case 0x0d:
+                storeBuffer();
+                processCommand();
+                clearBuffer();
+            break;
+                
+            default:
+                if(_linePos<_lineLength) {
+                    // INS mode
+                    if(false) {
+                        _lineBuffer[_linePos++] = c;
+                        _terminal->printf("%c",c);
+                    } else {    
+                        if(_lineBuffer[_linePos]==0x00) {
+                            _lineBuffer[_linePos++] = c;
+                        } else {
+                            // move everything to the right
+                            // so long as string end isn't at end of buffer
+                            int strEnd = _linePos;
+                            while(_lineBuffer[++strEnd]!=0x00);
+                            if(strEnd!=_lineLength) {
+                                int copyPointer = _lineLength;
+                                while(--copyPointer!=_linePos) {
+                                    _lineBuffer[copyPointer] = _lineBuffer[copyPointer-1];
+                                }
+                                
+                                // insert character
+                                _lineBuffer[_linePos++] = c;
+                            }
+                        }  
+                        reprintBuffer();
+                    }
+                    
+                }
+                  
+            break;
+        }
+            
+        #ifdef DEBUG
+        printLineBuffer();
+        #endif
+    }
+}
\ No newline at end of file