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 */

This documentation for µracoli was generated on Wed Feb 2 2011 by  doxygen 1.7.1