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

# sniffer.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.c,v 1.13 2009/12/22 16:47:10 joerg_wunsch Exp $ */
    00044 /* === includes ========================================== */
    00045 #include "sniffer.h"
    00046
    00047 /* === macros ============================================ */
    00048
    00049 /* === types ============================================= */
    00050
    00051 /* === globals =========================================== */
    00052 sniffer_context_t ctx;
    00053 static uint8_t rxbuf[MAX_FRAME_SIZE+1];
    00054
    00055 sniffer_packet_t rxpacket;
    00056
    00057 volatile uint8_t new_frame;
    00058 volatile dbg_t dbg;
    00059
    00060 static time_stamp_t rxstarttime;
    00061
    00062 /* === prototypes ======================================== */
    00063 void scan_update_status(void);
    00064
    00065 /* === functions ========================================= */
    00066
    00078 void sniffer_init(void)
    00079 {
    00080 uint8_t val;
    00081
    00082     /* Phase 1: initialize MCU peripherals */
    00083     LED_INIT();
    00084     LED_SET_VALUE(1);
    00085     memset(&ctx, 0, sizeof(ctx));
    00086     memset((void*)&dbg, 0, sizeof(dbg));
    00087     timer_init();
    00088     hif_init(38400);
    00089     trx_io_init(DEFAULT_SPI_RATE);
    00090     sei();
    00091
    00092     PRINTF(NL"Sniffer V%s [%s]"NL, VERSION, BOARD_NAME);
    00093     LED_SET_VALUE(2);
    00094     /* Phase 2: initialize the radio transceiver */
    00095     TRX_RESET_LOW();
    00096     TRX_SLPTR_LOW();
    00097     DELAY_US(TRX_RESET_TIME_US);
    00098     TRX_RESET_HIGH();
    00099     trx_reg_write(RG_TRX_STATE, CMD_TRX_OFF);
    00100     DELAY_US(TRX_INIT_TIME_US);
    00101     val = trx_reg_read(RG_TRX_STATUS);
    00102     if (val != TRX_OFF)
    00103     {
    00104         PRINTF("FATAL ERROR: TRX not in state TRX_OFF [0x%02x]"NL, val);
    00105         while(1);
    00106     }
    00107     /* Phase 3: enable IRQ's and enter RX-Mode */
    00108     LED_SET_VALUE(3);
    00109 #if defined(TRX_IRQ_RX_START) && defined(TRX_IRQ_TRX_END) && defined(TRX_IRQ_UR)
    00110     trx_reg_write(RG_IRQ_MASK, (TRX_IRQ_RX_START|TRX_IRQ_TRX_END|TRX_IRQ_UR));
    00111 #elif defined(TRX_IRQ_RX_START) && defined(TRX_IRQ_RX_END)
    00112     trx_reg_write(RG_IRQ_MASK, (TRX_IRQ_RX_START | TRX_IRQ_RX_END));
    00113 #else
    00114 #  error "Unknown IRQ bits"
    00115 #endif
    00116     trx_reg_write(RG_TRX_STATE, CMD_RX_ON);
    00117     DELAY_US(180);
    00118     val = trx_reg_read(RG_TRX_STATUS);
    00119     if ((val != RX_ON) && (val != BUSY_RX))
    00120     {
    00121         PRINTF("FATAL ERROR: TRX not in state RX_ON [0x%02x]"NL, val);
    00122         while(1);
    00123     }
    00124     LED_SET_VALUE(0);
    00125     /* init context structure */
    00126     ctx.state = IDLE;
    00127     ctx.cchan = TRX_MIN_CHANNEL;
    00128     ctx.cmask = TRX_SUPPORTED_CHANNELS;
    00129 }
    00130
    00134 void sniffer_start(sniffer_state_t state)
    00135 {
    00136     switch (state)
    00137     {
    00138         case IDLE:
    00139             trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);
    00140             ctx.state = IDLE;
    00141             LED_SET_VALUE(0);
    00142             break;
    00143         case SCAN:
    00144             ctx.state = SCAN;
    00145             scan_init();
    00146             break;
    00147         case SNIFF:
    00148             trx_reg_write(RG_TRX_STATE, CMD_RX_ON);
    00149             ctx.state = SNIFF;
    00150             break;
    00151
    00152         default:
    00153             break;
    00154     }
    00155 }
    00156
    00160 void sniffer_stop(void)
    00161 {
    00162 sniffer_state_t curr_state;
    00163
    00164     trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);
    00165     cli();
    00166     curr_state = ctx.state;
    00167     ctx.state = IDLE;
    00168     sei();
    00169
    00170     switch(curr_state)
    00171     {
    00172         case SCAN:
    00173             ctx.cchan = TRX_MIN_CHANNEL;
    00174             ctx.thdl = timer_stop(ctx.thdl);
    00175             break;
    00176         case SNIFF:
    00177         case IDLE:
    00178             break;
    00179         default:
    00180             PRINTF("Unknown state %d"NL,ctx.state);
    00181             break;
    00182
    00183     }
    00184 }
    00185
    00193 int main(void)
    00194 {
    00195
    00196     sniffer_init();
    00197
    00198     while(1)
    00199     {
    00200         ctrl_process_input();
    00201
    00202         if(ctx.state == SCAN_DONE)
    00203         {
    00204             scan_update_status();
    00205         }
    00206         if ((new_frame > 0) && (ctx.state == SNIFF))
    00207         {
    00208             hif_putc(1);
    00209             hif_putc(new_frame+sizeof(time_stamp_t));
    00210             hif_put_blk((unsigned char *)&rxpacket.ts, sizeof(time_stamp_t));
    00211             hif_put_blk(rxbuf, new_frame);
    00212             hif_putc(4);
    00213             new_frame = 0;
    00214         }
    00215     }
    00216 }
    00217
    00221 #if defined(DOXYGEN)
    00222 void TRX_IRQ_vect()
    00223 #elif !defined(TRX_IF_RFA1)
    00224 ISR(TRX_IRQ_vect)
    00225 {
    00226 static volatile uint8_t cause;
    00227 uint8_t ed, flen, lqi = 0, frmupl;
    00228 bool crc_ok = 0;
    00229 extern time_t systime;
    00230
    00231     DI_TRX_IRQ();
    00232     sei();
    00233     cause = trx_reg_read(RG_IRQ_STATUS);
    00234
    00235     if (dbg.irql) dbg.err = 1;
    00236     dbg.irql ++;
    00237
    00238     if (cause & TRX_IRQ_RX_START)
    00239     {
    00240         rxstarttime.time_usec = TRX_TSTAMP_REG;
    00241         rxstarttime.time_sec = systime;
    00242     }
    00243
    00244     if (cause & TRX_IRQ_TRX_END)
    00245     {
    00246         /* Upload frame at TRX_END IRQ */
    00247         ctx.frames++;
    00248         ed = trx_reg_read(RG_PHY_ED_LEVEL);
    00249         flen = trx_frame_read_crc(rxbuf, MAX_FRAME_SIZE, &crc_ok);
    00250         trx_sram_read(flen, 1, &lqi);
    00251         if (ctx.state == SCAN)
    00252         {
    00253             scan_update_frame(flen, crc_ok, lqi, ed, rxbuf);
    00254         }
    00255         if (ctx.state == SNIFF)
    00256         {
    00257             frmupl = 1;
    00258             if (new_frame != 0)
    00259             {
    00260                 frmupl = 0;
    00261                 ctx.missed_frames +=1;
    00262             }
    00263             else if(ctx.chkcrc == 1)
    00264             {
    00265                 frmupl = crc_ok;
    00266             }
    00267             if (frmupl != 0)
    00268             {
    00269                 memcpy(&rxpacket.ts, &rxstarttime, sizeof(rxstarttime));
    00270                 rxpacket.flen = flen;
    00271                 rxpacket.rxdata = rxbuf;
    00272                 rxpacket.lqi = lqi;
    00273                 rxpacket.ed = ed;
    00274                 rxpacket.crc = crc_ok;
    00275                 new_frame = flen;
    00276             }
    00277         }
    00278         LED_SET_VALUE(ctx.frames);
    00279     }
    00280
    00281     if (cause & TRX_IRQ_UR)
    00282     {
    00283         ctx.irq_ur ++;
    00284     }
    00285
    00286     dbg.irql --;
    00287
    00288     cli();
    00289     EI_TRX_IRQ();
    00290 }
    00291 #endif /* defined(DOXYGEN) || !RFA1 */
    00292
    00293 #if defined(TRX_IF_RFA1)
    00294 ISR(TRX24_RX_START_vect)
    00295 {
    00296 extern time_t systime;
    00297
    00298     rxstarttime.time_usec = TRX_TSTAMP_REG;
    00299     rxstarttime.time_sec = systime;
    00300 }
    00301
    00302 ISR(TRX24_RX_END_vect)
    00303 {
    00304 uint8_t ed, flen, lqi = 0, frmupl;
    00305 bool crc_ok = 0;
    00306
    00307     /* Upload frame at TRX_END IRQ */
    00308     ctx.frames++;
    00309     ed = trx_reg_read(RG_PHY_ED_LEVEL);
    00310     flen = trx_frame_read_crc(rxbuf, MAX_FRAME_SIZE, &crc_ok);
    00311     trx_sram_read(flen, 1, &lqi);
    00312     if (ctx.state == SCAN)
    00313     {
    00314         scan_update_frame(flen, crc_ok, lqi, ed, rxbuf);
    00315     }
    00316     if (ctx.state == SNIFF)
    00317     {
    00318         frmupl = 1;
    00319         if (new_frame != 0)
    00320         {
    00321             frmupl = 0;
    00322             ctx.missed_frames +=1;
    00323         }
    00324         else if(ctx.chkcrc == 1)
    00325         {
    00326             frmupl = crc_ok;
    00327         }
    00328         if (frmupl != 0)
    00329         {
    00330             memcpy(&rxpacket.ts, &rxstarttime, sizeof(rxstarttime));
    00331             rxpacket.flen = flen;
    00332             rxpacket.rxdata = rxbuf;
    00333             rxpacket.lqi = lqi;
    00334             rxpacket.ed = ed;
    00335             rxpacket.crc = crc_ok;
    00336             new_frame = flen;
    00337         }
    00338     }
    00339     LED_SET_VALUE(ctx.frames);
    00340 }
    00341 #endif  /* RFA1 */
    00342
    00343 /* EOF */