summaryrefslogtreecommitdiff
path: root/cesar/tools/sniffer_phy
diff options
context:
space:
mode:
Diffstat (limited to 'cesar/tools/sniffer_phy')
-rw-r--r--cesar/tools/sniffer_phy/Makefile2
-rw-r--r--cesar/tools/sniffer_phy/inc/context.h5
-rw-r--r--cesar/tools/sniffer_phy/inc/lowlevel.h95
-rw-r--r--cesar/tools/sniffer_phy/src/lowlevel.c157
-rw-r--r--cesar/tools/sniffer_phy/src/sniffer_phy.c2
5 files changed, 258 insertions, 3 deletions
diff --git a/cesar/tools/sniffer_phy/Makefile b/cesar/tools/sniffer_phy/Makefile
index a01f88d0b2..270432eb13 100644
--- a/cesar/tools/sniffer_phy/Makefile
+++ b/cesar/tools/sniffer_phy/Makefile
@@ -6,7 +6,7 @@ TARGET = sparc
TARGET_OPTIMIZE = -Os
TARGET_PROGRAMS = sniffer_phy
-sniffer_phy_SOURCES = sniffer_phy.c lhle.c
+sniffer_phy_SOURCES = sniffer_phy.c lhle.c lowlevel.c
sniffer_phy_MODULES = lib hal/phy mac/common hal/hle hle hal/arch
mac_common_MODULES_SOURCES = tonemask.c
diff --git a/cesar/tools/sniffer_phy/inc/context.h b/cesar/tools/sniffer_phy/inc/context.h
index ce79ea6e5f..9749f539d7 100644
--- a/cesar/tools/sniffer_phy/inc/context.h
+++ b/cesar/tools/sniffer_phy/inc/context.h
@@ -12,15 +12,16 @@
* \brief Sniffer context.
* \ingroup sniffer_phy
*/
-#include "hal/phy/forward.h"
-
#include "inc/lhle.h"
+#include "inc/lowlevel.h"
/** Sniffer context. */
struct sniffer_phy_t
{
/* Light HLE context. */
lhle_t lhle;
+ /* Low level context. */
+ lowlevel_t lowlevel;
};
/* Forward declaration in inc/forward.h. */
diff --git a/cesar/tools/sniffer_phy/inc/lowlevel.h b/cesar/tools/sniffer_phy/inc/lowlevel.h
new file mode 100644
index 0000000000..6584320b54
--- /dev/null
+++ b/cesar/tools/sniffer_phy/inc/lowlevel.h
@@ -0,0 +1,95 @@
+#ifndef inc_lowlevel_h
+#define inc_lowlevel_h
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file inc/lowlevel.h
+ * \brief Low level sniffer functions.
+ * \ingroup sniffer_phy
+ */
+#include "hal/phy/forward.h"
+#include "mac/common/tonemask.h"
+
+#include "inc/forward.h"
+
+/** Size of the low level pool. */
+#define LOWLEVEL_POOL_SIZE 512
+
+/** Received MPDU. */
+struct lowlevel_rx_t
+{
+ /** Preamble start date. */
+ u32 date;
+ /** Frame control 1.0. */
+ u32 fc10;
+ /** Frame control. */
+ u32 fc[4];
+ /** FC1.0 CRC. */
+ bool fc10_bad_crc;
+ /** FC AV CRC. */
+ bool fc_bad_crc;
+};
+typedef struct lowlevel_rx_t lowlevel_rx_t;
+
+/** Received MPDU descriptor. */
+union lowlevel_rx_desc_t
+{
+ /** Common block descriptor. */
+ blk_t blk;
+ struct
+ {
+ /** Pointer to next descriptor. */
+ union lowlevel_rx_desc_t *next;
+ /** Pointer to data. */
+ lowlevel_rx_t *rx;
+ };
+};
+typedef union lowlevel_rx_desc_t lowlevel_rx_desc_t;
+
+/** Low level context. */
+struct lowlevel_t
+{
+ /* Phy context. */
+ phy_t *phy;
+ /** Block pool head. */
+ blk_t *pool_head;
+ /** Block pool tail. */
+ blk_t *pool_tail;
+ /** Block pool size. */
+ uint pool_size;
+ /** RX MPDU queue head. */
+ lowlevel_rx_desc_t *rx_head;
+ /** RX MPDU queue tail. */
+ lowlevel_rx_desc_t *rx_tail;
+ /* Current tonemask. */
+ tonemask_info_t *tonemask_info;
+};
+typedef struct lowlevel_t lowlevel_t;
+
+BEGIN_DECLS
+
+/**
+ * Initialise low level.
+ * \param ctx sniffer context
+ */
+void
+lowlevel_init (sniffer_phy_t *ctx);
+
+/**
+ * Activate reception.
+ * \param ctx sniffer context
+ * \param state activation state
+ *
+ * Set tonemask when activating.
+ */
+void
+lowlevel_activate (sniffer_phy_t *ctx, bool state);
+
+END_DECLS
+
+#endif /* inc_lowlevel_h */
diff --git a/cesar/tools/sniffer_phy/src/lowlevel.c b/cesar/tools/sniffer_phy/src/lowlevel.c
new file mode 100644
index 0000000000..5531f2fc27
--- /dev/null
+++ b/cesar/tools/sniffer_phy/src/lowlevel.c
@@ -0,0 +1,157 @@
+/* Cesar project {{{
+ *
+ * Copyright (C) 2010 Spidcom
+ *
+ * <<<Licence>>>
+ *
+ * }}} */
+/**
+ * \file src/lowlevel.c
+ * \brief Low level sniffer functions.
+ * \ingroup sniffer_phy
+ *
+ * Handle FC and PB reception in ISR context and unlist them in DSR context.
+ *
+ * Received data is forwarded to MME layer to be sent to sniffer client.
+ */
+#include "common/std.h"
+
+#include "hal/phy/phy.h"
+#include "hal/arch/arch.h"
+#include "lib/slist.h"
+
+#include "inc/context.h"
+
+static bool ARCH_ILRAM
+lowlevel_rx_fc_cb (void *user, u32 rx_date, const u32 *fc_av)
+{
+ sniffer_phy_t *ctx = user;
+ dbg_assert (ctx);
+ /* Prepare hardware. */
+ phy_rx_prepare_short (ctx->lowlevel.phy);
+ /* Take a block to record the FC. */
+ if (ctx->lowlevel.pool_size)
+ {
+ blk_t *blk = slist_pop_front (ctx->lowlevel.pool_, paste_size);
+ lowlevel_rx_desc_t *desc = PARENT_OF (lowlevel_rx_desc_t, blk, blk);
+ lowlevel_rx_t *rx = desc->rx;
+ /* Fill FC information. */
+ rx->date = rx_date;
+ rx->fc10 = phy_rx_fc10 (ctx->lowlevel.phy);
+ rx->fc10_bad_crc = rx->fc10 == (u32) -1;
+ if (fc_av)
+ {
+ rx->fc[0] = fc_av[0];
+ rx->fc[1] = fc_av[1];
+ rx->fc[2] = fc_av[2];
+ rx->fc[3] = fc_av[3];
+ rx->fc_bad_crc = false;
+ }
+ else
+ {
+ rx->fc[0] = (u32) -1;
+ rx->fc[1] = (u32) -1;
+ rx->fc[2] = (u32) -1;
+ rx->fc[3] = (u32) -1;
+ rx->fc_bad_crc = true;
+ }
+ /* Enlist RX descriptor. */
+ slist_push_back (ctx->lowlevel.rx_, desc);
+ }
+ /* Restart RX now. */
+ phy_rx_activate (ctx->lowlevel.phy, true, 0, true);
+ /* Ask a DSR. */
+ return true;
+}
+
+static bool
+lowlevel_access_cb (void *user)
+{
+ /* This interrupt is not used in sniffer. */
+ dbg_assert_default ();
+ return false;
+}
+
+static bool
+lowlevel_access_conf_cb (void *user)
+{
+ /* This interrupt is not used in sniffer. */
+ dbg_assert_default ();
+ return false;
+}
+
+static bool ARCH_ILRAM
+lowlevel_pbdma_cb (void *user, u32 status_word)
+{
+ /* This interrupt is not used yet in sniffer. */
+ dbg_assert_default ();
+ return false;
+}
+
+static bool
+lowlevel_tx_false_alarm_cb (void *user)
+{
+ /* This interrupt is not implemented in hardware! */
+ dbg_assert_default ();
+ return false;
+}
+
+static void
+lowlevel_deferred_cb (void *user)
+{
+ sniffer_phy_t *ctx = user;
+ dbg_assert (ctx);
+ /* Unlist RX MPDU descriptors. */
+ while (!slist_empty (ctx->lowlevel.rx_, paste))
+ {
+ /* Extract MPDU. */
+ uint flags = arch_isr_lock ();
+ lowlevel_rx_desc_t *desc = slist_pop_front (ctx->lowlevel.rx_);
+ arch_isr_unlock (flags);
+ /* TODO: give to MME layer. */
+ slist_push_back (ctx->lowlevel.pool_, &desc->blk, paste_size);
+ }
+}
+
+void
+lowlevel_init (sniffer_phy_t *ctx)
+{
+ static tonemask_info_t tonemask_info;
+ dbg_assert (ctx);
+ /* Initialise context. */
+ slist_init (ctx->lowlevel.pool_, paste_size);
+ slist_init (ctx->lowlevel.rx_, paste);
+ /* Initialise tonemask information. */
+ ctx->lowlevel.tonemask_info = &tonemask_info;
+ tonemask_default (ctx->lowlevel.tonemask_info->tonemask);
+ tonemask_update (ctx->lowlevel.tonemask_info);
+ /* Initialise Phy. */
+ ctx->lowlevel.phy = phy_init (ctx, lowlevel_rx_fc_cb, lowlevel_access_cb,
+ lowlevel_access_conf_cb, lowlevel_pbdma_cb,
+ lowlevel_tx_false_alarm_cb,
+ lowlevel_deferred_cb);
+ /* Allocate pool. */
+ blk_t *first, *last;
+ first = blk_alloc_desc_range (LOWLEVEL_POOL_SIZE, &last);
+ slist_push_back_range (ctx->lowlevel.pool_, first, last,
+ LOWLEVEL_POOL_SIZE, paste_size);
+}
+
+void
+lowlevel_activate (sniffer_phy_t *ctx, bool state)
+{
+ dbg_assert (ctx);
+ if (state)
+ {
+ /* Program tonemask. */
+ phy_set_tonemask (
+ ctx->lowlevel.phy,
+ ARCH_CPU_TO_DMA (ctx->lowlevel.tonemask_info->tonemask),
+ ctx->lowlevel.tonemask_info->carrier_nb);
+ /* Set RX mode. */
+ phy_rx_param (ctx->lowlevel.phy, PHY_FC_MODE_HYBRID_1);
+ }
+ /* Change RX state. */
+ phy_rx_activate (ctx->lowlevel.phy, true, 0, state);
+}
+
diff --git a/cesar/tools/sniffer_phy/src/sniffer_phy.c b/cesar/tools/sniffer_phy/src/sniffer_phy.c
index 5095c39f7e..ca614add1a 100644
--- a/cesar/tools/sniffer_phy/src/sniffer_phy.c
+++ b/cesar/tools/sniffer_phy/src/sniffer_phy.c
@@ -31,6 +31,8 @@ static void
sniffer_phy_init (sniffer_phy_t *ctx)
{
lhle_init (ctx);
+ lowlevel_init (ctx);
+ lowlevel_activate (ctx, true);
}
/** Entry point. */