LCOV - code coverage report
Current view: top level - mscb/src - msc.cxx (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 1348 0
Test Date: 2025-11-11 10:26:08 Functions: 0.0 % 12 0

            Line data    Source code
       1              : /********************************************************************\
       2              : 
       3              :   Name:         msc.c
       4              :   Created by:   Stefan Ritt
       5              : 
       6              :   Contents:     Command-line interface for the Midas Slow Control Bus
       7              : 
       8              :   $Id$
       9              : 
      10              : \********************************************************************/
      11              : 
      12              : #ifdef _MSC_VER
      13              : #define OS_WINNT
      14              : #endif
      15              : #if defined(__linux__) || defined(__APPLE__) || defined(__CYGWIN__)
      16              : #define OS_LINUX
      17              : #endif
      18              : 
      19              : #ifdef OS_WINNT
      20              : 
      21              : #include <windows.h>
      22              : #include <conio.h>
      23              : #include <io.h>
      24              : #include <sys/timeb.h>
      25              : #include <time.h>
      26              : 
      27              : #elif defined(OS_LINUX)
      28              : 
      29              : #define O_BINARY 0
      30              : 
      31              : #include <unistd.h>
      32              : #include <ctype.h>
      33              : #include <sys/termios.h>
      34              : #include <sys/time.h>
      35              : #include <sys/types.h>
      36              : #include <pthread.h>
      37              : 
      38              : #endif
      39              : 
      40              : #include "mscb.h"
      41              : #include "mscbxx.h"
      42              : 
      43              : #include <stdio.h>
      44              : #include <assert.h>
      45              : #include <string.h>
      46              : #include <stdlib.h>
      47              : #include <fcntl.h>
      48              : #include <time.h>
      49              : #include <sys/timeb.h>
      50              : #include "mscbrpc.h"
      51              : #include "mxml.h"
      52              : #include "mstrlcpy.h"
      53              : 
      54              : extern int cmd_edit(const char *prompt, char *cmd, int(*dir)(char *, int *), int(*idle)(void));
      55              : 
      56            0 : int cmd_dir(char *line, int *cursor) {
      57            0 :    return FALSE;
      58              : }
      59              : 
      60              : /*------------------------------------------------------------------*/
      61              : 
      62              : typedef struct {
      63              :    char id;
      64              :    char name[32];
      65              : } NAME_TABLE;
      66              : 
      67              : NAME_TABLE prefix_table[] = {
      68              :         {(char) PRFX_PICO,  "pico",},
      69              :         {(char) PRFX_NANO,  "nano",},
      70              :         {(char) PRFX_MICRO, "micro",},
      71              :         {(char) PRFX_MILLI, "milli",},
      72              :         {(char) PRFX_NONE,  "",},
      73              :         {(char) PRFX_KILO,  "kilo",},
      74              :         {(char) PRFX_MEGA,  "mega",},
      75              :         {(char) PRFX_GIGA,  "giga",},
      76              :         {(char) PRFX_TERA,  "tera",},
      77              :         {(char) 99}
      78              : };
      79              : 
      80              : NAME_TABLE unit_table[] = {
      81              : 
      82              :         {UNIT_METER,       "meter",},
      83              :         {UNIT_GRAM,        "gram",},
      84              :         {UNIT_SECOND,      "second",},
      85              :         {UNIT_MINUTE,      "minute",},
      86              :         {UNIT_HOUR,        "hour",},
      87              :         {UNIT_AMPERE,      "ampere",},
      88              :         {UNIT_KELVIN,      "kelvin",},
      89              :         {UNIT_CELSIUS,     "deg. celsius",},
      90              :         {UNIT_FARENHEIT,   "deg. farenheit",},
      91              :         {UNIT_JOULE,       "joule",},
      92              :         {UNIT_NEWTON,      "newton",},
      93              : 
      94              :         {UNIT_HERTZ,       "hertz",},
      95              :         {UNIT_PASCAL,      "pascal",},
      96              :         {UNIT_BAR,         "bar",},
      97              :         {UNIT_WATT,        "watt",},
      98              :         {UNIT_VOLT,        "volt",},
      99              :         {UNIT_OHM,         "ohm",},
     100              :         {UNIT_TESLA,       "tesls",},
     101              :         {UNIT_LITERPERSEC, "liter/sec",},
     102              :         {UNIT_RPM,         "RPM",},
     103              :         {UNIT_FARAD,       "farad",},
     104              : 
     105              :         {UNIT_BOOLEAN,     "boolean",},
     106              :         {UNIT_BYTE,        "byte",},
     107              :         {UNIT_WORD,        "word",},
     108              :         {UNIT_DWORD,       "dword",},
     109              :         {UNIT_ASCII,       "ascii",},
     110              :         {UNIT_STRING,      "string",},
     111              :         {UNIT_BAUD,        "baud",},
     112              : 
     113              :         {UNIT_PERCENT,     "percent",},
     114              :         {UNIT_PPM,         "RPM",},
     115              :         {UNIT_COUNT,       "counts",},
     116              :         {UNIT_FACTOR,      "factor",},
     117              :         {UNIT_VOLTPERVOLT, "volt/volt",},
     118              :         {0}
     119              : };
     120              : 
     121              : /*------------------------------------------------------------------*/
     122              : 
     123              : /* special characters */
     124              : #define CH_BS             8
     125              : #define CH_TAB            9
     126              : #define CH_CR            13
     127              : 
     128              : #define CH_EXT 0x100
     129              : 
     130              : #define CH_HOME   (CH_EXT+0)
     131              : #define CH_INSERT (CH_EXT+1)
     132              : #define CH_DELETE (CH_EXT+2)
     133              : #define CH_END    (CH_EXT+3)
     134              : #define CH_PUP    (CH_EXT+4)
     135              : #define CH_PDOWN  (CH_EXT+5)
     136              : #define CH_UP     (CH_EXT+6)
     137              : #define CH_DOWN   (CH_EXT+7)
     138              : #define CH_RIGHT  (CH_EXT+8)
     139              : #define CH_LEFT   (CH_EXT+9)
     140              : 
     141            0 : int ss_getchar(int reset) {
     142              : #ifdef OS_LINUX
     143              : 
     144              :    static int init = FALSE;
     145              :    static struct termios save_termios;
     146              :    struct termios buf;
     147              :    int i, fd;
     148              :    char c[3];
     149              : 
     150            0 :    fd = fileno(stdin);
     151              : 
     152            0 :    if (reset) {
     153            0 :       if (init)
     154            0 :          tcsetattr(fd, TCSAFLUSH, &save_termios);
     155            0 :       init = FALSE;
     156            0 :       return 0;
     157              :    }
     158              : 
     159            0 :    if (!init) {
     160            0 :       tcgetattr(fd, &save_termios);
     161            0 :       memcpy(&buf, &save_termios, sizeof(buf));
     162              : 
     163            0 :       buf.c_lflag &= ~(ECHO | ICANON | IEXTEN);
     164              : 
     165            0 :       buf.c_iflag &= ~(ICRNL | INPCK | ISTRIP | IXON);
     166              : 
     167            0 :       buf.c_cflag &= ~(CSIZE | PARENB);
     168            0 :       buf.c_cflag |= CS8;
     169              :       /* buf.c_oflag &= ~(OPOST); */
     170            0 :       buf.c_cc[VMIN] = 0;
     171            0 :       buf.c_cc[VTIME] = 0;
     172              : 
     173            0 :       tcsetattr(fd, TCSAFLUSH, &buf);
     174            0 :       init = TRUE;
     175              :    }
     176              : 
     177            0 :    memset(c, 0, 3);
     178            0 :    i = read(fd, c, 1);
     179              : 
     180            0 :    if (i == 0) {
     181            0 :       Sleep(10);
     182            0 :       return 0;
     183              :    }
     184              : 
     185              :    /* check if ESC */
     186            0 :    if (c[0] == 27) {
     187            0 :       i = read(fd, c, 2);
     188            0 :       if (i == 0)               /* return if only ESC */
     189            0 :          return 27;
     190              : 
     191              :       /* cursor keys return 2 chars, others 3 chars */
     192            0 :       if (c[1] < 65)
     193            0 :          read(fd, c, 1);
     194              : 
     195              :       /* convert ESC sequence to CH_xxx */
     196            0 :       switch (c[1]) {
     197            0 :          case 49:
     198            0 :             return CH_HOME;
     199            0 :          case 50:
     200            0 :             return CH_INSERT;
     201            0 :          case 51:
     202            0 :             return CH_DELETE;
     203            0 :          case 52:
     204            0 :             return CH_END;
     205            0 :          case 53:
     206            0 :             return CH_PUP;
     207            0 :          case 54:
     208            0 :             return CH_PDOWN;
     209            0 :          case 65:
     210            0 :             return CH_UP;
     211            0 :          case 66:
     212            0 :             return CH_DOWN;
     213            0 :          case 67:
     214            0 :             return CH_RIGHT;
     215            0 :          case 68:
     216            0 :             return CH_LEFT;
     217              :       }
     218              :    }
     219              : 
     220              :    /* BS/DEL -> BS */
     221            0 :    if (c[0] == 127)
     222            0 :       return CH_BS;
     223              : 
     224            0 :    return c[0];
     225              : 
     226              : #elif defined(OS_WINNT)
     227              : 
     228              :    static BOOL init = FALSE;
     229              :    static INT repeat_count = 0;
     230              :    static INT repeat_char;
     231              :    HANDLE hConsole;
     232              :    DWORD nCharsRead;
     233              :    INPUT_RECORD ir;
     234              :    
     235              :    hConsole = GetStdHandle(STD_INPUT_HANDLE);
     236              :    
     237              :    if (reset) {
     238              :       SetConsoleMode(hConsole, ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT);
     239              :       init = FALSE;
     240              :       return 0;
     241              :    }
     242              :    
     243              :    if (!init) {
     244              :       SetConsoleMode(hConsole, ENABLE_PROCESSED_INPUT);
     245              :       init = TRUE;
     246              :    }
     247              :    
     248              :    if (repeat_count) {
     249              :       repeat_count--;
     250              :       return repeat_char;
     251              :    }
     252              :    
     253              :    PeekConsoleInput(hConsole, &ir, 1, &nCharsRead);
     254              :    
     255              :    if (nCharsRead == 0)
     256              :       return 0;
     257              :    
     258              :    ReadConsoleInput(hConsole, &ir, 1, &nCharsRead);
     259              :    
     260              :    if (ir.EventType != KEY_EVENT)
     261              :       return ss_getchar(0);
     262              :    
     263              :    if (!ir.Event.KeyEvent.bKeyDown)
     264              :       return ss_getchar(0);
     265              :    
     266              :    if (ir.Event.KeyEvent.wRepeatCount > 1) {
     267              :       repeat_count = ir.Event.KeyEvent.wRepeatCount - 1;
     268              :       repeat_char = ir.Event.KeyEvent.uChar.AsciiChar;
     269              :       return repeat_char;
     270              :    }
     271              :    
     272              :    if (ir.Event.KeyEvent.uChar.AsciiChar)
     273              :       return ir.Event.KeyEvent.uChar.AsciiChar;
     274              :    
     275              :    if (ir.Event.KeyEvent.dwControlKeyState & (ENHANCED_KEY)) {
     276              :       switch (ir.Event.KeyEvent.wVirtualKeyCode) {
     277              :          case 33:
     278              :             return CH_PUP;
     279              :          case 34:
     280              :             return CH_PDOWN;
     281              :          case 35:
     282              :             return CH_END;
     283              :          case 36:
     284              :             return CH_HOME;
     285              :          case 37:
     286              :             return CH_LEFT;
     287              :          case 38:
     288              :             return CH_UP;
     289              :          case 39:
     290              :             return CH_RIGHT;
     291              :          case 40:
     292              :             return CH_DOWN;
     293              :          case 45:
     294              :             return CH_INSERT;
     295              :          case 46:
     296              :             return CH_DELETE;
     297              :       }
     298              :       
     299              :       return ir.Event.KeyEvent.wVirtualKeyCode;
     300              :    }
     301              :    
     302              :    return ss_getchar(0);
     303              : 
     304              : #endif
     305              :    return -1;
     306              : }
     307              : 
     308              : /*------------------------------------------------------------------*/
     309              : 
     310            0 : unsigned int ss_millitime() {
     311              : #ifdef OS_WINNT
     312              : 
     313              :    return (int) GetTickCount();
     314              : 
     315              : #endif                          /* OS_WINNT */
     316              : #ifdef OS_LINUX
     317              :    {
     318              :       struct timeval tv;
     319              : 
     320            0 :       gettimeofday(&tv, NULL);
     321              : 
     322            0 :       return tv.tv_sec * 1000 + tv.tv_usec / 1000;
     323              :    }
     324              : 
     325              : #endif                          /* OS_LINUX */
     326              :    return 0;
     327              : }
     328              : 
     329              : /*------------------------------------------------------------------*/
     330              : 
     331            0 : char *ss_gets(char *string, int size) {
     332              :    char *p;
     333              : 
     334              :    do {
     335            0 :       p = fgets(string, size, stdin);
     336            0 :    } while (p == NULL);
     337              : 
     338              : 
     339            0 :    if (strlen(p) > 0 && p[strlen(p) - 1] == '\n')
     340            0 :       p[strlen(p) - 1] = 0;
     341              : 
     342            0 :    return p;
     343              : }
     344              : 
     345              : /*------------------------------------------------------------------*/
     346              : 
     347            0 : void print_help() {
     348            0 :    puts("Available commands:\n");
     349            0 :    puts("addr <addr>                Address individual node");
     350            0 :    puts("baddr                      Address all nodes (broadcast)");
     351            0 :    puts("baud                       Set baud rate of MSCB bus");
     352            0 :    puts("debug 0/1/2                Turn debuggin off/on, 2=show on screen");
     353            0 :    puts("echo [fc]                  Perform echo test [fast,continuous]");
     354            0 :    puts("flash                      Flash parameters into EEPROM");
     355            0 :    puts("gaddr <addr>               Address group of nodes");
     356            0 :    puts("info                       Retrive node info");
     357            0 :    puts("load <file>                Load node variables");
     358            0 :    puts("ping <addr> [r]            Ping node and set address [repeat mode]");
     359            0 :    puts("read <index> [r] [a]       Read node variable [repeat mode]  [all variables]");
     360            0 :    puts("read <i1>-<i2> [r] [a]     Read range of node variables [repeat]  [all]");
     361            0 :    puts("reboot                     Reboot addressed node");
     362            0 :    puts("sa <addr>                  Set node address of addressed node");
     363            0 :    puts("save <file> [first last]   Save current node variables [save range]");
     364            0 :    puts("scan [r] [a] [q]           Scan bus for nodes [repeat mode] [all] [quick]");
     365            0 :    puts("sg <addr>                  Set group address of addressed node(s)");
     366            0 :    puts("sn <name>                  Set node name (up to 16 characters)");
     367            0 :    puts("sr                         Reset current submaster");
     368            0 :    puts("submaster                  Show info for current submaster");
     369            0 :    puts("sync                       Synchronize local time with node(s)");
     370            0 :    puts("terminal                   Enter teminal mode for SCS-210");
     371            0 :    puts("upload [slot] <filename> [debug]  Upload new firmware to node in [slot] [with debug info]");
     372            0 :    puts("download [slot] <filename> Download firmware from node in [slot] to file");
     373            0 :    puts("memrd <slot> <adr> <count> Read from memory in <slot>");
     374            0 :    puts("memwr <slot> <adr> <value> Write to memory in <slot>");
     375            0 :    puts("mup <hex-file> <a1> <a2>   Upload new firmware to nodes a1-a2");
     376            0 :    puts("mwr <index> <value> <n1> <n2>  Write a variable to nodes from <n1> to <n2>");
     377            0 :    puts("verify [adr] <hex-file>    Compare current firmware in [adr] with file");
     378            0 :    puts("version                    Display version number");
     379            0 :    puts("write <index> <value> [r]  Write node variable");
     380            0 :    puts("write <i1>-<i2> <value>    Write range of node variables");
     381            0 :    puts("log [c]                    Read log / clear Log [c]");
     382              : 
     383            0 :    puts("");
     384            0 : }
     385              : 
     386              : /*------------------------------------------------------------------*/
     387              : 
     388            0 : void print_channel_str(int index, MSCB_INFO_VAR *info_chn, void *pdata, int verbose,
     389              :                        char *line) {
     390              :    char str[80];
     391              :    int i, data;
     392              : 
     393            0 :    line[0] = 0;
     394            0 :    if (verbose) {
     395            0 :       memset(str, 0, sizeof(str));
     396            0 :       strncpy(str, info_chn->name, sizeof(str));
     397            0 :       for (i = strlen(str); i < (int) sizeof(info_chn->name) + 1; i++)
     398            0 :          str[i] = ' ';
     399            0 :       snprintf(line + strlen(line), 256 - strlen(line), "%3d: %s ", index, str);
     400              :    } else {
     401            0 :       memset(str, 0, sizeof(str));
     402            0 :       strncpy(str, info_chn->name, sizeof(str));
     403            0 :       snprintf(line, 256, "%s: ", str);
     404              :    }
     405              : 
     406            0 :    if (info_chn->unit == UNIT_STRING) {
     407            0 :       memset(str, 0, sizeof(str));
     408            0 :       strncpy(str, (const char *) pdata, info_chn->width);
     409            0 :       if (verbose)
     410            0 :          snprintf(line + strlen(line), 256 - strlen(line), "STR%02d    \"", info_chn->width);
     411            0 :       for (i = 0; i < (int) strlen(str); i++)
     412            0 :          switch (str[i]) {
     413            0 :             case 1:
     414            0 :                strcat(line, "\\001");
     415            0 :                break;
     416            0 :             case 2:
     417            0 :                strcat(line, "\\002");
     418            0 :                break;
     419            0 :             case 9:
     420            0 :                strcat(line, "\\t");
     421            0 :                break;
     422            0 :             case 10:
     423            0 :                strcat(line, "\\n");
     424            0 :                break;
     425            0 :             case 13:
     426            0 :                strcat(line, "\\r");
     427            0 :                break;
     428            0 :             default:
     429            0 :                line[strlen(line) + 1] = 0;
     430            0 :                line[strlen(line)] = str[i];
     431            0 :                break;
     432              :          }
     433            0 :       strcat(line, "\"");
     434              :    } else {
     435            0 :       data = *((int *) pdata);
     436            0 :       switch (info_chn->width) {
     437            0 :          case 0:
     438            0 :             printf(" 0bit");
     439            0 :             break;
     440              : 
     441            0 :          case 1:
     442            0 :             data &= 0xFF;
     443            0 :             if (info_chn->flags & MSCBF_SIGNED) {
     444            0 :                if (verbose)
     445            0 :                   snprintf(line + strlen(line), 256 - strlen(line), " 8bit S %15d (0x%02X/", (char) data, data);
     446              :                else
     447            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "%15d (0x%02X/", (char) data, data);
     448              :             } else {
     449            0 :                if (verbose)
     450            0 :                   snprintf(line + strlen(line), 256 - strlen(line), " 8bit U %15u (0x%02X/", data, data);
     451              :                else
     452            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "%15u (0x%02X/", data, data);
     453              :             }
     454            0 :             for (i = 0; i < 8; i++)
     455            0 :                if (data & (0x80 >> i))
     456            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "1");
     457              :                else
     458            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "0");
     459            0 :             snprintf(line + strlen(line), 256 - strlen(line), ")");
     460            0 :             break;
     461              : 
     462            0 :          case 2:
     463            0 :             data &= 0xFFFF;
     464            0 :             if (info_chn->flags & MSCBF_SIGNED) {
     465            0 :                if (verbose)
     466            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "16bit S %15d (0x%04X)", (short) data, data);
     467              :                else
     468            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "%15d (0x%04X)", (short) data, data);
     469              :             } else {
     470            0 :                if (verbose)
     471            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "16bit U %15u (0x%04X)", data, data);
     472              :                else
     473            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "%15u (0x%04X)", data, data);
     474              :             }
     475            0 :             break;
     476              : 
     477            0 :          case 3:
     478            0 :             data &= 0xFFFFFF;
     479            0 :             if (info_chn->flags & MSCBF_SIGNED) {
     480            0 :                if (verbose)
     481            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "24bit S %15ld (0x%06X)", (long) data, data);
     482              :                else
     483            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "%15ld (0x%06X)", (long) data, data);
     484              :             } else {
     485            0 :                if (verbose)
     486            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "24bit U %15u (0x%06X)", data, data);
     487              :                else
     488            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "%15ld (0x%06X)", (long) data, data);
     489              :             }
     490            0 :             break;
     491              : 
     492            0 :          case 4:
     493            0 :             data &= 0xFFFFFFFF;
     494            0 :             if (info_chn->flags & MSCBF_FLOAT) {
     495            0 :                if (verbose)
     496            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "32bit F %15.6lg",
     497            0 :                            *((float *) (void *) &data));
     498              :                else
     499            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "%15.6lg", *((float *) (void *) &data));
     500              :             } else {
     501            0 :                if (info_chn->flags & MSCBF_SIGNED) {
     502            0 :                   if (verbose)
     503            0 :                      snprintf(line + strlen(line), 256 - strlen(line), "32bit S %15d (0x%08X)", data, data);
     504              :                   else
     505            0 :                      snprintf(line + strlen(line), 256 - strlen(line), "%15d (0x%08X)", data, data);
     506              :                } else {
     507            0 :                   if (verbose)
     508            0 :                      snprintf(line + strlen(line), 256 - strlen(line), "32bit U %15u (0x%08X)", data, data);
     509              :                   else
     510            0 :                      snprintf(line + strlen(line), 256 - strlen(line), "%15u (0x%08X)", data, data);
     511              :                }
     512              :             }
     513            0 :             break;
     514              : 
     515            0 :          case 8:
     516            0 :             unsigned long int qdata = *((unsigned long int *) pdata);
     517            0 :             if (info_chn->flags & MSCBF_SIGNED) {
     518            0 :                if (verbose)
     519            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "64bit S (0x%016lX) %ld", qdata, qdata);
     520              :                else
     521            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "(0x%016lX) %ld", qdata, qdata);
     522              :             } else {
     523            0 :                if (verbose)
     524            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "64bit U (0x%016lX) %lu", qdata, qdata);
     525              :                else
     526            0 :                   snprintf(line + strlen(line), 256 - strlen(line), "(0x%016lX) %lu", qdata, qdata);
     527              :             }
     528            0 :             break;
     529              :       }
     530              :    }
     531              : 
     532            0 :    snprintf(line + strlen(line), 256 - strlen(line), " ");
     533              : 
     534              :    /* evaluate prefix */
     535            0 :    if (info_chn->prefix) {
     536            0 :       for (i = 0; prefix_table[i].id != 99; i++)
     537            0 :          if ((unsigned char) prefix_table[i].id == info_chn->prefix)
     538            0 :             break;
     539            0 :       if (prefix_table[i].id)
     540            0 :          strcpy(line + strlen(line), prefix_table[i].name);
     541              :    }
     542              : 
     543              :    /* evaluate unit */
     544            0 :    if (info_chn->unit && info_chn->unit != UNIT_STRING) {
     545            0 :       for (i = 0; unit_table[i].id; i++)
     546            0 :          if ((unsigned char) unit_table[i].id == info_chn->unit)
     547            0 :             break;
     548            0 :       if (unit_table[i].id)
     549            0 :          strcpy(line + strlen(line), unit_table[i].name);
     550              :    }
     551              : 
     552            0 :    if (verbose)
     553            0 :       snprintf(line + strlen(line), 256 - strlen(line), "\n");
     554              :    else
     555            0 :       snprintf(line + strlen(line), 256 - strlen(line), "                    \r");
     556            0 : }
     557              : 
     558            0 : void print_channel(int index, MSCB_INFO_VAR *info_chn, void *pdata, int verbose) {
     559              :    char str[256];
     560              : 
     561            0 :    print_channel_str(index, info_chn, pdata, verbose, str);
     562            0 :    fputs(str, stdout);
     563            0 : }
     564              : 
     565              : /*------------------------------------------------------------------*/
     566              : 
     567            0 : void save_node_xml(MXML_WRITER *writer, int fd, int addr) {
     568              :    int i, j, status, size;
     569              :    char str[256], line[256], data[256];
     570              :    MSCB_INFO info;
     571              :    MSCB_INFO_VAR info_var;
     572              : 
     573            0 :    status = mscb_info(fd, (unsigned short) addr, &info);
     574            0 :    if (status == MSCB_CRC_ERROR) {
     575            0 :       puts("CRC Error");
     576            0 :       return;
     577            0 :    } else if (status != MSCB_SUCCESS) {
     578            0 :       puts("No response from node");
     579            0 :       return;
     580              :    }
     581              : 
     582            0 :    mxml_start_element(writer, "Node");
     583              : 
     584            0 :    mxml_start_element(writer, "Name");
     585            0 :    mxml_write_value(writer, info.node_name);
     586            0 :    mxml_end_element(writer);
     587              : 
     588            0 :    mxml_start_element(writer, "NodeAddress");
     589            0 :    snprintf(str, sizeof(str), "%d (0x%X)", addr, addr);
     590            0 :    mxml_write_value(writer, str);
     591            0 :    mxml_end_element(writer);
     592              : 
     593            0 :    mxml_start_element(writer, "GroupAddress");
     594            0 :    snprintf(str, sizeof(str), "%d (0x%X)", info.group_address, info.group_address);
     595            0 :    mxml_write_value(writer, str);
     596            0 :    mxml_end_element(writer);
     597              : 
     598            0 :    mxml_start_element(writer, "ProtocolVersion");
     599            0 :    snprintf(str, sizeof(str), "%d.%d", info.protocol_version / 16, info.protocol_version % 16);
     600            0 :    mxml_write_value(writer, str);
     601            0 :    mxml_end_element(writer);
     602              : 
     603            0 :    mxml_start_element(writer, "Variables");
     604            0 :    for (i = 0; i < info.n_variables; i++) {
     605            0 :       mxml_start_element(writer, "Variable");
     606              : 
     607            0 :       mscb_info_variable(fd, (unsigned short) addr, (unsigned char) i, &info_var);
     608            0 :       size = sizeof(data);
     609            0 :       mscb_read(fd, (unsigned short) addr, (unsigned char) i, data, &size);
     610              : 
     611            0 :       mxml_start_element(writer, "Index");
     612            0 :       snprintf(str, sizeof(str), "%d", i);
     613            0 :       mxml_write_value(writer, str);
     614            0 :       mxml_end_element(writer);
     615              : 
     616            0 :       mxml_start_element(writer, "Name");
     617            0 :       strncpy(str, info_var.name, sizeof(str));
     618            0 :       str[8] = 0;
     619            0 :       mxml_write_value(writer, str);
     620            0 :       mxml_end_element(writer);
     621              : 
     622            0 :       mxml_start_element(writer, "Width");
     623            0 :       snprintf(str, sizeof(str), "%dbit", info_var.width * 8);
     624            0 :       mxml_write_value(writer, str);
     625            0 :       mxml_end_element(writer);
     626              : 
     627            0 :       print_channel_str(i, &info_var, data, 1, line);
     628              : 
     629            0 :       mstrlcpy(str, line + 29, sizeof(str));
     630            0 :       for (j = 0; j < (int) strlen(str); j++)
     631            0 :          if (str[j] == ' ')
     632            0 :             break;
     633            0 :       str[j] = 0;
     634            0 :       mxml_start_element(writer, "Flags");
     635            0 :       mxml_write_value(writer, str);
     636            0 :       mxml_end_element(writer);
     637              : 
     638            0 :       for (j += 29; j < (int) strlen(line); j++)
     639            0 :          if (line[j] != ' ')
     640            0 :             break;
     641              : 
     642            0 :       mstrlcpy(str, line + j, sizeof(str));
     643            0 :       for (j = 0; j < (int) strlen(str); j++)
     644            0 :          if (str[j] == ' ')
     645            0 :             break;
     646            0 :       str[j] = 0;
     647            0 :       mxml_start_element(writer, "Value");
     648            0 :       mxml_write_value(writer, str);
     649            0 :       mxml_end_element(writer);
     650              : 
     651            0 :       if (line[39] == '(') {
     652            0 :          mstrlcpy(str, line + 40, sizeof(str));
     653            0 :          for (j = 0; j < (int) strlen(str); j++)
     654            0 :             if (str[j] == ')')
     655            0 :                break;
     656            0 :          str[j] = 0;
     657            0 :          mxml_start_element(writer, "HexBinValue");
     658            0 :          mxml_write_value(writer, str);
     659            0 :          mxml_end_element(writer);
     660            0 :          j += 42;
     661              :       } else
     662            0 :          j = 39;
     663              : 
     664            0 :       mstrlcpy(str, line + j, sizeof(str));
     665            0 :       for (j = 0; j < (int) strlen(str); j++)
     666            0 :          if (!isalnum(str[j]))
     667            0 :             break;
     668            0 :       str[j] = 0;
     669            0 :       mxml_start_element(writer, "Unit");
     670            0 :       mxml_write_value(writer, str);
     671            0 :       mxml_end_element(writer);
     672              : 
     673            0 :       mxml_end_element(writer); // "Variable"
     674              :    }
     675              : 
     676            0 :    mxml_end_element(writer);    // "Variables"
     677            0 :    mxml_end_element(writer);    // "Node"
     678              : }
     679              : 
     680              : /*------------------------------------------------------------------*/
     681              : 
     682            0 : void load_nodes_xml(int fd, char *file_name, int flash) {
     683              :    int i, j, index, status, ivar, addr;
     684              :    char str[256], error[256], chn_name[256][17], name[256], value[256];
     685              :    unsigned int data;
     686              :    float fvalue;
     687              :    PMXML_NODE root, node, nvarroot, nvar, nsub;
     688              :    MSCB_INFO info;
     689              :    MSCB_INFO_VAR info_var;
     690              : 
     691            0 :    root = mxml_parse_file(file_name, error, sizeof(error), NULL);
     692            0 :    if (root == NULL) {
     693            0 :       printf("Error loading \"%s\": %s\n", file_name, error);
     694            0 :       return;
     695              :    }
     696              : 
     697            0 :    root = mxml_find_node(root, "/MSCBDump");
     698            0 :    if (root == NULL) {
     699            0 :       printf("Error loading \"%s\": No MSCBDump structure in file\n", file_name);
     700            0 :       return;
     701              :    }
     702              : 
     703              :    /* loop over all nodes in file */
     704            0 :    for (index = 0; index < mxml_get_number_of_children(root); index++) {
     705            0 :       node = mxml_subnode(root, index);
     706              : 
     707            0 :       nsub = mxml_find_node(node, "NodeAddress");
     708            0 :       if (nsub == NULL) {
     709            0 :          printf("Error loading \"%s\": Node #%d does not contain NodeAddress\n",
     710              :                 file_name, index);
     711            0 :          return;
     712              :       }
     713              : 
     714            0 :       printf("\nLoading node #%s\n", mxml_get_value(nsub));
     715            0 :       addr = atoi(mxml_get_value(nsub));
     716              : 
     717            0 :       nvarroot = mxml_find_node(node, "Variables");
     718            0 :       if (nvarroot == NULL) {
     719            0 :          printf("Error loading \"%s\": Node #%d does not contain Variables\n", file_name,
     720              :                 index);
     721            0 :          return;
     722              :       }
     723              : 
     724              :       /* get list of channel names from node */
     725            0 :       if (mscb_info(fd, (unsigned short) addr, &info) != MSCB_SUCCESS) {
     726            0 :          printf("No response from node %d, skip node.\n", addr);
     727            0 :          continue;
     728              :       }
     729              : 
     730            0 :       memset(chn_name, 0, sizeof(chn_name));
     731            0 :       for (i = 0; i < info.n_variables; i++) {
     732            0 :          mscb_info_variable(fd, (unsigned short) addr, (unsigned char) i, &info_var);
     733            0 :          strncpy(chn_name[i], info_var.name, sizeof(chn_name[i]));
     734              :       }
     735              : 
     736              :       /* loop over variables */
     737            0 :       for (ivar = 0; ivar < mxml_get_number_of_children(nvarroot); ivar++) {
     738              : 
     739            0 :          nvar = mxml_subnode(nvarroot, ivar);
     740            0 :          nsub = mxml_find_node(nvar, "Index");
     741            0 :          if (nsub == NULL) {
     742            0 :             printf("Found variable without index\n");
     743            0 :             continue;
     744              :          }
     745            0 :          nsub = mxml_find_node(nvar, "Name");
     746            0 :          if (nsub == NULL) {
     747            0 :             printf("Found variable without name\n");
     748            0 :             continue;
     749              :          }
     750              : 
     751            0 :          strcpy(name, mxml_get_value(nsub));
     752              : 
     753            0 :          nsub = mxml_find_node(nvar, "Value");
     754            0 :          if (nsub == NULL) {
     755            0 :             printf("Found variable without value\n");
     756            0 :             continue;
     757              :          }
     758              : 
     759            0 :          strcpy(value, mxml_get_value(nsub));
     760              : 
     761              :          /* search for channel with same name */
     762            0 :          for (i = 0; chn_name[i][0]; i++)
     763            0 :             if (strcmp(chn_name[i], name) == 0) {
     764            0 :                mscb_info_variable(fd, (unsigned short) addr, (unsigned char) i,
     765              :                                   &info_var);
     766              : 
     767            0 :                if (info_var.unit == UNIT_STRING) {
     768            0 :                   memset(str, 0, sizeof(str));
     769            0 :                   mstrlcpy(str, value, sizeof(str));
     770            0 :                   str[info_var.width] = 0;
     771            0 :                   if (strlen(str) > 0 && str[strlen(str) - 1] == '\n')
     772            0 :                      str[strlen(str) - 1] = 0;
     773              : 
     774              :                   status =
     775            0 :                           mscb_write(fd, (unsigned short) addr, (unsigned char) i, str,
     776            0 :                                      info_var.width);
     777            0 :                   if (status != MSCB_SUCCESS)
     778            0 :                      printf("Error writing to node %d, variable %d\n", addr, i);
     779              : 
     780              :                } else {
     781            0 :                   if (info_var.flags & MSCBF_FLOAT) {
     782            0 :                      fvalue = (float) atof(value);
     783            0 :                      memcpy(&data, &fvalue, sizeof(float));
     784              :                   } else {
     785            0 :                      data = atoi(value);
     786              :                   }
     787              : 
     788              :                   status =
     789            0 :                           mscb_write(fd, (unsigned short) addr, (unsigned char) i, &data,
     790            0 :                                      info_var.width);
     791            0 :                   if (status != MSCB_SUCCESS)
     792            0 :                      printf("Error writing to node %d, variable %d\n", addr, i);
     793              : 
     794              :                   /* blank padding */
     795            0 :                   for (j = strlen(name); j < 8; j++)
     796            0 :                      name[j] = ' ';
     797            0 :                   name[j] = 0;
     798              : 
     799            0 :                   printf("%3d: %s %s\n", i, name, value);
     800              :                }
     801              : 
     802            0 :                break;
     803              :             }
     804              : 
     805            0 :          if (chn_name[i][0] == 0)
     806            0 :             printf("Variable \"%s\" from file not in node, variable skipped\n", name);
     807              :       }
     808              : 
     809            0 :       if (flash)
     810            0 :          mscb_flash(fd, addr, -1, 0);
     811              :    }
     812              : }
     813              : 
     814              : /*------------------------------------------------------------------*/
     815              : 
     816            0 : int match(const char *str, const char *cmd) {
     817              :    int i;
     818              : 
     819            0 :    if (str[0] == '\r' || str[0] == '\n' || str[0] == 0)
     820            0 :       return 0;
     821              : 
     822            0 :    for (i = 0; i < (int) strlen(str); i++) {
     823            0 :       if (toupper(str[i]) != toupper(cmd[i]) && str[i] != '\r' && str[i] != '\n')
     824            0 :          return 0;
     825              :    }
     826              : 
     827            0 :    return 1;
     828              : }
     829              : 
     830              : /*------------------------------------------------------------------*/
     831              : 
     832            0 : void cmd_loop(int fd, char *cmd, unsigned short adr) {
     833              :    int i, j, status, size, nparam, current_addr, current_group, reference_addr,
     834            0 :            first, last, broadcast, read_all, repeat, index, idx1, idx2, wait = 0, n_found, slot;
     835              :    int ping_addr[0x10000];
     836              :    unsigned short addr;
     837              :    unsigned int data, uptime, mem_addr;
     838              :    unsigned long int qdata;
     839              :    unsigned char c;
     840              :    float value;
     841              :    char str[256], line[256], dbuf[100 * 1024], param[10][100], *pc, lib[32],
     842              :            prot[32], *pdata, prompt[256], filename[256];
     843            0 :    FILE *cmd_file = NULL;
     844              :    MSCB_INFO info;
     845              :    MSCB_INFO_VAR info_var_array[256];
     846              :    MSCB_INFO_VAR info_var;
     847              :    time_t now;
     848              :    MXML_WRITER *writer;
     849              :    struct tm *ptm;
     850              : 
     851              :    /* open command file */
     852            0 :    if (cmd[0] == '@') {
     853            0 :       cmd_file = fopen(cmd + 1, "r");
     854            0 :       if (cmd_file == NULL) {
     855            0 :          printf("Command file %s not found.\n", cmd + 1);
     856            0 :          return;
     857              :       }
     858              :    }
     859              : 
     860            0 :    if (cmd[0])
     861              :       /* assumed some node correctly addressed in command mode */
     862            0 :       current_addr = 0;
     863              :    else
     864            0 :       current_addr = -1;
     865              : 
     866            0 :    current_group = -1;
     867              : 
     868            0 :    if (adr)
     869            0 :       current_addr = adr;
     870              : 
     871            0 :    broadcast = 0;
     872            0 :    reference_addr = 0;
     873            0 :    status = 0;
     874              : 
     875              :    /* fill table of possible addresses */
     876            0 :    for (i = 0; i < 0x10000; i++)
     877            0 :       ping_addr[i] = 0;
     878            0 :    for (i = 0; i < 1000; i++)        // 0..999
     879            0 :       ping_addr[i] = 1;
     880            0 :    for (i = 0; i < 0x10000; i += 100)  // 100, 200, ...
     881            0 :       ping_addr[i] = 1;
     882            0 :    for (i = 0; i < 0x10000; i += 0x100)
     883            0 :       ping_addr[i] = 1;            // 256, 512, ...
     884            0 :    for (i = 0xFF00; i < 0xFFFF; i++)
     885            0 :       ping_addr[i] = 1;            // 0xFF00-0xFFFF
     886              : 
     887              :    do {
     888              :       /* print prompt */
     889            0 :       if (!cmd[0]) {
     890            0 :          if (current_addr >= 0)
     891            0 :             snprintf(prompt, sizeof(prompt), "node%d(0x%X)> ", current_addr, current_addr);
     892            0 :          else if (current_group >= 0)
     893            0 :             snprintf(prompt, sizeof(prompt), "group%d> ", current_group);
     894            0 :          else if (broadcast)
     895            0 :             snprintf(prompt, sizeof(prompt), "all> ");
     896              :          else
     897            0 :             snprintf(prompt, sizeof(prompt), "> ");
     898            0 :          memset(line, 0, sizeof(line));
     899              : 
     900            0 :          cmd_edit(prompt, line, cmd_dir, NULL);
     901              : 
     902            0 :       } else if (cmd[0] != '@')
     903            0 :          strcpy(line, cmd);
     904              :       else {
     905            0 :          memset(line, 0, sizeof(line));
     906            0 :          fgets(line, sizeof(line), cmd_file);
     907              : 
     908            0 :          if (line[0] == 0)
     909            0 :             break;
     910              : 
     911              :          /* cut off CR */
     912            0 :          while (strlen(line) > 0 && line[strlen(line) - 1] == '\n')
     913            0 :             line[strlen(line) - 1] = 0;
     914              : 
     915            0 :          if (line[0] == 0)
     916            0 :             continue;
     917              :       }
     918              : 
     919              :       /* analyze line */
     920            0 :       nparam = 0;
     921            0 :       pc = line;
     922            0 :       while (*pc == ' ')
     923            0 :          pc++;
     924              : 
     925            0 :       memset(param, 0, sizeof(param));
     926              :       do {
     927            0 :          if (*pc == '"') {
     928            0 :             pc++;
     929            0 :             for (i = 0; *pc && *pc != '"'; i++)
     930            0 :                param[nparam][i] = *pc++;
     931            0 :             if (*pc)
     932            0 :                pc++;
     933            0 :          } else if (*pc == '\'') {
     934            0 :             pc++;
     935            0 :             for (i = 0; *pc && *pc != '\''; i++)
     936            0 :                param[nparam][i] = *pc++;
     937            0 :             if (*pc)
     938            0 :                pc++;
     939            0 :          } else if (*pc == '`') {
     940            0 :             pc++;
     941            0 :             for (i = 0; *pc && *pc != '`'; i++)
     942            0 :                param[nparam][i] = *pc++;
     943            0 :             if (*pc)
     944            0 :                pc++;
     945              :          } else
     946            0 :             for (i = 0; *pc && *pc != ' '; i++)
     947            0 :                param[nparam][i] = *pc++;
     948            0 :          param[nparam][i] = 0;
     949            0 :          while (*pc == ' ' || *pc == '\r' || *pc == '\n')
     950            0 :             pc++;
     951            0 :          nparam++;
     952            0 :       } while (*pc);
     953              : 
     954              :       /* help ---------- */
     955            0 :       if ((param[0][0] == 'h' && param[0][1] == 'e') || param[0][0] == '?')
     956            0 :          print_help();
     957              : 
     958              :          /* version ---------- */
     959            0 :       else if (match(param[0], "version")) {
     960            0 :          mscb_get_version(lib, prot);
     961            0 :          printf("MSCB library version  : %s\n", lib);
     962            0 :          printf("MSCB protocol version : %s\n", prot);
     963              :       }
     964              : 
     965              :       /* debug ---------- */
     966            0 :       if (match(param[0], "debug")) {
     967            0 :          mscb_debug(atoi(param[1]));
     968            0 :          printf("Debugging level changed successfully.\n");
     969              :       }
     970              : 
     971              :       /* scan ---------- */
     972            0 :       else if (match(param[0], "scan")) {
     973              :          do {
     974            0 :             n_found = 0;
     975            0 :             int quick = 0;
     976            0 :             if (param[1][0] == 'q' || param[2][0] == 'q')
     977            0 :                quick = 1;
     978            0 :             for (i = -1; i < 0x10000; i++) {
     979            0 :                if (i != -1 && param[1][0] != 'a' && param[2][0] != 'a' && i > 0 && !ping_addr[i])
     980            0 :                   continue;
     981            0 :                if (i == -1)
     982            0 :                   printf("Test address 65535 (0xFFFF)\r");
     983              :                else
     984            0 :                   printf("Test address %05d (0x%04X)\r", i, i);
     985            0 :                fflush(stdout);
     986              : 
     987            0 :                if (i == -1) {
     988              :                   /* do the first time with retry, to send '0's */
     989            0 :                   status = mscb_ping(fd, (unsigned short) 0xFFFF, 0, 0);
     990            0 :                   Sleep(100);
     991              :                } else
     992            0 :                   status = mscb_ping(fd, (unsigned short) i, quick, 0);
     993              : 
     994            0 :                if (status == MSCB_SUCCESS) {
     995              : 
     996            0 :                   n_found++;
     997              : 
     998              :                   /* node found, search next 100 as well */
     999            0 :                   for (j = i; j < i + 100 && j < 0x10000; j++)
    1000            0 :                      if (j >= 0)
    1001            0 :                         ping_addr[j] = 1;
    1002              : 
    1003            0 :                   status = mscb_info(fd, (unsigned short) i, &info);
    1004            0 :                   strncpy(str, info.node_name, sizeof(str));
    1005            0 :                   str[16] = 0;
    1006              : 
    1007            0 :                   if (status == MSCB_SUCCESS) {
    1008            0 :                      printf("Found node \"%s\", NA %d (0x%04X), GA %d (0x%04X), Rev. 0x%04X      \n",
    1009            0 :                               str, (unsigned short) i, (unsigned short) i, info.group_address,
    1010            0 :                               info.group_address, info.revision);
    1011              : 
    1012            0 :                      mscb_get_version(lib, prot);
    1013            0 :                      if (info.protocol_version != atoi(prot)) {
    1014              :                         printf
    1015            0 :                                 ("WARNING: Protocol version on node (%d) differs from local version (%s).\n",
    1016            0 :                                  info.protocol_version, prot);
    1017              :                      }
    1018              : 
    1019              :                   }
    1020            0 :                } else if (status == MSCB_SUBM_ERROR) {
    1021            0 :                   printf("Error: Submaster not responding\n");
    1022            0 :                   break;
    1023              :                }
    1024              : 
    1025            0 :                if (kbhit())
    1026            0 :                   break;
    1027              :             }
    1028              : 
    1029            0 :          } while ((param[1][0] == 'r' || param[2][0] == 'r') && !kbhit());
    1030              : 
    1031            0 :          while (kbhit())
    1032            0 :             getch();
    1033              : 
    1034            0 :          printf("                              \n");
    1035            0 :          if (n_found == 0)
    1036            0 :             printf("No nodes found                \n");
    1037            0 :          else if (n_found == 1)
    1038            0 :             printf("One node found                \n");
    1039            0 :          else if (n_found > 0)
    1040            0 :             printf("%d nodes found                \n", n_found);
    1041              :       }
    1042              : 
    1043              :       /* info ---------- */
    1044            0 :       else if (match(param[0], "info")) {
    1045            0 :          if (current_addr < 0)
    1046            0 :             printf("You must first address an individual node\n");
    1047              :          else {
    1048            0 :             status = mscb_info(fd, (unsigned short) current_addr, &info);
    1049            0 :             if (status == MSCB_CRC_ERROR)
    1050            0 :                puts("CRC Error");
    1051            0 :             else if (status != MSCB_SUCCESS)
    1052            0 :                puts("No response from node");
    1053              :             else {
    1054            0 :                strncpy(str, info.node_name, sizeof(str));
    1055            0 :                str[16] = 0;
    1056            0 :                printf("Node name         : %s\n", str);
    1057            0 :                printf("Node address      : %d (0x%X)\n", info.node_address,
    1058            0 :                       info.node_address);
    1059            0 :                printf("Group address     : %d (0x%X)\n", info.group_address,
    1060            0 :                       info.group_address);
    1061            0 :                printf("Protocol version  : %d\n", info.protocol_version);
    1062              : 
    1063              :                // check if it's an SCS3000 or not
    1064            0 :                if (info.pinExt_resets == 0) {
    1065            0 :                   printf("Revision          : 0x%04X\n", info.revision);
    1066              :                } else {
    1067            0 :                   printf("Revision          : V %d.%d.%d\n", info.revision >> 8, (info.revision >> 4) & 0xF,
    1068            0 :                          info.revision & 0xF);
    1069              :                }
    1070              : 
    1071              : 
    1072            0 :                if (info.rtc[0] && info.rtc[0] != 0xFF) {
    1073            0 :                   for (i = 0; i < 6; i++)
    1074            0 :                      info.rtc[i] = (info.rtc[i] / 0x10) * 10 + info.rtc[i] % 0x10;
    1075            0 :                   printf("Real Time Clock   : %02d-%02d-%02d %02d:%02d:%02d\n",
    1076            0 :                          info.rtc[0], info.rtc[1], info.rtc[2],
    1077            0 :                          info.rtc[3], info.rtc[4], info.rtc[5]);
    1078              :                }
    1079              : 
    1080            0 :                status = mscb_uptime(fd, (unsigned short) current_addr, &uptime);
    1081            0 :                if (status == MSCB_SUCCESS)
    1082            0 :                   printf("Uptime            : %dd %02dh %02dm %02ds\n",
    1083              :                          uptime / (3600 * 24),
    1084            0 :                          (uptime % (3600 * 24)) / 3600, (uptime % 3600) / 60,
    1085              :                          (uptime % 60));
    1086            0 :                if (info.buf_size != 0)
    1087            0 :                   printf("Buffer size       : %d\n", info.buf_size);
    1088              : 
    1089              :                // print variables for SCS3000
    1090            0 :                if (info.bootBank != 0) {
    1091            0 :                   printf("Pin/Ext WD Resets : %d\n", info.pinExt_resets);
    1092            0 :                   printf("SW-resets         : %d\n", info.SW_resets);
    1093            0 :                   printf("Int. WD resets    : %d\n", info.int_WD_resets);
    1094            0 :                   printf("Boot-Bank         : %d\n", info.bootBank);
    1095            0 :                   printf("Silicon Revision  : %c\n", info.siliconRevison);
    1096            0 :                   printf("System load       : %4.2f%%\n", info.systemLoad);
    1097            0 :                   printf("Peak system load  : %4.2f%%\n", info.peakSystemLoad);
    1098            0 :                   printf("PCB Temp          : %4.2f%cC\n", info.pcbTemp, 167);   // 167 is � symbol
    1099            0 :                   printf("Supply 1.8V       : %4.2fV\n", info.Supply1V8);
    1100            0 :                   printf("Supply 3.3V       : %4.2fV\n", info.Supply3V3);
    1101            0 :                   printf("Supply 5.0V       : %4.2fV\n", info.Supply5V0);
    1102            0 :                   printf("Supply 24.0V      : %4.2fV\n", info.Supply24V0);
    1103            0 :                   printf("Supply 5V Ext.    : %4.2fV\n", info.Supply5V0Ext);
    1104            0 :                   printf("Supply 24V Ext.   : %4.2fV\n", info.Supply24V0Ext);
    1105            0 :                   printf("Supply current    : %4.3fA\n", info.Supply24V0Current);
    1106            0 :                   printf("Battery voltage   : %4.2fV\n", info.Vbat);
    1107              :                }
    1108              : 
    1109            0 :                mscb_get_version(lib, prot);
    1110            0 :                if (info.protocol_version != atoi(prot)) {
    1111              :                   printf
    1112            0 :                           ("\nWARNING: Protocol version on node (%d) differs from local version (%s).\n",
    1113            0 :                            info.protocol_version, prot);
    1114              :                   printf
    1115            0 :                           ("Problems may arise communicating with this node. Please upgrade.\n\n");
    1116              :                }
    1117              :             }
    1118              :          }
    1119              :       }
    1120              : 
    1121              :       /* ping ---------- */
    1122            0 :       else if (match(param[0], "ping")) {
    1123            0 :          if (!param[1][0])
    1124            0 :             puts("Please specify node address");
    1125              :          else {
    1126            0 :             if (param[1][1] == 'x') {
    1127            0 :                sscanf(param[1] + 2, "%x", &i);
    1128            0 :                addr = (unsigned short) i;
    1129              :             } else
    1130            0 :                addr = (unsigned short) atoi(param[1]);
    1131              : 
    1132              :             do {
    1133            0 :                status = mscb_ping(fd, addr, 0, 1);
    1134              : 
    1135            0 :                if (status != MSCB_SUCCESS) {
    1136            0 :                   if (status == MSCB_MUTEX)
    1137            0 :                      printf("MSCB used by other thread\n");
    1138            0 :                   else if (status == MSCB_SUBM_ERROR)
    1139            0 :                      printf("Error: Submaster not responding\n");
    1140              :                   else
    1141            0 :                      printf("Node %d does not respond\n", addr);
    1142            0 :                   current_addr = -1;
    1143            0 :                   current_group = -1;
    1144            0 :                   broadcast = 0;
    1145              :                } else {
    1146            0 :                   printf("Node %d addressed\n", addr);
    1147            0 :                   current_addr = addr;
    1148            0 :                   current_group = -1;
    1149            0 :                   broadcast = 0;
    1150              :                }
    1151              : 
    1152            0 :                if (param[2][0] == 'r' && !kbhit())
    1153            0 :                   Sleep(1000);
    1154              : 
    1155            0 :             } while (param[2][0] == 'r' && !kbhit());
    1156              :          }
    1157              :       }
    1158              : 
    1159              :       /* address ---------- */
    1160            0 :       else if (match(param[0], "addr")) {
    1161            0 :          if (!param[1][0])
    1162            0 :             puts("Please specify node address");
    1163              :          else {
    1164            0 :             if (param[1][1] == 'x') {
    1165            0 :                sscanf(param[1] + 2, "%x", &i);
    1166            0 :                addr = (unsigned short) i;
    1167              :             } else
    1168            0 :                addr = (unsigned short) atoi(param[1]);
    1169              : 
    1170            0 :             mscb_addr(fd, MCMD_ADDR_NODE16, addr, 0, 10);
    1171            0 :             current_addr = addr;
    1172            0 :             current_group = -1;
    1173            0 :             broadcast = 0;
    1174              :          }
    1175              :       }
    1176              : 
    1177              :       /* ba, broadcast address ---------- */
    1178            0 :       else if (match(param[0], "baddr")) {
    1179            0 :          current_addr = -1;
    1180            0 :          current_group = -1;
    1181            0 :          broadcast = 1;
    1182              :       }
    1183              : 
    1184              :       /* ga, group address ---------- */
    1185            0 :       else if (match(param[0], "gaddr")) {
    1186            0 :          if (!param[1][0])
    1187            0 :             puts("Please specify group address");
    1188              :          else {
    1189            0 :             if (param[1][1] == 'x') {
    1190            0 :                sscanf(param[1] + 2, "%x", &i);
    1191            0 :                addr = (unsigned short) i;
    1192              :             } else
    1193            0 :                addr = (unsigned short) atoi(param[1]);
    1194              : 
    1195            0 :             printf("Enter address of first node in group %d: ", addr);
    1196            0 :             fgets(str, sizeof(str), stdin);
    1197            0 :             reference_addr = atoi(str);
    1198            0 :             current_addr = -1;
    1199            0 :             current_group = addr;
    1200            0 :             broadcast = 0;
    1201              :          }
    1202              :       }
    1203              : 
    1204              :       /* sa, set node address ---------- */
    1205            0 :       else if (match(param[0], "sa")) {
    1206            0 :          if (current_addr < 0 && current_group < 0 && !broadcast)
    1207            0 :             printf("You must first address node(s)\n");
    1208              :          else {
    1209            0 :             if (!param[1][0])
    1210            0 :                puts("Please specify node address");
    1211              :             else {
    1212            0 :                if (param[1][1] == 'x') {
    1213            0 :                   sscanf(param[1] + 2, "%x", &i);
    1214            0 :                   addr = (unsigned short) i;
    1215              :                } else
    1216            0 :                   addr = (unsigned short) atoi(param[1]);
    1217              : 
    1218            0 :                status =
    1219            0 :                        mscb_set_node_addr(fd, current_addr, current_group, broadcast, addr);
    1220            0 :                if (current_addr >= 0) {
    1221            0 :                   if (status == MSCB_ADDR_EXISTS)
    1222            0 :                      printf("Error: Address %d exists already on this network\n", addr);
    1223              :                   else
    1224            0 :                      current_addr = addr;
    1225              :                }
    1226              :             }
    1227              :          }
    1228              :       }
    1229              : 
    1230              :       /* sg, set group address ---------- */
    1231            0 :       else if (match(param[0], "sg")) {
    1232            0 :          if (current_addr < 0 && current_group < 0 && !broadcast)
    1233            0 :             printf("You must first address node(s)\n");
    1234              :          else {
    1235            0 :             if (!param[1][0])
    1236            0 :                puts("Please specify group address");
    1237              :             else {
    1238            0 :                if (param[1][1] == 'x') {
    1239            0 :                   sscanf(param[1] + 2, "%x", &i);
    1240            0 :                   addr = (unsigned short) i;
    1241              :                } else
    1242            0 :                   addr = (unsigned short) atoi(param[1]);
    1243              : 
    1244            0 :                mscb_set_group_addr(fd, current_addr, current_group, broadcast, addr);
    1245              :             }
    1246              :          }
    1247              :       }
    1248              : 
    1249              :       /* sn, set node name ---------- */
    1250            0 :       else if (match(param[0], "sn")) {
    1251            0 :          if (current_addr < 0)
    1252            0 :             printf("You must first address an individual node\n");
    1253              :          else {
    1254            0 :             if (!param[1][0])
    1255            0 :                puts("Please specify node name");
    1256              :             else {
    1257            0 :                str[0] = '\0';
    1258            0 :                for (j = 1; j < 10; j++) {
    1259            0 :                   strcat(str, param[j]);
    1260            0 :                   if (j < 9 && param[j + 1][0] != '\0') {
    1261            0 :                      strcat(str, " ");
    1262              :                   }
    1263              :                }
    1264            0 :                while (strlen(str) > 0
    1265            0 :                       && (str[strlen(str) - 1] == '\r' || str[strlen(str) - 1] == '\n'))
    1266            0 :                   str[strlen(str) - 1] = 0;
    1267              : 
    1268            0 :                if (strlen(str) > 15)
    1269            0 :                   printf("Maximum length is 15 characters, please choose shorter name\n");
    1270              :                else
    1271            0 :                   mscb_set_name(fd, (unsigned short) current_addr, str);
    1272              :             }
    1273              :          }
    1274              :       }
    1275              : 
    1276              :       /* sm, set MAC address etc. ---------- */
    1277            0 :       else if (match(param[0], "sm")) {
    1278            0 :          if (set_mac_address(fd))
    1279            0 :             break;              // exit program
    1280              :       }
    1281              : 
    1282              :       /* baud, set baud rate ---------- */
    1283            0 :       else if (match(param[0], "baud")) {
    1284            0 :          puts("Possible baud rates:\n");
    1285            0 :          puts("   1:    2400");
    1286            0 :          puts("   2:    4800");
    1287            0 :          puts("   3:    9600");
    1288            0 :          puts("   4:   19200");
    1289            0 :          puts("   5:   28800");
    1290            0 :          puts("   6:   38400");
    1291            0 :          puts("   7:   57600");
    1292            0 :          puts("   8:  115200 <= default");
    1293            0 :          puts("   9:  172800");
    1294            0 :          puts("  10:  345600");
    1295              : 
    1296            0 :          printf("\nSelect rate: ");
    1297            0 :          fgets(str, sizeof(str), stdin);
    1298            0 :          i = atoi(str);
    1299            0 :          mscb_set_baud(fd, i);
    1300              :       }
    1301              : 
    1302              : 
    1303              :       /* write ---------- */
    1304            0 :       else if (match(param[0], "write")) {
    1305            0 :          if (current_addr < 0 && current_group < 0)
    1306            0 :             printf("You must first address a node or a group\n");
    1307              :          else {
    1308            0 :             if (!param[1][0])
    1309            0 :                puts("Please specify channel number");
    1310              :             else {
    1311            0 :                idx1 = atoi(param[1]);
    1312            0 :                if (strchr(param[1], '-'))
    1313            0 :                   idx2 = atoi(strchr(param[1], '-') + 1);
    1314              :                else
    1315            0 :                   idx2 = idx1;
    1316              : 
    1317            0 :                if (current_addr < 0) {
    1318            0 :                   addr = reference_addr;
    1319              :                } else
    1320            0 :                   addr = current_addr;
    1321              : 
    1322            0 :                idx1 = idx1 > 255 ? 255 : idx1;
    1323            0 :                idx2 = idx2 > 255 ? 255 : idx2;
    1324              : 
    1325            0 :                for (index = idx1; index <= idx2; index++) {
    1326            0 :                   status = mscb_info_variable(fd, (unsigned short) addr, (unsigned char) index,
    1327              :                                               &info_var);
    1328              : 
    1329            0 :                   if (status == MSCB_NO_VAR) {
    1330            0 :                      printf("Node has no variable #%d\n", index);
    1331            0 :                      break;
    1332              :                   }
    1333              : 
    1334            0 :                   if (info_var.unit == UNIT_STRING) {
    1335            0 :                      memset(str, 0, sizeof(str));
    1336            0 :                      strncpy(str, param[2], info_var.width);
    1337            0 :                      if (strlen(str) > 0 && str[strlen(str) - 1] == '\n')
    1338            0 :                         str[strlen(str) - 1] = 0;
    1339              : 
    1340              :                      do {
    1341            0 :                         if (current_addr >= 0)
    1342            0 :                            status = mscb_write(fd, (unsigned short) current_addr,
    1343            0 :                                                (unsigned char) index, str, strlen(str) + 1);
    1344              :                         else
    1345            0 :                            status = mscb_write_group(fd, (unsigned short) current_group,
    1346              :                                                      (unsigned char) index, str,
    1347            0 :                                                      strlen(str) + 1);
    1348            0 :                         if (param[3][0])
    1349            0 :                            Sleep(1000);
    1350            0 :                      } while (param[3][0] && !kbhit());
    1351              : 
    1352            0 :                   } else if (info_var.unit == UNIT_ASCII) {
    1353            0 :                      memset(str, 0, sizeof(str));
    1354            0 :                      strncpy(str, param[2], sizeof(str));
    1355            0 :                      if (strlen(str) > 0 && str[strlen(str) - 1] == '\n')
    1356            0 :                         str[strlen(str) - 1] = 0;
    1357              : 
    1358              :                      do {
    1359            0 :                         if (current_addr >= 0)
    1360            0 :                            status =
    1361            0 :                                    mscb_write(fd, (unsigned short) current_addr,
    1362            0 :                                               (unsigned char) index, str, strlen(str) + 1);
    1363            0 :                         Sleep(100);
    1364            0 :                      } while (param[3][0] && !kbhit());
    1365              : 
    1366              :                   } else {
    1367            0 :                      if (!param[2][0])
    1368            0 :                         puts("Please specify data");
    1369              :                      else {
    1370            0 :                         if (info_var.unit == UNIT_BYTE && info_var.width == 8) {
    1371            0 :                            if (param[2][1] == 'x')
    1372            0 :                               sscanf(param[2] + 2, "%lx", &qdata);
    1373              :                            else
    1374            0 :                               qdata = atol(param[2]);
    1375              :                         } else {
    1376            0 :                            if (info_var.flags & MSCBF_FLOAT) {
    1377            0 :                               value = (float) atof(param[2]);
    1378            0 :                               memcpy(&data, &value, sizeof(float));
    1379              :                            } else {
    1380            0 :                               if (param[2][1] == 'x')
    1381            0 :                                  sscanf(param[2] + 2, "%x", &data);
    1382              :                               else
    1383            0 :                                  data = atoi(param[2]);
    1384              :                            }
    1385            0 :                            qdata = data;
    1386              :                         }
    1387              : 
    1388              :                         do {
    1389            0 :                            if (current_addr >= 0)
    1390            0 :                               status = mscb_write(fd, (unsigned short) current_addr,
    1391            0 :                                                   (unsigned char) index, &qdata, info_var.width);
    1392              :                            else
    1393            0 :                               status = mscb_write_group(fd, (unsigned short) current_group,
    1394              :                                                         (unsigned char) index, &qdata,
    1395            0 :                                                         info_var.width);
    1396              : 
    1397            0 :                            if (param[3][0])
    1398            0 :                               Sleep(100);
    1399              : 
    1400            0 :                         } while (param[3][0] && !kbhit());
    1401              :                      }
    1402              :                   }
    1403              :                }
    1404              : 
    1405            0 :                if (status != MSCB_SUCCESS)
    1406            0 :                   printf("Error: %d\n", status);
    1407              :             }
    1408              :          }
    1409              :       }
    1410              : 
    1411              :       /* mwrite ---------- */
    1412            0 :       else if (match(param[0], "mwrite")) {
    1413            0 :          if (!param[1][0] || !param[2][0] || !param[3][0] || !param[4][0])
    1414            0 :             puts("Please specify variable index, value, and node range");
    1415              :          else {
    1416            0 :             index = atoi(param[1]);
    1417            0 :             first = atoi(param[3]);
    1418            0 :             last = atoi(param[4]);
    1419              : 
    1420            0 :             mscb_info_variable(fd, (unsigned short) first, (unsigned char) index,
    1421              :                                &info_var);
    1422              : 
    1423            0 :             for (addr = first; addr <= last; addr++) {
    1424              : 
    1425            0 :                printf("Node %d\n", addr);
    1426            0 :                if (info_var.unit == UNIT_STRING) {
    1427            0 :                   memset(str, 0, sizeof(str));
    1428            0 :                   strncpy(str, param[2], info_var.width);
    1429            0 :                   if (strlen(str) > 0 && str[strlen(str) - 1] == '\n')
    1430            0 :                      str[strlen(str) - 1] = 0;
    1431              : 
    1432            0 :                   status = mscb_write(fd, (unsigned short) addr,
    1433            0 :                                       (unsigned char) index, str, strlen(str) + 1);
    1434              : 
    1435            0 :                } else if (info_var.unit == UNIT_ASCII) {
    1436            0 :                   memset(str, 0, sizeof(str));
    1437            0 :                   strncpy(str, param[2], sizeof(str));
    1438            0 :                   if (strlen(str) > 0 && str[strlen(str) - 1] == '\n')
    1439            0 :                      str[strlen(str) - 1] = 0;
    1440              : 
    1441            0 :                   mscb_write(fd, (unsigned short) addr,
    1442            0 :                              (unsigned char) index, str, strlen(str) + 1);
    1443              :                } else {
    1444            0 :                   if (info_var.flags & MSCBF_FLOAT) {
    1445            0 :                      value = (float) atof(param[2]);
    1446            0 :                      memcpy(&data, &value, sizeof(float));
    1447              :                   } else {
    1448            0 :                      if (param[2][1] == 'x')
    1449            0 :                         sscanf(param[2] + 2, "%x", &data);
    1450              :                      else
    1451            0 :                         data = atoi(param[2]);
    1452              :                   }
    1453              : 
    1454            0 :                   status = mscb_write(fd, (unsigned short) addr,
    1455            0 :                                       (unsigned char) index, &data, info_var.width);
    1456              :                }
    1457              :             }
    1458              : 
    1459            0 :             if (status != MSCB_SUCCESS)
    1460            0 :                printf("Error: %d\n", status);
    1461              :          }
    1462              :       }
    1463              : 
    1464              :       /* read ---------- */
    1465            0 :       else if (match(param[0], "read")) {
    1466            0 :          if (current_addr < 0)
    1467            0 :             printf("You must first address an individual node\n");
    1468              :          else {
    1469            0 :             if (!param[1][0] || param[1][0] == 'a' || param[1][0] == 'r') {
    1470            0 :                first = 0;
    1471            0 :                last = 255;
    1472            0 :             } else if (strchr(param[1], '-')) {
    1473            0 :                first = atoi(param[1]);
    1474            0 :                last = atoi(strchr(param[1], '-') + 1);
    1475              :             } else {
    1476            0 :                first = last = atoi(param[1]);
    1477              :             }
    1478              : 
    1479            0 :             first = first > 255 ? 255 : first;
    1480            0 :             last = last > 255 ? 255 : last;
    1481              : 
    1482            0 :             read_all = (param[1][0] == 'a' || param[2][0] == 'a' || param[3][0] == 'a');
    1483            0 :             repeat = (param[1][0] == 'r' || param[2][0] == 'r' || param[3][0] == 'r');
    1484            0 :             if (repeat) {
    1485            0 :                wait = 0;
    1486            0 :                for (i = 1; i < 4; i++)
    1487            0 :                   if (param[i][0] == 'r')
    1488            0 :                      break;
    1489            0 :                if (atoi(param[i + 1]) > 0)
    1490            0 :                   wait = atoi(param[i + 1]);
    1491              :             }
    1492              : 
    1493            0 :             n_found = 0;
    1494            0 :             memset(info_var_array, 0, sizeof(info_var_array));
    1495            0 :             for (i = first; i <= last; i++) {
    1496            0 :                status = mscb_info_variable(fd, (unsigned short) current_addr, (unsigned char) i, &info_var_array[i]);
    1497            0 :                if (status == MSCB_NO_VAR) {
    1498            0 :                   if (first == last)
    1499            0 :                      printf("Node has no variable #%d\n", first);
    1500            0 :                   break;
    1501            0 :                } else if (status == MSCB_CRC_ERROR)
    1502            0 :                   puts("CRC Error\n");
    1503            0 :                else if (status != MSCB_SUCCESS)
    1504            0 :                   puts("Timeout or invalid channel number\n");
    1505              :                else
    1506            0 :                   n_found++;
    1507              :             }
    1508              : 
    1509            0 :             if (n_found) {
    1510              :                do {
    1511            0 :                   if (first == last) { // read single variable
    1512            0 :                      i = first;
    1513            0 :                      size = info_var_array[i].width;
    1514            0 :                      memset(dbuf, 0, sizeof(dbuf));
    1515            0 :                      status = mscb_read(fd, (unsigned short) current_addr, (unsigned char) i, dbuf, &size);
    1516              : 
    1517            0 :                      if (status == MSCB_SUCCESS)
    1518            0 :                         print_channel(i, &info_var_array[i], dbuf, first != last);
    1519              :                   } else { // read multiple variables
    1520            0 :                      last = first + n_found - 1;
    1521            0 :                      size = 1400;
    1522            0 :                      status = mscb_read_range(fd, (unsigned short) current_addr, (unsigned char) first,
    1523              :                                               (unsigned char) last, dbuf, &size);
    1524              : 
    1525            0 :                      if (status == MSCB_CRC_ERROR)
    1526            0 :                         puts("CRC Error\n");
    1527            0 :                      else if (status == MSCB_TIMEOUT)
    1528            0 :                         puts("Timeout receivig acknowledge\n");
    1529            0 :                      else if (status != MSCB_SUCCESS)
    1530            0 :                         puts("Reading not successful!\n");
    1531              :                      else {
    1532            0 :                         pdata = dbuf;
    1533            0 :                         for (i = first; i <= last; i++) {
    1534            0 :                            size = info_var_array[i].width;
    1535            0 :                            if (size == 2) {
    1536            0 :                               WORD_SWAP(pdata);
    1537            0 :                            } else if (size == 4) {
    1538            0 :                               DWORD_SWAP(pdata);
    1539              :                            }
    1540              : 
    1541            0 :                            if ((info_var_array[i].flags & MSCBF_HIDDEN) == 0 || read_all || first > 0)
    1542            0 :                               print_channel(i, &info_var_array[i], pdata, first != last);
    1543              : 
    1544            0 :                            if (kbhit())
    1545            0 :                               break;
    1546              : 
    1547            0 :                            pdata += size;
    1548              :                         }
    1549              :                      }
    1550              :                   }
    1551              : 
    1552            0 :                   if (kbhit())
    1553            0 :                      break;
    1554              : 
    1555            0 :                   if (first != last && repeat)
    1556            0 :                      printf("\n");
    1557              : 
    1558            0 :                   if (repeat) {
    1559            0 :                      if (wait) {
    1560            0 :                         Sleep(wait);
    1561            0 :                         printf("\n");
    1562              :                      } else
    1563            0 :                         Sleep(10);
    1564              :                   }
    1565              : 
    1566            0 :                } while (!kbhit() && repeat);
    1567              :             }
    1568              : 
    1569            0 :             if (first == last)
    1570            0 :                printf("\n");
    1571            0 :             while (kbhit())
    1572            0 :                getch();
    1573              :          }
    1574              :       }
    1575              : 
    1576              :       /* save ---------- */
    1577            0 :       else if (match(param[0], "save")) {
    1578            0 :          if (current_addr < 0 && param[1][0] == 0 && param[2][0] == 0)
    1579            0 :             printf("You must first address an individual node or specify a range\n");
    1580              :          else {
    1581            0 :             if (param[1][0] == 0 || strchr(param[1], '.') == NULL) {
    1582            0 :                printf("Enter file name: ");
    1583            0 :                fgets(str, sizeof(str), stdin);
    1584              :             } else
    1585            0 :                strcpy(str, param[1]);
    1586              : 
    1587            0 :             if (str[strlen(str) - 1] == '\n')
    1588            0 :                str[strlen(str) - 1] = 0;
    1589              : 
    1590            0 :             if (param[2][0] == 0)
    1591            0 :                first = last = current_addr;
    1592              :             else {
    1593            0 :                if (param[3][0]) {
    1594            0 :                   first = atoi(param[2]);
    1595            0 :                   last = atoi(param[3]);
    1596              :                } else {
    1597            0 :                   first = atoi(param[1]);
    1598            0 :                   last = atoi(param[2]);
    1599              :                }
    1600              :             }
    1601              : 
    1602            0 :             writer = mxml_open_file(str);
    1603            0 :             if (writer == NULL)
    1604            0 :                printf("Cannot open xml file \"%s\"\n", str);
    1605              :             else {
    1606            0 :                mxml_start_element(writer, "MSCBDump");
    1607            0 :                for (i = first, j = 0; i <= last; i++) {
    1608            0 :                   status = mscb_ping(fd, (unsigned short) i, 0, 1);
    1609            0 :                   if (status == MSCB_SUCCESS) {
    1610            0 :                      j++;
    1611            0 :                      printf("Save node %d (0x%04X)     \r", i, i);
    1612            0 :                      fflush(stdout);
    1613            0 :                      save_node_xml(writer, fd, i);
    1614              :                   } else {
    1615            0 :                      printf("Test address %d (0x%04X)     \r", i, i);
    1616            0 :                      fflush(stdout);
    1617              :                   }
    1618              :                }
    1619            0 :                printf("\n");
    1620            0 :                if (j > 1)
    1621            0 :                   printf("%d nodes saved               \n", j);
    1622              : 
    1623            0 :                mxml_end_element(writer);
    1624            0 :                mxml_close_file(writer);
    1625              :             }
    1626              :          }
    1627              :       }
    1628              : 
    1629              :       /* load ---------- */
    1630            0 :       else if (match(param[0], "load")) {
    1631            0 :          if (param[1][0] == 0) {
    1632            0 :             printf("Enter file name: ");
    1633            0 :             fgets(str, sizeof(str), stdin);
    1634              :          } else
    1635            0 :             strcpy(str, param[1]);
    1636              : 
    1637            0 :          if (str[strlen(str) - 1] == '\n')
    1638            0 :             str[strlen(str) - 1] = 0;
    1639              : 
    1640            0 :          printf("Write parameters to flash? (y/[n]) ");
    1641            0 :          fgets(line, sizeof(line), stdin);
    1642              : 
    1643            0 :          load_nodes_xml(fd, str, line[0] == 'y');
    1644              :       }
    1645              : 
    1646              :       /* terminal ---------- */
    1647            0 :       else if (match(param[0], "terminal")) {
    1648              :          int status, chn;
    1649              : 
    1650              :          /* find first dataless variable */
    1651            0 :          memset(info_var_array, 0, sizeof(info_var_array));
    1652            0 :          for (chn = 0; chn < 255; chn++) {
    1653            0 :             status = mscb_info_variable(fd, (unsigned short) current_addr, (unsigned char) chn, &info_var_array[chn]);
    1654            0 :             if (status == MSCB_NO_VAR)
    1655            0 :                break;
    1656            0 :             if (info_var_array[chn].flags & MSCBF_DATALESS)
    1657            0 :                break;
    1658              :          }
    1659              : 
    1660            0 :          if (status == MSCB_NO_VAR) {
    1661              : 
    1662            0 :             puts("Node does not support terminal mode.\n");
    1663              : 
    1664              :          } else {
    1665              : 
    1666            0 :             puts("Exit with <ESC>\n");
    1667            0 :             c = 0;
    1668              : 
    1669              :             do {
    1670            0 :                if ((c = ss_getchar(0)) != 0) {
    1671            0 :                   if (c == 27)
    1672            0 :                      break;
    1673              : 
    1674            0 :                   putchar(c);
    1675            0 :                   fflush(stdout);
    1676            0 :                   status = mscb_write(fd, (unsigned short) current_addr, chn, &c, 1);
    1677            0 :                   if (status != MSCB_SUCCESS) {
    1678            0 :                      printf("\nError: %d\n", status);
    1679            0 :                      break;
    1680              :                   }
    1681              : 
    1682            0 :                   if (c == '\r') {
    1683            0 :                      putchar('\n');
    1684            0 :                      c = '\n';
    1685            0 :                      mscb_write(fd, (unsigned short) current_addr, chn, &c, 1);
    1686              :                   }
    1687              : 
    1688              :                }
    1689              : 
    1690            0 :                memset(line, 0, sizeof(line));
    1691            0 :                size = sizeof(line);
    1692            0 :                mscb_read(fd, (unsigned short) current_addr, chn, line, &size);
    1693            0 :                if (size > 0) {
    1694            0 :                   fputs(line, stdout);
    1695            0 :                   fflush(stdout);
    1696              :                }
    1697              : 
    1698            0 :                Sleep(10);
    1699              :             } while (TRUE);
    1700              : 
    1701            0 :             puts("\n");
    1702            0 :             while (kbhit())
    1703            0 :                getch();
    1704              :          }
    1705              :       }
    1706              : 
    1707              :       /* flash ---------- */
    1708            0 :       else if (match(param[0], "flash")) {
    1709            0 :          if (current_addr < 0 && current_group < 0 && !broadcast)
    1710            0 :             printf("You must first address node (s)\n");
    1711              :          else {
    1712            0 :             status = mscb_flash(fd, current_addr, current_group, broadcast);
    1713              : 
    1714            0 :             if (status != MSCB_SUCCESS)
    1715            0 :                printf("Error: %d\n", status);
    1716              :          }
    1717              :       }
    1718              : 
    1719              :       /* upload ---------- */
    1720            0 :       else if (match(param[0], "upload")) {
    1721            0 :          if (isdigit(param[1][0])) {
    1722              :             // address given: upload to WaveDAQ slot
    1723            0 :             if (param[2][0] == 0) {
    1724            0 :                printf("Enter name of file: ");
    1725            0 :                fgets(filename, sizeof(filename), stdin);
    1726              :             } else
    1727            0 :                strcpy(filename, param[2]);
    1728              : 
    1729            0 :             if (str[strlen(filename) - 1] == '\n')
    1730            0 :                str[strlen(filename) - 1] = 0;
    1731              : 
    1732            0 :             i = 0;
    1733            0 :             if (match(param[2], "debug") ||
    1734            0 :                 match(param[3], "deubg"))
    1735            0 :                i = 1;
    1736              : 
    1737            0 :             status = mscb_upload(fd, (unsigned short) current_addr, (unsigned short) atoi(param[1]), filename,
    1738              :                                  i | MSCB_UPLOAD_SUBADDR);
    1739            0 :             if (status == MSCB_NOT_FOUND)
    1740            0 :                printf("File \"%s\" not found\n", filename);
    1741            0 :             else if (status == MSCB_FORMAT_ERROR)
    1742            0 :                printf("Syntax error in file \"%s\"\n", filename);
    1743            0 :             else if (status == MSCB_TIMEOUT)
    1744            0 :                printf("Node %d does not respond\n", current_addr);
    1745            0 :             else if (status == MSCB_SUBADDR)
    1746            0 :                printf("Cannot program subaddress\n");
    1747            0 :             else if (status == MSCB_NOTREADY)
    1748            0 :                printf("Note just rebooted and not ready for upgrade\n");
    1749              : 
    1750              :          } else {
    1751            0 :             if (current_addr < 0)
    1752            0 :                printf("You must first address an individual node\n");
    1753              :             else {
    1754            0 :                if (param[1][0] == 0) {
    1755            0 :                   printf("Enter name of file: ");
    1756            0 :                   fgets(filename, sizeof(filename), stdin);
    1757              :                } else
    1758            0 :                   strcpy(filename, param[1]);
    1759              : 
    1760            0 :                if (str[strlen(filename) - 1] == '\n')
    1761            0 :                   str[strlen(filename) - 1] = 0;
    1762              : 
    1763            0 :                status = mscb_upload(fd, (unsigned short) current_addr, 0, filename, param[2][0] == 'd');
    1764            0 :                if (status == MSCB_NOT_FOUND)
    1765            0 :                   printf("File \"%s\" not found\n", filename);
    1766            0 :                else if (status == MSCB_FORMAT_ERROR)
    1767            0 :                   printf("Syntax error in file \"%s\"\n", filename);
    1768            0 :                else if (status == MSCB_TIMEOUT)
    1769            0 :                   printf("Node %d does not respond\n", current_addr);
    1770            0 :                else if (status == MSCB_SUBADDR)
    1771            0 :                   printf("Cannot program subaddress\n");
    1772            0 :                else if (status == MSCB_NOTREADY)
    1773            0 :                   printf("Note just rebooted and not ready for upgrade\n");
    1774              : 
    1775              :             }
    1776              :          }
    1777              :       }
    1778              : 
    1779              :       /* download ---------- */
    1780            0 :       else if (match(param[0], "download")) {
    1781            0 :          if (isdigit(param[1][0])) {
    1782              :             // address given: upload to WaveDAQ slot
    1783            0 :             if (param[2][0] == 0) {
    1784            0 :                printf("Enter name of file: ");
    1785            0 :                fgets(filename, sizeof(filename), stdin);
    1786              :             } else
    1787            0 :                strcpy(filename, param[2]);
    1788              : 
    1789            0 :             if (str[strlen(filename) - 1] == '\n')
    1790            0 :                str[strlen(filename) - 1] = 0;
    1791              : 
    1792            0 :             status = mscb_download(fd, (unsigned short) current_addr, (unsigned short) atoi(param[1]), filename);
    1793            0 :             if (status == MSCB_NOT_FOUND)
    1794            0 :                printf("File \"%s\" exists already\n", filename);
    1795            0 :             else if (status == MSCB_NO_MEM)
    1796            0 :                printf("Cannot write to file \"%s\"\n", filename);
    1797            0 :             else if (status == MSCB_TIMEOUT)
    1798            0 :                printf("Node %d does not respond\n", current_addr);
    1799            0 :             else if (status == MSCB_SUBADDR)
    1800            0 :                printf("Cannot read subaddress\n");
    1801              : 
    1802              :          } else {
    1803            0 :             if (current_addr < 0)
    1804            0 :                printf("You must first address an individual node\n");
    1805              :             else {
    1806            0 :                if (param[1][0] == 0) {
    1807            0 :                   printf("Enter name of file: ");
    1808            0 :                   fgets(filename, sizeof(filename), stdin);
    1809              :                } else
    1810            0 :                   strcpy(filename, param[1]);
    1811              : 
    1812            0 :                if (str[strlen(filename) - 1] == '\n')
    1813            0 :                   str[strlen(filename) - 1] = 0;
    1814              : 
    1815            0 :                status = mscb_download(fd, (unsigned short) current_addr, 0, filename);
    1816            0 :                if (status == MSCB_NOT_FOUND)
    1817            0 :                   printf("File \"%s\" exists already\n", filename);
    1818            0 :                else if (status == MSCB_NO_MEM)
    1819            0 :                   printf("Cannot write to file \"%s\"\n", filename);
    1820            0 :                else if (status == MSCB_TIMEOUT)
    1821            0 :                   printf("Node %d does not respond\n", current_addr);
    1822            0 :                else if (status == MSCB_SUBADDR)
    1823            0 :                   printf("Cannot read subaddress\n");
    1824              :             }
    1825              :          }
    1826              :       }
    1827              : 
    1828              :       /* mupload ---------- */
    1829            0 :       else if (match(param[0], "mupload")) {
    1830              : 
    1831            0 :          first = atoi(param[2]);
    1832            0 :          last = atoi(param[3]);
    1833              : 
    1834            0 :          if (last == 0)
    1835            0 :             printf("You must specify an address range\n");
    1836              :          else {
    1837            0 :             strcpy(filename, param[1]);
    1838              : 
    1839            0 :             for (i = first; i <= last; i++) {
    1840            0 :                printf("Node%d: ", i);
    1841            0 :                status = mscb_upload(fd, (unsigned short) i, 0, filename, 0);
    1842              : 
    1843            0 :                if (status == MSCB_NOT_FOUND) {
    1844            0 :                   printf("File \"%s\" not found\n", filename);
    1845            0 :                   break;
    1846            0 :                } else if (status == MSCB_FORMAT_ERROR) {
    1847            0 :                   printf("Syntax error in file \"%s\"\n", filename);
    1848            0 :                   break;
    1849            0 :                } else if (status == MSCB_TIMEOUT)
    1850            0 :                   printf("Node %d does not respond\n", current_addr);
    1851            0 :                else if (status == MSCB_SUBADDR)
    1852            0 :                   printf("Cannot program subaddress\n");
    1853            0 :                else if (status == MSCB_NOTREADY)
    1854            0 :                   printf("Note just rebooted and not ready for upgrade\n");
    1855              :             }
    1856              :          }
    1857              :       }
    1858              : 
    1859              :       /* verify ---------- */
    1860            0 :       else if (match(param[0], "verify")) {
    1861            0 :          if (isdigit(param[1][0])) {
    1862              :             // address given: verify WaveDAQ slot
    1863            0 :             if (param[2][0] == 0) {
    1864            0 :                printf("Enter name of file: ");
    1865            0 :                fgets(filename, sizeof(filename), stdin);
    1866              :             } else
    1867            0 :                strcpy(filename, param[2]);
    1868              : 
    1869            0 :             if (str[strlen(filename) - 1] == '\n')
    1870            0 :                str[strlen(filename) - 1] = 0;
    1871              : 
    1872            0 :             status = mscb_verify(fd, (unsigned short) current_addr, (short) atoi(param[1]), filename,
    1873              :                                  MSCB_UPLOAD_SUBADDR);
    1874            0 :             if (status == MSCB_NOT_FOUND)
    1875            0 :                printf("File \"%s\" not found\n", filename);
    1876            0 :             else if (status == MSCB_FORMAT_ERROR)
    1877            0 :                printf("Syntax error in file \"%s\"\n", filename);
    1878            0 :             else if (status == MSCB_TIMEOUT)
    1879            0 :                printf("Node %d does not respond\n", current_addr);
    1880            0 :             else if (status == MSCB_SUBADDR)
    1881            0 :                printf("Cannot program subaddress\n");
    1882            0 :             else if (status == MSCB_NOTREADY)
    1883            0 :                printf("Note just rebooted and not ready for upgrade\n");
    1884              : 
    1885              :          } else {
    1886            0 :             if (current_addr < 0)
    1887            0 :                printf("You must first address an individual node\n");
    1888              :             else {
    1889            0 :                if (param[1][0] == 0) {
    1890            0 :                   printf("Enter name of file: ");
    1891            0 :                   fgets(filename, sizeof(filename), stdin);
    1892              :                } else
    1893            0 :                   strcpy(filename, param[1]);
    1894              : 
    1895            0 :                if (str[strlen(filename) - 1] == '\n')
    1896            0 :                   str[strlen(filename) - 1] = 0;
    1897              : 
    1898            0 :                status = mscb_verify(fd, (unsigned short) current_addr, 0, filename, 0);
    1899            0 :                if (status == MSCB_NOT_FOUND)
    1900            0 :                   printf("File \"%s\" not found\n", filename);
    1901            0 :                else if (status == MSCB_FORMAT_ERROR)
    1902            0 :                   printf("Syntax error in file \"%s\"\n", filename);
    1903            0 :                else if (status == MSCB_TIMEOUT)
    1904            0 :                   printf("Node %d does not respond\n", current_addr);
    1905            0 :                else if (status == MSCB_SUBADDR)
    1906            0 :                   printf("Cannot program subaddress\n");
    1907            0 :                else if (status == MSCB_NOTREADY)
    1908            0 :                   printf("Note just rebooted and not ready for upgrade\n");
    1909              :             }
    1910              :          }
    1911              :       }
    1912              : 
    1913              :       /* memory write ---------- */
    1914            0 :       else if (match(param[0], "memwr")) {
    1915            0 :          if (current_addr < 0 && current_group < 0 && !broadcast)
    1916            0 :             printf("You must first address node (s)\n");
    1917              :          else {
    1918            0 :             slot = atoi(param[1]);
    1919              : 
    1920            0 :             if (param[2][1] == 'x')
    1921            0 :                sscanf(param[2] + 2, "%X", &mem_addr);
    1922              :             else
    1923            0 :                mem_addr = atoi(param[2]);
    1924              : 
    1925            0 :             mem_addr |= MSCB_BASE_RAM;
    1926              : 
    1927            0 :             if (param[3][1] == 'x') {
    1928            0 :                sscanf(param[3] + 2, "%X", &data);
    1929            0 :                if (strlen(param[3]) == 4)
    1930            0 :                   size = 1;
    1931            0 :                else if (strlen(param[3]) == 6) {
    1932            0 :                   size = 2;
    1933            0 :                   WORD_SWAP(&data);
    1934              :                } else {
    1935            0 :                   size = 4;
    1936            0 :                   DWORD_SWAP(&data);
    1937              :                }
    1938            0 :             } else if (isdigit(param[3][0])) {
    1939            0 :                size = 4;
    1940            0 :                data = atoi(param[3]);
    1941            0 :                DWORD_SWAP(&data);
    1942              :             } else {
    1943              :                // TBD: String
    1944              :             }
    1945              : 
    1946            0 :             mscb_write_mem(fd, (unsigned short) current_addr, slot, mem_addr, &data, size);
    1947              :          }
    1948              :       }
    1949              : 
    1950              :       /* memory read ---------- */
    1951            0 :       else if (match(param[0], "memrd")) {
    1952            0 :          if (current_addr < 0 && current_group < 0 && !broadcast)
    1953            0 :             printf("You must first address node (s)\n");
    1954              :          else {
    1955            0 :             slot = atoi(param[1]);
    1956              : 
    1957            0 :             if (param[2][1] == 'x')
    1958            0 :                sscanf(param[2] + 2, "%X", &mem_addr);
    1959              :             else
    1960            0 :                mem_addr = atoi(param[2]);
    1961              : 
    1962            0 :             mem_addr |= MSCB_BASE_RAM;
    1963              : 
    1964            0 :             if (param[3][1] == 'x')
    1965            0 :                sscanf(param[3] + 2, "%X", &size);
    1966              :             else
    1967            0 :                size = atoi(param[3]);
    1968              : 
    1969            0 :             status = mscb_read_mem(fd, (unsigned short) current_addr, slot, mem_addr, &dbuf, size);
    1970              : 
    1971              :             /* print result */
    1972            0 :             if (status == MSCB_SUCCESS) {
    1973            0 :                printf("0x%02X: ", mem_addr);
    1974            0 :                for (i = 0; i < size; i++)
    1975            0 :                   printf("%02X ", (unsigned char) dbuf[i]);
    1976            0 :                printf("\n");
    1977              :             }
    1978              :          }
    1979              :       }
    1980              : 
    1981              :       /* reboot ---------- */
    1982            0 :       else if (match(param[0], "reboot")) {
    1983            0 :          if (current_addr < 0 && current_group < 0 && !broadcast)
    1984            0 :             printf("You must first address node (s)\n");
    1985              :          else {
    1986            0 :             status = mscb_reboot(fd, current_addr, current_group, broadcast);
    1987              : 
    1988            0 :             if (status != MSCB_SUCCESS)
    1989            0 :                printf("Error: %d\n", status);
    1990              :          }
    1991              :       }
    1992              : 
    1993              :       /* sr ---------- */
    1994            0 :       else if (match(param[0], "sr")) {
    1995            0 :          mscb_subm_reset(fd);
    1996              :       }
    1997              : 
    1998              :       /* submaster ---------- */
    1999            0 :       else if (match(param[0], "submaster")) {
    2000            0 :          mscb_subm_info(fd);
    2001              :       }
    2002              : 
    2003              :       /* sync ---------- */
    2004            0 :       else if (match(param[0], "sync")) {
    2005            0 :          if (current_addr < 0 && current_group < 0 && !broadcast)
    2006            0 :             printf("You must first address node (s)\n");
    2007              :          else {
    2008            0 :             status = mscb_set_time(fd, current_addr, current_group, broadcast);
    2009              : 
    2010            0 :             if (status != MSCB_SUCCESS)
    2011            0 :                printf("Error: %d\n", status);
    2012              :             else {
    2013            0 :                now = time(NULL);
    2014            0 :                ptm = localtime(&now);
    2015            0 :                printf("Synchornized to %02d-%02d-%02d %02d:%02d:%02d\n",
    2016            0 :                       ptm->tm_mday, ptm->tm_mon + 1, ptm->tm_year - 100,
    2017              :                       ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
    2018              :             }
    2019              :          }
    2020              :       }
    2021              : 
    2022              :       /* echo test ---------- */
    2023            0 :       else if (match(param[0], "echo")) {
    2024              :          unsigned char d1, d2;
    2025              :          int i, status;
    2026              : 
    2027            0 :          if (current_addr < 0)
    2028            0 :             printf("You must first address an individual node\n");
    2029              :          else {
    2030            0 :             d1 = i = 0;
    2031            0 :             while (!kbhit()) {
    2032            0 :                d1 = (d1 + 1) % 256;
    2033              : 
    2034            0 :                status = mscb_echo(fd, (unsigned short) current_addr, d1, &d2);
    2035              : 
    2036            0 :                if (status == MSCB_TIMEOUT)
    2037            0 :                   printf("Timeout in submaster communictation\n");
    2038            0 :                else if (status == MSCB_TIMEOUT_BUS)
    2039            0 :                   printf("Timeout from RS485 bus\n");
    2040            0 :                else if (status == MSCB_CRC_ERROR)
    2041            0 :                   printf("CRC Error on RS485 bus\n");
    2042            0 :                else if (status != MSCB_SUCCESS)
    2043            0 :                   printf("Error: %d\n", status);
    2044              : 
    2045            0 :                if (d2 != d1) {
    2046            0 :                   printf("%d\nReceived: %02X, should be %02X, status = %d\n", i, d2, d1,
    2047              :                          status);
    2048              : 
    2049            0 :                   if (param[1][0] != 'c' && param[1][1] != 'c')
    2050            0 :                      break;
    2051              :                }
    2052              : 
    2053            0 :                i++;
    2054            0 :                if (i % 100 == 0) {
    2055            0 :                   printf("%d\r", i);
    2056            0 :                   fflush(stdout);
    2057              :                }
    2058              : 
    2059            0 :                if (param[1][0] != 'f' && param[1][1] != 'c')
    2060            0 :                   Sleep(10);
    2061              :             }
    2062            0 :             printf("%d\n", i);
    2063            0 :             while (kbhit())
    2064            0 :                getch();
    2065              :          }
    2066              :       }
    2067              : 
    2068              :       /* call user function ----------- */
    2069            0 :       else if (match(param[0], "user")) {
    2070            0 :          if (current_addr < 0 && current_group < 0 && !broadcast)
    2071            0 :             printf("You must first address node (s)\n");
    2072              :          else {
    2073              : 
    2074            0 :             if (param[1][0]) {
    2075            0 :                data = atoi(param[1]);
    2076            0 :                size = sizeof(status);
    2077            0 :                status = mscb_user(fd, current_addr, &data, 1, &status, &size);
    2078              :             } else {
    2079            0 :                status = mscb_user(fd, current_addr, NULL, 0, &data, &size);
    2080              :             }
    2081              : 
    2082            0 :             if (status != MSCB_SUCCESS)
    2083            0 :                printf("Error: %d\n", status);
    2084              :          }
    2085            0 :       } else if (match(param[0], "log")) {
    2086            0 :          if (broadcast)
    2087            0 :             printf("Log command not allowed in broadcast mode!\n");
    2088            0 :          else if (current_group > 0)
    2089            0 :             printf("Log command not allowed in group address mode!\n");
    2090            0 :          if (current_addr < 0)
    2091            0 :             printf("You must first address a single node\n");
    2092              :          else {
    2093              : 
    2094              :             // check first if its an SCS3000
    2095            0 :             memset(&info, 0, sizeof(info));
    2096            0 :             status = mscb_info(fd, (unsigned short) current_addr, &info);
    2097            0 :             if (status == MSCB_CRC_ERROR)
    2098            0 :                puts("CRC Error");
    2099            0 :             else if (status != MSCB_SUCCESS)
    2100            0 :                puts("node does not respond.");
    2101            0 :             else if (info.bootBank == 0)
    2102            0 :                puts("Log command not supported!");
    2103              :             else {
    2104            0 :                if (param[1][0] == 'c')
    2105              :                   // clear log
    2106            0 :                   status = mscb_clear_log(fd, current_addr);
    2107              :                else {
    2108              :                   // +3 becasue of ACK and datalength of answer
    2109            0 :                   char *LogMsg = &dbuf[3];
    2110              : 
    2111              :                   // read log
    2112              :                   do {
    2113            0 :                      status = mscb_read_log(fd, current_addr, dbuf, sizeof(dbuf));
    2114              : 
    2115            0 :                      if (status == MSCB_SUCCESS)
    2116            0 :                         printf("%s", LogMsg);
    2117              : 
    2118            0 :                   } while (status == MSCB_SUCCESS && *LogMsg != '\0');
    2119              :                }
    2120              : 
    2121            0 :                if (status != MSCB_SUCCESS)
    2122            0 :                   printf("Error: %d\n", status);
    2123              :             }
    2124              :          }
    2125              :       }
    2126              : 
    2127              :       /* test1 ---------- */
    2128            0 :       else if (match(param[0], "t1")) {
    2129            0 :          data = atoi(param[1]);
    2130              : 
    2131              :          do {
    2132            0 :             mscb_link(fd, (unsigned short) current_addr, 4, &data, 1);
    2133            0 :             printf("Data: %d\r", data);
    2134            0 :          } while (!kbhit());
    2135            0 :          while (kbhit())
    2136            0 :             getch();
    2137              :       }
    2138              : 
    2139              :       /* test2 -----------*/
    2140            0 :       else if (match(param[0], "t2")) {
    2141              :          float a[16];
    2142            0 :          unsigned int start = ss_millitime();
    2143              : 
    2144            0 :          for (i = 0; i < 16; i++) {
    2145            0 :             a[i] = i * 1.01f;
    2146            0 :             DWORD_SWAP(&a[i]);
    2147              :          }
    2148            0 :          for (i = 0; i < 900; i++) {
    2149            0 :             mscb_write_range(fd, (unsigned short) current_addr, 0, 16, a, sizeof(a));
    2150            0 :             printf("%d\r", i);
    2151            0 :             if (kbhit())
    2152            0 :                break;
    2153              :          }
    2154            0 :          printf("\n%3.2lf sec.\n", (ss_millitime() - start) / 1000.0);
    2155            0 :          while (kbhit())
    2156            0 :             getch();
    2157              :       }
    2158              : 
    2159              :       /* calib1 -----------*/
    2160            0 :       else if (match(param[0], "c1")) {
    2161            0 :          status = mscb_info(fd, (unsigned short) current_addr, &info);
    2162            0 :          if (std::string(info.node_name) == "MPDC") {
    2163            0 :             uint8_t state = 0;
    2164            0 :             size = sizeof(state);
    2165            0 :             status = mscb_read(fd, (unsigned short) current_addr, 68, &state, &size);
    2166            0 :             if (state == 0) {
    2167            0 :                printf("Power (var #68) must be on for the calibration to work correctly\n");
    2168              :             } else {
    2169              : 
    2170              :                float current[32];
    2171            0 :                size = sizeof(current);
    2172            0 :                status = mscb_read_range(fd, (unsigned short) current_addr, 32, 63, current, &size);
    2173              : 
    2174            0 :                for (i = 0; i < 32; i++) {
    2175            0 :                   DWORD_SWAP(&current[i]);
    2176              :                   // printf("I%d: %1.2lf\n", i, current[i]);
    2177              :                }
    2178              : 
    2179              :                float current_offset[32];
    2180            0 :                size = sizeof(current_offset);
    2181            0 :                status = mscb_read_range(fd, (unsigned short) current_addr, 70, 101, current_offset, &size);
    2182              : 
    2183            0 :                for (i = 0; i < 32; i++) {
    2184            0 :                   DWORD_SWAP(&current_offset[i]);
    2185              :                   // printf("IOfs%d: %1.2lf\n", i, current_offset[i]);
    2186              :                }
    2187              : 
    2188              :                // do correction
    2189            0 :                for (i = 0; i < 32; i++)
    2190            0 :                   current_offset[i] += current[i];
    2191              : 
    2192              :                // write back offsets
    2193            0 :                size = sizeof(current_offset);
    2194            0 :                for (i = 0; i < 32; i++) {
    2195            0 :                   printf("IOfs%d = %1.2lf\n", i, current_offset[i]);
    2196            0 :                   status = mscb_write(fd, (unsigned short) current_addr, 70 + i, &current_offset[i], sizeof(float));
    2197              :                }
    2198              : 
    2199            0 :                if (status == MSCB_SUCCESS)
    2200            0 :                   printf("\nCurrent offsets successfully updated, please flash values\n");
    2201              :                else
    2202            0 :                   printf("Error %d\n", status);
    2203              :             }
    2204              :          } else
    2205            0 :             printf("MPDC device not present\n");
    2206              :       }
    2207              : 
    2208              :       /* exit/quit ---------- */
    2209            0 :       else if (match(param[0], "exit") || match(param[0], "quit"))
    2210            0 :          break;
    2211              : 
    2212            0 :       else if (param[0][0] == 0);
    2213              : 
    2214            0 :       else if (param[0][0] == '\n');
    2215              : 
    2216              :       else
    2217            0 :          printf("Unknown command %s %s %s\n", param[0], param[1], param[2]);
    2218              : 
    2219              :       /* exit after single command */
    2220            0 :       if (cmd[0] && cmd[0] != '@')
    2221            0 :          break;
    2222              : 
    2223            0 :    } while (1);
    2224              : }
    2225              : 
    2226              : /*------------------------------------------------------------------*/
    2227              : 
    2228            0 : int main(int argc, char *argv[]) {
    2229              :    int i, fd, server, scan;
    2230              :    unsigned short adr;
    2231              :    char cmd[256], device[256], str[256], password[256], ip[256];
    2232              :    int debug;
    2233              : 
    2234            0 :    cmd[0] = 0;
    2235            0 :    adr = 0;
    2236              : 
    2237            0 :    debug = server = scan = 0;
    2238            0 :    device[0] = password[0] = 0;
    2239              : 
    2240              :    /* parse command line parameters */
    2241            0 :    for (i = 1; i < argc; i++) {
    2242            0 :       if (argv[i][0] == '-' && argv[i][1] == 'v')
    2243            0 :          debug = 2;
    2244            0 :       else if (argv[i][0] == '-' && argv[i][1] == 'w')
    2245            0 :          debug = 1;
    2246            0 :       else if (argv[i][0] == '-' && argv[i][1] == 'r')
    2247            0 :          server = 1;
    2248            0 :       else if (argv[i][0] == '-' && argv[i][1] == 's')
    2249            0 :          scan = 1;
    2250            0 :       else if (argv[i][0] == '-') {
    2251            0 :          if (i + 1 >= argc || argv[i + 1][0] == '-')
    2252            0 :             goto usage;
    2253            0 :          else if (argv[i][1] == 'd')
    2254            0 :             strcpy(device, argv[++i]);
    2255            0 :          else if (argv[i][1] == 'p')
    2256            0 :             strcpy(password, argv[++i]);
    2257            0 :          else if (argv[i][1] == 'a')
    2258            0 :             adr = atoi(argv[++i]);
    2259            0 :          else if (argv[i][1] == 'c') {
    2260            0 :             if (strlen(argv[i]) >= 256) {
    2261            0 :                printf("error: command line too long (>256).\n");
    2262            0 :                return 0;
    2263              :             }
    2264            0 :             strcpy(cmd, argv[++i]);
    2265              :          } else {
    2266            0 :             usage:
    2267              :             printf
    2268            0 :                     ("usage: msc [-d host:device] [-p password] [-a addr] [-c Command] [-c @CommandFile] [-v] [-s]\n\n");
    2269            0 :             printf("       -d     device, \"<host>:usb0\" for RPC connection\n");
    2270              :             printf
    2271            0 :                     ("              or \"mscb<xxx>\" for Ethernet connection to SUBM_260\n");
    2272            0 :             printf("       -p     optional password for SUBM_260\n");
    2273            0 :             printf("       -r     Start RPC server\n");
    2274            0 :             printf("       -s     Scan for Ethernet submasters on local net\n");
    2275            0 :             printf("       -a     Address node before executing command\n");
    2276            0 :             printf("       -c     Execute command immediately\n");
    2277            0 :             printf("       -v     Produce verbose debugging output into mscb_debug.log\n");
    2278            0 :             printf("       -w     Log all write commands to mscb_write.log\n\n");
    2279            0 :             printf("For a list of valid commands start msc interactively\n");
    2280            0 :             printf("and type \"help\".\n");
    2281            0 :             return 0;
    2282              :          }
    2283              :       }
    2284              :    }
    2285              : 
    2286            0 :    if (server) {
    2287              : #ifdef HAVE_MRPC
    2288              :       mrpc_server_loop();
    2289              : #endif
    2290            0 :       return 0;
    2291              :    }
    2292              : 
    2293            0 :    if (scan) {
    2294            0 :       mscb_scan_udp();
    2295            0 :       return 0;
    2296              :    }
    2297              : 
    2298            0 :    if (device[0])
    2299            0 :       host2ip(device, ip, sizeof(ip));
    2300              :    else
    2301            0 :       ip[0] = 0;
    2302              : 
    2303            0 :    if (device[0] == 0) {
    2304            0 :       printf("Please specify MSCB submaster via -d flag\n");
    2305            0 :       return 0;
    2306              :    }
    2307              : 
    2308              :    /* open port */
    2309            0 :    fd = mscb_init(device, sizeof(device), password, debug);
    2310              : 
    2311            0 :    if (fd == EMSCB_WRONG_PASSWORD) {
    2312            0 :       printf("Enter password to access %s: ", device);
    2313            0 :       fgets(str, sizeof(str), stdin);
    2314            0 :       while (strlen(str) > 0
    2315            0 :              && (str[strlen(str) - 1] == '\r' || str[strlen(str) - 1] == '\n'))
    2316            0 :          str[strlen(str) - 1] = 0;
    2317            0 :       fd = mscb_init(device, sizeof(device), str, debug);
    2318              :    }
    2319              : 
    2320            0 :    if (fd < 0) {
    2321            0 :       if (fd == EMSCB_COMM_ERROR) {
    2322            0 :          printf("\nCannot communicate with MSCB submaster %s (%s)\n", device, ip);
    2323            0 :          puts("Please disconnect and reconnect submaster\n");
    2324            0 :       } else if (fd == EMSCB_PROTOCOL_VERSION) {
    2325            0 :          printf("\nSubmaster %s (%s) runs old protocol version\n", device, ip);
    2326            0 :          puts("Please upgrade submaster software\n");
    2327            0 :       } else if (fd == EMSCB_NOT_FOUND) {
    2328              : #ifdef HAVE_USB
    2329              :          printf("\nCannot find USB submaster\n");
    2330              : #else
    2331            0 :          printf("\nNo USB support available in this verson of msc\n");
    2332            0 :          printf("An ethernet node address must explicitly be supplied via the '-d [host]' flag\n");
    2333              : #endif
    2334            0 :       } else if (fd == EMSCB_WRONG_PASSWORD) {
    2335            0 :          printf("\nWrong password\n");
    2336            0 :       } else if (fd == EMSCB_NO_WRITE_ACCESS) {
    2337            0 :          printf("\nNo write access to MSCB submaster %s (%s)\n", device, ip);
    2338            0 :          puts("Please install hotplug script \"drivers/linux/usb.usermap_scs_250\" to \"/etc/hotplug/\".\n");
    2339            0 :       } else if (fd == EMSCB_LOCKED) {
    2340            0 :          puts("\nMSCB system is locked by other process");
    2341            0 :          puts("Please stop all running MSCB clients\n");
    2342            0 :       } else if (device[0])
    2343            0 :          printf("Cannot connect to device \"%s\" (%s)\n", device, ip);
    2344              :       else
    2345            0 :          printf("Please specify MSCB submaster via -d flag\n");
    2346              : 
    2347              : #ifdef _MSC_VER
    2348              :       puts("\n-- hit any key to exit --");
    2349              : 
    2350              :       while (!kbhit())
    2351              :          Sleep(100);
    2352              :       while (kbhit())
    2353              :          getch();
    2354              : #endif
    2355              : 
    2356            0 :       return 0;
    2357              :    }
    2358              : 
    2359            0 :    printf("Connected to submaster %s (%s)\n", device, ip);
    2360              : 
    2361            0 :    cmd_loop(fd, cmd, adr);
    2362              : 
    2363            0 :    mscb_exit(fd);
    2364              : 
    2365            0 :    return 0;
    2366              : }
        

Generated by: LCOV version 2.0-1