# sniffer_ctrl.c

Go to the documentation of this file.

    00001 /* Copyright (c) 2007 Axel Wachtler
    00002    All rights reserved.
    00003
    00004    Redistribution and use in source and binary forms, with or without
    00005    modification, are permitted provided that the following conditions
    00006    are met:
    00007
    00008    * Redistributions of source code must retain the above copyright
    00009      notice, this list of conditions and the following disclaimer.
    00010    * Redistributions in binary form must reproduce the above copyright
    00011      notice, this list of conditions and the following disclaimer in the
    00012      documentation and/or other materials provided with the distribution.
    00013    * Neither the name of the authors nor the names of its contributors
    00014      may be used to endorse or promote products derived from this software
    00015      without specific prior written permission.
    00016
    00017    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    00018    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    00019    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    00020    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
    00021    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    00022    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    00023    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    00024    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    00025    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    00026    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    00027    POSSIBILITY OF SUCH DAMAGE. */
    00028
    00029 /* $Id: sniffer_ctrl.c,v 1.14 2010/05/11 18:47:58 awachtler Exp $ */
    00036 /* === includes ============================================================ */
    00037 #include "sniffer.h"
    00038
    00039 /* === macros ============================================================== */
    00040
    00041 /* === types =============================================================== */
    00042
    00048 typedef enum {
    00050      CMD_CHKCRC = 0x23,
    00052      CMD_TIMESET = 0x35,
    00054      CMD_SCAN = 0x4d,
    00056      CMD_CHAN = 0x4e,
    00058      CMD_CMCLR = 0x52,
    00060      CMD_SNIFF = 0x64,
    00062      CMD_CMSET = 0x74,
    00064      CMD_CPAGE = 0x87,
    00066      CMD_DRATE = 0xa0,
    00068      CMD_IDLE = 0xa1,
    00070      CMD_CMASK = 0xa9,
    00072      CMD_ED = 0xc7,
    00074      CMD_PARMS = 0xf1,
    00076      CMD_SFD = 0xc4,
    00078      CMD_EMPTY = 0x00,
    00079 } SHORTENUM cmd_hash_t;
    00080
    00081 /* === globals ============================================================= */
    00082
    00083 /* === prototypes ========================================================== */
    00084 static bool process_hotkey(char cmdkey);
    00085 static bool process_command(char * cmd);
    00086 static cmd_hash_t get_cmd_hash(char *cmd);
    00087
    00088 /* === functions =========================================================== */
    00089
    00090 void ctrl_process_input(void)
    00091 {
    00092 bool success;
    00093 uint16_t inchar;
    00094 static char  cmdline[16];
    00095 static uint8_t  cmdidx = 0;
    00096
    00097     /* command processing */
    00098     inchar = hif_getc();
    00099     if(inchar<0x100)
    00100     {
    00101         cmdline[cmdidx++] = (char) inchar;
    00102         if (inchar == '\n' || inchar == '\r')
    00103         {
    00104             cmdline[cmdidx-1] = 0;
    00105             process_command(cmdline);
    00106             cmdidx = 0;
    00107         }
    00108         else if (cmdidx == 1)
    00109         {
    00110            hif_putc('\r');
    00111            success = process_hotkey(cmdline[0]);
    00112            if (success == true)
    00113            {
    00114                 cmdidx = 0;
    00115            }
    00116         }
    00117     }
    00118 }
    00119
    00120 uint8_t cnt_active_channels(uint32_t cmask)
    00121 {
    00122 uint8_t ret = 0;
    00123
    00124     while (cmask != 0)
    00125     {
    00126         ret += (uint8_t)(cmask & 1UL);
    00127         cmask >>= 1;
    00128     }
    00129     return ret;
    00130 }
    00131
    00135 static bool process_hotkey(char cmdkey)
    00136 {
    00137     bool ret = true;
    00138     sniffer_state_t next_state;
    00139     next_state = ctx.state;
    00140     switch (cmdkey)
    00141     {
    00142         case 'I':
    00143         case ' ': /* panic mode switch off: hit space bar*/
    00144             next_state = IDLE;
    00145             PRINT("IDLE\n");
    00146             break;
    00147
    00148         case '+':
    00149             if (ctx.state != SCAN)
    00150             {
    00151                 ctx.cchan = (ctx.cchan >= TRX_MAX_CHANNEL) ? TRX_MIN_CHANNEL : ctx.cchan + 1;
    00152                 trx_bit_write(SR_CHANNEL, ctx.cchan);
    00153                 PRINTF("Channel %u"NL, ctx.cchan);
    00154             }
    00155             break;
    00156
    00157         case '-':
    00158             if (ctx.state != SCAN)
    00159             {
    00160                 ctx.cchan = (ctx.cchan <= TRX_MIN_CHANNEL) ? TRX_MAX_CHANNEL : ctx.cchan - 1;
    00161                 trx_bit_write(SR_CHANNEL, ctx.cchan);
    00162                 PRINTF("Channel %u"NL, ctx.cchan);
    00163             }
    00164             break;
    00165
    00166         case 'r':
    00167             if (ctx.scanres_reset != 0)
    00168             {
    00169                 ctx.scanres_reset = 0;
    00170             }
    00171             else
    00172             {
    00173                 ctx.scanres_reset = cnt_active_channels(ctx.cmask);
    00174             }
    00175             break;
    00176
    00177         case 'R':
    00178             if (ctx.scanres_reset != 0)
    00179             {
    00180                 ctx.scanres_reset = 0;
    00181             }
    00182             else
    00183             {
    00184                 ctx.scanres_reset = TRX_NB_CHANNELS + 1;
    00185             }
    00186             break;
    00187
    00188         default:
    00189             ret = false;
    00190             break;
    00191     }
    00192
    00193     if (next_state != ctx.state)
    00194     {
    00195         sniffer_stop();
    00196         sniffer_start(next_state);
    00197     }
    00198
    00199     return ret;
    00200 }
    00201
    00205 static bool process_command(char * cmd)
    00206 {
    00207     char *argv[4];
    00208     uint8_t argc;
    00209     uint8_t ch, tmp;
    00210     volatile uint8_t i;
    00211     bool cmdok;
    00212     sniffer_state_t next_state;
    00213     time_t tv;
    00214     next_state = ctx.state;
    00215
    00216     PRINTF("> %s"NL,cmd);
    00217     argc = hif_split_args(cmd, sizeof(argv), argv);
    00218     ch = get_cmd_hash(argv[0]);
    00219     cmdok = true;
    00220     switch (ch)
    00221     {
    00222         case CMD_TIMESET:
    00223             PRINTF("\n\rct1=%ld\n\r", timer_systime());
    00224             tv = strtol(argv[1],NULL,10);
    00225             PRINTF("tv=%ld %s\n\r", tv , argv[1]);
    00226             timer_set_systime(tv);
    00227             PRINTF("ct2=%ld\n\r", timer_systime());
    00228             break;
    00229         case CMD_CHAN:
    00230             tmp = atoi(argv[1]);
    00231             if (tmp>= TRX_MIN_CHANNEL && tmp <= TRX_MAX_CHANNEL)
    00232             {
    00233                 ctx.cchan = tmp;
    00234                 trx_bit_write(SR_CHANNEL, ctx.cchan);
    00235             }
    00236             else
    00237             {
    00238                 cmdok = false;
    00239             }
    00240             break;
    00241         case CMD_CPAGE:
    00242             ctx.cpage = atoi(argv[1]);
    00243             break;
    00244         case CMD_CMASK:
    00245             ctx.cmask = (strtol(argv[1],NULL,0) & TRX_SUPPORTED_CHANNELS);
    00246             break;
    00247         case CMD_CMCLR:
    00248             if (argc < 2)
    00249             {
    00250                 ctx.cmask &= ~TRX_SUPPORTED_CHANNELS;
    00251             }
    00252             else
    00253             {
    00254                 ctx.cmask &= ~(uint32_t)(1UL << (atoi(argv[1])));
    00255             }
    00256             break;
    00257         case CMD_CMSET:
    00258             if (argc < 2)
    00259             {
    00260                 ctx.cmask |= TRX_SUPPORTED_CHANNELS;
    00261             }
    00262             else
    00263             {
    00264                 ctx.cmask |= (uint32_t)((1UL << (atoi(argv[1]))) & TRX_SUPPORTED_CHANNELS);
    00265             }
    00266             break;
    00267         case CMD_PARMS:
    00268             PRINTF(NL"PLATFORM: %s V%s"NL, BOARD_NAME, VERSION);
    00269             PRINTF("SUPP_CMSK: 0x%08lx"NL, (unsigned long)TRX_SUPPORTED_CHANNELS);
    00270             PRINTF("CURR_CMSK: 0x%08lx"NL, (unsigned long)ctx.cmask);
    00271             PRINTF("CURR_CHAN: %d"NL, ctx.cchan);
    00272             PRINTF("CURR_PAGE: %d"NL"CURR_RATE: ", ctx.cpage);
    00273             hif_puts_p(trx_decode_datarate_p(trx_get_datarate()));
    00274             PRINT(NL"SUPP_RATES: ");
    00275             for (i=0;i<trx_get_number_datarates();i++)
    00276             {
    00277                 hif_puts_p(trx_get_datarate_str_p(i));
    00278                 PRINT(" ");
    00279             }
    00280             PRINT(NL);
    00281             PRINTF("TIMER_SCALE: %d.0/%ld"NL, HWTMR_PRESCALE, F_CPU);
    00282             PRINTF("TICK_NUMBER: %ld"NL, HWTIMER_TICK_NB);
    00283             PRINTF("CHKCRC: %d"NL, ctx.chkcrc);
    00284             PRINTF("MISSED_FRAMES: %d"NL,ctx.missed_frames);
    00285             break;
    00286         case CMD_SCAN:
    00287             next_state = SCAN;
    00288             break;
    00289         case CMD_SNIFF:
    00290             next_state = SNIFF;
    00291             break;
    00292         case CMD_IDLE:
    00293             next_state = IDLE;
    00294             break;
    00295         case CMD_DRATE:
    00296             tmp = get_cmd_hash(argv[1]);
    00297             if (trx_set_datarate(tmp) == RATE_NONE)
    00298             {
    00299                 PRINTF("Invalid datarate: %s [0x%02x]"NL,argv[1], tmp);
    00300                 cmdok = false;
    00301             }
    00302             break;
    00303         case CMD_CHKCRC:
    00304             if (argc < 2)
    00305             {
    00306                 ctx.chkcrc ^= 1;
    00307             }
    00308             else if (atoi(argv[1]) != 0)
    00309             {
    00310                 ctx.chkcrc = 1;
    00311             }
    00312             else
    00313             {
    00314                 ctx.chkcrc = 0;
    00315             }
    00316             PRINTF("crc_ok=%d"NL,ctx.chkcrc );
    00317             break;
    00318         case CMD_EMPTY:
    00319             break;
    00320         default:
    00321             cmdok = false;
    00322             break;
    00323     }
    00324
    00325     if(cmdok != true)
    00326     {
    00327         PRINTF("INVALID CMD !!! argc=%d, argv[0]=%s : 0x%02x "NL, argc, argv[0], ch);
    00328     }
    00329
    00330     if (next_state != ctx.state)
    00331     {
    00332         sniffer_stop();
    00333         sniffer_start(next_state);
    00334     }
    00335
    00336     return false;
    00337 }
    00338
    00339 static cmd_hash_t get_cmd_hash(char *cmd)
    00340 {
    00341 cmd_hash_t h, accu;
    00342
    00343     h = 0;
    00344     while (*cmd != 0)
    00345     {
    00346         accu = h & 0xe0;
    00347         h = h << 5;
    00348         h = h ^ (accu >> 5);
    00349         h = h ^ *cmd;
    00350         h &= 0xff;
    00351         cmd ++;
    00352     }
    00353     return h;
    00354 }
    00355 /* EOF */