This commit is contained in:
Bastian Bloessl
2013-03-24 17:34:51 +01:00
commit 8e266d3f5c
85 changed files with 23053 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
build
examples/*.py
.cproject
.project
.pydevproject
.settings
+134
View File
@@ -0,0 +1,134 @@
#
# Copyright 2013 Free Software Foundation, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
########################################################################
# Project setup
########################################################################
cmake_minimum_required(VERSION 2.6)
project(gr-ieee802-11 CXX C)
enable_testing()
#select the release build type by default to get optimization flags
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
message(STATUS "Build type not specified: defaulting to release.")
endif(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE} CACHE STRING "")
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/Modules)
########################################################################
# Compiler specific setup
########################################################################
if(CMAKE_COMPILER_IS_GNUCXX AND NOT WIN32)
#http://gcc.gnu.org/wiki/Visibility
add_definitions(-fvisibility=hidden)
add_definitions(-fvisibility-inlines-hidden)
add_definitions(-std=c++0x)
endif()
########################################################################
# Find boost
########################################################################
if(UNIX AND EXISTS "/usr/lib64")
list(APPEND BOOST_LIBRARYDIR "/usr/lib64") #fedora 64-bit fix
endif(UNIX AND EXISTS "/usr/lib64")
set(Boost_ADDITIONAL_VERSIONS
"1.35.0" "1.35" "1.36.0" "1.36" "1.37.0" "1.37" "1.38.0" "1.38" "1.39.0" "1.39"
"1.40.0" "1.40" "1.41.0" "1.41" "1.42.0" "1.42" "1.43.0" "1.43" "1.44.0" "1.44"
"1.45.0" "1.45" "1.46.0" "1.46" "1.47.0" "1.47" "1.48.0" "1.48" "1.49.0" "1.49"
"1.50.0" "1.50" "1.51.0" "1.51" "1.52.0" "1.52" "1.53.0" "1.53" "1.54.0" "1.54"
"1.55.0" "1.55" "1.56.0" "1.56" "1.57.0" "1.57" "1.58.0" "1.58" "1.59.0" "1.59"
"1.60.0" "1.60" "1.61.0" "1.61" "1.62.0" "1.62" "1.63.0" "1.63" "1.64.0" "1.64"
"1.65.0" "1.65" "1.66.0" "1.66" "1.67.0" "1.67" "1.68.0" "1.68" "1.69.0" "1.69"
)
find_package(Boost "1.35")
if(NOT Boost_FOUND)
message(FATAL_ERROR "Boost required to compile howto")
endif()
########################################################################
# Install directories
########################################################################
include(GrPlatform) #define LIB_SUFFIX
set(GR_RUNTIME_DIR bin)
set(GR_LIBRARY_DIR lib${LIB_SUFFIX})
set(GR_INCLUDE_DIR include)
set(GR_DATA_DIR share)
set(GR_PKG_DATA_DIR ${GR_DATA_DIR}/gnuradio)
set(GR_DOC_DIR ${GR_DATA_DIR}/doc)
set(GR_PKG_DOC_DIR ${GR_DOC_DIR}/gnuradio)
set(GR_CONF_DIR etc)
set(GR_PKG_CONF_DIR ${GR_CONF_DIR}/gnuradio/conf.d)
set(GR_LIBEXEC_DIR libexec)
set(GR_PKG_LIBEXEC_DIR ${GR_LIBEXEC_DIR}/gnuradio)
set(GRC_BLOCKS_DIR ${GR_PKG_DATA_DIR}/grc/blocks)
########################################################################
# Find gnuradio build dependencies
########################################################################
find_package(Gruel)
find_package(GnuradioCore)
if(NOT GRUEL_FOUND)
message(FATAL_ERROR "Gruel required to compile IEEE802-15-4")
endif()
if(NOT GNURADIO_CORE_FOUND)
message(FATAL_ERROR "GnuRadio Core required to compile IEEE802-15-4")
endif()
########################################################################
# Setup the include and linker paths
########################################################################
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/lib
${Boost_INCLUDE_DIRS}
${GRUEL_INCLUDE_DIRS}
${GNURADIO_CORE_INCLUDE_DIRS}
)
link_directories(
${Boost_LIBRARY_DIRS}
${GRUEL_LIBRARY_DIRS}
${GNURADIO_CORE_LIBRARY_DIRS}
)
set(GR_IEEE802_11_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include)
########################################################################
# Create uninstall target
########################################################################
configure_file(
${CMAKE_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
@ONLY)
add_custom_target(uninstall
${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake
)
########################################################################
# Add subdirectories
########################################################################
add_subdirectory(include/gnuradio)
add_subdirectory(lib)
add_subdirectory(swig)
add_subdirectory(python)
add_subdirectory(grc)
+2
View File
@@ -0,0 +1,2 @@
Hi!
+138
View File
@@ -0,0 +1,138 @@
# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...)
#
# CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for
# parsing the arguments given to that macro or function.
# It processes the arguments and defines a set of variables which hold the
# values of the respective options.
#
# The <options> argument contains all options for the respective macro,
# i.e. keywords which can be used when calling the macro without any value
# following, like e.g. the OPTIONAL keyword of the install() command.
#
# The <one_value_keywords> argument contains all keywords for this macro
# which are followed by one value, like e.g. DESTINATION keyword of the
# install() command.
#
# The <multi_value_keywords> argument contains all keywords for this macro
# which can be followed by more than one value, like e.g. the TARGETS or
# FILES keywords of the install() command.
#
# When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the
# keywords listed in <options>, <one_value_keywords> and
# <multi_value_keywords> a variable composed of the given <prefix>
# followed by "_" and the name of the respective keyword.
# These variables will then hold the respective value from the argument list.
# For the <options> keywords this will be TRUE or FALSE.
#
# All remaining arguments are collected in a variable
# <prefix>_UNPARSED_ARGUMENTS, this can be checked afterwards to see whether
# your macro was called with unrecognized parameters.
#
# As an example here a my_install() macro, which takes similar arguments as the
# real install() command:
#
# function(MY_INSTALL)
# set(options OPTIONAL FAST)
# set(oneValueArgs DESTINATION RENAME)
# set(multiValueArgs TARGETS CONFIGURATIONS)
# cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} )
# ...
#
# Assume my_install() has been called like this:
# my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub)
#
# After the cmake_parse_arguments() call the macro will have set the following
# variables:
# MY_INSTALL_OPTIONAL = TRUE
# MY_INSTALL_FAST = FALSE (this option was not used when calling my_install()
# MY_INSTALL_DESTINATION = "bin"
# MY_INSTALL_RENAME = "" (was not used)
# MY_INSTALL_TARGETS = "foo;bar"
# MY_INSTALL_CONFIGURATIONS = "" (was not used)
# MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL"
#
# You can the continue and process these variables.
#
# Keywords terminate lists of values, e.g. if directly after a one_value_keyword
# another recognized keyword follows, this is interpreted as the beginning of
# the new option.
# E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in
# MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would
# be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor.
#=============================================================================
# Copyright 2010 Alexander Neundorf <neundorf@kde.org>
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
if(__CMAKE_PARSE_ARGUMENTS_INCLUDED)
return()
endif()
set(__CMAKE_PARSE_ARGUMENTS_INCLUDED TRUE)
function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames)
# first set all result variables to empty/FALSE
foreach(arg_name ${_singleArgNames} ${_multiArgNames})
set(${prefix}_${arg_name})
endforeach(arg_name)
foreach(option ${_optionNames})
set(${prefix}_${option} FALSE)
endforeach(option)
set(${prefix}_UNPARSED_ARGUMENTS)
set(insideValues FALSE)
set(currentArgName)
# now iterate over all arguments and fill the result variables
foreach(currentArg ${ARGN})
list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword
list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword
if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1)
if(insideValues)
if("${insideValues}" STREQUAL "SINGLE")
set(${prefix}_${currentArgName} ${currentArg})
set(insideValues FALSE)
elseif("${insideValues}" STREQUAL "MULTI")
list(APPEND ${prefix}_${currentArgName} ${currentArg})
endif()
else(insideValues)
list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg})
endif(insideValues)
else()
if(NOT ${optionIndex} EQUAL -1)
set(${prefix}_${currentArg} TRUE)
set(insideValues FALSE)
elseif(NOT ${singleArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "SINGLE")
elseif(NOT ${multiArgIndex} EQUAL -1)
set(currentArgName ${currentArg})
set(${prefix}_${currentArgName})
set(insideValues "MULTI")
endif()
endif()
endforeach(currentArg)
# propagate the result variables to the caller:
foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames})
set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE)
endforeach(arg_name)
set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE)
endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs)
+26
View File
@@ -0,0 +1,26 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_GNURADIO_CORE gnuradio-core)
FIND_PATH(
GNURADIO_CORE_INCLUDE_DIRS
NAMES gr_random.h
HINTS $ENV{GNURADIO_CORE_DIR}/include/gnuradio
${PC_GNURADIO_CORE_INCLUDEDIR}
PATHS /usr/local/include/gnuradio
/usr/include/gnuradio
)
FIND_LIBRARY(
GNURADIO_CORE_LIBRARIES
NAMES gnuradio-core
HINTS $ENV{GNURADIO_CORE_DIR}/lib
${PC_GNURADIO_CORE_LIBDIR}
PATHS /usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GNURADIO_CORE DEFAULT_MSG GNURADIO_CORE_LIBRARIES GNURADIO_CORE_INCLUDE_DIRS)
MARK_AS_ADVANCED(GNURADIO_CORE_LIBRARIES GNURADIO_CORE_INCLUDE_DIRS)
+26
View File
@@ -0,0 +1,26 @@
INCLUDE(FindPkgConfig)
PKG_CHECK_MODULES(PC_GRUEL gruel)
FIND_PATH(
GRUEL_INCLUDE_DIRS
NAMES gruel/attributes.h
HINTS $ENV{GRUEL_DIR}/include
${PC_GRUEL_INCLUDEDIR}
PATHS /usr/local/include
/usr/include
)
FIND_LIBRARY(
GRUEL_LIBRARIES
NAMES gruel
HINTS $ENV{GRUEL_DIR}/lib
${PC_GRUEL_LIBDIR}
PATHS /usr/local/lib
/usr/local/lib64
/usr/lib
/usr/lib64
)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GRUEL DEFAULT_MSG GRUEL_LIBRARIES GRUEL_INCLUDE_DIRS)
MARK_AS_ADVANCED(GRUEL_LIBRARIES GRUEL_INCLUDE_DIRS)
+210
View File
@@ -0,0 +1,210 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_MISC_UTILS_CMAKE)
return()
endif()
set(__INCLUDED_GR_MISC_UTILS_CMAKE TRUE)
########################################################################
# Set global variable macro.
# Used for subdirectories to export settings.
# Example: include and library paths.
########################################################################
function(GR_SET_GLOBAL var)
set(${var} ${ARGN} CACHE INTERNAL "" FORCE)
endfunction(GR_SET_GLOBAL)
########################################################################
# Set the pre-processor definition if the condition is true.
# - def the pre-processor definition to set and condition name
########################################################################
function(GR_ADD_COND_DEF def)
if(${def})
add_definitions(-D${def})
endif(${def})
endfunction(GR_ADD_COND_DEF)
########################################################################
# Check for a header and conditionally set a compile define.
# - hdr the relative path to the header file
# - def the pre-processor definition to set
########################################################################
function(GR_CHECK_HDR_N_DEF hdr def)
include(CheckIncludeFileCXX)
CHECK_INCLUDE_FILE_CXX(${hdr} ${def})
GR_ADD_COND_DEF(${def})
endfunction(GR_CHECK_HDR_N_DEF)
########################################################################
# Include subdirectory macro.
# Sets the CMake directory variables,
# includes the subdirectory CMakeLists.txt,
# resets the CMake directory variables.
#
# This macro includes subdirectories rather than adding them
# so that the subdirectory can affect variables in the level above.
# This provides a work-around for the lack of convenience libraries.
# This way a subdirectory can append to the list of library sources.
########################################################################
macro(GR_INCLUDE_SUBDIRECTORY subdir)
#insert the current directories on the front of the list
list(INSERT _cmake_source_dirs 0 ${CMAKE_CURRENT_SOURCE_DIR})
list(INSERT _cmake_binary_dirs 0 ${CMAKE_CURRENT_BINARY_DIR})
#set the current directories to the names of the subdirs
set(CMAKE_CURRENT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/${subdir})
set(CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${subdir})
#include the subdirectory CMakeLists to run it
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
include(${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt)
#reset the value of the current directories
list(GET _cmake_source_dirs 0 CMAKE_CURRENT_SOURCE_DIR)
list(GET _cmake_binary_dirs 0 CMAKE_CURRENT_BINARY_DIR)
#pop the subdir names of the front of the list
list(REMOVE_AT _cmake_source_dirs 0)
list(REMOVE_AT _cmake_binary_dirs 0)
endmacro(GR_INCLUDE_SUBDIRECTORY)
########################################################################
# Check if a compiler flag works and conditionally set a compile define.
# - flag the compiler flag to check for
# - have the variable to set with result
########################################################################
macro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE flag have)
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG(${flag} ${have})
if(${have})
add_definitions(${flag})
endif(${have})
endmacro(GR_ADD_CXX_COMPILER_FLAG_IF_AVAILABLE)
########################################################################
# Generates the .la libtool file
# This appears to generate libtool files that cannot be used by auto*.
# Usage GR_LIBTOOL(TARGET [target] DESTINATION [dest])
# Notice: there is not COMPONENT option, these will not get distributed.
########################################################################
function(GR_LIBTOOL)
if(NOT DEFINED GENERATE_LIBTOOL)
set(GENERATE_LIBTOOL OFF) #disabled by default
endif()
if(GENERATE_LIBTOOL)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_LIBTOOL "" "TARGET;DESTINATION" "" ${ARGN})
find_program(LIBTOOL libtool)
if(LIBTOOL)
include(CMakeMacroLibtoolFile)
CREATE_LIBTOOL_FILE(${GR_LIBTOOL_TARGET} /${GR_LIBTOOL_DESTINATION})
endif(LIBTOOL)
endif(GENERATE_LIBTOOL)
endfunction(GR_LIBTOOL)
########################################################################
# Do standard things to the library target
# - set target properties
# - make install rules
# Also handle gnuradio custom naming conventions w/ extras mode.
########################################################################
function(GR_LIBRARY_FOO target)
#parse the arguments for component names
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_LIBRARY "" "RUNTIME_COMPONENT;DEVEL_COMPONENT" "" ${ARGN})
#set additional target properties
set_target_properties(${target} PROPERTIES SOVERSION ${LIBVER})
#install the generated files like so...
install(TARGETS ${target}
LIBRARY DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .so/.dylib file
ARCHIVE DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_DEVEL_COMPONENT} # .lib file
RUNTIME DESTINATION ${GR_RUNTIME_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT} # .dll file
)
#extras mode enabled automatically on linux
if(NOT DEFINED LIBRARY_EXTRAS)
set(LIBRARY_EXTRAS ${LINUX})
endif()
#special extras mode to enable alternative naming conventions
if(LIBRARY_EXTRAS)
#create .la file before changing props
GR_LIBTOOL(TARGET ${target} DESTINATION ${GR_LIBRARY_DIR})
#give the library a special name with ultra-zero soversion
set_target_properties(${target} PROPERTIES LIBRARY_OUTPUT_NAME ${target}-${LIBVER} SOVERSION "0.0.0")
set(target_name lib${target}-${LIBVER}.so.0.0.0)
#custom command to generate symlinks
add_custom_command(
TARGET ${target}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
COMMAND ${CMAKE_COMMAND} -E create_symlink ${target_name} ${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
COMMAND ${CMAKE_COMMAND} -E touch ${target_name} #so the symlinks point to something valid so cmake 2.6 will install
)
#and install the extra symlinks
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/lib${target}.so
${CMAKE_CURRENT_BINARY_DIR}/lib${target}-${LIBVER}.so.0
DESTINATION ${GR_LIBRARY_DIR} COMPONENT ${GR_LIBRARY_RUNTIME_COMPONENT}
)
endif(LIBRARY_EXTRAS)
endfunction(GR_LIBRARY_FOO)
########################################################################
# Create a dummy custom command that depends on other targets.
# Usage:
# GR_GEN_TARGET_DEPS(unique_name target_deps <target1> <target2> ...)
# ADD_CUSTOM_COMMAND(<the usual args> ${target_deps})
#
# Custom command cant depend on targets, but can depend on executables,
# and executables can depend on targets. So this is the process:
########################################################################
function(GR_GEN_TARGET_DEPS name var)
file(
WRITE ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in
"int main(void){return 0;}\n"
)
execute_process(
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp.in
${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp
)
add_executable(${name} ${CMAKE_CURRENT_BINARY_DIR}/${name}.cpp)
if(ARGN)
add_dependencies(${name} ${ARGN})
endif(ARGN)
if(CMAKE_CROSSCOMPILING)
set(${var} "DEPENDS;${name}" PARENT_SCOPE) #cant call command when cross
else()
set(${var} "DEPENDS;${name};COMMAND;${name}" PARENT_SCOPE)
endif()
endfunction(GR_GEN_TARGET_DEPS)
+46
View File
@@ -0,0 +1,46 @@
# Copyright 2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_PLATFORM_CMAKE)
return()
endif()
set(__INCLUDED_GR_PLATFORM_CMAKE TRUE)
########################################################################
# Setup additional defines for OS types
########################################################################
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(LINUX TRUE)
endif()
if(LINUX AND EXISTS "/etc/debian_version")
set(DEBIAN TRUE)
endif()
if(LINUX AND EXISTS "/etc/redhat-release")
set(REDHAT TRUE)
endif()
########################################################################
# when the library suffix should be 64 (applies to redhat linux family)
########################################################################
if(NOT DEFINED LIB_SUFFIX AND REDHAT AND CMAKE_SYSTEM_PROCESSOR MATCHES "64$")
set(LIB_SUFFIX 64)
endif()
set(LIB_SUFFIX ${LIB_SUFFIX} CACHE STRING "lib directory suffix")
+227
View File
@@ -0,0 +1,227 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_PYTHON_CMAKE)
return()
endif()
set(__INCLUDED_GR_PYTHON_CMAKE TRUE)
########################################################################
# Setup the python interpreter:
# This allows the user to specify a specific interpreter,
# or finds the interpreter via the built-in cmake module.
########################################################################
#this allows the user to override PYTHON_EXECUTABLE
if(PYTHON_EXECUTABLE)
set(PYTHONINTERP_FOUND TRUE)
#otherwise if not set, try to automatically find it
else(PYTHON_EXECUTABLE)
#use the built-in find script
find_package(PythonInterp)
#and if that fails use the find program routine
if(NOT PYTHONINTERP_FOUND)
find_program(PYTHON_EXECUTABLE NAMES python python2.7 python2.6 python2.5)
if(PYTHON_EXECUTABLE)
set(PYTHONINTERP_FOUND TRUE)
endif(PYTHON_EXECUTABLE)
endif(NOT PYTHONINTERP_FOUND)
endif(PYTHON_EXECUTABLE)
#make the path to the executable appear in the cmake gui
set(PYTHON_EXECUTABLE ${PYTHON_EXECUTABLE} CACHE FILEPATH "python interpreter")
#make sure we can use -B with python (introduced in 2.6)
if(PYTHON_EXECUTABLE)
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -B -c ""
OUTPUT_QUIET ERROR_QUIET
RESULT_VARIABLE PYTHON_HAS_DASH_B_RESULT
)
if(PYTHON_HAS_DASH_B_RESULT EQUAL 0)
set(PYTHON_DASH_B "-B")
endif()
endif(PYTHON_EXECUTABLE)
########################################################################
# Check for the existence of a python module:
# - desc a string description of the check
# - mod the name of the module to import
# - cmd an additional command to run
# - have the result variable to set
########################################################################
macro(GR_PYTHON_CHECK_MODULE desc mod cmd have)
message(STATUS "")
message(STATUS "Python checking for ${desc}")
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c "
#########################################
try: import ${mod}
except: exit(-1)
try: assert ${cmd}
except: exit(-1)
#########################################"
RESULT_VARIABLE ${have}
)
if(${have} EQUAL 0)
message(STATUS "Python checking for ${desc} - found")
set(${have} TRUE)
else(${have} EQUAL 0)
message(STATUS "Python checking for ${desc} - not found")
set(${have} FALSE)
endif(${have} EQUAL 0)
endmacro(GR_PYTHON_CHECK_MODULE)
########################################################################
# Sets the python installation directory GR_PYTHON_DIR
########################################################################
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "
from distutils import sysconfig
print sysconfig.get_python_lib(plat_specific=True, prefix='')
" OUTPUT_VARIABLE GR_PYTHON_DIR OUTPUT_STRIP_TRAILING_WHITESPACE
)
file(TO_CMAKE_PATH ${GR_PYTHON_DIR} GR_PYTHON_DIR)
########################################################################
# Create an always-built target with a unique name
# Usage: GR_UNIQUE_TARGET(<description> <dependencies list>)
########################################################################
function(GR_UNIQUE_TARGET desc)
file(RELATIVE_PATH reldir ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR})
execute_process(COMMAND ${PYTHON_EXECUTABLE} -c "import re, hashlib
unique = hashlib.md5('${reldir}${ARGN}').hexdigest()[:5]
print(re.sub('\\W', '_', '${desc} ${reldir} ' + unique))"
OUTPUT_VARIABLE _target OUTPUT_STRIP_TRAILING_WHITESPACE)
add_custom_target(${_target} ALL DEPENDS ${ARGN})
endfunction(GR_UNIQUE_TARGET)
########################################################################
# Install python sources (also builds and installs byte-compiled python)
########################################################################
function(GR_PYTHON_INSTALL)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_PYTHON_INSTALL "" "DESTINATION;COMPONENT" "FILES;PROGRAMS" ${ARGN})
####################################################################
if(GR_PYTHON_INSTALL_FILES)
####################################################################
install(${ARGN}) #installs regular python files
#create a list of all generated files
unset(pysrcfiles)
unset(pycfiles)
unset(pyofiles)
foreach(pyfile ${GR_PYTHON_INSTALL_FILES})
get_filename_component(pyfile ${pyfile} ABSOLUTE)
list(APPEND pysrcfiles ${pyfile})
#determine if this file is in the source or binary directory
file(RELATIVE_PATH source_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${pyfile})
string(LENGTH "${source_rel_path}" source_rel_path_len)
file(RELATIVE_PATH binary_rel_path ${CMAKE_CURRENT_BINARY_DIR} ${pyfile})
string(LENGTH "${binary_rel_path}" binary_rel_path_len)
#and set the generated path appropriately
if(${source_rel_path_len} GREATER ${binary_rel_path_len})
set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${binary_rel_path})
else()
set(pygenfile ${CMAKE_CURRENT_BINARY_DIR}/${source_rel_path})
endif()
list(APPEND pycfiles ${pygenfile}c)
list(APPEND pyofiles ${pygenfile}o)
#ensure generation path exists
get_filename_component(pygen_path ${pygenfile} PATH)
file(MAKE_DIRECTORY ${pygen_path})
endforeach(pyfile)
#the command to generate the pyc files
add_custom_command(
DEPENDS ${pysrcfiles} OUTPUT ${pycfiles}
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pycfiles}
)
#the command to generate the pyo files
add_custom_command(
DEPENDS ${pysrcfiles} OUTPUT ${pyofiles}
COMMAND ${PYTHON_EXECUTABLE} -O ${CMAKE_BINARY_DIR}/python_compile_helper.py ${pysrcfiles} ${pyofiles}
)
#create install rule and add generated files to target list
set(python_install_gen_targets ${pycfiles} ${pyofiles})
install(FILES ${python_install_gen_targets}
DESTINATION ${GR_PYTHON_INSTALL_DESTINATION}
COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
)
####################################################################
elseif(GR_PYTHON_INSTALL_PROGRAMS)
####################################################################
file(TO_NATIVE_PATH ${PYTHON_EXECUTABLE} pyexe_native)
foreach(pyfile ${GR_PYTHON_INSTALL_PROGRAMS})
get_filename_component(pyfile_name ${pyfile} NAME)
get_filename_component(pyfile ${pyfile} ABSOLUTE)
string(REPLACE "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" pyexefile "${pyfile}.exe")
list(APPEND python_install_gen_targets ${pyexefile})
get_filename_component(pyexefile_path ${pyexefile} PATH)
file(MAKE_DIRECTORY ${pyexefile_path})
add_custom_command(
OUTPUT ${pyexefile} DEPENDS ${pyfile}
COMMAND ${PYTHON_EXECUTABLE} -c
\"open('${pyexefile}', 'w').write('\#!${pyexe_native}\\n'+open('${pyfile}').read())\"
COMMENT "Shebangin ${pyfile_name}"
)
#on windows, python files need an extension to execute
get_filename_component(pyfile_ext ${pyfile} EXT)
if(WIN32 AND NOT pyfile_ext)
set(pyfile_name "${pyfile_name}.py")
endif()
install(PROGRAMS ${pyexefile} RENAME ${pyfile_name}
DESTINATION ${GR_PYTHON_INSTALL_DESTINATION}
COMPONENT ${GR_PYTHON_INSTALL_COMPONENT}
)
endforeach(pyfile)
endif()
GR_UNIQUE_TARGET("pygen" ${python_install_gen_targets})
endfunction(GR_PYTHON_INSTALL)
########################################################################
# Write the python helper script that generates byte code files
########################################################################
file(WRITE ${CMAKE_BINARY_DIR}/python_compile_helper.py "
import sys, py_compile
files = sys.argv[1:]
srcs, gens = files[:len(files)/2], files[len(files)/2:]
for src, gen in zip(srcs, gens):
py_compile.compile(file=src, cfile=gen, doraise=True)
")
+229
View File
@@ -0,0 +1,229 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_SWIG_CMAKE)
return()
endif()
set(__INCLUDED_GR_SWIG_CMAKE TRUE)
include(GrPython)
########################################################################
# Builds a swig documentation file to be generated into python docstrings
# Usage: GR_SWIG_MAKE_DOCS(output_file input_path input_path....)
#
# Set the following variable to specify extra dependent targets:
# - GR_SWIG_DOCS_SOURCE_DEPS
# - GR_SWIG_DOCS_TARGET_DEPS
########################################################################
function(GR_SWIG_MAKE_DOCS output_file)
find_package(Doxygen)
if(DOXYGEN_FOUND)
#setup the input files variable list, quote formated
set(input_files)
unset(INPUT_PATHS)
foreach(input_path ${ARGN})
if (IS_DIRECTORY ${input_path}) #when input path is a directory
file(GLOB input_path_h_files ${input_path}/*.h)
else() #otherwise its just a file, no glob
set(input_path_h_files ${input_path})
endif()
list(APPEND input_files ${input_path_h_files})
set(INPUT_PATHS "${INPUT_PATHS} \"${input_path}\"")
endforeach(input_path)
#determine the output directory
get_filename_component(name ${output_file} NAME_WE)
get_filename_component(OUTPUT_DIRECTORY ${output_file} PATH)
set(OUTPUT_DIRECTORY ${OUTPUT_DIRECTORY}/${name}_swig_docs)
make_directory(${OUTPUT_DIRECTORY})
#generate the Doxyfile used by doxygen
configure_file(
${CMAKE_SOURCE_DIR}/docs/doxygen/Doxyfile.swig_doc.in
${OUTPUT_DIRECTORY}/Doxyfile
@ONLY)
#Create a dummy custom command that depends on other targets
include(GrMiscUtils)
GR_GEN_TARGET_DEPS(_${name}_tag tag_deps ${GR_SWIG_DOCS_TARGET_DEPS})
#call doxygen on the Doxyfile + input headers
add_custom_command(
OUTPUT ${OUTPUT_DIRECTORY}/xml/index.xml
DEPENDS ${input_files} ${GR_SWIG_DOCS_SOURCE_DEPS} ${tag_deps}
COMMAND ${DOXYGEN_EXECUTABLE} ${OUTPUT_DIRECTORY}/Doxyfile
COMMENT "Generating doxygen xml for ${name} docs"
)
#call the swig_doc script on the xml files
add_custom_command(
OUTPUT ${output_file}
DEPENDS ${input_files} ${OUTPUT_DIRECTORY}/xml/index.xml
COMMAND ${PYTHON_EXECUTABLE} ${PYTHON_DASH_B}
${CMAKE_SOURCE_DIR}/docs/doxygen/swig_doc.py
${OUTPUT_DIRECTORY}/xml
${output_file}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/docs/doxygen
)
else(DOXYGEN_FOUND)
file(WRITE ${output_file} "\n") #no doxygen -> empty file
endif(DOXYGEN_FOUND)
endfunction(GR_SWIG_MAKE_DOCS)
########################################################################
# Build a swig target for the common gnuradio use case. Usage:
# GR_SWIG_MAKE(target ifile ifile ifile...)
#
# Set the following variables before calling:
# - GR_SWIG_FLAGS
# - GR_SWIG_INCLUDE_DIRS
# - GR_SWIG_LIBRARIES
# - GR_SWIG_SOURCE_DEPS
# - GR_SWIG_TARGET_DEPS
# - GR_SWIG_DOC_FILE
# - GR_SWIG_DOC_DIRS
########################################################################
macro(GR_SWIG_MAKE name)
set(ifiles ${ARGN})
#do swig doc generation if specified
if (GR_SWIG_DOC_FILE)
set(GR_SWIG_DOCS_SOURCE_DEPS ${GR_SWIG_SOURCE_DEPS})
set(GR_SWIG_DOCS_TAREGT_DEPS ${GR_SWIG_TARGET_DEPS})
GR_SWIG_MAKE_DOCS(${GR_SWIG_DOC_FILE} ${GR_SWIG_DOC_DIRS})
list(APPEND GR_SWIG_SOURCE_DEPS ${GR_SWIG_DOC_FILE})
endif()
#append additional include directories
find_package(PythonLibs)
list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH}) #deprecated name (now dirs)
list(APPEND GR_SWIG_INCLUDE_DIRS ${PYTHON_INCLUDE_DIRS})
list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR})
list(APPEND GR_SWIG_INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR})
#determine include dependencies for swig file
execute_process(
COMMAND ${PYTHON_EXECUTABLE}
${CMAKE_BINARY_DIR}/get_swig_deps.py
"${ifiles}" "${GR_SWIG_INCLUDE_DIRS}"
OUTPUT_STRIP_TRAILING_WHITESPACE
OUTPUT_VARIABLE SWIG_MODULE_${name}_EXTRA_DEPS
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
#Create a dummy custom command that depends on other targets
include(GrMiscUtils)
GR_GEN_TARGET_DEPS(_${name}_swig_tag tag_deps ${GR_SWIG_TARGET_DEPS})
set(tag_file ${CMAKE_CURRENT_BINARY_DIR}/${name}.tag)
add_custom_command(
OUTPUT ${tag_file}
DEPENDS ${GR_SWIG_SOURCE_DEPS} ${tag_deps}
COMMAND ${CMAKE_COMMAND} -E touch ${tag_file}
)
#append the specified include directories
include_directories(${GR_SWIG_INCLUDE_DIRS})
list(APPEND SWIG_MODULE_${name}_EXTRA_DEPS ${tag_file})
#setup the swig flags with flags and include directories
set(CMAKE_SWIG_FLAGS -fvirtual -modern -keyword -w511 -module ${name} ${GR_SWIG_FLAGS})
foreach(dir ${GR_SWIG_INCLUDE_DIRS})
list(APPEND CMAKE_SWIG_FLAGS "-I${dir}")
endforeach(dir)
#set the C++ property on the swig .i file so it builds
set_source_files_properties(${ifiles} PROPERTIES CPLUSPLUS ON)
#setup the actual swig library target to be built
include(UseSWIG)
SWIG_ADD_MODULE(${name} python ${ifiles})
SWIG_LINK_LIBRARIES(${name} ${PYTHON_LIBRARIES} ${GR_SWIG_LIBRARIES})
endmacro(GR_SWIG_MAKE)
########################################################################
# Install swig targets generated by GR_SWIG_MAKE. Usage:
# GR_SWIG_INSTALL(
# TARGETS target target target...
# [DESTINATION destination]
# [COMPONENT component]
# )
########################################################################
macro(GR_SWIG_INSTALL)
include(CMakeParseArgumentsCopy)
CMAKE_PARSE_ARGUMENTS(GR_SWIG_INSTALL "" "DESTINATION;COMPONENT" "TARGETS" ${ARGN})
foreach(name ${GR_SWIG_INSTALL_TARGETS})
install(TARGETS ${SWIG_MODULE_${name}_REAL_NAME}
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
COMPONENT ${GR_SWIG_INSTALL_COMPONENT}
)
include(GrPython)
GR_PYTHON_INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.py
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
COMPONENT ${GR_SWIG_INSTALL_COMPONENT}
)
GR_LIBTOOL(
TARGET ${SWIG_MODULE_${name}_REAL_NAME}
DESTINATION ${GR_SWIG_INSTALL_DESTINATION}
)
endforeach(name)
endmacro(GR_SWIG_INSTALL)
########################################################################
# Generate a python file that can determine swig dependencies.
# Used by the make macro above to determine extra dependencies.
# When you build C++, CMake figures out the header dependencies.
# This code essentially performs that logic for swig includes.
########################################################################
file(WRITE ${CMAKE_BINARY_DIR}/get_swig_deps.py "
import os, sys, re
include_matcher = re.compile('[#|%]include\\s*[<|\"](.*)[>|\"]')
include_dirs = sys.argv[2].split(';')
def get_swig_incs(file_path):
file_contents = open(file_path, 'r').read()
return include_matcher.findall(file_contents, re.MULTILINE)
def get_swig_deps(file_path, level):
deps = [file_path]
if level == 0: return deps
for inc_file in get_swig_incs(file_path):
for inc_dir in include_dirs:
inc_path = os.path.join(inc_dir, inc_file)
if not os.path.exists(inc_path): continue
deps.extend(get_swig_deps(inc_path, level-1))
return deps
if __name__ == '__main__':
ifiles = sys.argv[1].split(';')
deps = sum([get_swig_deps(ifile, 3) for ifile in ifiles], [])
#sys.stderr.write(';'.join(set(deps)) + '\\n\\n')
print(';'.join(set(deps)))
")
+133
View File
@@ -0,0 +1,133 @@
# Copyright 2010-2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
if(DEFINED __INCLUDED_GR_TEST_CMAKE)
return()
endif()
set(__INCLUDED_GR_TEST_CMAKE TRUE)
########################################################################
# Add a unit test and setup the environment for a unit test.
# Takes the same arguments as the ADD_TEST function.
#
# Before calling set the following variables:
# GR_TEST_TARGET_DEPS - built targets for the library path
# GR_TEST_LIBRARY_DIRS - directories for the library path
# GR_TEST_PYTHON_DIRS - directories for the python path
########################################################################
function(GR_ADD_TEST test_name)
if(WIN32)
#Ensure that the build exe also appears in the PATH.
list(APPEND GR_TEST_TARGET_DEPS ${ARGN})
#In the land of windows, all libraries must be in the PATH.
#Since the dependent libraries are not yet installed,
#we must manually set them in the PATH to run tests.
#The following appends the path of a target dependency.
foreach(target ${GR_TEST_TARGET_DEPS})
get_target_property(location ${target} LOCATION)
if(location)
get_filename_component(path ${location} PATH)
string(REGEX REPLACE "\\$\\(.*\\)" ${CMAKE_BUILD_TYPE} path ${path})
list(APPEND GR_TEST_LIBRARY_DIRS ${path})
endif(location)
endforeach(target)
#SWIG generates the python library files into a subdirectory.
#Therefore, we must append this subdirectory into PYTHONPATH.
#Only do this for the python directories matching the following:
foreach(pydir ${GR_TEST_PYTHON_DIRS})
get_filename_component(name ${pydir} NAME)
if(name MATCHES "^(swig|lib|src)$")
list(APPEND GR_TEST_PYTHON_DIRS ${pydir}/${CMAKE_BUILD_TYPE})
endif()
endforeach(pydir)
endif(WIN32)
file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} srcdir)
file(TO_NATIVE_PATH "${GR_TEST_LIBRARY_DIRS}" libpath) #ok to use on dir list?
file(TO_NATIVE_PATH "${GR_TEST_PYTHON_DIRS}" pypath) #ok to use on dir list?
set(environs "GR_DONT_LOAD_PREFS=1" "srcdir=${srcdir}")
#http://www.cmake.org/pipermail/cmake/2009-May/029464.html
#Replaced this add test + set environs code with the shell script generation.
#Its nicer to be able to manually run the shell script to diagnose problems.
#ADD_TEST(${ARGV})
#SET_TESTS_PROPERTIES(${test_name} PROPERTIES ENVIRONMENT "${environs}")
if(UNIX)
set(binpath "${CMAKE_CURRENT_BINARY_DIR}:$PATH")
#set both LD and DYLD paths to cover multiple UNIX OS library paths
list(APPEND libpath "$LD_LIBRARY_PATH" "$DYLD_LIBRARY_PATH")
list(APPEND pypath "$PYTHONPATH")
#replace list separator with the path separator
string(REPLACE ";" ":" libpath "${libpath}")
string(REPLACE ";" ":" pypath "${pypath}")
list(APPEND environs "PATH=${binpath}" "LD_LIBRARY_PATH=${libpath}" "DYLD_LIBRARY_PATH=${libpath}" "PYTHONPATH=${pypath}")
#generate a bat file that sets the environment and runs the test
find_program(SHELL sh)
set(sh_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.sh)
file(WRITE ${sh_file} "#!${SHELL}\n")
#each line sets an environment variable
foreach(environ ${environs})
file(APPEND ${sh_file} "export ${environ}\n")
endforeach(environ)
#load the command to run with its arguments
foreach(arg ${ARGN})
file(APPEND ${sh_file} "${arg} ")
endforeach(arg)
file(APPEND ${sh_file} "\n")
#make the shell file executable
execute_process(COMMAND chmod +x ${sh_file})
add_test(${test_name} ${SHELL} ${sh_file})
endif(UNIX)
if(WIN32)
list(APPEND libpath ${DLL_PATHS} "%PATH%")
list(APPEND pypath "%PYTHONPATH%")
#replace list separator with the path separator (escaped)
string(REPLACE ";" "\\;" libpath "${libpath}")
string(REPLACE ";" "\\;" pypath "${pypath}")
list(APPEND environs "PATH=${libpath}" "PYTHONPATH=${pypath}")
#generate a bat file that sets the environment and runs the test
set(bat_file ${CMAKE_CURRENT_BINARY_DIR}/${test_name}_test.bat)
file(WRITE ${bat_file} "@echo off\n")
#each line sets an environment variable
foreach(environ ${environs})
file(APPEND ${bat_file} "SET ${environ}\n")
endforeach(environ)
#load the command to run with its arguments
foreach(arg ${ARGN})
file(APPEND ${bat_file} "${arg} ")
endforeach(arg)
file(APPEND ${bat_file} "\n")
add_test(${test_name} ${bat_file})
endif(WIN32)
endfunction(GR_ADD_TEST)
+32
View File
@@ -0,0 +1,32 @@
# http://www.vtk.org/Wiki/CMake_FAQ#Can_I_do_.22make_uninstall.22_with_CMake.3F
IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
STRING(REGEX REPLACE "\n" ";" files "${files}")
FOREACH(file ${files})
MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
IF(EXISTS "$ENV{DESTDIR}${file}")
EXEC_PROGRAM(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
IF(NOT "${rm_retval}" STREQUAL 0)
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
ENDIF(NOT "${rm_retval}" STREQUAL 0)
ELSEIF(IS_SYMLINK "$ENV{DESTDIR}${file}")
EXEC_PROGRAM(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
IF(NOT "${rm_retval}" STREQUAL 0)
MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
ENDIF(NOT "${rm_retval}" STREQUAL 0)
ELSE(EXISTS "$ENV{DESTDIR}${file}")
MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
ENDIF(EXISTS "$ENV{DESTDIR}${file}")
ENDFOREACH(file)
+52
View File
@@ -0,0 +1,52 @@
# Copyright 2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
########################################################################
# Create the doxygen configuration file
########################################################################
file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} top_srcdir)
file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} top_builddir)
file(TO_NATIVE_PATH ${CMAKE_SOURCE_DIR} abs_top_srcdir)
file(TO_NATIVE_PATH ${CMAKE_BINARY_DIR} abs_top_builddir)
set(HAVE_DOT ${DOXYGEN_DOT_FOUND})
set(enable_html_docs YES)
set(enable_latex_docs NO)
set(enable_xml_docs YES)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in
${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
@ONLY)
set(BUILT_DIRS ${CMAKE_CURRENT_BINARY_DIR}/xml ${CMAKE_CURRENT_BINARY_DIR}/html)
########################################################################
# Make and install doxygen docs
########################################################################
add_custom_command(
OUTPUT ${BUILT_DIRS}
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating documentation with doxygen"
)
add_custom_target(doxygen_target ALL DEPENDS ${BUILT_DIRS})
install(DIRECTORY ${BUILT_DIRS} DESTINATION ${GR_PKG_DOC_DIR})
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+3
View File
@@ -0,0 +1,3 @@
/Makefile
/Makefile.in
+52
View File
@@ -0,0 +1,52 @@
#
# Copyright 2007,2009,2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
include $(top_srcdir)/Makefile.common
EXTRA_DIST = \
example/aadvark.cc \
example/aadvark.h \
example/Doxyfile \
example/xml/aadvark_8cc.xml \
example/xml/aadvark_8h.xml \
example/xml/classAadvark.xml \
example/xml/combine.xslt \
example/xml/compound.xsd \
example/xml/index.xml \
example/xml/index.xsd
if PYTHON
utilspythondir = $(grpythondir)/doxyxml
TESTS = \
run_tests
nobase_utilspython_PYTHON = \
__init__.py \
base.py \
doxyindex.py \
text.py \
generated/__init__.py \
generated/index.py \
generated/indexsuper.py \
generated/compound.py \
generated/compoundsuper.py
endif
+82
View File
@@ -0,0 +1,82 @@
#
# Copyright 2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
Python interface to contents of doxygen xml documentation.
Example use:
See the contents of the example folder for the C++ and
doxygen-generated xml used in this example.
>>> # Parse the doxygen docs.
>>> import os
>>> this_dir = os.path.dirname(globals()['__file__'])
>>> xml_path = this_dir + "/example/xml/"
>>> di = DoxyIndex(xml_path)
Get a list of all top-level objects.
>>> print([mem.name() for mem in di.members()])
[u'Aadvark', u'aadvarky_enough', u'main']
Get all functions.
>>> print([mem.name() for mem in di.in_category(DoxyFunction)])
[u'aadvarky_enough', u'main']
Check if an object is present.
>>> di.has_member(u'Aadvark')
True
>>> di.has_member(u'Fish')
False
Get an item by name and check its properties.
>>> aad = di.get_member(u'Aadvark')
>>> print(aad.brief_description)
Models the mammal Aadvark.
>>> print(aad.detailed_description)
Sadly the model is incomplete and cannot capture all aspects of an aadvark yet.
<BLANKLINE>
This line is uninformative and is only to test line breaks in the comments.
>>> [mem.name() for mem in aad.members()]
[u'aadvarkness', u'print', u'Aadvark', u'get_aadvarkness']
>>> aad.get_member(u'print').brief_description
u'Outputs the vital aadvark statistics.'
"""
from doxyindex import DoxyIndex, DoxyFunction, DoxyParam, DoxyClass, DoxyFile, DoxyNamespace, DoxyGroup, DoxyFriend, DoxyOther
def _test():
import os
this_dir = os.path.dirname(globals()['__file__'])
xml_path = this_dir + "/example/xml/"
di = DoxyIndex(xml_path)
# Get the Aadvark class
aad = di.get_member('Aadvark')
aad.brief_description
import doctest
return doctest.testmod()
if __name__ == "__main__":
_test()
+219
View File
@@ -0,0 +1,219 @@
#
# Copyright 2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
A base class is created.
Classes based upon this are used to make more user-friendly interfaces
to the doxygen xml docs than the generated classes provide.
"""
import os
import pdb
from xml.parsers.expat import ExpatError
from generated import compound
class Base(object):
class Duplicate(StandardError):
pass
class NoSuchMember(StandardError):
pass
class ParsingError(StandardError):
pass
def __init__(self, parse_data, top=None):
self._parsed = False
self._error = False
self._parse_data = parse_data
self._members = []
self._dict_members = {}
self._in_category = {}
self._data = {}
if top is not None:
self._xml_path = top._xml_path
# Set up holder of references
else:
top = self
self._refs = {}
self._xml_path = parse_data
self.top = top
@classmethod
def from_refid(cls, refid, top=None):
""" Instantiate class from a refid rather than parsing object. """
# First check to see if its already been instantiated.
if top is not None and refid in top._refs:
return top._refs[refid]
# Otherwise create a new instance and set refid.
inst = cls(None, top=top)
inst.refid = refid
inst.add_ref(inst)
return inst
@classmethod
def from_parse_data(cls, parse_data, top=None):
refid = getattr(parse_data, 'refid', None)
if refid is not None and top is not None and refid in top._refs:
return top._refs[refid]
inst = cls(parse_data, top=top)
if refid is not None:
inst.refid = refid
inst.add_ref(inst)
return inst
def add_ref(self, obj):
if hasattr(obj, 'refid'):
self.top._refs[obj.refid] = obj
mem_classes = []
def get_cls(self, mem):
for cls in self.mem_classes:
if cls.can_parse(mem):
return cls
raise StandardError(("Did not find a class for object '%s'." \
% (mem.get_name())))
def convert_mem(self, mem):
try:
cls = self.get_cls(mem)
converted = cls.from_parse_data(mem, self.top)
if converted is None:
raise StandardError('No class matched this object.')
self.add_ref(converted)
return converted
except StandardError, e:
print e
@classmethod
def includes(cls, inst):
return isinstance(inst, cls)
@classmethod
def can_parse(cls, obj):
return False
def _parse(self):
self._parsed = True
def _get_dict_members(self, cat=None):
"""
For given category a dictionary is returned mapping member names to
members of that category. For names that are duplicated the name is
mapped to None.
"""
self.confirm_no_error()
if cat not in self._dict_members:
new_dict = {}
for mem in self.in_category(cat):
if mem.name() not in new_dict:
new_dict[mem.name()] = mem
else:
new_dict[mem.name()] = self.Duplicate
self._dict_members[cat] = new_dict
return self._dict_members[cat]
def in_category(self, cat):
self.confirm_no_error()
if cat is None:
return self._members
if cat not in self._in_category:
self._in_category[cat] = [mem for mem in self._members
if cat.includes(mem)]
return self._in_category[cat]
def get_member(self, name, cat=None):
self.confirm_no_error()
# Check if it's in a namespace or class.
bits = name.split('::')
first = bits[0]
rest = '::'.join(bits[1:])
member = self._get_dict_members(cat).get(first, self.NoSuchMember)
# Raise any errors that are returned.
if member in set([self.NoSuchMember, self.Duplicate]):
raise member()
if rest:
return member.get_member(rest, cat=cat)
return member
def has_member(self, name, cat=None):
try:
mem = self.get_member(name, cat=cat)
return True
except self.NoSuchMember:
return False
def data(self):
self.confirm_no_error()
return self._data
def members(self):
self.confirm_no_error()
return self._members
def process_memberdefs(self):
mdtss = []
for sec in self._retrieved_data.compounddef.sectiondef:
mdtss += sec.memberdef
# At the moment we lose all information associated with sections.
# Sometimes a memberdef is in several sectiondef.
# We make sure we don't get duplicates here.
uniques = set([])
for mem in mdtss:
converted = self.convert_mem(mem)
pair = (mem.name, mem.__class__)
if pair not in uniques:
uniques.add(pair)
self._members.append(converted)
def retrieve_data(self):
filename = os.path.join(self._xml_path, self.refid + '.xml')
try:
self._retrieved_data = compound.parse(filename)
except ExpatError:
print('Error in xml in file %s' % filename)
self._error = True
self._retrieved_data = None
def check_parsed(self):
if not self._parsed:
self._parse()
def confirm_no_error(self):
self.check_parsed()
if self._error:
raise self.ParsingError()
def error(self):
self.check_parsed()
return self._error
def name(self):
# first see if we can do it without processing.
if self._parse_data is not None:
return self._parse_data.name
self.check_parsed()
return self._retrieved_data.compounddef.name
+237
View File
@@ -0,0 +1,237 @@
#
# Copyright 2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
Classes providing more user-friendly interfaces to the doxygen xml
docs than the generated classes provide.
"""
import os
from generated import index
from base import Base
from text import description
class DoxyIndex(Base):
"""
Parses a doxygen xml directory.
"""
__module__ = "gnuradio.utils.doxyxml"
def _parse(self):
if self._parsed:
return
super(DoxyIndex, self)._parse()
self._root = index.parse(os.path.join(self._xml_path, 'index.xml'))
for mem in self._root.compound:
converted = self.convert_mem(mem)
# For files we want the contents to be accessible directly
# from the parent rather than having to go through the file
# object.
if self.get_cls(mem) == DoxyFile:
if mem.name.endswith('.h'):
self._members += converted.members()
self._members.append(converted)
else:
self._members.append(converted)
def generate_swig_doc_i(self):
"""
%feature("docstring") gr_make_align_on_samplenumbers_ss::align_state "
Wraps the C++: gr_align_on_samplenumbers_ss::align_state";
"""
pass
class DoxyCompMem(Base):
kind = None
def __init__(self, *args, **kwargs):
super(DoxyCompMem, self).__init__(*args, **kwargs)
@classmethod
def can_parse(cls, obj):
return obj.kind == cls.kind
def set_descriptions(self, parse_data):
bd = description(getattr(parse_data, 'briefdescription', None))
dd = description(getattr(parse_data, 'detaileddescription', None))
self._data['brief_description'] = bd
self._data['detailed_description'] = dd
class DoxyCompound(DoxyCompMem):
pass
class DoxyMember(DoxyCompMem):
pass
class DoxyFunction(DoxyMember):
__module__ = "gnuradio.utils.doxyxml"
kind = 'function'
def _parse(self):
if self._parsed:
return
super(DoxyFunction, self)._parse()
self.set_descriptions(self._parse_data)
self._data['params'] = []
prms = self._parse_data.param
for prm in prms:
self._data['params'].append(DoxyParam(prm))
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
params = property(lambda self: self.data()['params'])
Base.mem_classes.append(DoxyFunction)
class DoxyParam(DoxyMember):
__module__ = "gnuradio.utils.doxyxml"
def _parse(self):
if self._parsed:
return
super(DoxyParam, self)._parse()
self.set_descriptions(self._parse_data)
self._data['declname'] = self._parse_data.declname
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
declname = property(lambda self: self.data()['declname'])
class DoxyClass(DoxyCompound):
__module__ = "gnuradio.utils.doxyxml"
kind = 'class'
def _parse(self):
if self._parsed:
return
super(DoxyClass, self)._parse()
self.retrieve_data()
if self._error:
return
self.set_descriptions(self._retrieved_data.compounddef)
# Sectiondef.kind tells about whether private or public.
# We just ignore this for now.
self.process_memberdefs()
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
Base.mem_classes.append(DoxyClass)
class DoxyFile(DoxyCompound):
__module__ = "gnuradio.utils.doxyxml"
kind = 'file'
def _parse(self):
if self._parsed:
return
super(DoxyFile, self)._parse()
self.retrieve_data()
self.set_descriptions(self._retrieved_data.compounddef)
if self._error:
return
self.process_memberdefs()
brief_description = property(lambda self: self.data()['brief_description'])
detailed_description = property(lambda self: self.data()['detailed_description'])
Base.mem_classes.append(DoxyFile)
class DoxyNamespace(DoxyCompound):
__module__ = "gnuradio.utils.doxyxml"
kind = 'namespace'
Base.mem_classes.append(DoxyNamespace)
class DoxyGroup(DoxyCompound):
__module__ = "gnuradio.utils.doxyxml"
kind = 'group'
def _parse(self):
if self._parsed:
return
super(DoxyGroup, self)._parse()
self.retrieve_data()
if self._error:
return
cdef = self._retrieved_data.compounddef
self._data['title'] = description(cdef.title)
# Process inner groups
grps = cdef.innergroup
for grp in grps:
converted = DoxyGroup.from_refid(grp.refid, top=self.top)
self._members.append(converted)
# Process inner classes
klasses = cdef.innerclass
for kls in klasses:
converted = DoxyClass.from_refid(kls.refid, top=self.top)
self._members.append(converted)
# Process normal members
self.process_memberdefs()
title = property(lambda self: self.data()['title'])
Base.mem_classes.append(DoxyGroup)
class DoxyFriend(DoxyMember):
__module__ = "gnuradio.utils.doxyxml"
kind = 'friend'
Base.mem_classes.append(DoxyFriend)
class DoxyOther(Base):
__module__ = "gnuradio.utils.doxyxml"
kinds = set(['variable', 'struct', 'union', 'define', 'typedef', 'enum', 'dir', 'page'])
@classmethod
def can_parse(cls, obj):
return obj.kind in cls.kinds
Base.mem_classes.append(DoxyOther)
File diff suppressed because it is too large Load Diff
+50
View File
@@ -0,0 +1,50 @@
/* -*- c++ -*- */
/*
* Copyright 2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <iostream>
#include "aadvark.h"
void Aadvark::print() {
std::cout << "aadvark is " << aadvarkness << "/10 aadvarky" << std::endl;
}
Aadvark::Aadvark(int aaness): aadvarkness(aaness) {}
bool aadvarky_enough(Aadvark aad) {
if (aad.get_aadvarkness() > 6)
return true;
else
return false;
}
int Aadvark::get_aadvarkness() {
return aadvarkness;
}
int main() {
Aadvark arold = Aadvark(6);
arold.print();
if (aadvarky_enough(arold))
std::cout << "He is aadvarky enough" << std::endl;
else
std::cout << "He is not aadvarky enough" << std::endl;
}
+44
View File
@@ -0,0 +1,44 @@
/* -*- c++ -*- */
/*
* Copyright 2010 Free Software Foundation, Inc.
*
* This file is part of GNU Radio
*
* GNU Radio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* GNU Radio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU Radio; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include <iostream>
/*!
* \brief Models the mammal Aadvark.
*
* Sadly the model is incomplete and cannot capture all aspects of an aadvark yet.
*
* This line is uninformative and is only to test line breaks in the comments.
*/
class Aadvark {
public:
//! \brief Outputs the vital aadvark statistics.
void print();
//! \param aaness The aadvarkness of an aadvark is a measure of how aadvarky it is.
Aadvark(int aaness);
int get_aadvarkness();
private:
int aadvarkness;
};
bool aadvarky_enough(Aadvark aad);
int main();
@@ -0,0 +1,88 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.6.3">
<compounddef id="aadvark_8cc" kind="file">
<compoundname>aadvark.cc</compoundname>
<includes local="no">iostream</includes>
<includes refid="aadvark_8cc" local="yes">aadvark.h</includes>
<includedby refid="aadvark_8cc" local="yes">aadvark.cc</includedby>
<incdepgraph>
<node id="0">
<label>aadvark.cc</label>
<link refid="aadvark.cc"/>
<childnode refid="1" relation="include">
</childnode>
</node>
<node id="1">
<label>iostream</label>
</node>
</incdepgraph>
<sectiondef kind="func">
<memberdef kind="function" id="aadvark_8cc_1acb52858524210ec6dddc3e16d1e52946" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type>bool</type>
<definition>bool aadvarky_enough</definition>
<argsstring>(Aadvark aad)</argsstring>
<name>aadvarky_enough</name>
<param>
<type><ref refid="classAadvark" kindref="compound">Aadvark</ref></type>
<declname>aad</declname>
</param>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" line="10" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="10" bodyend="15"/>
</memberdef>
<memberdef kind="function" id="aadvark_8cc_1ae66f6b31b5ad750f1fe042a706a4e3d4" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type>int</type>
<definition>int main</definition>
<argsstring>()</argsstring>
<name>main</name>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" line="21" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="21" bodyend="28"/>
</memberdef>
</sectiondef>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<programlisting>
<codeline lineno="1"><highlight class="preprocessor">#include<sp/>&lt;iostream&gt;</highlight><highlight class="normal"></highlight></codeline>
<codeline lineno="2"><highlight class="normal"></highlight><highlight class="preprocessor">#include<sp/>&quot;aadvark.h&quot;</highlight><highlight class="normal"></highlight></codeline>
<codeline lineno="3"><highlight class="normal"></highlight></codeline>
<codeline lineno="4"><highlight class="normal"></highlight><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/><ref refid="classAadvark_1abd061aa5f998002e72080a34f512a059" kindref="member" tooltip="Outputs the vital aadvark statistics.">Aadvark::print</ref>()<sp/>{</highlight></codeline>
<codeline lineno="5"><highlight class="normal"><sp/><sp/>std::cout<sp/>&lt;&lt;<sp/></highlight><highlight class="stringliteral">&quot;aadvark<sp/>is<sp/>&quot;</highlight><highlight class="normal"><sp/>&lt;&lt;<sp/>aadvarkness<sp/>&lt;&lt;<sp/></highlight><highlight class="stringliteral">&quot;/10<sp/>aadvarky&quot;</highlight><highlight class="normal"><sp/>&lt;&lt;<sp/>std::endl;</highlight></codeline>
<codeline lineno="6"><highlight class="normal">}</highlight></codeline>
<codeline lineno="7"><highlight class="normal"></highlight></codeline>
<codeline lineno="8"><highlight class="normal"><ref refid="classAadvark_1adf1a4b97a641411a74a04ab312484462" kindref="member">Aadvark::Aadvark</ref>(</highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>aaness):<sp/>aadvarkness(aaness)<sp/>{}</highlight></codeline>
<codeline lineno="9"><highlight class="normal"></highlight></codeline>
<codeline lineno="10"><highlight class="normal"></highlight><highlight class="keywordtype">bool</highlight><highlight class="normal"><sp/>aadvarky_enough(<ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref><sp/>aad)<sp/>{</highlight></codeline>
<codeline lineno="11"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">if</highlight><highlight class="normal"><sp/>(aad.get_aadvarkness()<sp/>&gt;<sp/>6)</highlight></codeline>
<codeline lineno="12"><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/></highlight><highlight class="keyword">true</highlight><highlight class="normal">;</highlight></codeline>
<codeline lineno="13"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">else</highlight><highlight class="normal"></highlight></codeline>
<codeline lineno="14"><highlight class="normal"><sp/><sp/><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/></highlight><highlight class="keyword">false</highlight><highlight class="normal">;</highlight></codeline>
<codeline lineno="15"><highlight class="normal">}</highlight></codeline>
<codeline lineno="16"><highlight class="normal"></highlight></codeline>
<codeline lineno="17"><highlight class="normal"></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>Aadvark::get_aadvarkness()<sp/>{</highlight></codeline>
<codeline lineno="18"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">return</highlight><highlight class="normal"><sp/>aadvarkness;</highlight></codeline>
<codeline lineno="19"><highlight class="normal">}</highlight></codeline>
<codeline lineno="20"><highlight class="normal"></highlight></codeline>
<codeline lineno="21"><highlight class="normal"></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>main()<sp/>{</highlight></codeline>
<codeline lineno="22"><highlight class="normal"><sp/><sp/><ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref><sp/>arold<sp/>=<sp/><ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref>(6);</highlight></codeline>
<codeline lineno="23"><highlight class="normal"><sp/><sp/>arold.<ref refid="classAadvark_1abd061aa5f998002e72080a34f512a059" kindref="member" tooltip="Outputs the vital aadvark statistics.">print</ref>();</highlight></codeline>
<codeline lineno="24"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">if</highlight><highlight class="normal"><sp/>(aadvarky_enough(arold))</highlight></codeline>
<codeline lineno="25"><highlight class="normal"><sp/><sp/><sp/><sp/>std::cout<sp/>&lt;&lt;<sp/></highlight><highlight class="stringliteral">&quot;He<sp/>is<sp/>aadvarky<sp/>enough&quot;</highlight><highlight class="normal"><sp/>&lt;&lt;<sp/>std::endl;</highlight></codeline>
<codeline lineno="26"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordflow">else</highlight><highlight class="normal"></highlight></codeline>
<codeline lineno="27"><highlight class="normal"><sp/><sp/><sp/><sp/>std::cout<sp/>&lt;&lt;<sp/></highlight><highlight class="stringliteral">&quot;He<sp/>is<sp/>not<sp/>aadvarky<sp/>enough&quot;</highlight><highlight class="normal"><sp/>&lt;&lt;<sp/>std::endl;</highlight></codeline>
<codeline lineno="28"><highlight class="normal">}</highlight></codeline>
<codeline lineno="29"><highlight class="normal"></highlight></codeline>
</programlisting>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc"/>
</compounddef>
</doxygen>
@@ -0,0 +1,72 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.6.3">
<compounddef id="aadvark_8h" kind="file">
<compoundname>aadvark.h</compoundname>
<includes local="no">iostream</includes>
<incdepgraph>
<node id="3">
<label>aadvark.h</label>
<link refid="aadvark.h"/>
<childnode refid="4" relation="include">
</childnode>
</node>
<node id="4">
<label>iostream</label>
</node>
</incdepgraph>
<innerclass refid="classAadvark" prot="public">Aadvark</innerclass>
<sectiondef kind="func">
<memberdef kind="function" id="aadvark_8h_1acb52858524210ec6dddc3e16d1e52946" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type>bool</type>
<definition>bool aadvarky_enough</definition>
<argsstring>(Aadvark aad)</argsstring>
<name>aadvarky_enough</name>
<param>
<type><ref refid="classAadvark" kindref="compound">Aadvark</ref></type>
<declname>aad</declname>
</param>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="21" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="10" bodyend="15"/>
</memberdef>
<memberdef kind="function" id="aadvark_8h_1ae66f6b31b5ad750f1fe042a706a4e3d4" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type>int</type>
<definition>int main</definition>
<argsstring>()</argsstring>
<name>main</name>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="23" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="21" bodyend="28"/>
</memberdef>
</sectiondef>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<programlisting>
<codeline lineno="1"><highlight class="preprocessor">#include<sp/>&lt;iostream&gt;</highlight><highlight class="normal"></highlight></codeline>
<codeline lineno="2"><highlight class="normal"></highlight></codeline>
<codeline lineno="10" refid="classAadvark" refkind="compound"><highlight class="keyword">class<sp/></highlight><highlight class="normal"><ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref><sp/>{</highlight></codeline>
<codeline lineno="11"><highlight class="normal"></highlight><highlight class="keyword">public</highlight><highlight class="normal">:</highlight></codeline>
<codeline lineno="13"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordtype">void</highlight><highlight class="normal"><sp/><ref refid="classAadvark_1abd061aa5f998002e72080a34f512a059" kindref="member" tooltip="Outputs the vital aadvark statistics.">print</ref>();</highlight></codeline>
<codeline lineno="15"><highlight class="normal"><sp/><sp/><ref refid="classAadvark_1adf1a4b97a641411a74a04ab312484462" kindref="member">Aadvark</ref>(</highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>aaness);</highlight></codeline>
<codeline lineno="16"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>get_aadvarkness();</highlight></codeline>
<codeline lineno="17"><highlight class="normal"></highlight><highlight class="keyword">private</highlight><highlight class="normal">:</highlight></codeline>
<codeline lineno="18"><highlight class="normal"><sp/><sp/></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>aadvarkness;</highlight></codeline>
<codeline lineno="19"><highlight class="normal">};</highlight></codeline>
<codeline lineno="20"><highlight class="normal"></highlight></codeline>
<codeline lineno="21"><highlight class="normal"></highlight><highlight class="keywordtype">bool</highlight><highlight class="normal"><sp/>aadvarky_enough(<ref refid="classAadvark" kindref="compound" tooltip="Models the mammal Aadvark.">Aadvark</ref><sp/>aad);</highlight></codeline>
<codeline lineno="22"><highlight class="normal"></highlight></codeline>
<codeline lineno="23"><highlight class="normal"></highlight><highlight class="keywordtype">int</highlight><highlight class="normal"><sp/>main();</highlight></codeline>
</programlisting>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h"/>
</compounddef>
</doxygen>
@@ -0,0 +1,86 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="compound.xsd" version="1.6.3">
<compounddef id="classAadvark" kind="class" prot="public">
<compoundname>Aadvark</compoundname>
<includes refid="aadvark_8h" local="no">aadvark.h</includes>
<sectiondef kind="private-attrib">
<memberdef kind="variable" id="classAadvark_1ab79eb58d7bb9d5ddfa5d6f783836cab9" prot="private" static="no" mutable="no">
<type>int</type>
<definition>int Aadvark::aadvarkness</definition>
<argsstring></argsstring>
<name>aadvarkness</name>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="18" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" bodystart="18" bodyend="-1"/>
</memberdef>
</sectiondef>
<sectiondef kind="public-func">
<memberdef kind="function" id="classAadvark_1abd061aa5f998002e72080a34f512a059" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type>void</type>
<definition>void Aadvark::print</definition>
<argsstring>()</argsstring>
<name>print</name>
<briefdescription>
<para>Outputs the vital aadvark statistics. </para> </briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="13" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="4" bodyend="6"/>
</memberdef>
<memberdef kind="function" id="classAadvark_1adf1a4b97a641411a74a04ab312484462" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type></type>
<definition>Aadvark::Aadvark</definition>
<argsstring>(int aaness)</argsstring>
<name>Aadvark</name>
<param>
<type>int</type>
<declname>aaness</declname>
</param>
<briefdescription>
</briefdescription>
<detaileddescription>
<para><parameterlist kind="param"><parameteritem>
<parameternamelist>
<parametername>aaness</parametername>
</parameternamelist>
<parameterdescription>
<para>The aadvarkness of an aadvark is a measure of how aadvarky it is. </para></parameterdescription>
</parameteritem>
</parameterlist>
</para> </detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="15" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="8" bodyend="8"/>
</memberdef>
<memberdef kind="function" id="classAadvark_1affd2ada0a85807efcbe26615a848f53e" prot="public" static="no" const="no" explicit="no" inline="no" virt="non-virtual">
<type>int</type>
<definition>int Aadvark::get_aadvarkness</definition>
<argsstring>()</argsstring>
<name>get_aadvarkness</name>
<briefdescription>
</briefdescription>
<detaileddescription>
</detaileddescription>
<inbodydescription>
</inbodydescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="16" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.cc" bodystart="17" bodyend="19"/>
</memberdef>
</sectiondef>
<briefdescription>
<para>Models the mammal <ref refid="classAadvark" kindref="compound">Aadvark</ref>. </para> </briefdescription>
<detaileddescription>
<para>Sadly the model is incomplete and cannot capture all aspects of an aadvark yet.</para><para>This line is uninformative and is only to test line breaks in the comments. </para> </detaileddescription>
<location file="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" line="10" bodyfile="/home/ben/gnuradio/gnuradio-core/src/python/gnuradio/utils/doxyxml/example/aadvark.h" bodystart="10" bodyend="19"/>
<listofallmembers>
<member refid="classAadvark_1adf1a4b97a641411a74a04ab312484462" prot="public" virt="non-virtual"><scope>Aadvark</scope><name>Aadvark</name></member>
<member refid="classAadvark_1ab79eb58d7bb9d5ddfa5d6f783836cab9" prot="private" virt="non-virtual"><scope>Aadvark</scope><name>aadvarkness</name></member>
<member refid="classAadvark_1affd2ada0a85807efcbe26615a848f53e" prot="public" virt="non-virtual"><scope>Aadvark</scope><name>get_aadvarkness</name></member>
<member refid="classAadvark_1abd061aa5f998002e72080a34f512a059" prot="public" virt="non-virtual"><scope>Aadvark</scope><name>print</name></member>
</listofallmembers>
</compounddef>
</doxygen>
@@ -0,0 +1,15 @@
<!-- XSLT script to combine the generated output into a single file.
If you have xsltproc you could use:
xsltproc combine.xslt index.xml >all.xml
-->
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" version="1.0" indent="yes" standalone="yes" />
<xsl:template match="/">
<doxygen version="{doxygenindex/@version}">
<!-- Load all doxgen generated xml files -->
<xsl:for-each select="doxygenindex/compound">
<xsl:copy-of select="document( concat( @refid, '.xml' ) )/doxygen/*" />
</xsl:for-each>
</doxygen>
</xsl:template>
</xsl:stylesheet>
@@ -0,0 +1,814 @@
<?xml version='1.0' encoding='utf-8' ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="doxygen" type="DoxygenType"/>
<!-- Complex types -->
<xsd:complexType name="DoxygenType">
<xsd:sequence maxOccurs="unbounded">
<xsd:element name="compounddef" type="compounddefType" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="version" type="DoxVersionNumber" use="required" />
</xsd:complexType>
<xsd:complexType name="compounddefType">
<xsd:sequence>
<xsd:element name="compoundname" type="xsd:string"/>
<xsd:element name="title" type="xsd:string" minOccurs="0" />
<xsd:element name="basecompoundref" type="compoundRefType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="derivedcompoundref" type="compoundRefType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="includes" type="incType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="includedby" type="incType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="incdepgraph" type="graphType" minOccurs="0" />
<xsd:element name="invincdepgraph" type="graphType" minOccurs="0" />
<xsd:element name="innerdir" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="innerfile" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="innerclass" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="innernamespace" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="innerpage" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="innergroup" type="refType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
<xsd:element name="sectiondef" type="sectiondefType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
<xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
<xsd:element name="inheritancegraph" type="graphType" minOccurs="0" />
<xsd:element name="collaborationgraph" type="graphType" minOccurs="0" />
<xsd:element name="programlisting" type="listingType" minOccurs="0" />
<xsd:element name="location" type="locationType" minOccurs="0" />
<xsd:element name="listofallmembers" type="listofallmembersType" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="kind" type="DoxCompoundKind" />
<xsd:attribute name="prot" type="DoxProtectionKind" />
</xsd:complexType>
<xsd:complexType name="listofallmembersType">
<xsd:sequence>
<xsd:element name="member" type="memberRefType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="memberRefType">
<xsd:sequence>
<xsd:element name="scope" />
<xsd:element name="name" />
</xsd:sequence>
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="prot" type="DoxProtectionKind" />
<xsd:attribute name="virt" type="DoxVirtualKind" />
<xsd:attribute name="ambiguityscope" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="compoundRefType" mixed="true">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="refid" type="xsd:string" use="optional" />
<xsd:attribute name="prot" type="DoxProtectionKind" />
<xsd:attribute name="virt" type="DoxVirtualKind" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="reimplementType" mixed="true">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="refid" type="xsd:string" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="incType" mixed="true">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="local" type="DoxBool" />
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="refType" mixed="true">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="prot" type="DoxProtectionKind" use="optional"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="refTextType" mixed="true">
<xsd:simpleContent>
<xsd:extension base="xsd:string">
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="kindref" type="DoxRefKind" />
<xsd:attribute name="external" type="xsd:string" use="optional"/>
<xsd:attribute name="tooltip" type="xsd:string" use="optional"/>
</xsd:extension>
</xsd:simpleContent>
</xsd:complexType>
<xsd:complexType name="sectiondefType">
<xsd:sequence>
<xsd:element name="header" type="xsd:string" minOccurs="0" />
<xsd:element name="description" type="descriptionType" minOccurs="0" />
<xsd:element name="memberdef" type="memberdefType" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="kind" type="DoxSectionKind" />
</xsd:complexType>
<xsd:complexType name="memberdefType">
<xsd:sequence>
<xsd:element name="templateparamlist" type="templateparamlistType" minOccurs="0" />
<xsd:element name="type" type="linkedTextType" minOccurs="0" />
<xsd:element name="definition" minOccurs="0" />
<xsd:element name="argsstring" minOccurs="0" />
<xsd:element name="name" />
<xsd:element name="read" minOccurs="0" />
<xsd:element name="write" minOccurs="0" />
<xsd:element name="bitfield" minOccurs="0" />
<xsd:element name="reimplements" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="reimplementedby" type="reimplementType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="enumvalue" type="enumvalueType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="initializer" type="linkedTextType" minOccurs="0" />
<xsd:element name="exceptions" type="linkedTextType" minOccurs="0" />
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
<xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
<xsd:element name="inbodydescription" type="descriptionType" minOccurs="0" />
<xsd:element name="location" type="locationType" />
<xsd:element name="references" type="referenceType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="referencedby" type="referenceType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="kind" type="DoxMemberKind" />
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="prot" type="DoxProtectionKind" />
<xsd:attribute name="static" type="DoxBool" />
<xsd:attribute name="const" type="DoxBool" />
<xsd:attribute name="explicit" type="DoxBool" />
<xsd:attribute name="inline" type="DoxBool" />
<xsd:attribute name="virt" type="DoxVirtualKind" />
<xsd:attribute name="volatile" type="DoxBool" />
<xsd:attribute name="mutable" type="DoxBool" />
<!-- Qt property -->
<xsd:attribute name="readable" type="DoxBool" use="optional"/>
<xsd:attribute name="writable" type="DoxBool" use="optional"/>
<!-- C++/CLI variable -->
<xsd:attribute name="initonly" type="DoxBool" use="optional"/>
<!-- C++/CLI and C# property -->
<xsd:attribute name="settable" type="DoxBool" use="optional"/>
<xsd:attribute name="gettable" type="DoxBool" use="optional"/>
<!-- C++/CLI function -->
<xsd:attribute name="final" type="DoxBool" use="optional"/>
<xsd:attribute name="sealed" type="DoxBool" use="optional"/>
<xsd:attribute name="new" type="DoxBool" use="optional"/>
<!-- C++/CLI event -->
<xsd:attribute name="add" type="DoxBool" use="optional"/>
<xsd:attribute name="remove" type="DoxBool" use="optional"/>
<xsd:attribute name="raise" type="DoxBool" use="optional"/>
<!-- Objective-C 2.0 protocol method -->
<xsd:attribute name="optional" type="DoxBool" use="optional"/>
<xsd:attribute name="required" type="DoxBool" use="optional"/>
<!-- Objective-C 2.0 property accessor -->
<xsd:attribute name="accessor" type="DoxAccessor" use="optional"/>
</xsd:complexType>
<xsd:complexType name="descriptionType" mixed="true">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" minOccurs="0"/>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="internal" type="docInternalType" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="enumvalueType" mixed="true">
<xsd:sequence>
<xsd:element name="name" />
<xsd:element name="initializer" type="linkedTextType" minOccurs="0" />
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
<xsd:element name="detaileddescription" type="descriptionType" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="prot" type="DoxProtectionKind" />
</xsd:complexType>
<xsd:complexType name="templateparamlistType">
<xsd:sequence>
<xsd:element name="param" type="paramType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="paramType">
<xsd:sequence>
<xsd:element name="type" type="linkedTextType" minOccurs="0" />
<xsd:element name="declname" minOccurs="0" />
<xsd:element name="defname" minOccurs="0" />
<xsd:element name="array" minOccurs="0" />
<xsd:element name="defval" type="linkedTextType" minOccurs="0" />
<xsd:element name="briefdescription" type="descriptionType" minOccurs="0" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="linkedTextType" mixed="true">
<xsd:sequence>
<xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="graphType">
<xsd:sequence>
<xsd:element name="node" type="nodeType" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="nodeType">
<xsd:sequence>
<xsd:element name="label" />
<xsd:element name="link" type="linkType" minOccurs="0" />
<xsd:element name="childnode" type="childnodeType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="childnodeType">
<xsd:sequence>
<xsd:element name="edgelabel" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="relation" type="DoxGraphRelation" />
</xsd:complexType>
<xsd:complexType name="linkType">
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="external" type="xsd:string" use="optional"/>
</xsd:complexType>
<xsd:complexType name="listingType">
<xsd:sequence>
<xsd:element name="codeline" type="codelineType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="codelineType">
<xsd:sequence>
<xsd:element name="highlight" type="highlightType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="lineno" type="xsd:integer" />
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="refkind" type="DoxRefKind" />
<xsd:attribute name="external" type="DoxBool" />
</xsd:complexType>
<xsd:complexType name="highlightType" mixed="true">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="sp" />
<xsd:element name="ref" type="refTextType" />
</xsd:choice>
<xsd:attribute name="class" type="DoxHighlightClass" />
</xsd:complexType>
<xsd:complexType name="referenceType" mixed="true">
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="compoundref" type="xsd:string" use="optional" />
<xsd:attribute name="startline" type="xsd:integer" />
<xsd:attribute name="endline" type="xsd:integer" />
</xsd:complexType>
<xsd:complexType name="locationType">
<xsd:attribute name="file" type="xsd:string" />
<xsd:attribute name="line" type="xsd:integer" />
<xsd:attribute name="bodyfile" type="xsd:string" />
<xsd:attribute name="bodystart" type="xsd:integer" />
<xsd:attribute name="bodyend" type="xsd:integer" />
</xsd:complexType>
<xsd:complexType name="docSect1Type" mixed="true">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" />
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="internal" type="docInternalS1Type" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docSect2Type" mixed="true">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" />
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="internal" type="docInternalS2Type" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docSect3Type" mixed="true">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" />
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect4" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="internal" type="docInternalS3Type" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docSect4Type" mixed="true">
<xsd:sequence>
<xsd:element name="title" type="xsd:string" />
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="internal" type="docInternalS4Type" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docInternalType" mixed="true">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docInternalS1Type" mixed="true">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect2" type="docSect2Type" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docInternalS2Type" mixed="true">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect3" type="docSect3Type" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docInternalS3Type" mixed="true">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect3" type="docSect4Type" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docInternalS4Type" mixed="true">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:group name="docTitleCmdGroup">
<xsd:choice>
<xsd:element name="ulink" type="docURLLink" />
<xsd:element name="bold" type="docMarkupType" />
<xsd:element name="emphasis" type="docMarkupType" />
<xsd:element name="computeroutput" type="docMarkupType" />
<xsd:element name="subscript" type="docMarkupType" />
<xsd:element name="superscript" type="docMarkupType" />
<xsd:element name="center" type="docMarkupType" />
<xsd:element name="small" type="docMarkupType" />
<xsd:element name="htmlonly" type="xsd:string" />
<xsd:element name="latexonly" type="xsd:string" />
<xsd:element name="dot" type="xsd:string" />
<xsd:element name="anchor" type="docAnchorType" />
<xsd:element name="formula" type="docFormulaType" />
<xsd:element name="ref" type="docRefTextType" />
<xsd:element name="copy" type="docEmptyType" />
<xsd:element name="trademark" type="docEmptyType" />
<xsd:element name="registered" type="docEmptyType" />
<xsd:element name="lsquo" type="docEmptyType" />
<xsd:element name="rsquo" type="docEmptyType" />
<xsd:element name="ldquo" type="docEmptyType" />
<xsd:element name="rdquo" type="docEmptyType" />
<xsd:element name="ndash" type="docEmptyType" />
<xsd:element name="mdash" type="docEmptyType" />
<xsd:element name="umlaut" type="docCharType" />
<xsd:element name="acute" type="docCharType" />
<xsd:element name="grave" type="docCharType" />
<xsd:element name="circ" type="docCharType" />
<xsd:element name="slash" type="docCharType" />
<xsd:element name="tilde" type="docCharType" />
<xsd:element name="cedil" type="docCharType" />
<xsd:element name="ring" type="docCharType" />
<xsd:element name="szlig" type="docEmptyType" />
<xsd:element name="nonbreakablespace" type="docEmptyType" />
</xsd:choice>
</xsd:group>
<xsd:complexType name="docTitleType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
</xsd:complexType>
<xsd:group name="docCmdGroup">
<xsd:choice>
<xsd:group ref="docTitleCmdGroup"/>
<xsd:element name="linebreak" type="docEmptyType" />
<xsd:element name="hruler" type="docEmptyType" />
<xsd:element name="preformatted" type="docMarkupType" />
<xsd:element name="programlisting" type="listingType" />
<xsd:element name="verbatim" type="xsd:string" />
<xsd:element name="indexentry" type="docIndexEntryType" />
<xsd:element name="orderedlist" type="docListType" />
<xsd:element name="itemizedlist" type="docListType" />
<xsd:element name="simplesect" type="docSimpleSectType" />
<xsd:element name="title" type="docTitleType" />
<xsd:element name="variablelist" type="docVariableListType" />
<xsd:element name="table" type="docTableType" />
<xsd:element name="heading" type="docHeadingType" />
<xsd:element name="image" type="docImageType" />
<xsd:element name="dotfile" type="docDotFileType" />
<xsd:element name="toclist" type="docTocListType" />
<xsd:element name="language" type="docLanguageType" />
<xsd:element name="parameterlist" type="docParamListType" />
<xsd:element name="xrefsect" type="docXRefSectType" />
<xsd:element name="copydoc" type="docCopyType" />
</xsd:choice>
</xsd:group>
<xsd:complexType name="docParaType" mixed="true">
<xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" />
</xsd:complexType>
<xsd:complexType name="docMarkupType" mixed="true">
<xsd:group ref="docCmdGroup" minOccurs="0" maxOccurs="unbounded" />
</xsd:complexType>
<xsd:complexType name="docURLLink" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="url" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docAnchorType" mixed="true">
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docFormulaType" mixed="true">
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docIndexEntryType">
<xsd:sequence>
<xsd:element name="primaryie" type="xsd:string" />
<xsd:element name="secondaryie" type="xsd:string" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docListType">
<xsd:sequence>
<xsd:element name="listitem" type="docListItemType" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docListItemType">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docSimpleSectType">
<xsd:sequence>
<xsd:element name="title" type="docTitleType" minOccurs="0" />
<xsd:sequence minOccurs="0" maxOccurs="unbounded">
<xsd:element name="para" type="docParaType" minOccurs="1" maxOccurs="unbounded" />
<xsd:element name="simplesectsep" type="docEmptyType" minOccurs="0"/>
</xsd:sequence>
</xsd:sequence>
<xsd:attribute name="kind" type="DoxSimpleSectKind" />
</xsd:complexType>
<xsd:complexType name="docVarListEntryType">
<xsd:sequence>
<xsd:element name="term" type="docTitleType" />
</xsd:sequence>
</xsd:complexType>
<xsd:group name="docVariableListGroup">
<xsd:sequence>
<xsd:element name="varlistentry" type="docVarListEntryType" />
<xsd:element name="listitem" type="docListItemType" />
</xsd:sequence>
</xsd:group>
<xsd:complexType name="docVariableListType">
<xsd:sequence>
<xsd:group ref="docVariableListGroup" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docRefTextType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="refid" type="xsd:string" />
<xsd:attribute name="kindref" type="DoxRefKind" />
<xsd:attribute name="external" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docTableType">
<xsd:sequence>
<xsd:element name="row" type="docRowType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="caption" type="docCaptionType" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="rows" type="xsd:integer" />
<xsd:attribute name="cols" type="xsd:integer" />
</xsd:complexType>
<xsd:complexType name="docRowType">
<xsd:sequence>
<xsd:element name="entry" type="docEntryType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docEntryType">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="thead" type="DoxBool" />
</xsd:complexType>
<xsd:complexType name="docCaptionType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
</xsd:complexType>
<xsd:complexType name="docHeadingType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="level" type="xsd:integer" /> <!-- todo: range 1-6 -->
</xsd:complexType>
<xsd:complexType name="docImageType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="type" type="DoxImageKind" />
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="width" type="xsd:string" />
<xsd:attribute name="height" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docDotFileType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docTocItemType" mixed="true">
<xsd:group ref="docTitleCmdGroup" minOccurs="0" maxOccurs="unbounded" />
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docTocListType">
<xsd:sequence>
<xsd:element name="tocitem" type="docTocItemType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docLanguageType">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="langid" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docParamListType">
<xsd:sequence>
<xsd:element name="parameteritem" type="docParamListItem" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
<xsd:attribute name="kind" type="DoxParamListKind" />
</xsd:complexType>
<xsd:complexType name="docParamListItem">
<xsd:sequence>
<xsd:element name="parameternamelist" type="docParamNameList" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="parameterdescription" type="descriptionType" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docParamNameList">
<xsd:sequence>
<xsd:element name="parametername" type="docParamName" minOccurs="0" maxOccurs="unbounded" />
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="docParamName" mixed="true">
<xsd:sequence>
<xsd:element name="ref" type="refTextType" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="direction" type="DoxParamDir" use="optional" />
</xsd:complexType>
<xsd:complexType name="docXRefSectType">
<xsd:sequence>
<xsd:element name="xreftitle" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="xrefdescription" type="descriptionType" />
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docCopyType">
<xsd:sequence>
<xsd:element name="para" type="docParaType" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="sect1" type="docSect1Type" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="internal" type="docInternalType" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="link" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="docCharType">
<xsd:attribute name="char" type="DoxCharRange"/>
</xsd:complexType>
<xsd:complexType name="docEmptyType"/>
<!-- Simple types -->
<xsd:simpleType name="DoxBool">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="yes" />
<xsd:enumeration value="no" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxGraphRelation">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="include" />
<xsd:enumeration value="usage" />
<xsd:enumeration value="template-instance" />
<xsd:enumeration value="public-inheritance" />
<xsd:enumeration value="protected-inheritance" />
<xsd:enumeration value="private-inheritance" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxRefKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="compound" />
<xsd:enumeration value="member" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxMemberKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="define" />
<xsd:enumeration value="property" />
<xsd:enumeration value="event" />
<xsd:enumeration value="variable" />
<xsd:enumeration value="typedef" />
<xsd:enumeration value="enum" />
<xsd:enumeration value="function" />
<xsd:enumeration value="signal" />
<xsd:enumeration value="prototype" />
<xsd:enumeration value="friend" />
<xsd:enumeration value="dcop" />
<xsd:enumeration value="slot" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxProtectionKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="public" />
<xsd:enumeration value="protected" />
<xsd:enumeration value="private" />
<xsd:enumeration value="package" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxVirtualKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="non-virtual" />
<xsd:enumeration value="virtual" />
<xsd:enumeration value="pure-virtual" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxCompoundKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="class" />
<xsd:enumeration value="struct" />
<xsd:enumeration value="union" />
<xsd:enumeration value="interface" />
<xsd:enumeration value="protocol" />
<xsd:enumeration value="category" />
<xsd:enumeration value="exception" />
<xsd:enumeration value="file" />
<xsd:enumeration value="namespace" />
<xsd:enumeration value="group" />
<xsd:enumeration value="page" />
<xsd:enumeration value="example" />
<xsd:enumeration value="dir" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxSectionKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="user-defined" />
<xsd:enumeration value="public-type" />
<xsd:enumeration value="public-func" />
<xsd:enumeration value="public-attrib" />
<xsd:enumeration value="public-slot" />
<xsd:enumeration value="signal" />
<xsd:enumeration value="dcop-func" />
<xsd:enumeration value="property" />
<xsd:enumeration value="event" />
<xsd:enumeration value="public-static-func" />
<xsd:enumeration value="public-static-attrib" />
<xsd:enumeration value="protected-type" />
<xsd:enumeration value="protected-func" />
<xsd:enumeration value="protected-attrib" />
<xsd:enumeration value="protected-slot" />
<xsd:enumeration value="protected-static-func" />
<xsd:enumeration value="protected-static-attrib" />
<xsd:enumeration value="package-type" />
<xsd:enumeration value="package-func" />
<xsd:enumeration value="package-attrib" />
<xsd:enumeration value="package-static-func" />
<xsd:enumeration value="package-static-attrib" />
<xsd:enumeration value="private-type" />
<xsd:enumeration value="private-func" />
<xsd:enumeration value="private-attrib" />
<xsd:enumeration value="private-slot" />
<xsd:enumeration value="private-static-func" />
<xsd:enumeration value="private-static-attrib" />
<xsd:enumeration value="friend" />
<xsd:enumeration value="related" />
<xsd:enumeration value="define" />
<xsd:enumeration value="prototype" />
<xsd:enumeration value="typedef" />
<xsd:enumeration value="enum" />
<xsd:enumeration value="func" />
<xsd:enumeration value="var" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxHighlightClass">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="comment" />
<xsd:enumeration value="normal" />
<xsd:enumeration value="preprocessor" />
<xsd:enumeration value="keyword" />
<xsd:enumeration value="keywordtype" />
<xsd:enumeration value="keywordflow" />
<xsd:enumeration value="stringliteral" />
<xsd:enumeration value="charliteral" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxSimpleSectKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="see" />
<xsd:enumeration value="return" />
<xsd:enumeration value="author" />
<xsd:enumeration value="authors" />
<xsd:enumeration value="version" />
<xsd:enumeration value="since" />
<xsd:enumeration value="date" />
<xsd:enumeration value="note" />
<xsd:enumeration value="warning" />
<xsd:enumeration value="pre" />
<xsd:enumeration value="post" />
<xsd:enumeration value="invariant" />
<xsd:enumeration value="remark" />
<xsd:enumeration value="attention" />
<xsd:enumeration value="par" />
<xsd:enumeration value="rcs" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxVersionNumber">
<xsd:restriction base="xsd:string">
<xsd:pattern value="\d+\.\d+.*" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxImageKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="html" />
<xsd:enumeration value="latex" />
<xsd:enumeration value="rtf" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxParamListKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="param" />
<xsd:enumeration value="retval" />
<xsd:enumeration value="exception" />
<xsd:enumeration value="templateparam" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxCharRange">
<xsd:restriction base="xsd:string">
<xsd:pattern value="[aeiouncAEIOUNC]" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxParamDir">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="in"/>
<xsd:enumeration value="out"/>
<xsd:enumeration value="inout"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="DoxAccessor">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="retain"/>
<xsd:enumeration value="copy"/>
<xsd:enumeration value="assign"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
@@ -0,0 +1,17 @@
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
<doxygenindex xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="index.xsd" version="1.6.3">
<compound refid="classAadvark" kind="class"><name>Aadvark</name>
<member refid="classAadvark_1ab79eb58d7bb9d5ddfa5d6f783836cab9" kind="variable"><name>aadvarkness</name></member>
<member refid="classAadvark_1abd061aa5f998002e72080a34f512a059" kind="function"><name>print</name></member>
<member refid="classAadvark_1adf1a4b97a641411a74a04ab312484462" kind="function"><name>Aadvark</name></member>
<member refid="classAadvark_1affd2ada0a85807efcbe26615a848f53e" kind="function"><name>get_aadvarkness</name></member>
</compound>
<compound refid="aadvark_8cc" kind="file"><name>aadvark.cc</name>
<member refid="aadvark_8cc_1acb52858524210ec6dddc3e16d1e52946" kind="function"><name>aadvarky_enough</name></member>
<member refid="aadvark_8cc_1ae66f6b31b5ad750f1fe042a706a4e3d4" kind="function"><name>main</name></member>
</compound>
<compound refid="aadvark_8h" kind="file"><name>aadvark.h</name>
<member refid="aadvark_8h_1acb52858524210ec6dddc3e16d1e52946" kind="function"><name>aadvarky_enough</name></member>
<member refid="aadvark_8h_1ae66f6b31b5ad750f1fe042a706a4e3d4" kind="function"><name>main</name></member>
</compound>
</doxygenindex>
@@ -0,0 +1,66 @@
<?xml version='1.0' encoding='utf-8' ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsd:element name="doxygenindex" type="DoxygenType"/>
<xsd:complexType name="DoxygenType">
<xsd:sequence>
<xsd:element name="compound" type="CompoundType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="version" type="xsd:string" use="required"/>
</xsd:complexType>
<xsd:complexType name="CompoundType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="member" type="MemberType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
<xsd:attribute name="refid" type="xsd:string" use="required"/>
<xsd:attribute name="kind" type="CompoundKind" use="required"/>
</xsd:complexType>
<xsd:complexType name="MemberType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="refid" type="xsd:string" use="required"/>
<xsd:attribute name="kind" type="MemberKind" use="required"/>
</xsd:complexType>
<xsd:simpleType name="CompoundKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="class"/>
<xsd:enumeration value="struct"/>
<xsd:enumeration value="union"/>
<xsd:enumeration value="interface"/>
<xsd:enumeration value="protocol"/>
<xsd:enumeration value="category"/>
<xsd:enumeration value="exception"/>
<xsd:enumeration value="file"/>
<xsd:enumeration value="namespace"/>
<xsd:enumeration value="group"/>
<xsd:enumeration value="page"/>
<xsd:enumeration value="example"/>
<xsd:enumeration value="dir"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="MemberKind">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="define"/>
<xsd:enumeration value="property"/>
<xsd:enumeration value="event"/>
<xsd:enumeration value="variable"/>
<xsd:enumeration value="typedef"/>
<xsd:enumeration value="enum"/>
<xsd:enumeration value="enumvalue"/>
<xsd:enumeration value="function"/>
<xsd:enumeration value="signal"/>
<xsd:enumeration value="prototype"/>
<xsd:enumeration value="friend"/>
<xsd:enumeration value="dcop"/>
<xsd:enumeration value="slot"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
@@ -0,0 +1,7 @@
"""
Contains generated files produced by generateDS.py.
These do the real work of parsing the doxygen xml files but the
resultant classes are not very friendly to navigate so the rest of the
doxyxml module processes them further.
"""
+503
View File
@@ -0,0 +1,503 @@
#!/usr/bin/env python
"""
Generated Mon Feb 9 19:08:05 2009 by generateDS.py.
"""
from string import lower as str_lower
from xml.dom import minidom
from xml.dom import Node
import sys
import compoundsuper as supermod
from compoundsuper import MixedContainer
class DoxygenTypeSub(supermod.DoxygenType):
def __init__(self, version=None, compounddef=None):
supermod.DoxygenType.__init__(self, version, compounddef)
def find(self, details):
return self.compounddef.find(details)
supermod.DoxygenType.subclass = DoxygenTypeSub
# end class DoxygenTypeSub
class compounddefTypeSub(supermod.compounddefType):
def __init__(self, kind=None, prot=None, id=None, compoundname='', title='', basecompoundref=None, derivedcompoundref=None, includes=None, includedby=None, incdepgraph=None, invincdepgraph=None, innerdir=None, innerfile=None, innerclass=None, innernamespace=None, innerpage=None, innergroup=None, templateparamlist=None, sectiondef=None, briefdescription=None, detaileddescription=None, inheritancegraph=None, collaborationgraph=None, programlisting=None, location=None, listofallmembers=None):
supermod.compounddefType.__init__(self, kind, prot, id, compoundname, title, basecompoundref, derivedcompoundref, includes, includedby, incdepgraph, invincdepgraph, innerdir, innerfile, innerclass, innernamespace, innerpage, innergroup, templateparamlist, sectiondef, briefdescription, detaileddescription, inheritancegraph, collaborationgraph, programlisting, location, listofallmembers)
def find(self, details):
if self.id == details.refid:
return self
for sectiondef in self.sectiondef:
result = sectiondef.find(details)
if result:
return result
supermod.compounddefType.subclass = compounddefTypeSub
# end class compounddefTypeSub
class listofallmembersTypeSub(supermod.listofallmembersType):
def __init__(self, member=None):
supermod.listofallmembersType.__init__(self, member)
supermod.listofallmembersType.subclass = listofallmembersTypeSub
# end class listofallmembersTypeSub
class memberRefTypeSub(supermod.memberRefType):
def __init__(self, virt=None, prot=None, refid=None, ambiguityscope=None, scope='', name=''):
supermod.memberRefType.__init__(self, virt, prot, refid, ambiguityscope, scope, name)
supermod.memberRefType.subclass = memberRefTypeSub
# end class memberRefTypeSub
class compoundRefTypeSub(supermod.compoundRefType):
def __init__(self, virt=None, prot=None, refid=None, valueOf_='', mixedclass_=None, content_=None):
supermod.compoundRefType.__init__(self, mixedclass_, content_)
supermod.compoundRefType.subclass = compoundRefTypeSub
# end class compoundRefTypeSub
class reimplementTypeSub(supermod.reimplementType):
def __init__(self, refid=None, valueOf_='', mixedclass_=None, content_=None):
supermod.reimplementType.__init__(self, mixedclass_, content_)
supermod.reimplementType.subclass = reimplementTypeSub
# end class reimplementTypeSub
class incTypeSub(supermod.incType):
def __init__(self, local=None, refid=None, valueOf_='', mixedclass_=None, content_=None):
supermod.incType.__init__(self, mixedclass_, content_)
supermod.incType.subclass = incTypeSub
# end class incTypeSub
class refTypeSub(supermod.refType):
def __init__(self, prot=None, refid=None, valueOf_='', mixedclass_=None, content_=None):
supermod.refType.__init__(self, mixedclass_, content_)
supermod.refType.subclass = refTypeSub
# end class refTypeSub
class refTextTypeSub(supermod.refTextType):
def __init__(self, refid=None, kindref=None, external=None, valueOf_='', mixedclass_=None, content_=None):
supermod.refTextType.__init__(self, mixedclass_, content_)
supermod.refTextType.subclass = refTextTypeSub
# end class refTextTypeSub
class sectiondefTypeSub(supermod.sectiondefType):
def __init__(self, kind=None, header='', description=None, memberdef=None):
supermod.sectiondefType.__init__(self, kind, header, description, memberdef)
def find(self, details):
for memberdef in self.memberdef:
if memberdef.id == details.refid:
return memberdef
return None
supermod.sectiondefType.subclass = sectiondefTypeSub
# end class sectiondefTypeSub
class memberdefTypeSub(supermod.memberdefType):
def __init__(self, initonly=None, kind=None, volatile=None, const=None, raise_=None, virt=None, readable=None, prot=None, explicit=None, new=None, final=None, writable=None, add=None, static=None, remove=None, sealed=None, mutable=None, gettable=None, inline=None, settable=None, id=None, templateparamlist=None, type_=None, definition='', argsstring='', name='', read='', write='', bitfield='', reimplements=None, reimplementedby=None, param=None, enumvalue=None, initializer=None, exceptions=None, briefdescription=None, detaileddescription=None, inbodydescription=None, location=None, references=None, referencedby=None):
supermod.memberdefType.__init__(self, initonly, kind, volatile, const, raise_, virt, readable, prot, explicit, new, final, writable, add, static, remove, sealed, mutable, gettable, inline, settable, id, templateparamlist, type_, definition, argsstring, name, read, write, bitfield, reimplements, reimplementedby, param, enumvalue, initializer, exceptions, briefdescription, detaileddescription, inbodydescription, location, references, referencedby)
supermod.memberdefType.subclass = memberdefTypeSub
# end class memberdefTypeSub
class descriptionTypeSub(supermod.descriptionType):
def __init__(self, title='', para=None, sect1=None, internal=None, mixedclass_=None, content_=None):
supermod.descriptionType.__init__(self, mixedclass_, content_)
supermod.descriptionType.subclass = descriptionTypeSub
# end class descriptionTypeSub
class enumvalueTypeSub(supermod.enumvalueType):
def __init__(self, prot=None, id=None, name='', initializer=None, briefdescription=None, detaileddescription=None, mixedclass_=None, content_=None):
supermod.enumvalueType.__init__(self, mixedclass_, content_)
supermod.enumvalueType.subclass = enumvalueTypeSub
# end class enumvalueTypeSub
class templateparamlistTypeSub(supermod.templateparamlistType):
def __init__(self, param=None):
supermod.templateparamlistType.__init__(self, param)
supermod.templateparamlistType.subclass = templateparamlistTypeSub
# end class templateparamlistTypeSub
class paramTypeSub(supermod.paramType):
def __init__(self, type_=None, declname='', defname='', array='', defval=None, briefdescription=None):
supermod.paramType.__init__(self, type_, declname, defname, array, defval, briefdescription)
supermod.paramType.subclass = paramTypeSub
# end class paramTypeSub
class linkedTextTypeSub(supermod.linkedTextType):
def __init__(self, ref=None, mixedclass_=None, content_=None):
supermod.linkedTextType.__init__(self, mixedclass_, content_)
supermod.linkedTextType.subclass = linkedTextTypeSub
# end class linkedTextTypeSub
class graphTypeSub(supermod.graphType):
def __init__(self, node=None):
supermod.graphType.__init__(self, node)
supermod.graphType.subclass = graphTypeSub
# end class graphTypeSub
class nodeTypeSub(supermod.nodeType):
def __init__(self, id=None, label='', link=None, childnode=None):
supermod.nodeType.__init__(self, id, label, link, childnode)
supermod.nodeType.subclass = nodeTypeSub
# end class nodeTypeSub
class childnodeTypeSub(supermod.childnodeType):
def __init__(self, relation=None, refid=None, edgelabel=None):
supermod.childnodeType.__init__(self, relation, refid, edgelabel)
supermod.childnodeType.subclass = childnodeTypeSub
# end class childnodeTypeSub
class linkTypeSub(supermod.linkType):
def __init__(self, refid=None, external=None, valueOf_=''):
supermod.linkType.__init__(self, refid, external)
supermod.linkType.subclass = linkTypeSub
# end class linkTypeSub
class listingTypeSub(supermod.listingType):
def __init__(self, codeline=None):
supermod.listingType.__init__(self, codeline)
supermod.listingType.subclass = listingTypeSub
# end class listingTypeSub
class codelineTypeSub(supermod.codelineType):
def __init__(self, external=None, lineno=None, refkind=None, refid=None, highlight=None):
supermod.codelineType.__init__(self, external, lineno, refkind, refid, highlight)
supermod.codelineType.subclass = codelineTypeSub
# end class codelineTypeSub
class highlightTypeSub(supermod.highlightType):
def __init__(self, class_=None, sp=None, ref=None, mixedclass_=None, content_=None):
supermod.highlightType.__init__(self, mixedclass_, content_)
supermod.highlightType.subclass = highlightTypeSub
# end class highlightTypeSub
class referenceTypeSub(supermod.referenceType):
def __init__(self, endline=None, startline=None, refid=None, compoundref=None, valueOf_='', mixedclass_=None, content_=None):
supermod.referenceType.__init__(self, mixedclass_, content_)
supermod.referenceType.subclass = referenceTypeSub
# end class referenceTypeSub
class locationTypeSub(supermod.locationType):
def __init__(self, bodystart=None, line=None, bodyend=None, bodyfile=None, file=None, valueOf_=''):
supermod.locationType.__init__(self, bodystart, line, bodyend, bodyfile, file)
supermod.locationType.subclass = locationTypeSub
# end class locationTypeSub
class docSect1TypeSub(supermod.docSect1Type):
def __init__(self, id=None, title='', para=None, sect2=None, internal=None, mixedclass_=None, content_=None):
supermod.docSect1Type.__init__(self, mixedclass_, content_)
supermod.docSect1Type.subclass = docSect1TypeSub
# end class docSect1TypeSub
class docSect2TypeSub(supermod.docSect2Type):
def __init__(self, id=None, title='', para=None, sect3=None, internal=None, mixedclass_=None, content_=None):
supermod.docSect2Type.__init__(self, mixedclass_, content_)
supermod.docSect2Type.subclass = docSect2TypeSub
# end class docSect2TypeSub
class docSect3TypeSub(supermod.docSect3Type):
def __init__(self, id=None, title='', para=None, sect4=None, internal=None, mixedclass_=None, content_=None):
supermod.docSect3Type.__init__(self, mixedclass_, content_)
supermod.docSect3Type.subclass = docSect3TypeSub
# end class docSect3TypeSub
class docSect4TypeSub(supermod.docSect4Type):
def __init__(self, id=None, title='', para=None, internal=None, mixedclass_=None, content_=None):
supermod.docSect4Type.__init__(self, mixedclass_, content_)
supermod.docSect4Type.subclass = docSect4TypeSub
# end class docSect4TypeSub
class docInternalTypeSub(supermod.docInternalType):
def __init__(self, para=None, sect1=None, mixedclass_=None, content_=None):
supermod.docInternalType.__init__(self, mixedclass_, content_)
supermod.docInternalType.subclass = docInternalTypeSub
# end class docInternalTypeSub
class docInternalS1TypeSub(supermod.docInternalS1Type):
def __init__(self, para=None, sect2=None, mixedclass_=None, content_=None):
supermod.docInternalS1Type.__init__(self, mixedclass_, content_)
supermod.docInternalS1Type.subclass = docInternalS1TypeSub
# end class docInternalS1TypeSub
class docInternalS2TypeSub(supermod.docInternalS2Type):
def __init__(self, para=None, sect3=None, mixedclass_=None, content_=None):
supermod.docInternalS2Type.__init__(self, mixedclass_, content_)
supermod.docInternalS2Type.subclass = docInternalS2TypeSub
# end class docInternalS2TypeSub
class docInternalS3TypeSub(supermod.docInternalS3Type):
def __init__(self, para=None, sect3=None, mixedclass_=None, content_=None):
supermod.docInternalS3Type.__init__(self, mixedclass_, content_)
supermod.docInternalS3Type.subclass = docInternalS3TypeSub
# end class docInternalS3TypeSub
class docInternalS4TypeSub(supermod.docInternalS4Type):
def __init__(self, para=None, mixedclass_=None, content_=None):
supermod.docInternalS4Type.__init__(self, mixedclass_, content_)
supermod.docInternalS4Type.subclass = docInternalS4TypeSub
# end class docInternalS4TypeSub
class docURLLinkSub(supermod.docURLLink):
def __init__(self, url=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docURLLink.__init__(self, mixedclass_, content_)
supermod.docURLLink.subclass = docURLLinkSub
# end class docURLLinkSub
class docAnchorTypeSub(supermod.docAnchorType):
def __init__(self, id=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docAnchorType.__init__(self, mixedclass_, content_)
supermod.docAnchorType.subclass = docAnchorTypeSub
# end class docAnchorTypeSub
class docFormulaTypeSub(supermod.docFormulaType):
def __init__(self, id=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docFormulaType.__init__(self, mixedclass_, content_)
supermod.docFormulaType.subclass = docFormulaTypeSub
# end class docFormulaTypeSub
class docIndexEntryTypeSub(supermod.docIndexEntryType):
def __init__(self, primaryie='', secondaryie=''):
supermod.docIndexEntryType.__init__(self, primaryie, secondaryie)
supermod.docIndexEntryType.subclass = docIndexEntryTypeSub
# end class docIndexEntryTypeSub
class docListTypeSub(supermod.docListType):
def __init__(self, listitem=None):
supermod.docListType.__init__(self, listitem)
supermod.docListType.subclass = docListTypeSub
# end class docListTypeSub
class docListItemTypeSub(supermod.docListItemType):
def __init__(self, para=None):
supermod.docListItemType.__init__(self, para)
supermod.docListItemType.subclass = docListItemTypeSub
# end class docListItemTypeSub
class docSimpleSectTypeSub(supermod.docSimpleSectType):
def __init__(self, kind=None, title=None, para=None):
supermod.docSimpleSectType.__init__(self, kind, title, para)
supermod.docSimpleSectType.subclass = docSimpleSectTypeSub
# end class docSimpleSectTypeSub
class docVarListEntryTypeSub(supermod.docVarListEntryType):
def __init__(self, term=None):
supermod.docVarListEntryType.__init__(self, term)
supermod.docVarListEntryType.subclass = docVarListEntryTypeSub
# end class docVarListEntryTypeSub
class docRefTextTypeSub(supermod.docRefTextType):
def __init__(self, refid=None, kindref=None, external=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docRefTextType.__init__(self, mixedclass_, content_)
supermod.docRefTextType.subclass = docRefTextTypeSub
# end class docRefTextTypeSub
class docTableTypeSub(supermod.docTableType):
def __init__(self, rows=None, cols=None, row=None, caption=None):
supermod.docTableType.__init__(self, rows, cols, row, caption)
supermod.docTableType.subclass = docTableTypeSub
# end class docTableTypeSub
class docRowTypeSub(supermod.docRowType):
def __init__(self, entry=None):
supermod.docRowType.__init__(self, entry)
supermod.docRowType.subclass = docRowTypeSub
# end class docRowTypeSub
class docEntryTypeSub(supermod.docEntryType):
def __init__(self, thead=None, para=None):
supermod.docEntryType.__init__(self, thead, para)
supermod.docEntryType.subclass = docEntryTypeSub
# end class docEntryTypeSub
class docHeadingTypeSub(supermod.docHeadingType):
def __init__(self, level=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docHeadingType.__init__(self, mixedclass_, content_)
supermod.docHeadingType.subclass = docHeadingTypeSub
# end class docHeadingTypeSub
class docImageTypeSub(supermod.docImageType):
def __init__(self, width=None, type_=None, name=None, height=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docImageType.__init__(self, mixedclass_, content_)
supermod.docImageType.subclass = docImageTypeSub
# end class docImageTypeSub
class docDotFileTypeSub(supermod.docDotFileType):
def __init__(self, name=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docDotFileType.__init__(self, mixedclass_, content_)
supermod.docDotFileType.subclass = docDotFileTypeSub
# end class docDotFileTypeSub
class docTocItemTypeSub(supermod.docTocItemType):
def __init__(self, id=None, valueOf_='', mixedclass_=None, content_=None):
supermod.docTocItemType.__init__(self, mixedclass_, content_)
supermod.docTocItemType.subclass = docTocItemTypeSub
# end class docTocItemTypeSub
class docTocListTypeSub(supermod.docTocListType):
def __init__(self, tocitem=None):
supermod.docTocListType.__init__(self, tocitem)
supermod.docTocListType.subclass = docTocListTypeSub
# end class docTocListTypeSub
class docLanguageTypeSub(supermod.docLanguageType):
def __init__(self, langid=None, para=None):
supermod.docLanguageType.__init__(self, langid, para)
supermod.docLanguageType.subclass = docLanguageTypeSub
# end class docLanguageTypeSub
class docParamListTypeSub(supermod.docParamListType):
def __init__(self, kind=None, parameteritem=None):
supermod.docParamListType.__init__(self, kind, parameteritem)
supermod.docParamListType.subclass = docParamListTypeSub
# end class docParamListTypeSub
class docParamListItemSub(supermod.docParamListItem):
def __init__(self, parameternamelist=None, parameterdescription=None):
supermod.docParamListItem.__init__(self, parameternamelist, parameterdescription)
supermod.docParamListItem.subclass = docParamListItemSub
# end class docParamListItemSub
class docParamNameListSub(supermod.docParamNameList):
def __init__(self, parametername=None):
supermod.docParamNameList.__init__(self, parametername)
supermod.docParamNameList.subclass = docParamNameListSub
# end class docParamNameListSub
class docParamNameSub(supermod.docParamName):
def __init__(self, direction=None, ref=None, mixedclass_=None, content_=None):
supermod.docParamName.__init__(self, mixedclass_, content_)
supermod.docParamName.subclass = docParamNameSub
# end class docParamNameSub
class docXRefSectTypeSub(supermod.docXRefSectType):
def __init__(self, id=None, xreftitle=None, xrefdescription=None):
supermod.docXRefSectType.__init__(self, id, xreftitle, xrefdescription)
supermod.docXRefSectType.subclass = docXRefSectTypeSub
# end class docXRefSectTypeSub
class docCopyTypeSub(supermod.docCopyType):
def __init__(self, link=None, para=None, sect1=None, internal=None):
supermod.docCopyType.__init__(self, link, para, sect1, internal)
supermod.docCopyType.subclass = docCopyTypeSub
# end class docCopyTypeSub
class docCharTypeSub(supermod.docCharType):
def __init__(self, char=None, valueOf_=''):
supermod.docCharType.__init__(self, char)
supermod.docCharType.subclass = docCharTypeSub
# end class docCharTypeSub
class docParaTypeSub(supermod.docParaType):
def __init__(self, char=None, valueOf_=''):
supermod.docParaType.__init__(self, char)
self.parameterlist = []
self.simplesects = []
self.content = []
def buildChildren(self, child_, nodeName_):
supermod.docParaType.buildChildren(self, child_, nodeName_)
if child_.nodeType == Node.TEXT_NODE:
obj_ = self.mixedclass_(MixedContainer.CategoryText,
MixedContainer.TypeNone, '', child_.nodeValue)
self.content.append(obj_)
elif child_.nodeType == Node.ELEMENT_NODE and \
nodeName_ == "ref":
obj_ = supermod.docRefTextType.factory()
obj_.build(child_)
self.content.append(obj_)
elif child_.nodeType == Node.ELEMENT_NODE and \
nodeName_ == 'parameterlist':
obj_ = supermod.docParamListType.factory()
obj_.build(child_)
self.parameterlist.append(obj_)
elif child_.nodeType == Node.ELEMENT_NODE and \
nodeName_ == 'simplesect':
obj_ = supermod.docSimpleSectType.factory()
obj_.build(child_)
self.simplesects.append(obj_)
supermod.docParaType.subclass = docParaTypeSub
# end class docParaTypeSub
def parse(inFilename):
doc = minidom.parse(inFilename)
rootNode = doc.documentElement
rootObj = supermod.DoxygenType.factory()
rootObj.build(rootNode)
return rootObj
File diff suppressed because it is too large Load Diff
+77
View File
@@ -0,0 +1,77 @@
#!/usr/bin/env python
"""
Generated Mon Feb 9 19:08:05 2009 by generateDS.py.
"""
from xml.dom import minidom
import os
import sys
import compound
import indexsuper as supermod
class DoxygenTypeSub(supermod.DoxygenType):
def __init__(self, version=None, compound=None):
supermod.DoxygenType.__init__(self, version, compound)
def find_compounds_and_members(self, details):
"""
Returns a list of all compounds and their members which match details
"""
results = []
for compound in self.compound:
members = compound.find_members(details)
if members:
results.append([compound, members])
else:
if details.match(compound):
results.append([compound, []])
return results
supermod.DoxygenType.subclass = DoxygenTypeSub
# end class DoxygenTypeSub
class CompoundTypeSub(supermod.CompoundType):
def __init__(self, kind=None, refid=None, name='', member=None):
supermod.CompoundType.__init__(self, kind, refid, name, member)
def find_members(self, details):
"""
Returns a list of all members which match details
"""
results = []
for member in self.member:
if details.match(member):
results.append(member)
return results
supermod.CompoundType.subclass = CompoundTypeSub
# end class CompoundTypeSub
class MemberTypeSub(supermod.MemberType):
def __init__(self, kind=None, refid=None, name=''):
supermod.MemberType.__init__(self, kind, refid, name)
supermod.MemberType.subclass = MemberTypeSub
# end class MemberTypeSub
def parse(inFilename):
doc = minidom.parse(inFilename)
rootNode = doc.documentElement
rootObj = supermod.DoxygenType.factory()
rootObj.build(rootNode)
return rootObj
@@ -0,0 +1,523 @@
#!/usr/bin/env python
#
# Generated Thu Jun 11 18:43:54 2009 by generateDS.py.
#
import sys
import getopt
from string import lower as str_lower
from xml.dom import minidom
from xml.dom import Node
#
# User methods
#
# Calls to the methods in these classes are generated by generateDS.py.
# You can replace these methods by re-implementing the following class
# in a module named generatedssuper.py.
try:
from generatedssuper import GeneratedsSuper
except ImportError, exp:
class GeneratedsSuper:
def format_string(self, input_data, input_name=''):
return input_data
def format_integer(self, input_data, input_name=''):
return '%d' % input_data
def format_float(self, input_data, input_name=''):
return '%f' % input_data
def format_double(self, input_data, input_name=''):
return '%e' % input_data
def format_boolean(self, input_data, input_name=''):
return '%s' % input_data
#
# If you have installed IPython you can uncomment and use the following.
# IPython is available from http://ipython.scipy.org/.
#
## from IPython.Shell import IPShellEmbed
## args = ''
## ipshell = IPShellEmbed(args,
## banner = 'Dropping into IPython',
## exit_msg = 'Leaving Interpreter, back to program.')
# Then use the following line where and when you want to drop into the
# IPython shell:
# ipshell('<some message> -- Entering ipshell.\nHit Ctrl-D to exit')
#
# Globals
#
ExternalEncoding = 'ascii'
#
# Support/utility functions.
#
def showIndent(outfile, level):
for idx in range(level):
outfile.write(' ')
def quote_xml(inStr):
s1 = (isinstance(inStr, basestring) and inStr or
'%s' % inStr)
s1 = s1.replace('&', '&amp;')
s1 = s1.replace('<', '&lt;')
s1 = s1.replace('>', '&gt;')
return s1
def quote_attrib(inStr):
s1 = (isinstance(inStr, basestring) and inStr or
'%s' % inStr)
s1 = s1.replace('&', '&amp;')
s1 = s1.replace('<', '&lt;')
s1 = s1.replace('>', '&gt;')
if '"' in s1:
if "'" in s1:
s1 = '"%s"' % s1.replace('"', "&quot;")
else:
s1 = "'%s'" % s1
else:
s1 = '"%s"' % s1
return s1
def quote_python(inStr):
s1 = inStr
if s1.find("'") == -1:
if s1.find('\n') == -1:
return "'%s'" % s1
else:
return "'''%s'''" % s1
else:
if s1.find('"') != -1:
s1 = s1.replace('"', '\\"')
if s1.find('\n') == -1:
return '"%s"' % s1
else:
return '"""%s"""' % s1
class MixedContainer:
# Constants for category:
CategoryNone = 0
CategoryText = 1
CategorySimple = 2
CategoryComplex = 3
# Constants for content_type:
TypeNone = 0
TypeText = 1
TypeString = 2
TypeInteger = 3
TypeFloat = 4
TypeDecimal = 5
TypeDouble = 6
TypeBoolean = 7
def __init__(self, category, content_type, name, value):
self.category = category
self.content_type = content_type
self.name = name
self.value = value
def getCategory(self):
return self.category
def getContenttype(self, content_type):
return self.content_type
def getValue(self):
return self.value
def getName(self):
return self.name
def export(self, outfile, level, name, namespace):
if self.category == MixedContainer.CategoryText:
outfile.write(self.value)
elif self.category == MixedContainer.CategorySimple:
self.exportSimple(outfile, level, name)
else: # category == MixedContainer.CategoryComplex
self.value.export(outfile, level, namespace,name)
def exportSimple(self, outfile, level, name):
if self.content_type == MixedContainer.TypeString:
outfile.write('<%s>%s</%s>' % (self.name, self.value, self.name))
elif self.content_type == MixedContainer.TypeInteger or \
self.content_type == MixedContainer.TypeBoolean:
outfile.write('<%s>%d</%s>' % (self.name, self.value, self.name))
elif self.content_type == MixedContainer.TypeFloat or \
self.content_type == MixedContainer.TypeDecimal:
outfile.write('<%s>%f</%s>' % (self.name, self.value, self.name))
elif self.content_type == MixedContainer.TypeDouble:
outfile.write('<%s>%g</%s>' % (self.name, self.value, self.name))
def exportLiteral(self, outfile, level, name):
if self.category == MixedContainer.CategoryText:
showIndent(outfile, level)
outfile.write('MixedContainer(%d, %d, "%s", "%s"),\n' % \
(self.category, self.content_type, self.name, self.value))
elif self.category == MixedContainer.CategorySimple:
showIndent(outfile, level)
outfile.write('MixedContainer(%d, %d, "%s", "%s"),\n' % \
(self.category, self.content_type, self.name, self.value))
else: # category == MixedContainer.CategoryComplex
showIndent(outfile, level)
outfile.write('MixedContainer(%d, %d, "%s",\n' % \
(self.category, self.content_type, self.name,))
self.value.exportLiteral(outfile, level + 1)
showIndent(outfile, level)
outfile.write(')\n')
class _MemberSpec(object):
def __init__(self, name='', data_type='', container=0):
self.name = name
self.data_type = data_type
self.container = container
def set_name(self, name): self.name = name
def get_name(self): return self.name
def set_data_type(self, data_type): self.data_type = data_type
def get_data_type(self): return self.data_type
def set_container(self, container): self.container = container
def get_container(self): return self.container
#
# Data representation classes.
#
class DoxygenType(GeneratedsSuper):
subclass = None
superclass = None
def __init__(self, version=None, compound=None):
self.version = version
if compound is None:
self.compound = []
else:
self.compound = compound
def factory(*args_, **kwargs_):
if DoxygenType.subclass:
return DoxygenType.subclass(*args_, **kwargs_)
else:
return DoxygenType(*args_, **kwargs_)
factory = staticmethod(factory)
def get_compound(self): return self.compound
def set_compound(self, compound): self.compound = compound
def add_compound(self, value): self.compound.append(value)
def insert_compound(self, index, value): self.compound[index] = value
def get_version(self): return self.version
def set_version(self, version): self.version = version
def export(self, outfile, level, namespace_='', name_='DoxygenType', namespacedef_=''):
showIndent(outfile, level)
outfile.write('<%s%s %s' % (namespace_, name_, namespacedef_, ))
self.exportAttributes(outfile, level, namespace_, name_='DoxygenType')
if self.hasContent_():
outfile.write('>\n')
self.exportChildren(outfile, level + 1, namespace_, name_)
showIndent(outfile, level)
outfile.write('</%s%s>\n' % (namespace_, name_))
else:
outfile.write(' />\n')
def exportAttributes(self, outfile, level, namespace_='', name_='DoxygenType'):
outfile.write(' version=%s' % (self.format_string(quote_attrib(self.version).encode(ExternalEncoding), input_name='version'), ))
def exportChildren(self, outfile, level, namespace_='', name_='DoxygenType'):
for compound_ in self.compound:
compound_.export(outfile, level, namespace_, name_='compound')
def hasContent_(self):
if (
self.compound is not None
):
return True
else:
return False
def exportLiteral(self, outfile, level, name_='DoxygenType'):
level += 1
self.exportLiteralAttributes(outfile, level, name_)
if self.hasContent_():
self.exportLiteralChildren(outfile, level, name_)
def exportLiteralAttributes(self, outfile, level, name_):
if self.version is not None:
showIndent(outfile, level)
outfile.write('version = %s,\n' % (self.version,))
def exportLiteralChildren(self, outfile, level, name_):
showIndent(outfile, level)
outfile.write('compound=[\n')
level += 1
for compound in self.compound:
showIndent(outfile, level)
outfile.write('model_.compound(\n')
compound.exportLiteral(outfile, level, name_='compound')
showIndent(outfile, level)
outfile.write('),\n')
level -= 1
showIndent(outfile, level)
outfile.write('],\n')
def build(self, node_):
attrs = node_.attributes
self.buildAttributes(attrs)
for child_ in node_.childNodes:
nodeName_ = child_.nodeName.split(':')[-1]
self.buildChildren(child_, nodeName_)
def buildAttributes(self, attrs):
if attrs.get('version'):
self.version = attrs.get('version').value
def buildChildren(self, child_, nodeName_):
if child_.nodeType == Node.ELEMENT_NODE and \
nodeName_ == 'compound':
obj_ = CompoundType.factory()
obj_.build(child_)
self.compound.append(obj_)
# end class DoxygenType
class CompoundType(GeneratedsSuper):
subclass = None
superclass = None
def __init__(self, kind=None, refid=None, name=None, member=None):
self.kind = kind
self.refid = refid
self.name = name
if member is None:
self.member = []
else:
self.member = member
def factory(*args_, **kwargs_):
if CompoundType.subclass:
return CompoundType.subclass(*args_, **kwargs_)
else:
return CompoundType(*args_, **kwargs_)
factory = staticmethod(factory)
def get_name(self): return self.name
def set_name(self, name): self.name = name
def get_member(self): return self.member
def set_member(self, member): self.member = member
def add_member(self, value): self.member.append(value)
def insert_member(self, index, value): self.member[index] = value
def get_kind(self): return self.kind
def set_kind(self, kind): self.kind = kind
def get_refid(self): return self.refid
def set_refid(self, refid): self.refid = refid
def export(self, outfile, level, namespace_='', name_='CompoundType', namespacedef_=''):
showIndent(outfile, level)
outfile.write('<%s%s %s' % (namespace_, name_, namespacedef_, ))
self.exportAttributes(outfile, level, namespace_, name_='CompoundType')
if self.hasContent_():
outfile.write('>\n')
self.exportChildren(outfile, level + 1, namespace_, name_)
showIndent(outfile, level)
outfile.write('</%s%s>\n' % (namespace_, name_))
else:
outfile.write(' />\n')
def exportAttributes(self, outfile, level, namespace_='', name_='CompoundType'):
outfile.write(' kind=%s' % (quote_attrib(self.kind), ))
outfile.write(' refid=%s' % (self.format_string(quote_attrib(self.refid).encode(ExternalEncoding), input_name='refid'), ))
def exportChildren(self, outfile, level, namespace_='', name_='CompoundType'):
if self.name is not None:
showIndent(outfile, level)
outfile.write('<%sname>%s</%sname>\n' % (namespace_, self.format_string(quote_xml(self.name).encode(ExternalEncoding), input_name='name'), namespace_))
for member_ in self.member:
member_.export(outfile, level, namespace_, name_='member')
def hasContent_(self):
if (
self.name is not None or
self.member is not None
):
return True
else:
return False
def exportLiteral(self, outfile, level, name_='CompoundType'):
level += 1
self.exportLiteralAttributes(outfile, level, name_)
if self.hasContent_():
self.exportLiteralChildren(outfile, level, name_)
def exportLiteralAttributes(self, outfile, level, name_):
if self.kind is not None:
showIndent(outfile, level)
outfile.write('kind = "%s",\n' % (self.kind,))
if self.refid is not None:
showIndent(outfile, level)
outfile.write('refid = %s,\n' % (self.refid,))
def exportLiteralChildren(self, outfile, level, name_):
showIndent(outfile, level)
outfile.write('name=%s,\n' % quote_python(self.name).encode(ExternalEncoding))
showIndent(outfile, level)
outfile.write('member=[\n')
level += 1
for member in self.member:
showIndent(outfile, level)
outfile.write('model_.member(\n')
member.exportLiteral(outfile, level, name_='member')
showIndent(outfile, level)
outfile.write('),\n')
level -= 1
showIndent(outfile, level)
outfile.write('],\n')
def build(self, node_):
attrs = node_.attributes
self.buildAttributes(attrs)
for child_ in node_.childNodes:
nodeName_ = child_.nodeName.split(':')[-1]
self.buildChildren(child_, nodeName_)
def buildAttributes(self, attrs):
if attrs.get('kind'):
self.kind = attrs.get('kind').value
if attrs.get('refid'):
self.refid = attrs.get('refid').value
def buildChildren(self, child_, nodeName_):
if child_.nodeType == Node.ELEMENT_NODE and \
nodeName_ == 'name':
name_ = ''
for text__content_ in child_.childNodes:
name_ += text__content_.nodeValue
self.name = name_
elif child_.nodeType == Node.ELEMENT_NODE and \
nodeName_ == 'member':
obj_ = MemberType.factory()
obj_.build(child_)
self.member.append(obj_)
# end class CompoundType
class MemberType(GeneratedsSuper):
subclass = None
superclass = None
def __init__(self, kind=None, refid=None, name=None):
self.kind = kind
self.refid = refid
self.name = name
def factory(*args_, **kwargs_):
if MemberType.subclass:
return MemberType.subclass(*args_, **kwargs_)
else:
return MemberType(*args_, **kwargs_)
factory = staticmethod(factory)
def get_name(self): return self.name
def set_name(self, name): self.name = name
def get_kind(self): return self.kind
def set_kind(self, kind): self.kind = kind
def get_refid(self): return self.refid
def set_refid(self, refid): self.refid = refid
def export(self, outfile, level, namespace_='', name_='MemberType', namespacedef_=''):
showIndent(outfile, level)
outfile.write('<%s%s %s' % (namespace_, name_, namespacedef_, ))
self.exportAttributes(outfile, level, namespace_, name_='MemberType')
if self.hasContent_():
outfile.write('>\n')
self.exportChildren(outfile, level + 1, namespace_, name_)
showIndent(outfile, level)
outfile.write('</%s%s>\n' % (namespace_, name_))
else:
outfile.write(' />\n')
def exportAttributes(self, outfile, level, namespace_='', name_='MemberType'):
outfile.write(' kind=%s' % (quote_attrib(self.kind), ))
outfile.write(' refid=%s' % (self.format_string(quote_attrib(self.refid).encode(ExternalEncoding), input_name='refid'), ))
def exportChildren(self, outfile, level, namespace_='', name_='MemberType'):
if self.name is not None:
showIndent(outfile, level)
outfile.write('<%sname>%s</%sname>\n' % (namespace_, self.format_string(quote_xml(self.name).encode(ExternalEncoding), input_name='name'), namespace_))
def hasContent_(self):
if (
self.name is not None
):
return True
else:
return False
def exportLiteral(self, outfile, level, name_='MemberType'):
level += 1
self.exportLiteralAttributes(outfile, level, name_)
if self.hasContent_():
self.exportLiteralChildren(outfile, level, name_)
def exportLiteralAttributes(self, outfile, level, name_):
if self.kind is not None:
showIndent(outfile, level)
outfile.write('kind = "%s",\n' % (self.kind,))
if self.refid is not None:
showIndent(outfile, level)
outfile.write('refid = %s,\n' % (self.refid,))
def exportLiteralChildren(self, outfile, level, name_):
showIndent(outfile, level)
outfile.write('name=%s,\n' % quote_python(self.name).encode(ExternalEncoding))
def build(self, node_):
attrs = node_.attributes
self.buildAttributes(attrs)
for child_ in node_.childNodes:
nodeName_ = child_.nodeName.split(':')[-1]
self.buildChildren(child_, nodeName_)
def buildAttributes(self, attrs):
if attrs.get('kind'):
self.kind = attrs.get('kind').value
if attrs.get('refid'):
self.refid = attrs.get('refid').value
def buildChildren(self, child_, nodeName_):
if child_.nodeType == Node.ELEMENT_NODE and \
nodeName_ == 'name':
name_ = ''
for text__content_ in child_.childNodes:
name_ += text__content_.nodeValue
self.name = name_
# end class MemberType
USAGE_TEXT = """
Usage: python <Parser>.py [ -s ] <in_xml_file>
Options:
-s Use the SAX parser, not the minidom parser.
"""
def usage():
print USAGE_TEXT
sys.exit(1)
def parse(inFileName):
doc = minidom.parse(inFileName)
rootNode = doc.documentElement
rootObj = DoxygenType.factory()
rootObj.build(rootNode)
# Enable Python to collect the space used by the DOM.
doc = None
sys.stdout.write('<?xml version="1.0" ?>\n')
rootObj.export(sys.stdout, 0, name_="doxygenindex",
namespacedef_='')
return rootObj
def parseString(inString):
doc = minidom.parseString(inString)
rootNode = doc.documentElement
rootObj = DoxygenType.factory()
rootObj.build(rootNode)
# Enable Python to collect the space used by the DOM.
doc = None
sys.stdout.write('<?xml version="1.0" ?>\n')
rootObj.export(sys.stdout, 0, name_="doxygenindex",
namespacedef_='')
return rootObj
def parseLiteral(inFileName):
doc = minidom.parse(inFileName)
rootNode = doc.documentElement
rootObj = DoxygenType.factory()
rootObj.build(rootNode)
# Enable Python to collect the space used by the DOM.
doc = None
sys.stdout.write('from index import *\n\n')
sys.stdout.write('rootObj = doxygenindex(\n')
rootObj.exportLiteral(sys.stdout, 0, name_="doxygenindex")
sys.stdout.write(')\n')
return rootObj
def main():
args = sys.argv[1:]
if len(args) == 1:
parse(args[0])
else:
usage()
if __name__ == '__main__':
main()
#import pdb
#pdb.run('main()')
+16
View File
@@ -0,0 +1,16 @@
#!/bin/sh
# 1st parameter is absolute path to component source directory
# 2nd parameter is absolute path to component build directory
# 3rd parameter is path to Python QA directory
# Note: calling master run_tests.sh in gnuradio core is not strictly
# correct, as it will result in a partially bogus PYTHONPATH, but it
# does make the correct paths in the second half so all is well.
@PYTHON@ @srcdir@/__init__.py
# @top_builddir@/run_tests.sh \
# @abs_top_srcdir@/gnuradio-core \
# @abs_top_builddir@/gnuradio-core \
# @srcdir@
+56
View File
@@ -0,0 +1,56 @@
#
# Copyright 2010 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
Utilities for extracting text from generated classes.
"""
def is_string(txt):
if isinstance(txt, str):
return True
try:
if isinstance(txt, unicode):
return True
except NameError:
pass
return False
def description(obj):
if obj is None:
return None
return description_bit(obj).strip()
def description_bit(obj):
if hasattr(obj, 'content'):
contents = [description_bit(item) for item in obj.content]
result = ''.join(contents)
elif hasattr(obj, 'content_'):
contents = [description_bit(item) for item in obj.content_]
result = ''.join(contents)
elif hasattr(obj, 'value'):
result = description_bit(obj.value)
elif is_string(obj):
return obj
else:
raise StandardError('Expecting a string or something with content, content_ or value attribute')
# If this bit is a paragraph then add one some line breaks.
if hasattr(obj, 'name') and obj.name == 'para':
result += "\n\n"
return result
+7
View File
@@ -0,0 +1,7 @@
/*!
* \defgroup block GNU Radio HOWTO C++ Signal Processing Blocks
* \brief All C++ blocks that can be used from the HOWTO GNU Radio
* module are listed here or in the subcategories below.
*
*/
+10
View File
@@ -0,0 +1,10 @@
/*! \mainpage
Welcome to the GNU Radio HOWTO Block
This is the intro page for the Doxygen manual generated for the HOWTO
block (docs/doxygen/other/main_page.dox). Edit it to add more detailed
documentation about the new GNU Radio modules contained in this
project.
*/
+255
View File
@@ -0,0 +1,255 @@
#
# Copyright 2010,2011 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
# GNU Radio is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GNU Radio is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GNU Radio; see the file COPYING. If not, write to
# the Free Software Foundation, Inc., 51 Franklin Street,
# Boston, MA 02110-1301, USA.
#
"""
Creates the swig_doc.i SWIG interface file.
Execute using: python swig_doc.py xml_path outputfilename
The file instructs SWIG to transfer the doxygen comments into the
python docstrings.
"""
import sys
try:
from doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base
except ImportError:
from gnuradio.doxyxml import DoxyIndex, DoxyClass, DoxyFriend, DoxyFunction, DoxyFile, base
def py_name(name):
bits = name.split('_')
return '_'.join(bits[1:])
def make_name(name):
bits = name.split('_')
return bits[0] + '_make_' + '_'.join(bits[1:])
class Block(object):
"""
Checks if doxyxml produced objects correspond to a gnuradio block.
"""
@classmethod
def includes(cls, item):
if not isinstance(item, DoxyClass):
return False
# Check for a parsing error.
if item.error():
return False
return item.has_member(make_name(item.name()), DoxyFriend)
def utoascii(text):
"""
Convert unicode text into ascii and escape quotes.
"""
if text is None:
return ''
out = text.encode('ascii', 'replace')
out = out.replace('"', '\\"')
return out
def combine_descriptions(obj):
"""
Combines the brief and detailed descriptions of an object together.
"""
description = []
bd = obj.brief_description.strip()
dd = obj.detailed_description.strip()
if bd:
description.append(bd)
if dd:
description.append(dd)
return utoascii('\n\n'.join(description)).strip()
entry_templ = '%feature("docstring") {name} "{docstring}"'
def make_entry(obj, name=None, templ="{description}", description=None):
"""
Create a docstring entry for a swig interface file.
obj - a doxyxml object from which documentation will be extracted.
name - the name of the C object (defaults to obj.name())
templ - an optional template for the docstring containing only one
variable named 'description'.
description - if this optional variable is set then it's value is
used as the description instead of extracting it from obj.
"""
if name is None:
name=obj.name()
if "operator " in name:
return ''
if description is None:
description = combine_descriptions(obj)
docstring = templ.format(description=description)
if not docstring:
return ''
return entry_templ.format(
name=name,
docstring=docstring,
)
def make_func_entry(func, name=None, description=None, params=None):
"""
Create a function docstring entry for a swig interface file.
func - a doxyxml object from which documentation will be extracted.
name - the name of the C object (defaults to func.name())
description - if this optional variable is set then it's value is
used as the description instead of extracting it from func.
params - a parameter list that overrides using func.params.
"""
if params is None:
params = func.params
params = [prm.declname for prm in params]
if params:
sig = "Params: (%s)" % ", ".join(params)
else:
sig = "Params: (NONE)"
templ = "{description}\n\n" + sig
return make_entry(func, name=name, templ=utoascii(templ),
description=description)
def make_class_entry(klass, description=None):
"""
Create a class docstring for a swig interface file.
"""
output = []
output.append(make_entry(klass, description=description))
for func in klass.in_category(DoxyFunction):
name = klass.name() + '::' + func.name()
output.append(make_func_entry(func, name=name))
return "\n\n".join(output)
def make_block_entry(di, block):
"""
Create class and function docstrings of a gnuradio block for a
swig interface file.
"""
descriptions = []
# Get the documentation associated with the class.
class_desc = combine_descriptions(block)
if class_desc:
descriptions.append(class_desc)
# Get the documentation associated with the make function
make_func = di.get_member(make_name(block.name()), DoxyFunction)
make_func_desc = combine_descriptions(make_func)
if make_func_desc:
descriptions.append(make_func_desc)
# Get the documentation associated with the file
try:
block_file = di.get_member(block.name() + ".h", DoxyFile)
file_desc = combine_descriptions(block_file)
if file_desc:
descriptions.append(file_desc)
except base.Base.NoSuchMember:
# Don't worry if we can't find a matching file.
pass
# And join them all together to make a super duper description.
super_description = "\n\n".join(descriptions)
# Associate the combined description with the class and
# the make function.
output = []
output.append(make_class_entry(block, description=super_description))
creator = block.get_member(block.name(), DoxyFunction)
output.append(make_func_entry(make_func, description=super_description,
params=creator.params))
return "\n\n".join(output)
def make_swig_interface_file(di, swigdocfilename, custom_output=None):
output = ["""
/*
* This file was automatically generated using swig_doc.py.
*
* Any changes to it will be lost next time it is regenerated.
*/
"""]
if custom_output is not None:
output.append(custom_output)
# Create docstrings for the blocks.
blocks = di.in_category(Block)
make_funcs = set([])
for block in blocks:
try:
make_func = di.get_member(make_name(block.name()), DoxyFunction)
make_funcs.add(make_func.name())
output.append(make_block_entry(di, block))
except block.ParsingError:
print('Parsing error for block %s' % block.name())
# Create docstrings for functions
# Don't include the make functions since they have already been dealt with.
funcs = [f for f in di.in_category(DoxyFunction) if f.name() not in make_funcs]
for f in funcs:
try:
output.append(make_func_entry(f))
except f.ParsingError:
print('Parsing error for function %s' % f.name())
# Create docstrings for classes
block_names = [block.name() for block in blocks]
klasses = [k for k in di.in_category(DoxyClass) if k.name() not in block_names]
for k in klasses:
try:
output.append(make_class_entry(k))
except k.ParsingError:
print('Parsing error for class %s' % k.name())
# Docstrings are not created for anything that is not a function or a class.
# If this excludes anything important please add it here.
output = "\n\n".join(output)
swig_doc = file(swigdocfilename, 'w')
swig_doc.write(output)
swig_doc.close()
if __name__ == "__main__":
# Parse command line options and set up doxyxml.
err_msg = "Execute using: python swig_doc.py xml_path outputfilename"
if len(sys.argv) != 3:
raise StandardError(err_msg)
xml_path = sys.argv[1]
swigdocfilename = sys.argv[2]
di = DoxyIndex(xml_path)
# gnuradio.gr.msq_queue.insert_tail and delete_head create errors unless docstrings are defined!
# This is presumably a bug in SWIG.
#msg_q = di.get_member(u'gr_msg_queue', DoxyClass)
#insert_tail = msg_q.get_member(u'insert_tail', DoxyFunction)
#delete_head = msg_q.get_member(u'delete_head', DoxyFunction)
output = []
#output.append(make_func_entry(insert_tail, name='gr_py_msg_queue__insert_tail'))
#output.append(make_func_entry(delete_head, name='gr_py_msg_queue__delete_head'))
custom_output = "\n\n".join(output)
# Generate the docstrings interface file.
make_swig_interface_file(di, swigdocfilename, custom_output=custom_output)
+1895
View File
File diff suppressed because it is too large Load Diff
+10
View File
@@ -0,0 +1,10 @@
install(FILES
ieee802_11_ofdm_decode_mac.xml
ieee802_11_ofdm_decode_signal.xml
ieee802_11_ofdm_equalize_symbols.xml
ieee802_11_ofdm_parse_mac.xml
ieee802_11_ofdm_sync_long.xml
ieee802_11_ofdm_sync_short.xml
DESTINATION share/gnuradio/grc/blocks
)
+41
View File
@@ -0,0 +1,41 @@
<?xml version="1.0"?>
<block>
<name>OFDM Decode MAC</name>
<key>ieee802_1_ofdm_decode_mac</key>
<category>IEEE802.11</category>
<import>import gnuradio.ieee802_11 as gr_ieee802_11</import>
<make>gr_ieee802_11.ofdm_decode_mac($debug)</make>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<sink>
<name>in</name>
<type>complex</type>
<vlen>48</vlen>
<nports>1</nports>
</sink>
<source>
<name>out</name>
<type>message</type>
</source>
</block>
+42
View File
@@ -0,0 +1,42 @@
<?xml version="1.0"?>
<block>
<name>OFDM Decode Signal</name>
<key>ieee802_1_ofdm_decode_signal</key>
<category>IEEE802.11</category>
<import>import gnuradio.ieee802_11 as gr_ieee802_11</import>
<make>gr_ieee802_11.ofdm_decode_signal($debug)</make>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<sink>
<name>in</name>
<type>complex</type>
<vlen>48</vlen>
<nports>1</nports>
</sink>
<source>
<name>out</name>
<type>complex</type>
<vlen>48</vlen>
<nports>1</nports>
</source>
</block>
+41
View File
@@ -0,0 +1,41 @@
<?xml version="1.0"?>
<block>
<name>OFDM Equalize Symbols</name>
<key>ieee802_1_ofdm_equalize_symbols</key>
<category>IEEE802.11</category>
<import>import gnuradio.ieee802_11 as gr_ieee802_11</import>
<make>gr_ieee802_11.ofdm_equalize_symbols($debug)</make>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<sink>
<name>in</name>
<type>complex</type>
<vlen>64</vlen>
<nports>1</nports>
</sink>
<source>
<name>out</name>
<type>complex</type>
<vlen>48</vlen>
<nports>1</nports>
</source>
</block>
+36
View File
@@ -0,0 +1,36 @@
<?xml version="1.0"?>
<block>
<name>OFDM Parse MAC</name>
<key>ieee802_11_ofdm_parse_mac</key>
<category>IEEE802.11</category>
<import>import gnuradio.ieee802_11 as gr_ieee802_11</import>
<make>gr_ieee802_11.ofdm_parse_mac($debug)</make>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<sink>
<name>in</name>
<type>message</type>
</sink>
<source>
<name>out</name>
<type>message</type>
</source>
</block>
+61
View File
@@ -0,0 +1,61 @@
<?xml version="1.0"?>
<block>
<name>OFDM Sync Long</name>
<key>ieee802_1_ofdm_sync_long</key>
<category>IEEE802.11</category>
<import>import gnuradio.ieee802_11 as gr_ieee802_11</import>
<make>gr_ieee802_11.ofdm_sync_long($sync_length, $freq_est, $debug)</make>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>Sync Length</name>
<key>sync_length</key>
<value>240</value>
<type>int</type>
</param>
<param>
<name>Freq Est Samples</name>
<key>freq_est</key>
<value>100</value>
<type>int</type>
</param>
<check>$freq_est > 0</check>
<check>$sync_length > 0</check>
<sink>
<name>in</name>
<type>complex</type>
<nports>1</nports>
</sink>
<sink>
<name>in delayed</name>
<type>complex</type>
<nports>1</nports>
</sink>
<source>
<name>out</name>
<type>complex</type>
<nports>1</nports>
</source>
</block>
+69
View File
@@ -0,0 +1,69 @@
<?xml version="1.0"?>
<block>
<name>OFDM Sync Short</name>
<key>ieee802_1_ofdm_sync_short</key>
<category>IEEE802.11</category>
<import>import gnuradio.ieee802_11 as gr_ieee802_11</import>
<make>gr_ieee802_11.ofdm_sync_short($threshold, $max_samples, $min_plateau, $debug)</make>
<param>
<name>Debug</name>
<key>debug</key>
<value>False</value>
<type>bool</type>
<option>
<name>Enable</name>
<key>True</key>
</option>
<option>
<name>Disable</name>
<key>False</key>
</option>
</param>
<param>
<name>Threshold</name>
<key>threshold</key>
<value>0.8</value>
<type>real</type>
</param>
<param>
<name>Max Samples</name>
<key>max_samples</key>
<value>5200</value>
<type>int</type>
</param>
<param>
<name>Min Plateau</name>
<key>min_plateau</key>
<value>2</value>
<type>int</type>
</param>
<check>$threshold > 0</check>
<check>$max_samples > 400</check>
<check>$min_plateau > 0</check>
<sink>
<name>in</name>
<type>complex</type>
<nports>1</nports>
</sink>
<sink>
<name>cor</name>
<type>float</type>
<nports>1</nports>
</sink>
<source>
<name>out</name>
<type>complex</type>
<nports>1</nports>
</source>
</block>
+2
View File
@@ -0,0 +1,2 @@
add_subdirectory(ieee802_11)
@@ -0,0 +1,36 @@
#
# Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
########################################################################
# Install public header files
########################################################################
list(APPEND include_sources
api.h
ofdm_decode_mac.h
ofdm_decode_signal.h
ofdm_equalize_symbols.h
ofdm_parse_mac.h
ofdm_sync_long.h
ofdm_sync_short.h
)
install(
FILES ${include_sources}
DESTINATION ${GR_INCLUDE_DIR}/gnuradio/ieee802_11
COMPONENT "ieee802_11_devel"
)
+28
View File
@@ -0,0 +1,28 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_GR_IEEE802_11_API_H
#define INCLUDED_GR_IEEE802_11_API_H
#include <gruel/attributes.h>
#ifdef gnuradio_ieee802_11_EXPORTS
# define GR_IEEE802_11_API __GR_ATTR_EXPORT
#else
# define GR_IEEE802_11_API __GR_ATTR_IMPORT
#endif
#endif /* INCLUDED_GR_IEEE802_11_API_H */
@@ -0,0 +1,40 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_GR_IEEE802_11_OFDM_DECODE_MAC_H
#define INCLUDED_GR_IEEE802_11_OFDM_DECODE_MAC_H
#include <gnuradio/ieee802_11/api.h>
#include <gnuradio/gr_block.h>
namespace gr {
namespace ieee802_11 {
class GR_IEEE802_11_API ofdm_decode_mac : virtual public gr_block
{
public:
typedef boost::shared_ptr<ofdm_decode_mac> sptr;
static sptr make(bool debug = false);
};
} // namespace ieee802_11
} // namespace gr
#endif /* INCLUDED_GR_IEEE802_11_OFDM_DECODE_MAC_H */
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_GR_IEEE802_11_OFDM_DECODE_SIGNAL_H
#define INCLUDED_GR_IEEE802_11_OFDM_DECODE_SIGNAL_H
#include <gnuradio/ieee802_11/api.h>
#include <gnuradio/gr_block.h>
namespace gr {
namespace ieee802_11 {
class GR_IEEE802_11_API ofdm_decode_signal : virtual public gr_block
{
public:
typedef boost::shared_ptr<ofdm_decode_signal> sptr;
static sptr make(bool debug = false);
};
} // namespace ieee802_11
} // namespace gr
#endif /* INCLUDED_GR_IEEE802_11_OFDM_DECODE_SIGNAL_H */
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_GR_IEEE802_11_OFDM_EQUALIZE_SYMBOLS_H
#define INCLUDED_GR_IEEE802_11_OFDM_EQUALIZE_SYMBOLS_H
#include <gnuradio/ieee802_11/api.h>
#include <gnuradio/gr_block.h>
namespace gr {
namespace ieee802_11 {
class GR_IEEE802_11_API ofdm_equalize_symbols : virtual public gr_block
{
public:
typedef boost::shared_ptr<ofdm_equalize_symbols> sptr;
static sptr make(bool debug = false);
};
} // namespace ieee802_11
} // namespace gr
#endif /* INCLUDED_GR_IEEE802_11_OFDM_EQUALIZE_SYMBOLS_H*/
@@ -0,0 +1,38 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_GR_IEEE802_11_OFDM_PARSE_MAC_H
#define INCLUDED_GR_IEEE802_11_OFDM_PARSE_MAC_H
#include <gnuradio/ieee802_11/api.h>
#include <gnuradio/gr_block.h>
namespace gr {
namespace ieee802_11 {
class GR_IEEE802_11_API ofdm_parse_mac : virtual public gr_block
{
public:
typedef boost::shared_ptr<ofdm_parse_mac> sptr;
static sptr make(bool debug);
};
} // namespace ieee802_11
} // namespace gr
#endif /* INCLUDED_GR_IEEE802_11_OFDM_PARSE_MAC_H */
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_GR_IEEE802_11_OFDM_SYNC_LONG_H
#define INCLUDED_GR_IEEE802_11_OFDM_SYNC_LONG_H
#include <gnuradio/ieee802_11/api.h>
#include <gnuradio/gr_block.h>
namespace gr {
namespace ieee802_11 {
class GR_IEEE802_11_API ofdm_sync_long : virtual public gr_block
{
public:
typedef boost::shared_ptr<ofdm_sync_long> sptr;
static sptr make(unsigned int sync_length, unsigned int freq_est,
bool debug = false);
};
} // namespace ieee802_11
} // namespace gr
#endif /* INCLUDED_GR_IEEE802_11_OFDM_SYNC_LONG_H */
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_GR_IEEE802_11_OFDM_SYNC_SHORT_H
#define INCLUDED_GR_IEEE802_11_OFDM_SYNC_SHORT_H
#include <gnuradio/ieee802_11/api.h>
#include <gnuradio/gr_block.h>
namespace gr {
namespace ieee802_11 {
class GR_IEEE802_11_API ofdm_sync_short : virtual public gr_block
{
public:
typedef boost::shared_ptr<ofdm_sync_short> sptr;
static sptr make(double threshold, unsigned int max_samples,
unsigned int min_plateau, bool debug = false);
};
} // namespace ieee802_11
} // namespace gr
#endif /* INCLUDED_GR_IEEE802_11_OFDM_SYNC_SHORT_H */
+49
View File
@@ -0,0 +1,49 @@
#
# Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
########################################################################
# Setup library
########################################################################
include(GrPlatform) #define LIB_SUFFIX
list(APPEND gr_ieee802_11_sources
ofdm_decode_mac.cc
ofdm_decode_signal.cc
ofdm_equalize_symbols.cc
ofdm_parse_mac.cc
ofdm_sync_long.cc
ofdm_sync_short.cc
)
list(APPEND gr_ieee802_11_libs
${Boost_LIBRARIES}
${GRUEL_LIBRARIES}
${GNURADIO_CORE_LIBRARIES}
)
add_library(gnuradio-ieee802_11 SHARED ${gr_ieee802_11_sources})
target_link_libraries(gnuradio-ieee802_11 ${gr_ieee802_11_libs} itpp gnuradio-fft gnuradio-filter)
set_target_properties(gnuradio-ieee802_11 PROPERTIES DEFINE_SYMBOL "gnuradio_ieee802_11_EXPORTS")
########################################################################
# Install built library files
########################################################################
install(TARGETS gnuradio-ieee802_11
LIBRARY DESTINATION lib${LIB_SUFFIX} # .so/.dylib file
ARCHIVE DESTINATION lib${LIB_SUFFIX} # .lib file
RUNTIME DESTINATION bin # .dll file
)
+426
View File
@@ -0,0 +1,426 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gnuradio/ieee802_11/ofdm_decode_mac.h>
#include <gnuradio/gr_io_signature.h>
#include <itpp/itcomm.h>
#include <iostream>
#include <iomanip>
using namespace gr::ieee802_11;
using namespace itpp;
enum ENCODING {
BPSK_1_2,
BPSK_3_4,
QPSK_1_2,
QPSK_3_4,
QAM16_1_2,
QAM16_3_4,
QAM64_2_3,
QAM64_3_4,
};
/**
* OFDM parameters
*/
class GR_IEEE802_11_API ofdm_param {
public:
ofdm_param(ENCODING e) {
encoding = e;
switch(e) {
case BPSK_1_2:
n_bpsc = 1;
n_cbps = 48;
n_dbps = 24;
rate_field = 0x0D; // 0b00001101
break;
case BPSK_3_4:
n_bpsc = 1;
n_cbps = 48;
n_dbps = 36;
rate_field = 0x0F; // 0b00001111
break;
case QPSK_1_2:
n_bpsc = 2;
n_cbps = 96;
n_dbps = 48;
rate_field = 0x05; // 0b00000101
break;
case QPSK_3_4:
n_bpsc = 2;
n_cbps = 96;
n_dbps = 72;
rate_field = 0x07; // 0b00000111
break;
case QAM16_1_2:
n_bpsc = 4;
n_cbps = 192;
n_dbps = 96;
rate_field = 0x09; // 0b00001001
break;
case QAM16_3_4:
n_bpsc = 4;
n_cbps = 192;
n_dbps = 144;
rate_field = 0x0B; // 0b00001011
break;
case QAM64_2_3:
n_bpsc = 6;
n_cbps = 288;
n_dbps = 192;
rate_field = 0x01; // 0b00000001
break;
case QAM64_3_4:
n_bpsc = 6;
n_cbps = 288;
n_dbps = 216;
rate_field = 0x03; // 0b00000011
break;
defaut:
assert(false);
break;
}
}
void print_out() {
std::cout << "OFDM Parameters:" << std::endl;
std::cout << "endcoding :" << encoding << std::endl;
std::cout << "rate_field :" << (int)rate_field << std::endl;
std::cout << "n_bpsc :" << n_bpsc << std::endl;
std::cout << "n_cbps :" << n_cbps << std::endl;
std::cout << "n_dbps :" << n_dbps << std::endl;
}
// data rate
ENCODING encoding;
// rate field of the SIGNAL header
char rate_field;
// number of coded bits per sub carrier
int n_bpsc;
// number of coded bits per OFDM symbol
int n_cbps;
// number of data bits per OFDM symbol
int n_dbps;
};
/**
* packet specific parameters
*/
class tx_param {
public:
tx_param(ofdm_param &ofdm, int psdu_length) {
psdu_size = psdu_length;
// number of symbols (17-11)
n_sym = (int) ceil((16 + 8 * psdu_size + 6) / (double) ofdm.n_dbps);
// number of bits of the data field (17-12)
n_data = n_sym * ofdm.n_dbps;
// number of padding bits (17-13)
n_pad = n_data - (16 + 8 * psdu_size + 6);
n_encoded_bits = n_sym * ofdm.n_cbps;
}
// PSDU size in bytes
int psdu_size;
// number of OFDM symbols (17-11)
int n_sym;
// number of data bits in the DATA field, including service and padding (17-12)
int n_data;
// number of padding bits in the DATA field (17-13)
int n_pad;
int n_encoded_bits;
void print_out() {
std::cout << "TX Parameters:" << std::endl;
std::cout << "psdu_size: " << psdu_size << std::endl;
std::cout << "n_sym: " << n_sym << std::endl;
std::cout << "n_data: " << n_data << std::endl;
std::cout << "n_pad: " << n_pad << std::endl;
}
};
class ofdm_decode_mac_impl : public ofdm_decode_mac {
#define dout d_debug && std::cout
public:
ofdm_decode_mac_impl(bool debug) : gr_block("ofdm_decode_mac",
gr_make_io_signature(1, 1, 48 * sizeof(gr_complex)),
gr_make_io_signature(0, 0, 0)),
d_debug(debug),
ofdm(BPSK_1_2),
tx(ofdm, 0) {
message_port_register_out(pmt::mp("out"));
}
~ofdm_decode_mac_impl(){
}
int general_work (int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items) {
const gr_complex *in = (const gr_complex*)input_items[0];
int i = 0;
std::vector<gr_tag_t> tags;
const uint64_t nread = this->nitems_read(0);
dout << "Decode MAC: input " << ninput_items[0] << std::endl;
while(i < ninput_items[0]) {
get_tags_in_range(tags, 0, nread + i * 48, nread + (i + 1) * 48 - 1,
pmt::pmt_string_to_symbol("ofdm_start"));
if(tags.size()) {
pmt::pmt_t tuple = tags[0].value;
int len_data = pmt::pmt_to_uint64(pmt::pmt_car(tuple));
int encoding = pmt::pmt_to_uint64(pmt::pmt_cdr(tuple));
ofdm = ofdm_param((ENCODING)encoding);
tx = tx_param(ofdm, len_data);
if(tx.n_sym > 100) {
tx.n_sym = 100;
}
copied = 0;
dout << "Decode MAC: frame start -- len " << len_data
<< " symbols " << tx.n_sym << " encoding "
<< encoding << std::endl;
}
if(copied < tx.n_sym) {
std::memcpy(sym + (copied * 48), in, 48 * sizeof(gr_complex));
copied++;
if(copied == tx.n_sym) {
dout << "received complete frame - decoding" << std::endl;
decode();
break;
}
}
in += 48;
i++;
}
consume(0, i);
return 0;
}
void decode() {
if(ofdm.encoding > 3) {
return;
}
demodulate();
deinterleave();
decode_conv();
descramble();
print_output();
// skip service field
pmt::pmt_t blob = pmt::pmt_make_blob(out_bytes + 2, tx.psdu_size);
message_port_pub(pmt::mp("out"), blob);
}
void demodulate() {
gr_complex s;
for(int i = 0; i < tx.n_sym; i++) {
for(int n = 0; n < 48; n++) {
switch(ofdm.encoding) {
case 0: // BPSK
case 1:
bits[i * 48 + n] = -real(sym[i * 48 + n]);
break;
case 2: // QPSK
case 3:
s = sym[i * 48 + n];
bits[(i * 48 + n) * 2] = -real(s);
bits[(i * 48 + n) * 2 + 1] = -imag(s);
break;
case 4:
case 5:
case 6:
case 7:
default:
assert(false);
}
}
}
}
void deinterleave() {
int n_cbps = ofdm.n_cbps;
int first[n_cbps];
int second[n_cbps];
int s = std::max(ofdm.n_bpsc / 2, 1);
for(int j = 0; j < n_cbps; j++) {
first[j] = s * (j / s) + ((j + int(floor(16.0 * j / n_cbps))) % s);
}
for(int i = 0; i < n_cbps; i++) {
second[i] = 16 * i - (n_cbps - 1) * int(floor(16.0 * i / n_cbps));
}
for(int i = 0; i < tx.n_sym; i++) {
for(int k = 0; k < n_cbps; k++) {
deinter[i * n_cbps + second[first[k]]] = bits[i * n_cbps + k];
}
}
}
void decode_conv() {
Punctured_Convolutional_Code code;
ivec generator(2);
generator(0)=0133;
generator(1)=0171;
code.set_generator_polynomials(generator, 7);
bmat puncture_matrix;
switch(ofdm.encoding) {
case 0:
case 2:
puncture_matrix = "1 1; 1 1";
break;
case 1:
case 3:
puncture_matrix = "1 1 0; 1 0 1;";
break;
case 4:
case 5:
case 6:
case 7:
break;
default:
assert(false);
}
code.set_puncture_matrix(puncture_matrix);
code.set_truncation_length(30);
dout << "coding rate " << code.get_rate() << std::endl;
dout << tx.n_encoded_bits << std::endl;
vec rx_signal(deinter, tx.n_encoded_bits);
code.reset();
decoded_bits.set_length(tx.n_encoded_bits);
code.decode_tail(rx_signal, decoded_bits);
//dout << "length decoded " << decoded_bits.size() << std::endl;
//std::cout << decoded_bits << std::endl;
//
}
void descramble () {
int index = 0;
for(int i = 0; i < 7; i++) {
if(decoded_bits(i)) {
index |= 1 << (6 - i);
}
}
int state = scrambler_init[index];
int feedback;
for(int i = 0; i < decoded_bits.size(); i++) {
feedback = ((!!(state & 64))) ^ (!!(state & 8));
out_bits[i] = feedback ^ decoded_bits(i);
state = ((state << 1) & 0x7e) | feedback;
}
for(int i = 0; i < decoded_bits.size(); i++) {
int bit = i % 8;
int byte = i / 8;
if(bit == 0) {
out_bytes[byte] = 0;
}
if(out_bits[i]) {
out_bytes[byte] |= (1 << bit);
}
}
}
void print_output() {
dout << std::endl;
for(int i = 0; i < decoded_bits.size() / 8; i++) {
dout << std::setfill('0') << std::setw(2) << std::hex << ((unsigned int)out_bytes[i] & 0xFF) << std::dec << " ";
if(i % 16 == 15) {
dout << std::endl;
}
}
dout << std::endl;
for(int i = 0; i < decoded_bits.size() / 8; i++) {
if((out_bytes[i] > 31) && (out_bytes[i] < 127)) {
dout << ((char) out_bytes[i]);
} else {
dout << ".";
}
}
dout << std::endl;
}
private:
gr_complex sym[1000 * 48 * 100];
double bits[1000 * 48];
double deinter[1000 * 48];
char out_bits[40000];
char out_bytes[40000];
bvec decoded_bits;
bool d_debug;
tx_param tx;
ofdm_param ofdm;
int copied;
static int scrambler_init[128];
};
ofdm_decode_mac::sptr
ofdm_decode_mac::make(bool debug) {
return gnuradio::get_initial_sptr(new ofdm_decode_mac_impl(debug));
}
int ofdm_decode_mac_impl::scrambler_init[128] = {
0, 73, 18, 91, 36, 109, 54, 127, 72, 1, 90, 19, 108, 37, 126, 55, 89, 16, 75, 2, 125, 52, 111, 38, 17, 88, 3, 74, 53, 124, 39, 110, 50, 123, 32, 105, 22, 95, 4, 77, 122, 51, 104, 33, 94, 23, 76, 5, 107, 34, 121, 48, 79, 6, 93, 20, 35, 106, 49, 120, 7, 78, 21, 92, 100, 45, 118, 63, 64, 9, 82, 27, 44, 101, 62, 119, 8, 65, 26, 83, 61, 116, 47, 102, 25, 80, 11, 66, 117, 60, 103, 46, 81, 24, 67, 10, 86, 31, 68, 13, 114, 59, 96, 41, 30, 87, 12, 69, 58, 115, 40, 97, 15, 70, 29, 84, 43, 98, 57, 112, 71, 14, 85, 28, 99, 42, 113, 56};
+224
View File
@@ -0,0 +1,224 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gnuradio/ieee802_11/ofdm_decode_signal.h>
#include <gnuradio/gr_io_signature.h>
#include <iostream>
#include <itpp/itcomm.h>
using namespace gr::ieee802_11;
using namespace itpp;
class ofdm_decode_signal_impl : public ofdm_decode_signal {
#define dout d_debug && std::cout
public:
ofdm_decode_signal_impl(bool debug) : gr_block("ofdm_decode_signal",
gr_make_io_signature(1, 1, 48 * sizeof(gr_complex)),
gr_make_io_signature(1, 1, 48 * sizeof(gr_complex))),
d_debug(debug),
d_copy_symbols(0) {
decoded_bits.set_size(24);
set_relative_rate(1);
set_tag_propagation_policy(gr_block::TPP_DONT);
}
~ofdm_decode_signal_impl(){
}
int general_work (int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items) {
const gr_complex *in = (const gr_complex*)input_items[0];
gr_complex *out = (gr_complex*)output_items[0];
int i = 0;
int o = 0;
std::vector<gr_tag_t> tags;
const uint64_t nread = nitems_read(0);
dout << "Decode Signal: input " << ninput_items[0]
<< " output " << noutput_items << std::endl;
while((i < ninput_items[0]) && (o < noutput_items)) {
get_tags_in_range(tags, 0, nread + i * 48, nread + (i + 1) * 48 - 1,
pmt::pmt_string_to_symbol("ofdm_start"));
if(tags.size()) {
for(int n = 0; n < 48; n++) {
bits[n] = -real(in[n]);
}
deinterleave();
decode();
if(print_signal()) {
add_item_tag(0, nitems_written(0) + o * 48,
pmt::pmt_string_to_symbol("ofdm_start"),
pmt::pmt_cons(pmt::pmt_from_uint64(d_len),
pmt::pmt_from_uint64(d_encoding)),
pmt::pmt_string_to_symbol(name()));
}
} else if(d_copy_symbols) {
std::memcpy(out, in, 48 * sizeof(gr_complex));
o++;
out += 48;
d_copy_symbols--;
}
in += 48;
i++;
}
dout << "Decode Signal consumed " << i <<
" produced " << o << std::endl;
consume(0, i);
return o;
}
void deinterleave() {
double tmp[48];
for(int i = 0; i < 48; i++) {
tmp[i] = bits[inter[i]];
}
for(int i = 0; i < 48; i++) {
bits[i] = tmp[i];
}
for(int i = 0; i < 48; i++) {
dout << bits[i] << " ";
}
dout << std::endl;
}
void decode() {
Convolutional_Code code;
ivec generator(2);
generator(0)=0133;
generator(1)=0171;
code.set_generator_polynomials(generator, 7);
code.set_truncation_length(30);
vec rx_signal(bits, 48);
code.reset();
code.decode_tail(rx_signal, decoded_bits);
dout << "length rx " << rx_signal.size() << std::endl;
dout << rx_signal << std::endl;
dout << "length decoded " << decoded_bits.size() << std::endl;
dout << decoded_bits << std::endl;
}
bool print_signal() {
int r = 0;
d_len = 0;
bool parity = false;
for(int i = 0; i < 17; i++) {
parity ^= decoded_bits[i];
if((i < 4) && decoded_bits[i]) {
r = r | (1 << i);
}
if(decoded_bits[i] && (i > 4) && (i < 17)) {
d_len = d_len | (1 << (i-5));
}
}
if(parity != (bool)decoded_bits[17]) {
dout << "SIGNAL: wrong parity" << std::endl;
return false;
}
if(r == 11) {
d_encoding = 0;
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 24);
dout << "Encoding: 3 Mbit/s ";
} else if(r == 15) {
d_encoding = 1;
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 36);
dout << "Encoding: 4.5 Mbit/s ";
} else if(r == 10) {
d_encoding = 2;
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 48);
dout << "Encoding: 6 Mbit/s ";
} else if(r == 14) {
d_encoding = 3;
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 72);
dout << "Encoding: 9 Mbit/s ";
} else if(r == 9) {
d_encoding = 4;
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 96);
dout << "Encoding: 12 Mbit/s ";
} else if(r == 13) {
d_encoding = 5;
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 144);
dout << "Encoding: 18 Mbit/s ";
} else if(r == 8) {
d_encoding = 6;
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 192);
dout << "Encoding: 24 Mbit/s ";
} else if(r == 12) {
d_encoding = 7;
d_copy_symbols = (int) ceil((16 + 8 * d_len + 6) / (double) 216);
dout << "Encoding: 27 Mbit/s ";
} else {
dout << "unknown encoding" << std::endl;
return false;
}
if(d_copy_symbols > 57) {
d_copy_symbols = 0;
}
dout << "d_copy_symbols: " << d_copy_symbols << std::endl;
dout << "length: " << d_len << std::endl;
return true;
}
private:
int d_len;
int d_encoding;
bool d_debug;
double bits[48];
int d_copy_symbols;
bvec decoded_bits;
static int inter[48];
};
ofdm_decode_signal::sptr
ofdm_decode_signal::make(bool debug) {
return gnuradio::get_initial_sptr(new ofdm_decode_signal_impl(debug));
}
int ofdm_decode_signal_impl::inter[48]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,1,4,7,10,13,16,19,22,25,28,31,34,37,40,43,46,2,5,8,11,14,17,20,23,26,29,32,35,38,41,44,47};
+122
View File
@@ -0,0 +1,122 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gnuradio/ieee802_11/ofdm_equalize_symbols.h>
#include <gnuradio/gr_io_signature.h>
#include <iostream>
using namespace gr::ieee802_11;
class ofdm_equalize_symbols_impl : public ofdm_equalize_symbols {
#define dout d_debug && std::cout
public:
ofdm_equalize_symbols_impl(bool debug) : gr_block("ofdm_equalize_symbols",
gr_make_io_signature(1, 1, 64 * sizeof(gr_complex)),
gr_make_io_signature(1, 1, 48 * sizeof(gr_complex))),
d_debug(debug) {
set_relative_rate(1);
}
~ofdm_equalize_symbols_impl(){
}
int general_work (int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items) {
const gr_complex *in = (const gr_complex*)input_items[0];
gr_complex *out = (gr_complex*)output_items[0];
int noutput = noutput_items;
int i = 0;
std::vector<gr_tag_t> tags;
const uint64_t nread = nitems_read(0);
dout << "SYMBOLS: input " << ninput_items[0] << " output " << noutput_items << std::endl;
while((i < ninput_items[0]) && (i < noutput)) {
get_tags_in_range(tags, 0, nread + i * 64, nread + (i + 1) * 64 - 1,
pmt::pmt_string_to_symbol("ofdm_start"));
if(tags.size()) {
index = 0;
}
gr_complex p = POLARITY[index];
index++;
double p1 = arg( p * in[11]);
double p2 = arg( p * in[25] * conj(p * in[11])) + p1;
double p3 = arg( p * in[39] * conj(p * in[25])) + p2;
double p4 = arg(-p * in[53] * conj(p * in[39])) + p3;
double my = (p1 + p2 + p3 + p4) / 4;
double mx = (11.0 + 25 + 39 + 53) / 4;
double var = (((11.0 * 11.0) + (25.0 * 25.0) + (39.0 * 39.0) + (53.0 * 53.0)) / 4) - (mx * mx);
double cov = (( (p1 * 11) + (p2 * 25) + (p3 * 39) + (p4 * 53) ) / 4) - (mx * my);
double beta = cov / var;
double alpha = my - beta * mx;
int o = 0;
for(int n = 0; n < 64; n++) {
if( (n == 11) || (n == 25) || (n == 32) || (n == 39) || (n == 53) || (n < 6) || ( n > 58)) {
continue;
} else {
out[o] = in[n] * exp(gr_complex(0, -n * beta - alpha));
o++;
}
}
i++;
in += 64;
out += 48;
}
dout << "SYMBOLS: produced / consumed " << i << std::endl;
consume(0, i);
return i;
}
private:
int index;
const bool d_debug;
static const gr_complex POLARITY[127];
};
const gr_complex ofdm_equalize_symbols_impl::POLARITY[127] = {
1, 1, 1, 1,-1,-1,-1, 1,-1,-1,-1,-1, 1, 1,-1, 1,
-1,-1, 1, 1,-1, 1, 1,-1, 1, 1, 1, 1, 1, 1,-1, 1,
1, 1,-1, 1, 1,-1,-1, 1, 1, 1,-1, 1,-1,-1,-1, 1,
-1, 1,-1,-1, 1,-1,-1, 1, 1, 1, 1, 1,-1,-1, 1, 1,
-1,-1, 1,-1, 1,-1, 1, 1,-1,-1,-1, 1, 1,-1,-1,-1,
-1, 1,-1,-1, 1,-1, 1, 1, 1, 1,-1, 1,-1, 1,-1, 1,
-1,-1,-1,-1,-1, 1,-1, 1, 1,-1, 1,-1, 1, 1, 1,-1,
-1, 1,-1,-1,-1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1 };
ofdm_equalize_symbols::sptr
ofdm_equalize_symbols::make(bool debug) {
return gnuradio::get_initial_sptr(new ofdm_equalize_symbols_impl(debug));
}
+407
View File
@@ -0,0 +1,407 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gnuradio/ieee802_11/ofdm_parse_mac.h>
#include "ofdm_parse_mac_impl.h"
#include <gr_io_signature.h>
#include <gr_block_detail.h>
#include <string>
using namespace gr::ieee802_11;
class ofdm_parse_mac_impl : public ofdm_parse_mac {
#define dout d_debug && std::cout
public:
ofdm_parse_mac_impl(bool debug) :
gr_block("ofdm_parse_mac",
gr_make_io_signature (0, 0, 0),
gr_make_io_signature (0, 0, 0)),
d_debug(debug) {
message_port_register_out(pmt::mp("out"));
message_port_register_in(pmt::mp("in"));
set_msg_handler(pmt::mp("in"), boost::bind(&ofdm_parse_mac_impl::parse, this, _1));
}
~ofdm_parse_mac_impl() {
}
unsigned int update_crc32(unsigned int crc, const char *data, size_t len) {
int j;
unsigned int byte, mask;
static unsigned int table[256];
/* Set up the table if necesary */
if (table[1] == 0) {
for (byte = 0; byte <= 255; byte++) {
crc = byte;
for (j = 7; j >= 0; j--) {
mask = -(crc & 1);
crc = (crc >> 1) ^ (0xEDB88320 & mask);
}
table[byte] = crc;
}
}
/* Calculate the CRC32*/
size_t i = 0;
crc = 0xFFFFFFFF;
for (i = 0; i < len; i++) {
byte = data[i]; //Get next byte
crc = (crc >> 8) ^ table[(crc ^ byte) & 0xFF];
}
unsigned int crc_reversed;
crc_reversed = 0x00000000;
for (j = 31; j >= 0; j--) {
crc_reversed |= ((crc >> j) & 1) << (31 - j);
}
return crc;
}
unsigned int crc32(const char *buf, int len) {
return update_crc32(0xffffffff, buf, len) ^ 0xffffffff;
}
void parse(pmt::pmt_t msg) {
if(pmt::pmt_is_eof_object(msg)) {
message_port_pub(pmt::mp("out"), pmt::PMT_EOF);
detail().get()->set_done(true);
return;
}
assert(pmt::pmt_is_blob(msg));
int data_len = pmt::pmt_blob_length(msg);
mac_header *h = (mac_header*)pmt::pmt_blob_data(msg);
dout << std::endl << "new mac frame (length " << data_len << ")" << std::endl;
dout << "=========================================" << std::endl;
if(data_len < 20) {
dout << "frame too short to parse (<20)" << std::endl;
return;
}
#define HEX(a) std::hex << std::setfill('0') << std::setw(2) << int(a) << std::dec
dout << "duration: " << HEX(h->duration >> 8) << " " << HEX(h->duration & 0xff) << std::endl;
dout << "frame control: " << HEX(h->frame_control >> 8) << " " << HEX(h->frame_control & 0xff);
switch((h->frame_control >> 2) & 3) {
case 0:
dout << " (MANAGEMENT)" << std::endl;
parse_management((char*)h, data_len);
break;
case 1:
dout << " (CONTROL)" << std::endl;
parse_control((char*)h, data_len);
break;
case 2:
dout << " (DATA)" << std::endl;
parse_data((char*)h, data_len);
break;
default:
dout << " (unknown)" << std::endl;
break;
}
bool crc = check_crc((char*)pmt::pmt_blob_data(msg), data_len);
dout << "crc ";
dout << (crc ? "correct" : "wrong") << std::endl;
if(!crc || data_len < 32) {
return;
}
char *frame = (char*)pmt::pmt_blob_data(msg);
frame[data_len - 4] = '\n';
// DATA
if((((h->frame_control) >> 2) & 63) == 2) {
print_ascii(frame + 24, data_len - 24 - 4);
pmt::pmt_t payload = pmt::pmt_make_blob(frame + 24, data_len - 24 - 3);
message_port_pub(pmt::mp("out"), pmt::pmt_cons(pmt::PMT_NIL, payload));
// QoS Data
} else if((((h->frame_control) >> 2) & 63) == 34) {
print_ascii(frame + 26, data_len - 26 - 4);
pmt::pmt_t payload = pmt::pmt_make_blob(frame + 26, data_len - 26 - 3);
message_port_pub(pmt::mp("out"), pmt::pmt_cons(pmt::PMT_NIL, payload));
}
}
void parse_management(char *buf, int length) {
mac_header* h = (mac_header*)buf;
if(length < 24) {
dout << "too short for a management frame" << std::endl;
return;
}
dout << "Subtype: ";
switch(((h->frame_control) >> 4) & 0xf) {
case 0:
dout << "Association Request";
break;
case 1:
dout << "Association Response";
break;
case 2:
dout << "Reassociation Request";
break;
case 3:
dout << "Reassociation Response";
break;
case 4:
dout << "Probe Request";
break;
case 5:
dout << "Probe Response";
break;
case 6:
dout << "Timing Advertisement";
break;
case 7:
dout << "Reserved";
break;
case 8:
dout << "Beacon" << std::endl;
if(length < 38) {
return;
}
{
uint8_t* len = (uint8_t*) (buf + 24 + 13);
if(length < 38 + *len) {
return;
}
std::string s(buf + 24 + 14, *len);
dout << "SSID: " << s;
}
break;
case 9:
dout << "ATIM";
break;
case 10:
dout << "Disassociation";
break;
case 11:
dout << "Authentication";
break;
case 12:
dout << "Deauthentication";
break;
case 13:
dout << "Action";
break;
case 14:
dout << "Action No ACK";
break;
case 15:
dout << "Reserved";
break;
default:
break;
}
dout << std::endl;
dout << "seq nr: " << int(h->seq_control >> 4) << std::endl;
dout << "mac 1: ";
print_mac_address(h->addr1, true);
dout << "mac 2: ";
print_mac_address(h->addr2, true);
dout << "mac 3: ";
print_mac_address(h->addr3, true);
}
void parse_data(char *buf, int length) {
mac_header* h = (mac_header*)buf;
if(length < 24) {
dout << "too short for a data frame" << std::endl;
return;
}
dout << "Subtype: ";
switch(((h->frame_control) >> 4) & 0xf) {
case 0:
dout << "Data";
break;
case 1:
dout << "Data + CF-ACK";
break;
case 2:
dout << "Data + CR-Poll";
break;
case 3:
dout << "Data + CF-ACK + CF-Poll";
break;
case 4:
dout << "Null";
break;
case 5:
dout << "CF-ACK";
break;
case 6:
dout << "CF-Poll";
break;
case 7:
dout << "CF-ACK + CF-Poll";
break;
case 8:
dout << "QoS Data";
break;
case 9:
dout << "QoS Data + CF-ACK";
break;
case 10:
dout << "QoS Data + CF-Poll";
break;
case 11:
dout << "QoS Data + CF-ACK + CF-Poll";
break;
case 12:
dout << "QoS Null";
break;
case 13:
dout << "Reserved";
break;
case 14:
dout << "QoS CF-Poll";
break;
case 15:
dout << "QoS CF-ACK + CF-Poll";
break;
default:
break;
}
dout << std::endl;
dout << "seq nr: " << int(h->seq_control >> 4) << std::endl;
dout << "mac 1: ";
print_mac_address(h->addr1, true);
dout << "mac 2: ";
print_mac_address(h->addr2, true);
dout << "mac 3: ";
print_mac_address(h->addr3, true);
}
void parse_control(char *buf, int length) {
mac_header* h = (mac_header*)buf;
dout << "Subtype: ";
switch(((h->frame_control) >> 4) & 0xf) {
case 7:
dout << "Control Wrapper";
break;
case 8:
dout << "Block ACK Requrest";
break;
case 9:
dout << "Block ACK";
break;
case 10:
dout << "PS Poll";
break;
case 11:
dout << "RTS";
break;
case 12:
dout << "CTS";
break;
case 13:
dout << "ACK";
break;
case 14:
dout << "CF-End";
break;
case 15:
dout << "CF-End + CF-ACK";
break;
default:
dout << "Reserved";
break;
}
dout << std::endl;
dout << "RA: ";
print_mac_address(h->addr1, true);
dout << "TA: ";
print_mac_address(h->addr2, true);
}
void print_mac_address(uint8_t *addr, bool new_line = false) {
if(!d_debug) {
return;
}
std::cout << std::setfill('0') << std::hex << std::setw(2);
for(int i = 0; i < 6; i++) {
std::cout << (int)addr[i];
if(i != 5) {
std::cout << ":";
}
}
std::cout << std::dec;
if(new_line) {
std::cout << std::endl;
}
}
void print_ascii(char* buf, int length) {
for(int i = 0; i < length; i++) {
if((buf[i] > 31) && (buf[i] < 127)) {
dout << buf[i];
} else {
dout << ".";
}
}
dout << std::endl;
}
bool check_crc(char *data, int len) {
unsigned int crc = crc32(data, len);
if(crc == 558161692) {
return true;
}
return false;
}
private:
bool d_debug;
};
ofdm_parse_mac::sptr
ofdm_parse_mac::make(bool debug) {
return gnuradio::get_initial_sptr(new ofdm_parse_mac_impl(debug));
}
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_GR_IEEE802_11_OFDM_PARSE_MAC_IMPL_H
#define INCLUDED_GR_IEEE802_11_OFDM_PARSE_MAC_IMPL_H
struct mac_header {
uint16_t frame_control;
uint16_t duration;
uint8_t addr1[6];
uint8_t addr2[6];
uint8_t addr3[6];
uint16_t seq_control;
}__attribute__((packed));
#endif /* INCLUDED_GR_IEEE802_11_OFDM_PARSE_MAC_IMPL_H */
+262
View File
@@ -0,0 +1,262 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gnuradio/ieee802_11/ofdm_sync_long.h>
#include <gnuradio/gr_io_signature.h>
#include <filter/fir_filter.h>
#include <fft/fft.h>
#include <list>
#include <tuple>
#include <iostream>
using namespace gr::ieee802_11;
class ofdm_sync_long_impl : public ofdm_sync_long {
#define dout d_debug && std::cout
public:
ofdm_sync_long_impl(unsigned int sync_lenght, unsigned int freq_est, bool debug) : gr_block("ofdm_sync_long",
gr_make_io_signature2(2, 2, sizeof(gr_complex), sizeof(gr_complex)),
gr_make_io_signature(1, 1, sizeof(gr_complex))),
d_debug(debug),
d_offset(0),
d_freq_est(0),
d_state(SYNC),
SYNC_LENGTH(sync_lenght),
FREQ_EST(freq_est) {
set_tag_propagation_policy(gr_block::TPP_DONT);
d_fir = new gr::filter::kernel::fir_filter_ccc(1, LONG);
d_correlation = gr::fft::malloc_complex(8192);
}
~ofdm_sync_long_impl(){
delete d_fir;
gr::fft::free(d_correlation);
}
int general_work (int noutput, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items) {
const gr_complex *in = (const gr_complex*)input_items[0];
const gr_complex *in_delayed = (const gr_complex*)input_items[1];
gr_complex *out = (gr_complex*)output_items[0];
dout << "LONG ninput[0] " << ninput_items[0] << " ninput[1] " <<
ninput_items[1] << " noutput " << noutput <<
" state " << d_state << std::endl;
int ninput = std::min(ninput_items[0], ninput_items[1]);
const unsigned int nread = nitems_read(0);
get_tags_in_range(d_tags, 0, nread, nread + ninput);
if (d_tags.size()) {
std::sort(d_tags.begin(), d_tags.end(), gr_tag_t::offset_compare);
const gr_tag_t &tag = d_tags.front();
const uint64_t offset = tag.offset;
if(offset > nread) {
ninput = offset - nread;
} else {
if(d_state == COPY) {
d_state = RESET;
}
}
}
int i = 0;
int o = 0;
switch(d_state) {
case SYNC:
d_fir->filterN(d_correlation, in, std::min(SYNC_LENGTH, std::max(ninput - 63, 0)));
while(i + 63 < ninput) {
if(d_offset < FREQ_EST) {
d_freq_est += in[i] * conj(in[i + 16]);
}
d_cor.push_back(std::tuple<double, int>(abs(d_correlation[i]), d_offset));
i++;
d_offset++;
if(d_offset == SYNC_LENGTH) {
search_frame_start();
d_offset = 0;
d_state = COPY;
break;
}
}
break;
case COPY:
while(i < ninput) {
int rel = d_offset - d_frame_start;
if( (rel >= 0) && (rel % 80 > 15)) {
if(o >= noutput) {
break;
}
if(rel == 16) {
assert(o == 0);
add_item_tag(0, nitems_written(0) + o,
pmt::pmt_string_to_symbol("ofdm_start"),
pmt::PMT_T,
pmt::pmt_string_to_symbol(name()));
}
out[o] = in_delayed[i] * exp(gr_complex(0, d_offset * arg(d_freq_est) / 16));
o++;
}
i++;
d_offset++;
}
break;
case RESET:
while(o < noutput) {
int rel = (d_offset - d_frame_start) % 80;
if(!rel) {
d_offset = 0;
d_freq_est = gr_complex(0, 0);
d_state = SYNC;
break;
}
d_offset++;
out[o] = 0;
o++;
}
break;
default:
assert(false);
break;
}
dout << "produced : " << o << " consumed: " << i << std::endl;
consume(0, i);
consume(1, i);
return o;
}
void forecast (int noutput_items, gr_vector_int &ninput_items_required) {
if(d_state == SYNC) {
ninput_items_required[0] = 64;
ninput_items_required[1] = 64;
} else {
ninput_items_required[0] = noutput_items;
ninput_items_required[1] = noutput_items;
}
0 && dout << "LONG forecast noutput_items: " << noutput_items
<< " state: " << d_state
<< " req[0] " << ninput_items_required[0]
<< " req[1] " << ninput_items_required[1]
<< std::endl;
}
void search_frame_start() {
assert(d_cor.size() == SYNC_LENGTH);
d_cor.sort();
d_cor.reverse();
std::list<std::tuple<double, int>>::iterator it = d_cor.begin();
int m1 = std::get<1>(*it);
it++;
int m2 = std::get<1>(*it);
it++;
int m3 = std::get<1>(*it);
int m = std::max(m1, std::max(m2, m3));
d_frame_start = m + 64;
dout << "d_frame_start " << d_frame_start << std::endl;
dout << "peaks " << m1 << " " << m2 << " " << m3 << std::endl;
//for(it = d_cor.begin(); it != d_cor.end(); it++) {
//std::cout << std::get<0>(*it) << " " << std::get<1>(*it) << std::endl;
//}
d_cor.clear();
}
private:
enum {SYNC, COPY, RESET} d_state;
int d_offset;
int d_frame_start;
gr_complex d_freq_est;
gr_complex *d_correlation;
std::list<std::tuple<double, int>> d_cor;
std::vector<gr_tag_t> d_tags;
gr::filter::kernel::fir_filter_ccc *d_fir;
const bool d_debug;
const int SYNC_LENGTH;
const int FREQ_EST;
static const std::vector<gr_complex> LONG;
};
ofdm_sync_long::sptr
ofdm_sync_long::make(unsigned int sync_length, unsigned int freq_est, bool debug) {
return gnuradio::get_initial_sptr(new ofdm_sync_long_impl(sync_length, freq_est, debug));
}
const std::vector<gr_complex> ofdm_sync_long_impl::LONG = {
gr_complex( -0.04097-0.9626011), gr_complex( 0.3179976-0.8892635), gr_complex( 0.7746551+0.6623833),
gr_complex( 0.1688942+0.2230874), gr_complex( 0.4785908-0.7016541), gr_complex( -0.9210497-0.441444),
gr_complex( -0.3065277-0.8493673), gr_complex( 0.7803301-0.2071068), gr_complex( 0.4267019+0.0326106),
gr_complex( 0.0079118-0.9200371), gr_complex( -1.094439-0.379038), gr_complex( 0.1958068-0.4682544),
gr_complex( 0.4693501-0.119512), gr_complex( -0.179866+1.285259), gr_complex( 0.9539127-0.0327648),
gr_complex( 0.5-0.5), gr_complex( 0.2953435+0.7867532), gr_complex( -0.4576508+0.3143887),
gr_complex( -1.050101+0.521818), gr_complex( 0.6577466+0.7388524), gr_complex( 0.5564548+0.1129757),
gr_complex( -0.4824808+0.650289), gr_complex( -0.451641-0.1744314), gr_complex( -0.28033-1.207107),
gr_complex( -0.9750961-0.1325297), gr_complex( -1.018595-0.164011), gr_complex( 0.6005896-0.5923234),
gr_complex( -0.0224476+0.4301941), gr_complex( -0.7351004+0.9210297), gr_complex( 0.7337324+0.8469733),
gr_complex( 0.0982767+0.7807964), gr_complex( -1.25+0), gr_complex( 0.0982767-0.7807964),
gr_complex( 0.7337324-0.8469733), gr_complex( -0.7351004-0.9210297), gr_complex( -0.0224476-0.4301941),
gr_complex( 0.6005896+0.5923234), gr_complex( -1.018595+0.164011), gr_complex( -0.9750961+0.1325297),
gr_complex( -0.28033+1.207107), gr_complex( -0.451641+0.1744314), gr_complex( -0.4824808-0.650289),
gr_complex( 0.5564548-0.1129757), gr_complex( 0.6577466-0.7388524), gr_complex( -1.050101-0.521818),
gr_complex( -0.4576508-0.3143887), gr_complex( 0.2953435-0.7867532), gr_complex( 0.5+0.5),
gr_complex( 0.9539127+0.0327648), gr_complex( -0.179866-1.285259), gr_complex( 0.4693501+0.119512),
gr_complex( 0.1958068+0.4682544), gr_complex( -1.094439+0.379038), gr_complex( 0.0079118+0.9200371),
gr_complex( 0.4267019-0.0326106), gr_complex( 0.7803301+0.2071068), gr_complex( -0.3065277+0.8493673),
gr_complex( -0.9210497+0.441444), gr_complex( 0.4785908+0.7016541), gr_complex( 0.1688942-0.2230874),
gr_complex( 0.7746551-0.6623833), gr_complex( 0.3179976+0.8892635), gr_complex( -0.04097+0.9626011),
gr_complex( 1.25+0)};
+134
View File
@@ -0,0 +1,134 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <gnuradio/ieee802_11/ofdm_sync_short.h>
#include <gnuradio/gr_io_signature.h>
#include <iostream>
using namespace gr::ieee802_11;
class ofdm_sync_short_impl : public ofdm_sync_short {
#define dout d_debug && std::cout
public:
ofdm_sync_short_impl(double threshold, unsigned int max_samples,
unsigned int min_plateau, bool debug) : gr_block("ofdm_sync_short",
gr_make_io_signature2(2, 2, sizeof(gr_complex), sizeof(float)),
gr_make_io_signature(1, 1, sizeof(gr_complex))),
d_debug(debug),
d_state(SEARCH),
d_plateau(0),
MAX_SAMPLES(max_samples),
MIN_PLATEAU(min_plateau),
d_threshold(threshold) {
set_tag_propagation_policy(gr_block::TPP_DONT);
}
~ofdm_sync_short_impl(){
}
int general_work (int noutput_items, gr_vector_int& ninput_items,
gr_vector_const_void_star& input_items,
gr_vector_void_star& output_items) {
const gr_complex *in = (const gr_complex*)input_items[0];
const float *in2 = (const float*)input_items[1];
gr_complex *out = (gr_complex*)output_items[0];
int noutput = noutput_items;
int ninput = std::min(ninput_items[0], ninput_items[1]);
// dout << "SHORT noutput : " << noutput << " ninput: " << ninput_items[0] << std::endl;
switch(d_state) {
case SEARCH: {
int i;
for(i = 0; i < ninput; i++) {
if(in2[i] > d_threshold) {
if(d_plateau < MIN_PLATEAU) {
d_plateau++;
} else {
d_state = COPY;
d_copy_left = MAX_SAMPLES;
d_plateau = 0;
insert_tag(nitems_written(0));
dout << "SHORT Frame!" << std::endl;
break;
}
} else {
d_plateau = 0;
}
}
consume(0, i);
consume(1, i);
return 0;
}
case COPY: {
int to_copy = std::min(d_copy_left, std::min(noutput, ninput));
std::memcpy(out, in, to_copy * sizeof(gr_complex));
d_copy_left -= to_copy;
if(!d_copy_left) {
d_state = SEARCH;
}
dout << "SHORT copied " << to_copy << std::endl;
consume(0, to_copy);
consume(1, to_copy);
return to_copy;
}
}
throw std::runtime_error("sync short: unknown state");
return 0;
}
void insert_tag(uint64_t item) {
dout << "SYNC SHORT: insert ofdm_start at: " << item << std::endl;
const pmt::pmt_t key = pmt::pmt_string_to_symbol("ofdm_start");
const pmt::pmt_t value = pmt::PMT_T;
const pmt::pmt_t srcid = pmt::pmt_string_to_symbol(name());
add_item_tag(0, item, key, value, srcid);
}
private:
enum {SEARCH, COPY} d_state;
int d_copy_left;
int d_plateau;
const double d_threshold;
const bool d_debug;
const unsigned int MAX_SAMPLES;
const unsigned int MIN_PLATEAU;
};
ofdm_sync_short::sptr
ofdm_sync_short::make(double threshold, unsigned int max_samples,
unsigned int min_plateau, bool debug) {
return gnuradio::get_initial_sptr(new ofdm_sync_short_impl(threshold,
max_samples, min_plateau, debug));
}
+40
View File
@@ -0,0 +1,40 @@
#
# Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
########################################################################
# Setup python install
########################################################################
include(GrPython)
list(APPEND python_sources
__init__.py
)
GR_PYTHON_INSTALL(
FILES ${python_sources}
DESTINATION ${GR_PYTHON_DIR}/gnuradio/ieee802_11
COMPONENT "ieee802_11_python"
)
########################################################################
# Handle the unit tests
########################################################################
include(GrTest)
#set(GR_TEST_TARGET_DEPS gnuradio-ieee802-15-4)
#set(GR_TEST_PYTHON_DIRS ${CMAKE_BINARY_DIR}/swig)
#GR_ADD_TEST(qa_howto ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/qa_howto.py)
+19
View File
@@ -0,0 +1,19 @@
#
# Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
from ieee802_11_swig import *
+79
View File
@@ -0,0 +1,79 @@
#
# Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
########################################################################
# Include swig generation macros
########################################################################
include(GrPython)
find_package(SWIG)
find_package(PythonLibs)
if(NOT SWIG_FOUND OR NOT PYTHONLIBS_FOUND)
return()
endif()
include(GrSwig)
########################################################################
# Setup swig generation
########################################################################
set(GR_SWIG_INCLUDE_DIRS
${GR_IEEE802_11_INCLUDE_DIRS}
${CMAKE_CURRENT_SOURCE_DIR}
)
foreach(incdir ${GNURADIO_CORE_INCLUDE_DIRS})
list(APPEND GR_SWIG_INCLUDE_DIRS ${incdir}/swig)
endforeach(incdir)
foreach(incdir ${GRUEL_INCLUDE_DIRS})
list(APPEND GR_SWIG_INCLUDE_DIRS ${incdir}/gruel/swig)
endforeach(incdir)
set(GR_SWIG_LIBRARIES gnuradio-ieee802_11)
set(GR_SWIG_DOC_FILE ${CMAKE_CURRENT_BINARY_DIR}/ieee802_11_swig_doc.i)
set(GR_SWIG_DOC_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/../include/gnuradio/ieee802_11)
GR_SWIG_MAKE(ieee802_11_swig ieee802_11_swig.i)
########################################################################
# Install the build swig module
########################################################################
GR_SWIG_INSTALL(
TARGETS ieee802_11_swig
DESTINATION ${GR_PYTHON_DIR}/gnuradio/ieee802_11
COMPONENT "ieee802_11_python"
)
########################################################################
# Install swig .i files for development
########################################################################
list(APPEND swig_sources
ieee802_11_swig.i
ieee802_11_factory.i
ieee802_11_ofdm_decode_mac.i
ieee802_11_ofdm_decode_signal.i
ieee802_11_ofdm_equalize_symbols.i
ieee802_11_ofdm_parse_mac.i
ieee802_11_ofdm_sync_long.i
ieee802_11_ofdm_sync_short.i
${CMAKE_CURRENT_BINARY_DIR}/ieee802_11_swig_doc.i
)
install(
FILES ${swig_sources}
DESTINATION ${GR_INCLUDE_DIR}/gnuradio/ieee802_11/swig
COMPONENT "ieee802_11_swig"
)
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
%define GR_IEEE802_11_BLOCK_MAGIC2(PKG, BASE_NAME)
%template(BASE_NAME ## _sptr) boost::shared_ptr<gr:: ## PKG ## :: ## BASE_NAME>;
%pythoncode %{
BASE_NAME ## _sptr.__repr__ = lambda self: "<gr_block %s (%d)>" % (self.name(), self.unique_id())
BASE_NAME = BASE_NAME.make;
%}
%enddef
+33
View File
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
########################################################################
# block headers
########################################################################
%{
#include <gnuradio/ieee802_11/ofdm_decode_mac.h>
%}
%include <gnuradio/ieee802_11/ofdm_decode_mac.h>
########################################################################
# block magic
########################################################################
using namespace gr::ieee802_11;
GR_IEEE802_11_BLOCK_MAGIC2(ieee802_11, ofdm_decode_mac)
+32
View File
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
########################################################################
# block headers
########################################################################
%{
#include <gnuradio/ieee802_11/ofdm_decode_signal.h>
%}
%include <gnuradio/ieee802_11/ofdm_decode_signal.h>
########################################################################
# block magic
########################################################################
using namespace gr::ieee802_11;
GR_IEEE802_11_BLOCK_MAGIC2(ieee802_11, ofdm_decode_signal)
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
########################################################################
# block headers
########################################################################
%{
#include <gnuradio/ieee802_11/ofdm_equalize_symbols.h>
%}
%include <gnuradio/ieee802_11/ofdm_equalize_symbols.h>
########################################################################
# block magic
########################################################################
using namespace gr::ieee802_11;
GR_IEEE802_11_BLOCK_MAGIC2(ieee802_11, ofdm_equalize_symbols)
+31
View File
@@ -0,0 +1,31 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
########################################################################
# block headers
########################################################################
%{
#include <gnuradio/ieee802_11/ofdm_parse_mac.h>
%}
%include <gnuradio/ieee802_11/ofdm_parse_mac.h>
########################################################################
# block magic
########################################################################
using namespace gr::ieee802_11;
GR_IEEE802_11_BLOCK_MAGIC2(ieee802_11, ofdm_parse_mac)
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
########################################################################
# block headers
########################################################################
%{
#include <gnuradio/ieee802_11/ofdm_sync_long.h>
%}
%include <gnuradio/ieee802_11/ofdm_sync_long.h>
########################################################################
# block magic
########################################################################
using namespace gr::ieee802_11;
GR_IEEE802_11_BLOCK_MAGIC2(ieee802_11, ofdm_sync_long)
+30
View File
@@ -0,0 +1,30 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
########################################################################
# block headers
########################################################################
%{
#include <gnuradio/ieee802_11/ofdm_sync_short.h>
%}
%include <gnuradio/ieee802_11/ofdm_sync_short.h>
########################################################################
# block magic
########################################################################
using namespace gr::ieee802_11;
GR_IEEE802_11_BLOCK_MAGIC2(ieee802_11, ofdm_sync_short)
+33
View File
@@ -0,0 +1,33 @@
/*
* Copyright (C) 2013 Bastian Bloessl <bloessl@ccs-labs.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define GR_IEEE802_11_API
########################################################################
# standard includes
########################################################################
%include <gnuradio.i>
%include "ieee802_11_factory.i"
########################################################################
# block includes
########################################################################
%include <ieee802_11_ofdm_decode_mac.i>
%include <ieee802_11_ofdm_decode_signal.i>
%include <ieee802_11_ofdm_equalize_symbols.i>
%include <ieee802_11_ofdm_parse_mac.i>
%include <ieee802_11_ofdm_sync_long.i>
%include <ieee802_11_ofdm_sync_short.i>
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
IFACE=wlan0
### check for command line arguments
if [[ $# -eq 1 ]]
then
IFACE=$1
elif [[ $# != "0" ]]
then
echo "too much command line arguments!"
exit
fi
echo "setting interface >>${IFACE}<< to managed mode"
sudo ifconfig ${IFACE} down
sudo iwconfig ${IFACE} mode managed
sudo ifconfig ${IFACE} up
sudo service network-manager start
+29
View File
@@ -0,0 +1,29 @@
#!/bin/bash
IFACE=wlan0
CHANNEL=3
### check for command line arguments
if [[ $# -eq 2 ]]
then
CHANNEL=$1
IFACE=$2
elif [[ $# -eq 1 ]]
then
CHANNEL=$1
elif [[ $# != "0" ]]
then
echo "too much command line arguments!"
exit
fi
echo "setting interface >>${IFACE}<< to monitor channel >>${CHANNEL}<<"
sudo service network-manager stop
sudo ifconfig ${IFACE} down
sudo iwconfig ${IFACE} mode monitor
sudo iwconfig ${IFACE} channel ${CHANNEL}
sudo ifconfig ${IFACE} up
+16
View File
@@ -0,0 +1,16 @@
packetspammer: packetspammer.c
gcc -Wall radiotap.c packetspammer.c -o packetspammer -lpcap
clean:
rm -f packetspammer *~
send: packetspammer
scp packetspammer root@192.168.0.60:/usr/local/bin
# scp packetspammer root@192.168.0.99:/usr/local/bin
install:
mkdir -p $(DESTDIR)/usr/bin
cp packetspammer $(DESTDIR)/usr/bin
style:
cstyle packetspammer.c radiotap.c
+34
View File
@@ -0,0 +1,34 @@
Packetspammer
Andy Green <andy@warmcat.com>
Packetspammer sends unencrypted broadcast packets down a mac80211 wireless
interface that should be set for Monitor mode. It spams the packets down the
interface as fast as it can, although you can specify a delay between packets.
At the same time it is listening for packets with a MAC of 13:22:33:44:xx:xx
and will display metadata about any incoming packets (like the bitrate) and
the packet contents. So if you run packetspammer on two nearby machines, they
will show each other's packets like this:
RX: Rate: 54.0Mbps, Freq: 2.417GHz, Ant: 0, Flags: 10
0000: 50 61 63 6B 65 74 73 70 61 6D 6D 65 72 20 2D 2D Packetspammer --
0010: 62 72 6F 61 64 63 61 73 74 20 70 61 63 6B 65 74 broadcast packet
0020: 23 34 37 39 31 36 20 2D 2D 20 3A 2D 44 20 2D 2D #47916 -- :-D --
0030: 75 6C 74 72 61 63 61 74 2E 68 6F 6D 65 2E 77 61 ultracat.home.wa
0040: 72 6D 63 61 74 2E 63 6F 6D rmcat.com
Typical usage:
echo -n mon0 > /sys/class/ieee80211/phy0/add_iface
iwconfig mon0 mode monitor
ifconfig mon0 up
packetspammer mon0
You may need to bring up your normal interface first and set its channel, eg
ifconfig wlan0 up
iwconfig wlan0 channel 2
If you normal interface is associated to an AP on a particular channel, that's
fine, the packet injection won't disturb the association.
+260
View File
@@ -0,0 +1,260 @@
/* $FreeBSD: src/sys/net80211/ieee80211_radiotap.h,v 1.5 2005/01/22 20:12:05 sam Exp $ */
/* $NetBSD: ieee80211_radiotap.h,v 1.11 2005/06/22 06:16:02 dyoung Exp $ */
/*-
* Copyright (c) 2003, 2004 David Young. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of David Young may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
* YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
/*
* Modifications to fit into the linux IEEE 802.11 stack,
* Mike Kershaw (dragorn@kismetwireless.net)
*/
#ifndef IEEE80211RADIOTAP_H
#define IEEE80211RADIOTAP_H
#include <linux/if_ether.h>
#include <linux/kernel.h>
/* Radiotap header version (from official NetBSD feed) */
#define IEEE80211RADIOTAP_VERSION "1.5"
/* Base version of the radiotap packet header data */
#define PKTHDR_RADIOTAP_VERSION 0
/* A generic radio capture format is desirable. There is one for
* Linux, but it is neither rigidly defined (there were not even
* units given for some fields) nor easily extensible.
*
* I suggest the following extensible radio capture format. It is
* based on a bitmap indicating which fields are present.
*
* I am trying to describe precisely what the application programmer
* should expect in the following, and for that reason I tell the
* units and origin of each measurement (where it applies), or else I
* use sufficiently weaselly language ("is a monotonically nondecreasing
* function of...") that I cannot set false expectations for lawyerly
* readers.
*/
/* XXX tcpdump/libpcap do not tolerate variable-length headers,
* yet, so we pad every radiotap header to 64 bytes. Ugh.
*/
#define IEEE80211_RADIOTAP_HDRLEN 64
/* The radio capture header precedes the 802.11 header.
* All data in the header is little endian on all platforms.
*/
struct ieee80211_radiotap_header {
u8 it_version; /* Version 0. Only increases
* for drastic changes,
* introduction of compatible
* new fields does not count.
*/
u8 it_pad;
__le16 it_len; /* length of the whole
* header in bytes, including
* it_version, it_pad,
* it_len, and data fields.
*/
__le32 it_present; /* A bitmap telling which
* fields are present. Set bit 31
* (0x80000000) to extend the
* bitmap by another 32 bits.
* Additional extensions are made
* by setting bit 31.
*/
};
#define IEEE80211_RADIOTAP_PRESENT_EXTEND_MASK 0x80000000
/* Name Data type Units
* ---- --------- -----
*
* IEEE80211_RADIOTAP_TSFT __le64 microseconds
*
* Value in microseconds of the MAC's 64-bit 802.11 Time
* Synchronization Function timer when the first bit of the
* MPDU arrived at the MAC. For received frames, only.
*
* IEEE80211_RADIOTAP_CHANNEL 2 x __le16 MHz, bitmap
*
* Tx/Rx frequency in MHz, followed by flags (see below).
*
* IEEE80211_RADIOTAP_FHSS __le16 see below
*
* For frequency-hopping radios, the hop set (first byte)
* and pattern (second byte).
*
* IEEE80211_RADIOTAP_RATE u8 500kb/s
*
* Tx/Rx data rate
*
* IEEE80211_RADIOTAP_DBM_ANTSIGNAL s8 decibels from
* one milliwatt (dBm)
*
* RF signal power at the antenna, decibel difference from
* one milliwatt.
*
* IEEE80211_RADIOTAP_DBM_ANTNOISE s8 decibels from
* one milliwatt (dBm)
*
* RF noise power at the antenna, decibel difference from one
* milliwatt.
*
* IEEE80211_RADIOTAP_DB_ANTSIGNAL u8 decibel (dB)
*
* RF signal power at the antenna, decibel difference from an
* arbitrary, fixed reference.
*
* IEEE80211_RADIOTAP_DB_ANTNOISE u8 decibel (dB)
*
* RF noise power at the antenna, decibel difference from an
* arbitrary, fixed reference point.
*
* IEEE80211_RADIOTAP_LOCK_QUALITY __le16 unitless
*
* Quality of Barker code lock. Unitless. Monotonically
* nondecreasing with "better" lock strength. Called "Signal
* Quality" in datasheets. (Is there a standard way to measure
* this?)
*
* IEEE80211_RADIOTAP_TX_ATTENUATION __le16 unitless
*
* Transmit power expressed as unitless distance from max
* power set at factory calibration. 0 is max power.
* Monotonically nondecreasing with lower power levels.
*
* IEEE80211_RADIOTAP_DB_TX_ATTENUATION __le16 decibels (dB)
*
* Transmit power expressed as decibel distance from max power
* set at factory calibration. 0 is max power. Monotonically
* nondecreasing with lower power levels.
*
* IEEE80211_RADIOTAP_DBM_TX_POWER s8 decibels from
* one milliwatt (dBm)
*
* Transmit power expressed as dBm (decibels from a 1 milliwatt
* reference). This is the absolute power level measured at
* the antenna port.
*
* IEEE80211_RADIOTAP_FLAGS u8 bitmap
*
* Properties of transmitted and received frames. See flags
* defined below.
*
* IEEE80211_RADIOTAP_ANTENNA u8 antenna index
*
* Unitless indication of the Rx/Tx antenna for this packet.
* The first antenna is antenna 0.
*
* IEEE80211_RADIOTAP_RX_FLAGS __le16 bitmap
*
* Properties of received frames. See flags defined below.
*
* IEEE80211_RADIOTAP_TX_FLAGS __le16 bitmap
*
* Properties of transmitted frames. See flags defined below.
*
* IEEE80211_RADIOTAP_RTS_RETRIES u8 data
*
* Number of rts retries a transmitted frame used.
*
* IEEE80211_RADIOTAP_DATA_RETRIES u8 data
*
* Number of unicast retries a transmitted frame used.
*
*/
enum ieee80211_radiotap_type {
IEEE80211_RADIOTAP_TSFT = 0,
IEEE80211_RADIOTAP_FLAGS = 1,
IEEE80211_RADIOTAP_RATE = 2,
IEEE80211_RADIOTAP_CHANNEL = 3,
IEEE80211_RADIOTAP_FHSS = 4,
IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
IEEE80211_RADIOTAP_ANTENNA = 11,
IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
IEEE80211_RADIOTAP_RX_FLAGS = 14,
IEEE80211_RADIOTAP_TX_FLAGS = 15,
IEEE80211_RADIOTAP_RTS_RETRIES = 16,
IEEE80211_RADIOTAP_DATA_RETRIES = 17,
IEEE80211_RADIOTAP_EXT = 31
};
/* Channel flags. */
#define IEEE80211_CHAN_TURBO 0x0010 /* Turbo channel */
#define IEEE80211_CHAN_CCK 0x0020 /* CCK channel */
#define IEEE80211_CHAN_OFDM 0x0040 /* OFDM channel */
#define IEEE80211_CHAN_2GHZ 0x0080 /* 2 GHz spectrum channel. */
#define IEEE80211_CHAN_5GHZ 0x0100 /* 5 GHz spectrum channel */
#define IEEE80211_CHAN_PASSIVE 0x0200 /* Only passive scan allowed */
#define IEEE80211_CHAN_DYN 0x0400 /* Dynamic CCK-OFDM channel */
#define IEEE80211_CHAN_GFSK 0x0800 /* GFSK channel (FHSS PHY) */
/* For IEEE80211_RADIOTAP_FLAGS */
#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
* during CFP
*/
#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
* with short
* preamble
*/
#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
* with WEP encryption
*/
#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
* with fragmentation
*/
#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */
#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between
* 802.11 header and payload
* (to 32-bit boundary)
*/
/* For IEEE80211_RADIOTAP_RX_FLAGS */
#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */
/* For IEEE80211_RADIOTAP_TX_FLAGS */
#define IEEE80211_RADIOTAP_F_TX_FAIL 0x0001 /* failed due to excessive
* retries */
#define IEEE80211_RADIOTAP_F_TX_CTS 0x0002 /* used cts 'protection' */
#define IEEE80211_RADIOTAP_F_TX_RTS 0x0004 /* used rts/cts handshake */
/* Ugly macro to convert literal channel numbers into their mhz equivalents
* There are certianly some conditions that will break this (like feeding it '30')
* but they shouldn't arise since nothing talks on channel 30. */
#define ieee80211chan2mhz(x) \
(((x) <= 14) ? \
(((x) == 14) ? 2484 : ((x) * 5) + 2407) : \
((x) + 1000) * 5)
#endif /* IEEE80211_RADIOTAP_H */
+388
View File
@@ -0,0 +1,388 @@
// (c)2007 Andy Green <andy@warmcat.com>
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
// Thanks for contributions:
// 2007-03-15 fixes to getopt_long code by Matteo Croce rootkit85@yahoo.it
#include "packetspammer.h"
#include "radiotap.h"
/* wifi bitrate to use in 500kHz units */
static const u8 u8aRatesToUse[] = {
54*2,
48*2,
36*2,
24*2,
18*2,
12*2,
9*2,
11*2,
11, // 5.5
2*2,
1*2
};
/* this is the template radiotap header we send packets out with */
static const u8 u8aRadiotapHeader[] = {
0x00, 0x00, // <-- radiotap version
0x16, 0x00, // <- radiotap header length
0x0f, 0x00, 0x00, 0x00, // <-- bitmap
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // <-- timestamp
0x00, // <-- flags (Offset +0x10)
0x6c, // <-- rate (0ffset +0x11)
0x64, 0x14, 0x40, 0x01, // <-- channel
// 0x00, // <-- antsignal
// 0x00, // <-- antnoise
// 0x00, // <-- antenna
};
#define OFFSET_FLAGS 0x10
#define OFFSET_RATE 0x11
/* Penumbra IEEE80211 header */
static const u8 u8aIeeeHeader[] = {
0x08, 0x01, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
0x13, 0x22, 0x33, 0x44, 0x55, 0x66,
0x10, 0x86,
};
// this is where we store a summary of the
// information from the radiotap header
typedef struct {
int m_nChannel;
int m_nChannelFlags;
int m_nRate;
int m_nAntenna;
int m_nRadiotapFlags;
} __attribute__((packed)) PENUMBRA_RADIOTAP_DATA;
int flagHelp = 0, flagMarkWithFCS = 0;
void
Dump(u8 * pu8, int nLength)
{
char sz[256], szBuf[512], szChar[17], *buf, fFirst = 1;
unsigned char baaLast[2][16];
uint n, nPos = 0, nStart = 0, nLine = 0, nSameCount = 0;
buf = szBuf;
szChar[0] = '\0';
for (n = 0; n < nLength; n++) {
baaLast[(nLine&1)^1][n&0xf] = pu8[n];
if ((pu8[n] < 32) || (pu8[n] >= 0x7f))
szChar[n&0xf] = '.';
else
szChar[n&0xf] = pu8[n];
szChar[(n&0xf)+1] = '\0';
nPos += sprintf(&sz[nPos], "%02X ",
baaLast[(nLine&1)^1][n&0xf]);
if ((n&15) != 15)
continue;
if ((memcmp(baaLast[0], baaLast[1], 16) == 0) && (!fFirst)) {
nSameCount++;
} else {
if (nSameCount)
buf += sprintf(buf, "(repeated %d times)\n",
nSameCount);
buf += sprintf(buf, "%04x: %s %s\n",
nStart, sz, szChar);
nSameCount = 0;
printf("%s", szBuf);
buf = szBuf;
}
nPos = 0; nStart = n+1; nLine++;
fFirst = 0; sz[0] = '\0'; szChar[0] = '\0';
}
if (nSameCount)
buf += sprintf(buf, "(repeated %d times)\n", nSameCount);
buf += sprintf(buf, "%04x: %s", nStart, sz);
if (n & 0xf) {
*buf++ = ' ';
while (n & 0xf) {
buf += sprintf(buf, " ");
n++;
}
}
buf += sprintf(buf, "%s\n", szChar);
printf("%s", szBuf);
}
void
usage(void)
{
printf(
"(c)2006-2007 Andy Green <andy@warmcat.com> Licensed under GPL2\n"
"\n"
"Usage: packetspammer [options] <interface>\n\nOptions\n"
"-d/--delay <delay> Delay between packets\n\n"
"-f/--fcs Mark as having FCS (CRC) already\n"
" (pkt ends with 4 x sacrificial - chars)\n"
"Example:\n"
" echo -n mon0 > /sys/class/ieee80211/phy0/add_iface\n"
" iwconfig mon0 mode monitor\n"
" ifconfig mon0 up\n"
" packetspammer mon0 Spam down mon0 with\n"
" radiotap header first\n"
"\n");
exit(1);
}
int
main(int argc, char *argv[])
{
u8 u8aSendBuffer[500];
char szErrbuf[PCAP_ERRBUF_SIZE];
int nCaptureHeaderLength = 0, n80211HeaderLength = 0, nLinkEncap = 0;
int nOrdinal = 0, r, nDelay = 100000;
int nRateIndex = 0, retval, bytes;
pcap_t *ppcap = NULL;
struct bpf_program bpfprogram;
char * szProgram = "", fBrokenSocket = 0;
u16 u16HeaderLen;
char szHostname[PATH_MAX];
if (gethostname(szHostname, sizeof (szHostname) - 1)) {
perror("unable to get hostname");
}
szHostname[sizeof (szHostname) - 1] = '\0';
printf("Packetspammer (c)2007 Andy Green <andy@warmcat.com> GPL2\n");
while (1) {
int nOptionIndex;
static const struct option optiona[] = {
{ "delay", required_argument, NULL, 'd' },
{ "fcs", no_argument, &flagMarkWithFCS, 1 },
{ "help", no_argument, &flagHelp, 1 },
{ 0, 0, 0, 0 }
};
int c = getopt_long(argc, argv, "d:hf",
optiona, &nOptionIndex);
if (c == -1)
break;
switch (c) {
case 0: // long option
break;
case 'h': // help
usage();
case 'd': // delay
nDelay = atoi(optarg);
break;
case 'f': // mark as FCS attached
flagMarkWithFCS = 1;
break;
default:
printf("unknown switch %c\n", c);
usage();
break;
}
}
if (optind >= argc)
usage();
// open the interface in pcap
szErrbuf[0] = '\0';
ppcap = pcap_open_live(argv[optind], 800, 1, 20, szErrbuf);
if (ppcap == NULL) {
printf("Unable to open interface %s in pcap: %s\n",
argv[optind], szErrbuf);
return (1);
}
nLinkEncap = pcap_datalink(ppcap);
nCaptureHeaderLength = 0;
switch (nLinkEncap) {
case DLT_PRISM_HEADER:
printf("DLT_PRISM_HEADER Encap\n");
nCaptureHeaderLength = 0x40;
n80211HeaderLength = 0x20; // ieee80211 comes after this
szProgram = "radio[0x4a:4]==0x13223344";
break;
case DLT_IEEE802_11_RADIO:
printf("DLT_IEEE802_11_RADIO Encap\n");
nCaptureHeaderLength = 0x40;
n80211HeaderLength = 0x18; // ieee80211 comes after this
szProgram = "ether[0x0a:4]==0x13223344";
break;
default:
printf("!!! unknown encapsulation on %s !\n", argv[1]);
return (1);
}
if (pcap_compile(ppcap, &bpfprogram, szProgram, 1, 0) == -1) {
puts(szProgram);
puts(pcap_geterr(ppcap));
return (1);
} else {
if (pcap_setfilter(ppcap, &bpfprogram) == -1) {
puts(szProgram);
puts(pcap_geterr(ppcap));
} else {
printf("RX Filter applied\n");
}
pcap_freecode(&bpfprogram);
}
pcap_setnonblock(ppcap, 1, szErrbuf);
printf(" (delay between packets %dus)\n", nDelay);
memset(u8aSendBuffer, 0, sizeof (u8aSendBuffer));
while (!fBrokenSocket) {
u8 * pu8 = u8aSendBuffer;
struct pcap_pkthdr * ppcapPacketHeader = NULL;
struct ieee80211_radiotap_iterator rti;
PENUMBRA_RADIOTAP_DATA prd;
u8 * pu8Payload = u8aSendBuffer;
int n, nRate;
// receive
retval = pcap_next_ex(ppcap, &ppcapPacketHeader,
(const u_char**)&pu8Payload);
if (retval < 0) {
fBrokenSocket = 1;
continue;
}
if (retval != 1)
goto do_tx;
u16HeaderLen = (pu8Payload[2] + (pu8Payload[3] << 8));
printf("rtap: ");
Dump(pu8Payload, u16HeaderLen);
if (ppcapPacketHeader->len <
(u16HeaderLen + n80211HeaderLength))
continue;
bytes = ppcapPacketHeader->len -
(u16HeaderLen + n80211HeaderLength);
if (bytes < 0)
continue;
if (ieee80211_radiotap_iterator_init(&rti,
(struct ieee80211_radiotap_header *)pu8Payload,
bytes) < 0)
continue;
while ((n = ieee80211_radiotap_iterator_next(&rti)) == 0) {
switch (rti.this_arg_index) {
case IEEE80211_RADIOTAP_RATE:
prd.m_nRate = (*rti.this_arg);
break;
case IEEE80211_RADIOTAP_CHANNEL:
prd.m_nChannel =
le16_to_cpu(*((u16 *)rti.this_arg));
prd.m_nChannelFlags =
le16_to_cpu(*((u16 *)(rti.this_arg + 2)));
break;
case IEEE80211_RADIOTAP_ANTENNA:
prd.m_nAntenna = (*rti.this_arg) + 1;
break;
case IEEE80211_RADIOTAP_FLAGS:
prd.m_nRadiotapFlags = *rti.this_arg;
break;
}
}
pu8Payload += u16HeaderLen + n80211HeaderLength;
if (prd.m_nRadiotapFlags & IEEE80211_RADIOTAP_F_FCS)
bytes -= 4;
printf("RX: Rate: %2d.%dMbps, Freq: %d.%dGHz, "
"Ant: %d, Flags: 0x%X\n",
prd.m_nRate / 2, 5 * (prd.m_nRate & 1),
prd.m_nChannel / 1000,
prd.m_nChannel - ((prd.m_nChannel / 1000) * 1000),
prd.m_nAntenna,
prd.m_nRadiotapFlags);
Dump(pu8Payload, bytes);
do_tx:
// transmit
memcpy(u8aSendBuffer, u8aRadiotapHeader,
sizeof (u8aRadiotapHeader));
if (flagMarkWithFCS)
pu8[OFFSET_FLAGS] |= IEEE80211_RADIOTAP_F_FCS;
nRate = pu8[OFFSET_RATE] = u8aRatesToUse[nRateIndex++];
if (nRateIndex >= sizeof (u8aRatesToUse))
nRateIndex = 0;
pu8 += sizeof (u8aRadiotapHeader);
memcpy(pu8, u8aIeeeHeader, sizeof (u8aIeeeHeader));
pu8 += sizeof (u8aIeeeHeader);
pu8 += sprintf((char *)pu8,
"Packetspammer %02d"
"broadcast packet"
"#%05d -- :-D --%s ----",
nRate/2, nOrdinal++, szHostname);
r = pcap_inject(ppcap, u8aSendBuffer, pu8 - u8aSendBuffer);
if (r != (pu8-u8aSendBuffer)) {
perror("Trouble injecting packet");
return (1);
}
if (nDelay)
usleep(nDelay);
}
return (0);
}
+28
View File
@@ -0,0 +1,28 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <resolv.h>
#include <string.h>
#include <utime.h>
#include <unistd.h>
#include <getopt.h>
#include <pcap.h>
#include <endian.h>
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef u32 __le32;
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define le16_to_cpu(x) (x)
#define le32_to_cpu(x) (x)
#else
#define le16_to_cpu(x) ((((x)&0xff)<<8)|(((x)&0xff00)>>8))
#define le32_to_cpu(x) \
((((x)&0xff)<<24)|(((x)&0xff00)<<8)|(((x)&0xff0000)>>8)|(((x)&0xff000000)>>24))
#endif
#define unlikely(x) (x)
#define MAX_PENUMBRA_INTERFACES 8
+238
View File
@@ -0,0 +1,238 @@
/*
* Radiotap parser
*
* Copyright 2007 Andy Green <andy@warmcat.com>
*/
#include "packetspammer.h"
#include "radiotap.h"
/**
* ieee80211_radiotap_iterator_init - radiotap parser iterator initialization
* @iterator: radiotap_iterator to initialize
* @radiotap_header: radiotap header to parse
* @max_length: total length we can parse into (eg, whole packet length)
*
* Returns: 0 or a negative error code if there is a problem.
*
* This function initializes an opaque iterator struct which can then
* be passed to ieee80211_radiotap_iterator_next() to visit every radiotap
* argument which is present in the header. It knows about extended
* present headers and handles them.
*
* How to use:
* call __ieee80211_radiotap_iterator_init() to init a semi-opaque iterator
* struct ieee80211_radiotap_iterator (no need to init the struct beforehand)
* checking for a good 0 return code. Then loop calling
* __ieee80211_radiotap_iterator_next()... it returns either 0,
* -ENOENT if there are no more args to parse, or -EINVAL if there is a problem.
* The iterator's @this_arg member points to the start of the argument
* associated with the current argument index that is present, which can be
* found in the iterator's @this_arg_index member. This arg index corresponds
* to the IEEE80211_RADIOTAP_... defines.
*
* Radiotap header length:
* You can find the CPU-endian total radiotap header length in
* iterator->max_length after executing ieee80211_radiotap_iterator_init()
* successfully.
*
* Example code:
* See Documentation/networking/radiotap-headers.txt
*/
int ieee80211_radiotap_iterator_init(
struct ieee80211_radiotap_iterator *iterator,
struct ieee80211_radiotap_header *radiotap_header,
int max_length)
{
/* Linux only supports version 0 radiotap format */
if (radiotap_header->it_version)
return -EINVAL;
/* sanity check for allowed length and radiotap length field */
if (max_length < le16_to_cpu(radiotap_header->it_len))
return -EINVAL;
iterator->rtheader = radiotap_header;
iterator->max_length = le16_to_cpu(radiotap_header->it_len);
iterator->arg_index = 0;
iterator->bitmap_shifter = le32_to_cpu(radiotap_header->it_present);
iterator->arg = (u8 *)radiotap_header + sizeof(*radiotap_header);
iterator->this_arg = 0;
/* find payload start allowing for extended bitmap(s) */
if (unlikely(iterator->bitmap_shifter & (1<<IEEE80211_RADIOTAP_EXT))) {
while (le32_to_cpu(*((u32 *)iterator->arg)) &
(1<<IEEE80211_RADIOTAP_EXT)) {
iterator->arg += sizeof(u32);
/*
* check for insanity where the present bitmaps
* keep claiming to extend up to or even beyond the
* stated radiotap header length
*/
if (((ulong)iterator->arg -
(ulong)iterator->rtheader) > iterator->max_length)
return -EINVAL;
}
iterator->arg += sizeof(u32);
/*
* no need to check again for blowing past stated radiotap
* header length, because ieee80211_radiotap_iterator_next
* checks it before it is dereferenced
*/
}
/* we are all initialized happily */
return 0;
}
/**
* ieee80211_radiotap_iterator_next - return next radiotap parser iterator arg
* @iterator: radiotap_iterator to move to next arg (if any)
*
* Returns: 0 if there is an argument to handle,
* -ENOENT if there are no more args or -EINVAL
* if there is something else wrong.
*
* This function provides the next radiotap arg index (IEEE80211_RADIOTAP_*)
* in @this_arg_index and sets @this_arg to point to the
* payload for the field. It takes care of alignment handling and extended
* present fields. @this_arg can be changed by the caller (eg,
* incremented to move inside a compound argument like
* IEEE80211_RADIOTAP_CHANNEL). The args pointed to are in
* little-endian format whatever the endianess of your CPU.
*/
int ieee80211_radiotap_iterator_next(
struct ieee80211_radiotap_iterator *iterator)
{
/*
* small length lookup table for all radiotap types we heard of
* starting from b0 in the bitmap, so we can walk the payload
* area of the radiotap header
*
* There is a requirement to pad args, so that args
* of a given length must begin at a boundary of that length
* -- but note that compound args are allowed (eg, 2 x u16
* for IEEE80211_RADIOTAP_CHANNEL) so total arg length is not
* a reliable indicator of alignment requirement.
*
* upper nybble: content alignment for arg
* lower nybble: content length for arg
*/
static const u8 rt_sizes[] = {
[IEEE80211_RADIOTAP_TSFT] = 0x88,
[IEEE80211_RADIOTAP_FLAGS] = 0x11,
[IEEE80211_RADIOTAP_RATE] = 0x11,
[IEEE80211_RADIOTAP_CHANNEL] = 0x24,
[IEEE80211_RADIOTAP_FHSS] = 0x22,
[IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = 0x11,
[IEEE80211_RADIOTAP_DBM_ANTNOISE] = 0x11,
[IEEE80211_RADIOTAP_LOCK_QUALITY] = 0x22,
[IEEE80211_RADIOTAP_TX_ATTENUATION] = 0x22,
[IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = 0x22,
[IEEE80211_RADIOTAP_DBM_TX_POWER] = 0x11,
[IEEE80211_RADIOTAP_ANTENNA] = 0x11,
[IEEE80211_RADIOTAP_DB_ANTSIGNAL] = 0x11,
[IEEE80211_RADIOTAP_DB_ANTNOISE] = 0x11
/*
* add more here as they are defined in
* include/net/ieee80211_radiotap.h
*/
};
/*
* for every radiotap entry we can at
* least skip (by knowing the length)...
*/
while (iterator->arg_index < sizeof(rt_sizes)) {
int hit = 0;
int pad;
if (!(iterator->bitmap_shifter & 1))
goto next_entry; /* arg not present */
/*
* arg is present, account for alignment padding
* 8-bit args can be at any alignment
* 16-bit args must start on 16-bit boundary
* 32-bit args must start on 32-bit boundary
* 64-bit args must start on 64-bit boundary
*
* note that total arg size can differ from alignment of
* elements inside arg, so we use upper nybble of length
* table to base alignment on
*
* also note: these alignments are ** relative to the
* start of the radiotap header **. There is no guarantee
* that the radiotap header itself is aligned on any
* kind of boundary.
*/
pad = (((ulong)iterator->arg) -
((ulong)iterator->rtheader)) &
((rt_sizes[iterator->arg_index] >> 4) - 1);
if (pad)
iterator->arg_index +=
(rt_sizes[iterator->arg_index] >> 4) - pad;
/*
* this is what we will return to user, but we need to
* move on first so next call has something fresh to test
*/
iterator->this_arg_index = iterator->arg_index;
iterator->this_arg = iterator->arg;
hit = 1;
/* internally move on the size of this arg */
iterator->arg += rt_sizes[iterator->arg_index] & 0x0f;
/*
* check for insanity where we are given a bitmap that
* claims to have more arg content than the length of the
* radiotap section. We will normally end up equalling this
* max_length on the last arg, never exceeding it.
*/
if (((ulong)iterator->arg - (ulong)iterator->rtheader) >
iterator->max_length)
return -EINVAL;
next_entry:
iterator->arg_index++;
if (unlikely((iterator->arg_index & 31) == 0)) {
/* completed current u32 bitmap */
if (iterator->bitmap_shifter & 1) {
/* b31 was set, there is more */
/* move to next u32 bitmap */
iterator->bitmap_shifter =
le32_to_cpu(*iterator->next_bitmap);
iterator->next_bitmap++;
} else {
/* no more bitmaps: end */
iterator->arg_index = sizeof(rt_sizes);
}
} else { /* just try the next bit */
iterator->bitmap_shifter >>= 1;
}
/* if we found a valid arg earlier, return it now */
if (hit)
return 0;
}
/* we don't know how to handle any more args, we're done */
return -ENOENT;
}
+38
View File
@@ -0,0 +1,38 @@
#include "ieee80211_radiotap.h"
/* Radiotap header iteration
* implemented in net/wireless/radiotap.c
* docs in Documentation/networking/radiotap-headers.txt
*/
/**
* struct ieee80211_radiotap_iterator - tracks walk thru present radiotap args
* @rtheader: pointer to the radiotap header we are walking through
* @max_length: length of radiotap header in cpu byte ordering
* @this_arg_index: IEEE80211_RADIOTAP_... index of current arg
* @this_arg: pointer to current radiotap arg
* @arg_index: internal next argument index
* @arg: internal next argument pointer
* @next_bitmap: internal pointer to next present u32
* @bitmap_shifter: internal shifter for curr u32 bitmap, b0 set == arg present
*/
struct ieee80211_radiotap_iterator {
struct ieee80211_radiotap_header *rtheader;
int max_length;
int this_arg_index;
u8 *this_arg;
int arg_index;
u8 *arg;
__le32 *next_bitmap;
u32 bitmap_shifter;
};
extern int ieee80211_radiotap_iterator_init(
struct ieee80211_radiotap_iterator *iterator,
struct ieee80211_radiotap_header *radiotap_header,
int max_length);
extern int ieee80211_radiotap_iterator_next(
struct ieee80211_radiotap_iterator *iterator);