# sniffer.c

Go to the documentation of this file.

    00001 /* Copyright (c) 2007 - 2010 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.15 2011/01/21 06:59:26 awachtler Exp $ */
    00044 /* === includes ========================================== */
    00045 #include "sniffer.h"
    00046 #include <avr/power.h>
    00047 /* === macros ============================================ */
    00048
    00049 /* === types ============================================= */
    00050
    00051 /* === globals =========================================== */
    00052 sniffer_context_t ctx;
    00053 pcap_pool_t PcapPool;
    00054
    00055 /* === prototypes ======================================== */
    00056 void scan_update_status(void);
    00057
    00058 /* === functions ========================================= */
    00059
    00060
    00061
    00073 void sniffer_init(void)
    00074 {
    00075 uint8_t val;
    00076
    00077     /* Phase 1: initialize MCU peripherals */
    00078     LED_INIT();
    00079
    00080     /* init memory locations */
    00081     memset(&ctx, 0, sizeof(ctx));
    00082     PcapPool.ridx = 0;
    00083     PcapPool.widx = 0;
    00084     ctx.state = IDLE;
    00085     ctx.cchan = TRX_MIN_CHANNEL;
    00086     ctx.cmask = TRX_SUPPORTED_CHANNELS;
    00087
    00088     LED_SET_VALUE(1);
    00089
    00090     /* initialize MCU ressources */
    00091     timer_init();
    00092 #if defined(TRX_IF_RFA1)
    00093     clock_prescale_set(clock_div_1_rc);
    00094     hif_init(38400);
    00095 #else
    00096     hif_init(38400);
    00097 #endif
    00098
    00099     LED_SET_VALUE(1);
    00100
    00101     /* initialize transceiver */
    00102     trx_io_init(DEFAULT_SPI_RATE);
    00103     trx_init();
    00104
    00105
    00106     LED_SET_VALUE(2);
    00107
    00108     /* check for PLL Lock */
    00109     val = trx_check_pll_lock();
    00110     if (val != TRX_OK)
    00111     {
    00112         while(1)
    00113         {
    00114             /* wait due to fatal error */
    00115         };
    00116     }
    00117
    00118 #if defined(TRX_IRQ_RX_START) && defined(TRX_IRQ_TRX_END) && defined(TRX_IRQ_UR)
    00119     trx_reg_write(RG_IRQ_MASK, (TRX_IRQ_RX_START|TRX_IRQ_TRX_END|TRX_IRQ_UR));
    00120 #elif defined(TRX_IRQ_RX_START) && defined(TRX_IRQ_RX_END)
    00121     trx_reg_write(RG_IRQ_MASK, (TRX_IRQ_RX_START | TRX_IRQ_RX_END));
    00122 #else
    00123 #  error "Unknown IRQ bits"
    00124 #endif
    00125
    00126     LED_SET_VALUE(3);
    00127     sei();
    00128
    00129     /* done with init */
    00130     PRINTF(NL"Sniffer V%s [%s]"NL, VERSION, BOARD_NAME);
    00131     LED_SET_VALUE(0);
    00132 }
    00133
    00137 void sniffer_start(sniffer_state_t state)
    00138 {
    00139     switch (state)
    00140     {
    00141         case IDLE:
    00142             trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);
    00143             ctx.state = IDLE;
    00144             LED_SET_VALUE(0);
    00145             break;
    00146         case SCAN:
    00147             ctx.state = SCAN;
    00148             scan_init();
    00149             break;
    00150         case SNIFF:
    00151             trx_reg_write(RG_TRX_STATE, CMD_RX_ON);
    00152             ctx.state = SNIFF;
    00153             break;
    00154
    00155         default:
    00156             break;
    00157     }
    00158 }
    00159
    00163 void sniffer_stop(void)
    00164 {
    00165 sniffer_state_t curr_state;
    00166
    00167     trx_reg_write(RG_TRX_STATE, CMD_FORCE_TRX_OFF);
    00168     cli();
    00169     curr_state = ctx.state;
    00170     ctx.state = IDLE;
    00171     sei();
    00172
    00173     switch(curr_state)
    00174     {
    00175         case SCAN:
    00176             ctx.cchan = TRX_MIN_CHANNEL;
    00177             ctx.thdl = timer_stop(ctx.thdl);
    00178             break;
    00179         case SNIFF:
    00180         case IDLE:
    00181             break;
    00182         default:
    00183             PRINTF("Unknown state %d"NL,ctx.state);
    00184             break;
    00185
    00186     }
    00187 }
    00188
    00196 int main(void)
    00197 {
    00198
    00199     sniffer_init();
    00200
    00201     while(1)
    00202     {
    00203         ctrl_process_input();
    00204
    00205         if(ctx.state == SCAN_DONE)
    00206         {
    00207             scan_update_status();
    00208         }
    00209         if (PcapPool.widx != PcapPool.ridx)
    00210         {
    00211             uint8_t tmp, len, *p;
    00212             pcap_packet_t *ppcap = &PcapPool.packet[PcapPool.ridx];
    00213             hif_putc(1);
    00214             #if 0
    00215                 hif_put_blk((uint8_t*)ppcap, ppcap->len+1);
    00216             #else
    00217                 len = ppcap->len+1;
    00218                 p = (uint8_t*)ppcap;
    00219                 do
    00220                 {
    00221                     tmp = hif_put_blk(p, len);
    00222                     p += tmp;
    00223                     len -= tmp;
    00224                 }
    00225                 while(len>0);
    00226             #endif
    00227             hif_putc(4);
    00228             /* mark buffer as processed */
    00229             ppcap->len = 0;
    00230             PcapPool.ridx++;
    00231             PcapPool.ridx &= (MAX_PACKET_BUFFERS-1);
    00232         }
    00233     }
    00234 }
    00235
    00239 #if defined(DOXYGEN)
    00240 void TRX_IRQ_vect()
    00241 #elif !defined(TRX_IF_RFA1)
    00242 ISR(TRX_IRQ_vect)
    00243 {
    00244 static volatile uint8_t cause;
    00245 uint8_t ed, flen, lqi = 0;
    00246 bool crc_ok = 0;
    00247 extern time_t systime;
    00248 static pcap_packet_t *ppcap;
    00249
    00250     DI_TRX_IRQ();
    00251     sei();
    00252     cause = trx_reg_read(RG_IRQ_STATUS);
    00253
    00254     if (cause & TRX_IRQ_RX_START)
    00255     {
    00256         ppcap = &PcapPool.packet[PcapPool.widx];
    00257         if (ppcap->len != 0)
    00258         {
    00259             /* drop packet, no free buffers*/
    00260             ppcap = NULL;
    00261             return;
    00262         }
    00263         ppcap->ts.time_usec = TRX_TSTAMP_REG;
    00264         ppcap->ts.time_sec = systime;
    00265     }
    00266
    00267     if (cause & TRX_IRQ_TRX_END)
    00268     {
    00269         /* Upload frame at TRX_END IRQ */
    00270         if (ppcap != NULL)
    00271         {
    00272             ed = trx_reg_read(RG_PHY_ED_LEVEL);
    00273             flen = trx_frame_read_crc(&ppcap->frame[0], MAX_FRAME_SIZE, &crc_ok);
    00274             trx_sram_read(flen, 1, &lqi);
    00275             if (ctx.state == SCAN)
    00276             {
    00277                 scan_update_frame(flen, crc_ok, lqi, ed, ppcap->frame);
    00278             }
    00279             if (ctx.state == SNIFF)
    00280             {
    00281                 ppcap->len = flen + sizeof(time_stamp_t);
    00282                 PcapPool.widx++;
    00283                 PcapPool.widx &= (MAX_PACKET_BUFFERS-1);
    00284             }
    00285         }
    00286         ctx.frames++;
    00287         LED_SET_VALUE(ctx.frames);
    00288     }
    00289
    00290     if (cause & TRX_IRQ_UR)
    00291     {
    00292         ctx.irq_ur ++;
    00293     }
    00294
    00295     cli();
    00296     EI_TRX_IRQ();
    00297 }
    00298 #endif /* defined(DOXYGEN) || !RFA1 */
    00299
    00300 #if defined(TRX_IF_RFA1)
    00301
    00302 pcap_packet_t *ppcap_trx24 = NULL;
    00303
    00304 ISR(TRX24_RX_START_vect)
    00305 {
    00306 extern time_t systime;
    00307     ppcap_trx24 = &PcapPool.packet[PcapPool.widx];
    00308     if (ppcap_trx24->len != 0)
    00309     {
    00310         /* drop packet, no free buffers*/
    00311         ppcap_trx24 = NULL;
    00312         return;
    00313     }
    00314     ppcap_trx24->ts.time_usec = TRX_TSTAMP_REG;
    00315     ppcap_trx24->ts.time_sec = systime;
    00316 }
    00317
    00318 ISR(TRX24_RX_END_vect)
    00319 {
    00320 uint8_t ed, flen, lqi = 0;
    00321 bool crc_ok = 0;
    00322
    00323     if (ppcap_trx24 != NULL)
    00324     {
    00325         ed = trx_reg_read(RG_PHY_ED_LEVEL);
    00326         flen = trx_frame_read_crc(&ppcap_trx24->frame[0], MAX_FRAME_SIZE, &crc_ok);
    00327         trx_sram_read(flen, 1, &lqi);
    00328         if (ctx.state == SCAN)
    00329         {
    00330             scan_update_frame(flen, crc_ok, lqi, ed, ppcap_trx24->frame);
    00331         }
    00332         if (ctx.state == SNIFF)
    00333         {
    00334             ppcap_trx24->len = flen + sizeof(time_stamp_t);
    00335             PcapPool.widx++;
    00336             PcapPool.widx &= (MAX_PACKET_BUFFERS-1);
    00337         }
    00338     }
    00339     ctx.frames++;
    00340     LED_SET_VALUE(ctx.frames);
    00341 }
    00342 #endif  /* RFA1 */
    00343
    00344 /* EOF */