// // THIS FILE IS OBSOLETE - see ww.c instead // // Copyright (C) 2006 Nathan (Acorn) Pooley // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // version 2 as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License (gpl.txt) for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // // You can contact the author, Nathan (Acorn) Pooley, by writing // to Nathan (Acorn) Pooley, 949 Buckeye Drive, Sunnyvale, CA 94086, USA // or through the form at http://www.rawbw.com/~acorn/wand/feedback.html // // // // //#@DOC@ OBSOLETE - old server program - use ww.c instead // // // // // // serv.c - wand functions // //########################################################################### //############################### INCLUDES ################################## //########################################################################### #include <stdio.h> #include <stdarg.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <ctype.h> #include "ac_serialio.h" #include "ac_fdio.h" //########################################################################### //############################### TYPEDEFS ################################## //########################################################################### #define CTRL(c) ((c) & 0x1f) //########################################################################### //############################### TYPEDEFS ################################## //########################################################################### typedef enum WandStateEnum { WS_UNKNOWN, WS_RECOVER, WS_PROMPT, WS_CMD, WS_PROMPT_PLUS, WS_ECHO, WS_REPLY, WS_END } WandState; //########################################################################### //############################### GLOBALS ################################### //########################################################################### int g_wand_fd = -1; WandState g_wand_state = WS_UNKNOWN; char g_wand_lastprompt[1000] = "?>"; char g_wand_line[1000] = ""; int g_wand_line_cnt = 0; int g_debug = 0; int g_wasprompt = 0; //########################################################################### //############################### PROTOTYPES ################################ //########################################################################### static void wandRecover(void); //########################################################################### //############################### CODE ###################################### //########################################################################### //=========================================================================== // stripCr() - remove cr/lf from end of line //=========================================================================== void stripCr(char *s) { while(1) { if (!*s || *s == '\n' || *s == '\r') { *s = 0; return; } s++; } } //=========================================================================== // makePrintable() //=========================================================================== char *makePrintable(char *s) { static char buf[2000]; char *d = buf; while(*s) { if (*s < ' ' || *s > '}' || *s == '@') { d += sprintf(d,"\\%02x",*(unsigned char*)s); } else { *(d++) = *s; } s++; } *d = 0; return buf; } //=========================================================================== // prePrint() //=========================================================================== void prePrint(void) { if (g_wasprompt) { printf("\n"); g_wasprompt = 0; } } //=========================================================================== // prompt() //=========================================================================== void prompt(void) { if (!g_wasprompt && g_wand_state == WS_PROMPT) { printf("%s",g_wand_lastprompt); fflush(stdout); g_wasprompt = 1; } } //=========================================================================== // wandPrintf() //=========================================================================== int wandPrintf(const char *fmt, ...) { int cnt; int scnt = 0; char *s; char buf[1000]; va_list va; va_start(va, fmt); cnt = vsnprintf(buf,sizeof(buf)-5,fmt,va); va_end(va); buf[cnt] = 0; if (g_debug) { prePrint(); printf("Send to wand: '%s'\n",makePrintable(buf)); } s = buf; while(cnt) { int c; #if 1 c = write(g_wand_fd, s, cnt); #else if (g_debug) { printf("Send to wand c=%02x\n",*(unsigned char*)s); } c = write(g_wand_fd, s, 1); if (g_debug) { printf("Send to wand c done\n"); } #endif if (c) { cnt -= c; scnt += c; //usleep(100); s += c; } else { prePrint(); fprintf(stderr,"Error writing to wand\n"); break; } } if (g_debug) { printf("Send to wand Done\n"); } return scnt; } //=========================================================================== // wandCmdf() //=========================================================================== int wandCmdf(const char *fmt, ...) { int ccnt; va_list va; char cbuf[1000]; char rbuf[1000]; char *s; char *r; char *se; char *re; int timeout = 0; va_start(va, fmt); ccnt = vsnprintf(cbuf,sizeof(cbuf)-5,fmt,va); va_end(va); if (g_debug) { prePrint(); printf("Got CMD: '%s'\n",cbuf); } if (g_wand_state != WS_PROMPT) { wandRecover(); } g_wand_state = WS_CMD; if (ccnt) { s = cbuf; se = cbuf + ccnt; while(s != se) { s += write(g_wand_fd, s, ccnt); } s = cbuf; while(s != se) { int rcnt = read(g_wand_fd, rbuf, sizeof(rbuf)); rbuf[rcnt] = 0; r = rbuf; re = r + rcnt; if (!rcnt) { if (++timeout > 3) { return -1; // timeout } usleep(10000); } while(r != re && s != se) { if (*r != *s) { prePrint(); fprintf(stderr, "Error in command: '%s'\n",cbuf); fprintf(stderr, "Error: Wand sent: '%s' (bad echo)\n", makePrintable(rbuf)); return -1; } s++; r++; } } if (r != re) { prePrint(); fprintf(stderr, "Error in command: '%s'\n",cbuf); fprintf(stderr, "Error: Wand sent: '%s' (too many)\n", makePrintable(rbuf)); return -1; } } if (g_debug) { printf("Sending LF\n"); } cbuf[0] = 0xa; write(g_wand_fd, cbuf, 1); return 0; } //=========================================================================== // wandChar() //=========================================================================== static void wandChar(int c) { g_wand_line[g_wand_line_cnt++] = c; // // check for prompt // if (c == ' ' && g_wand_line_cnt>2 && g_wand_line[g_wand_line_cnt-2] == '>') { int i; for (i=0; ; i++) { if (i==g_wand_line_cnt-2) { // // got a prompt // memcpy(g_wand_lastprompt, g_wand_line, g_wand_line_cnt); g_wand_lastprompt[g_wand_line_cnt] = 0; g_wand_line_cnt = 0; if (g_debug) { prePrint(); printf("Got prompt: '%s'\n",g_wand_lastprompt); } g_wand_state = WS_PROMPT; if (g_debug) { prePrint(); printf("state=WS_PROMPT=%d\n",g_wand_state); } return; } if (!isalpha(g_wand_line[i])) break; } } // // check for end of line // if (c!=0xa && c!=0xd) { if (g_wand_state == WS_PROMPT) { g_wand_state = WS_PROMPT_PLUS; if (g_debug) { prePrint(); printf("state=WS_PROMPT_PLUS=%d\n",g_wand_state); } } return; } g_wand_line[--g_wand_line_cnt] = 0; // // ignore blank lines // if (g_wand_line_cnt == 0) { return; } prePrint(); printf("Wand: '%s'\n",g_wand_line); g_wand_line_cnt = 0; return; } //=========================================================================== // wandRecover() - recover o known state //=========================================================================== static void wandRecover(void) { #if 0 int cnt; #endif char buf[1000]; usleep(10000); buf[0] = CTRL('X'); write(g_wand_fd, buf, 1); usleep(10000); #if 0 cnt = read(g_wand_fd, buf, sizeof(buf)-100); buf[cnt] = 0; prePrint(); printf("From wand: '%s' (recover)\n",makePrintable(buf)); g_wand_state = WS_PROMPT; #endif } //=========================================================================== // handleSerial() //=========================================================================== static void *handleSerial(int fd, void *data) { char buf[1000]; int cnt; cnt = read(fd, buf, sizeof(buf)-100); if (cnt) { int i; buf[cnt] = 0; if (g_debug) { prePrint(); printf("From wand: '%s'\n",makePrintable(buf)); } for (i=0; i<cnt; i++) { wandChar(buf[i]); } } prompt(); return 0; } //=========================================================================== // handleStdin() //=========================================================================== static void *handleStdin(int fd, void *data) { char buf[1000]; int cnt = read(fd, buf, sizeof(buf)-1); stripCr(buf); if (cnt > 0) { buf[cnt] = 0; g_wasprompt = 0; if (buf[0] == 'q' && buf[1] == 0) { return (void*)1; } // // send to wand // if (buf[0] == ':') { wandCmdf("%s",buf+1); } } prompt(); return 0; } //=========================================================================== // main() //=========================================================================== int main(int argc, char *argv[]) { AcSerial *sio; AcFdGroup *grp; sio = acSerialCreate("/dev/ttyS0", 9600); if (!sio) { fprintf(stderr,"Error in acSerialCreate\n"); exit(1); } acSerialSetNonCanonical(sio, 1, 200); acSerialOpen(sio); g_wand_fd = acSerialGetFD(sio); if (g_wand_fd < 0) { fprintf(stderr,"Error in acSerialOpen\n"); exit(1); } grp = AcFdGroupCreate(); if (!grp) { fprintf(stderr,"Error in AcFdGroupCreate\n"); exit(1); } // // add serial handler // AcFdGroupAdd(grp, g_wand_fd, handleSerial, 0); // // add stdin handler (fd=0) // AcFdGroupAdd(grp, 0, handleStdin, 0); wandRecover(); AcFdGroupLoop(grp); wandRecover(); AcFdGroupDestroy(grp); acSerialDestroy(sio); return 0; } |
This file Copyright (C) 2006 by Nathan (Acorn) Pooley
Go to TOP Wand page
Go to Acorn's personal webpage
Go to Hogwarts website: www.gotohogwarts.com
Snout: www.snout.org/game
Gadgets of Justice Unlimited
Snout GC (Wiki)
Snout Wiki
File created by do_doc at Wed May 30 03:28:48 PDT 2007