- Main Page
- Related Pages
- Modules
- Data Structures
- Files

# 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.12 2009/02/23 22:07:14 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_EMPTY = 0x00,
    00077 } SHORTENUM cmd_hash_t;
    00078
    00079 /* === globals ============================================================= */
    00080
    00081 /* === prototypes ========================================================== */
    00082 static bool process_hotkey(char cmdkey);
    00083 static bool process_command(char * cmd);
    00084 static cmd_hash_t get_cmd_hash(char *cmd);
    00085
    00086 /* === functions =========================================================== */
    00087
    00088 void ctrl_process_input(void)
    00089 {
    00090 bool success;
    00091 uint16_t inchar;
    00092 static char  cmdline[16];
    00093 static uint8_t  cmdidx = 0;
    00094
    00095     /* command processing */
    00096     inchar = hif_getc();
    00097     if(inchar<0x100)
    00098     {
    00099         cmdline[cmdidx++] = (char) inchar;
    00100         if (inchar == '\n' || inchar == '\r')
    00101         {
    00102             cmdline[cmdidx-1] = 0;
    00103             process_command(cmdline);
    00104             cmdidx = 0;
    00105         }
    00106         else if (cmdidx == 1)
    00107         {
    00108            hif_putc('\r');
    00109            success = process_hotkey(cmdline[0]);
    00110            if (success == true)
    00111            {
    00112                 cmdidx = 0;
    00113            }
    00114         }
    00115     }
    00116 }
    00117
    00118 uint8_t cnt_active_channels(uint32_t cmask)
    00119 {
    00120 uint8_t ret = 0;
    00121
    00122     while (cmask != 0)
    00123     {
    00124         ret += (uint8_t)(cmask & 1UL);
    00125         cmask >>= 1;
    00126     }
    00127     return ret;
    00128 }
    00129
    00133 static bool process_hotkey(char cmdkey)
    00134 {
    00135     bool ret = true;
    00136     sniffer_state_t next_state;
    00137     next_state = ctx.state;
    00138     switch (cmdkey)
    00139     {
    00140         case 'I':
    00141         case ' ': /* panic mode switch off: hit space bar*/
    00142             next_state = IDLE;
    00143             PRINT("IDLE\n");
    00144             break;
    00145
    00146         case '+':
    00147             if (ctx.state != SCAN)
    00148             {
    00149                 ctx.cchan = (ctx.cchan >= TRX_MAX_CHANNEL) ? TRX_MIN_CHANNEL : ctx.cchan + 1;
    00150                 trx_bit_write(SR_CHANNEL, ctx.cchan);
    00151                 PRINTF("Channel %u"NL, ctx.cchan);
    00152             }
    00153             break;
    00154
    00155         case '-':
    00156             if (ctx.state != SCAN)
    00157             {
    00158                 ctx.cchan = (ctx.cchan <= TRX_MIN_CHANNEL) ? TRX_MAX_CHANNEL : ctx.cchan - 1;
    00159                 trx_bit_write(SR_CHANNEL, ctx.cchan);
    00160                 PRINTF("Channel %u"NL, ctx.cchan);
    00161             }
    00162             break;
    00163
    00164         case 'r':
    00165             if (ctx.scanres_reset != 0)
    00166             {
    00167                 ctx.scanres_reset = 0;
    00168             }
    00169             else
    00170             {
    00171                 ctx.scanres_reset = cnt_active_channels(ctx.cmask);
    00172             }
    00173             break;
    00174
    00175         case 'R':
    00176             if (ctx.scanres_reset != 0)
    00177             {
    00178                 ctx.scanres_reset = 0;
    00179             }
    00180             else
    00181             {
    00182                 ctx.scanres_reset = TRX_NB_CHANNELS + 1;
    00183             }
    00184             break;
    00185
    00186         default:
    00187             ret = false;
    00188             break;
    00189     }
    00190
    00191     if (next_state != ctx.state)
    00192     {
    00193         sniffer_stop();
    00194         sniffer_start(next_state);
    00195     }
    00196
    00197     return ret;
    00198 }
    00199
    00203 static bool process_command(char * cmd)
    00204 {
    00205     char *argv[4];
    00206     uint8_t argc;
    00207     uint8_t ch, tmp;
    00208     volatile uint8_t i;
    00209     bool cmdok;
    00210     sniffer_state_t next_state;
    00211     time_t tv;
    00212     next_state = ctx.state;
    00213
    00214     PRINTF("> %s"NL,cmd);
    00215     argc = hif_split_args(cmd, sizeof(argv), argv);
    00216     ch = get_cmd_hash(argv[0]);
    00217     cmdok = true;
    00218     switch (ch)
    00219     {
    00220         case CMD_TIMESET:
    00221             PRINTF("\n\rct1=%ld\n\r", timer_systime());
    00222             tv = strtol(argv[1],NULL,10);
    00223             PRINTF("tv=%ld %s\n\r", tv , argv[1]);
    00224             timer_set_systime(tv);
    00225             PRINTF("ct2=%ld\n\r", timer_systime());
    00226             break;
    00227         case CMD_CHAN:
    00228             tmp = atoi(argv[1]);
    00229             if (tmp>= TRX_MIN_CHANNEL && tmp <= TRX_MAX_CHANNEL)
    00230             {
    00231                 ctx.cchan = tmp;
    00232                 trx_bit_write(SR_CHANNEL, ctx.cchan);
    00233             }
    00234             else
    00235             {
    00236                 cmdok = false;
    00237             }
    00238             break;
    00239         case CMD_CPAGE:
    00240             ctx.cpage = atoi(argv[1]);
    00241             break;
    00242         case CMD_CMASK:
    00243             ctx.cmask = (strtol(argv[1],NULL,0) & TRX_SUPPORTED_CHANNELS);
    00244             break;
    00245         case CMD_CMCLR:
    00246             if (argc < 2)
    00247             {
    00248                 ctx.cmask &= ~TRX_SUPPORTED_CHANNELS;
    00249             }
    00250             else
    00251             {
    00252                 ctx.cmask &= ~(uint32_t)(1UL << (atoi(argv[1])));
    00253             }
    00254             break;
    00255         case CMD_CMSET:
    00256             if (argc < 2)
    00257             {
    00258                 ctx.cmask |= TRX_SUPPORTED_CHANNELS;
    00259             }
    00260             else
    00261             {
    00262                 ctx.cmask |= (uint32_t)((1UL << (atoi(argv[1]))) & TRX_SUPPORTED_CHANNELS);
    00263             }
    00264             break;
    00265         case CMD_PARMS:
    00266             PRINTF(NL"PLATFORM: %s V%s"NL, BOARD_NAME, VERSION);
    00267             PRINTF("SUPP_CMSK: 0x%08lx"NL, (unsigned long)TRX_SUPPORTED_CHANNELS);
    00268             PRINTF("CURR_CMSK: 0x%08lx"NL, (unsigned long)ctx.cmask);
    00269             PRINTF("CURR_CHAN: %d"NL, ctx.cchan);
    00270             PRINTF("CURR_PAGE: %d"NL"CURR_RATE: ", ctx.cpage);
    00271             hif_puts_p(trx_decode_datarate_p(trx_get_datarate()));
    00272             PRINT(NL"SUPP_RATES: ");
    00273             for (i=0;i<trx_get_number_datarates();i++)
    00274             {
    00275                 hif_puts_p(trx_get_datarate_str_p(i));
    00276                 PRINT(" ");
    00277             }
    00278             PRINT(NL);
    00279             PRINTF("TIMER_SCALE: %d.0/%ld"NL, HWTMR_PRESCALE, F_CPU);
    00280             PRINTF("TICK_NUMBER: %ld"NL, HWTIMER_TICK_NB);
    00281             PRINTF("CHKCRC: %d"NL, ctx.chkcrc);
    00282             PRINTF("MISSED_FRAMES: %d"NL,ctx.missed_frames);
    00283             break;
    00284         case CMD_SCAN:
    00285             next_state = SCAN;
    00286             break;
    00287         case CMD_SNIFF:
    00288             next_state = SNIFF;
    00289             break;
    00290         case CMD_IDLE:
    00291             next_state = IDLE;
    00292             break;
    00293         case CMD_DRATE:
    00294             tmp = get_cmd_hash(argv[1]);
    00295             if (trx_set_datarate(tmp) == RATE_NONE_HSH)
    00296             {
    00297                 PRINTF("Invalid datarate: %s [0x%02x]"NL,argv[1], tmp);
    00298                 cmdok = false;
    00299             }
    00300             break;
    00301         case CMD_CHKCRC:
    00302             if (argc < 2)
    00303             {
    00304                 ctx.chkcrc ^= 1;
    00305             }
    00306             else if (atoi(argv[1]) != 0)
    00307             {
    00308                 ctx.chkcrc = 1;
    00309             }
    00310             else
    00311             {
    00312                 ctx.chkcrc = 0;
    00313             }
    00314             PRINTF("crc_ok=%d"NL,ctx.chkcrc );
    00315             break;
    00316         case CMD_EMPTY:
    00317             break;
    00318         default:
    00319             cmdok = false;
    00320             break;
    00321     }
    00322
    00323     if(cmdok != true)
    00324     {
    00325         PRINTF("INVALID CMD !!! argc=%d, argv[0]=%s : 0x%02x "NL, argc, argv[0], ch);
    00326     }
    00327
    00328     if (next_state != ctx.state)
    00329     {
    00330         sniffer_stop();
    00331         sniffer_start(next_state);
    00332     }
    00333
    00334     return false;
    00335 }
    00336
    00337 static cmd_hash_t get_cmd_hash(char *cmd)
    00338 {
    00339 cmd_hash_t h, accu;
    00340
    00341     h = 0;
    00342     while (*cmd != 0)
    00343     {
    00344         accu = h & 0xe0;
    00345         h = h << 5;
    00346         h = h ^ (accu >> 5);
    00347         h = h ^ *cmd;
    00348         h &= 0xff;
    00349         cmd ++;
    00350     }
    00351     return h;
    00352 }
    00353 /* EOF */