ajtcl-15.04b/000077500000000000000000000000001256742562600130015ustar00rootroot00000000000000ajtcl-15.04b/.gitignore000066400000000000000000000007431256742562600147750ustar00rootroot00000000000000TAGS LinuxTAGS tags cscope.out .sconsign.dblite *.pdb .*.swp .cproject *.ncb *.log *.suo *.aps *.user *.obj *.lib *.exe *.sln *.o *.d *.elf *.map *.os *.ilk *.dep *.creds *.a bin obj gen libs html latex build ajlite.nvram libajtcl.so ajtcl.dll whitespace.db *.pyc *.exp samples/basic/eventaction_service samples/network/net_bus samples/secure/SecureClientECDHE samples/secure/SecureServiceECDHE test/base64 test/certificate test/codisco test/nvramdump test/sessionslite test/sigtest ajtcl-15.04b/Doxyfile000066400000000000000000002072621256742562600145200ustar00rootroot00000000000000# Doxyfile 1.7.4 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = "AllJoyn™ Thin Client API Reference" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = "Version 15.04.00b" # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language # is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions # you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. EXTENSION_MAPPING = # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = YES #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = NO # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST = YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. The create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = ./inc/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is adviced to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = footer.html # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the stylesheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = NO # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the # mathjax.org site, so you can quickly see the result without installing # MathJax, but it is strongly recommended to install a local copy of MathJax # before deployment. MATHJAX_RELPATH = http://www.mathjax.org/mathjax # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client # using Javascript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvantages are that it is more difficult to setup # and does not have live searching capabilities. SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will write a font called Helvetica to the output # directory and reference it in all dot files that doxygen generates. # When you want a differently looking font you can specify the font name # using DOT_FONTNAME. You need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES ajtcl-15.04b/Makefile000066400000000000000000000305211256742562600144420ustar00rootroot00000000000000# Copyright AllSeen Alliance. All rights reserved. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # # This makefile is meant to be used solely for building WSL-enabled applications. # It is intended to be invoked from IDEs that do not support building using SCons. # All paths in this file are relative to the makefile location # # Some care has to be taken when passing string values into the makefile from the command-line. # An extra level of backslash escaping required to get a string presented to the compiler's preprocessor. # For example, passing the string "bar" to use as a character string initializer in a .c file: # const char foo_var[] = FOO_VAR; # # Is passed on the command line: # make target FOO_VAR=\\\"bar\\\" # # Which results in compiler arguments such as: # -DFOO_VAR=\"bar\" # # settings that can be defined: # AJ_CONFIGURE_WIFI_UPON_START: (boolean) should wifi network connections be started when the AllJoyn # application starts, 1 means yes, 0 or undef means no # example: AJ_CONFIGURE_WIFI_UPON_START=1 # WIFI_DEVICE_NAME: (quoted string) the hostname to assign to your device when connecting to the network # example: WIFI_DEVICE_NAME=\\\"WSLNode001\\\" # WIFI_SCAN: (boolean) should a scan of access points be performed when the device starts up, # 1 means yes, 0 or undef means no # example: WIFI_SCAN=1 # WIFI_SSID: (quoted string) the SSID of the network to connect to # example: WIFI_SSID=\\\"AP_SSID01\\\" # WIFI_PASSPHRASE: (quoted string) the passphrase used to connect to WIFI_SSID # example: WIFI_PASSPHRASE=\\\"PassPhrase\\\" # SOFTAP_SSID: (quoted string) the SSID to use when the device is put into Access Point mode # example: SOFTAP_SSID=\\\"SoftAP_SSID01\\\" # SOFTAP_PASSPHRASE: (quoted string) the passphrase needed by clients to connect to SOFTAP_SSID # example: SOFTAP_PASSPHRASE=\\\"My_PassPhrase\\\" ALLJOYN_DEFINES = # Check which options are defined on the command-line ifneq ($(AJ_DEBUG_RESTRICT), ) ALLJOYN_DEFINES += -DAJ_DEBUG_RESTRICT=${AJ_DEBUG_RESTRICT} endif ifneq ($(AJ_CONFIGURE_WIFI_UPON_START), ) ALLJOYN_DEFINES += -DAJ_CONFIGURE_WIFI_UPON_START=${AJ_CONFIGURE_WIFI_UPON_START} endif ifneq ($(WIFI_DEVICE_NAME),) ALLJOYN_DEFINES += -DWIFI_DEVICE_NAME=${WIFI_DEVICE_NAME} endif ifneq ($(WIFI_SCAN),) ALLJOYN_DEFINES += -DWIFI_SCAN=${WIFI_SCAN} endif ifneq ($(WIFI_SSID),) ALLJOYN_DEFINES += -DWIFI_SSID=${WIFI_SSID} endif ifneq ($(WIFI_PASSPHRASE),) ALLJOYN_DEFINES += -DWIFI_PASSPHRASE=${WIFI_PASSPHRASE} endif ifneq ($(SOFTAP_SSID),) ALLJOYN_DEFINES += -DSOFTAP_SSID=${SOFTAP_SSID} endif ifneq ($(SOFTAP_PASSPHRASE),) ALLJOYN_DEFINES += -DSOFTAP_PASSPHRASE=${SOFTAP_PASSPHRASE} endif DEFINES = -D__SAM3X8E__ \ -DARM_MATH_CM3=true \ -DBOARD=ARDUINO_DUE_X \ -Dprintf=iprintf DEFINES += $(ALLJOYN_DEFINES) RELEASE_DEFINES = -DNDEBUG \ # Linker flags LDFLAGS = -mthumb \ -Wl,-Map=$@.map \ -Wl,--start-group \ -larm_cortexM3l_math \ -lm \ -Wl,--end-group \ -L"$(ATMEL_DIR)/thirdparty/CMSIS/Lib/GCC" \ -Wl,--gc-sections \ -mcpu=cortex-m3 \ -Wl,--entry=Reset_Handler \ -Wl,--cref \ -mthumb \ -T$(ATMEL_DIR)/sam/utils/linker_scripts/sam3x/sam3x8/gcc/flash.ld RELEASE_LDFLAGS = \ -Os \ # Include Paths INCLUDES = -I. \ -Iconfig \ -I$(FREE_RTOS_DIR)/Source/include \ -I$(FREE_RTOS_DIR)/Source/portable/GCC/ARM_CM3 \ -I$(ATMEL_DIR)/common/boards \ -I$(ATMEL_DIR)/common/services/clock \ -I$(ATMEL_DIR)/common/services/clock/sam3x \ -I$(ATMEL_DIR)/common/services/gpio \ -I$(ATMEL_DIR)/common/services/ioport \ -I$(ATMEL_DIR)/common/services/freertos/sam \ -I$(ATMEL_DIR)/common/services/serial/sam_uart \ -I$(ATMEL_DIR)/common/services/serial \ -I$(ATMEL_DIR)/common/services/spi \ -I$(ATMEL_DIR)/common/services/sam_spi \ -I$(ATMEL_DIR)/common/services/spi/sam_spi/module_config \ -I$(ATMEL_DIR)/common/utils \ -I$(ATMEL_DIR)/common/utils/stdio/stdio_serial \ -I$(ATMEL_DIR)/common/drivers/nvm \ -I$(ATMEL_DIR)/common/drivers/nvm/sam/module_config \ -I$(ATMEL_DIR)/sam/boards \ -I$(ATMEL_DIR)/sam/boards/arduino_due_x \ -I$(ATMEL_DIR)/sam/drivers/dmac \ -I$(ATMEL_DIR)/sam/drivers/pio \ -I$(ATMEL_DIR)/sam/drivers/pmc \ -I$(ATMEL_DIR)/sam/drivers/pdc \ -I$(ATMEL_DIR)/sam/drivers/uart \ -I$(ATMEL_DIR)/sam/drivers/usart \ -I$(ATMEL_DIR)/sam/drivers/spi \ -I$(ATMEL_DIR)/sam/drivers/efc \ -I$(ATMEL_DIR)/sam/drivers/trng \ -I$(ATMEL_DIR)/sam/utils \ -I$(ATMEL_DIR)/sam/utils/cmsis/sam3x/include \ -I$(ATMEL_DIR)/sam/utils/cmsis/sam3x/source/templates \ -I$(ATMEL_DIR)/sam/utils/cmsis/sam3x/include/component \ -I$(ATMEL_DIR)/sam/utils/header_files \ -I$(ATMEL_DIR)/sam/utils/preprocessor \ -I$(ATMEL_DIR)/sam/services/flash_efc \ -I$(ATMEL_DIR)/thirdparty/CMSIS/Include \ -I$(ATMEL_DIR)/thirdparty/CMSIS/Lib/GCC \ -I$(ATMEL_DIR)/sam/boards/arduino_due_x/board_config \ -I$(ATMEL_DIR)/common/services/clock/sam3x/module_config \ -I$(ATMEL_DIR)/config \ -I$(ATMEL_DIR)/common/services/clock/sam3x \ -Iinc \ -IRTOS \ -IRTOS/FreeRTOS \ -Ibsp \ -Ibsp/due \ -Ibsp/due/config \ -Imalloc \ -Iexternal\sha2 \ -Icrypto \ -Icrypto/ecc \ -IWSL # Compiler flags FLAGS = -mthumb \ -fdata-sections \ -ffunction-sections \ -mlong-calls \ -g3 \ -Wall \ -mcpu=cortex-m3 \ -c \ -pipe \ -fno-strict-aliasing \ -Wmissing-prototypes \ -Wpointer-arith \ -std=gnu99 \ -Wchar-subscripts \ -Wcomment \ -Wformat=2 \ -Wimplicit-int \ -Wmain \ -Wparentheses \ -Wsequence-point \ -Wreturn-type \ -Wswitch \ -Wtrigraphs \ -Wunused \ -Wuninitialized \ -Wfloat-equal \ -Wundef \ -Wshadow \ -Wbad-function-cast \ -Wwrite-strings \ -Wsign-compare \ -Waggregate-return \ -Wmissing-declarations \ -Wformat \ -Wmissing-format-attribute \ -Wno-deprecated-declarations \ -Wpacked \ -Wlong-long \ -Wunreachable-code \ -Wcast-align \ --param max-inline-insns-single=500 \ -MD \ -MP \ -MF $(@:%.o=%.d) COMPILER = arm-none-eabi-gcc.exe SOURCE_FILES := $(FREE_RTOS_DIR)/Source/croutine.c \ $(FREE_RTOS_DIR)/Source/list.c \ $(FREE_RTOS_DIR)/Source/queue.c \ $(FREE_RTOS_DIR)/Source/tasks.c \ $(FREE_RTOS_DIR)/Source/timers.c \ $(FREE_RTOS_DIR)/Source/portable/MemMang/heap_3.c \ $(FREE_RTOS_DIR)/Source/portable/GCC/ARM_CM3/port.c \ $(ATMEL_DIR)/common/services/clock/sam3x/sysclk.c \ $(ATMEL_DIR)/common/services/spi/sam_spi/spi_master.c \ $(ATMEL_DIR)/common/services/freertos/sam/freertos_peripheral_control.c \ $(ATMEL_DIR)/common/services/freertos/sam/freertos_usart_serial.c \ $(ATMEL_DIR)/common/utils/interrupt/interrupt_sam_nvic.c \ $(ATMEL_DIR)/common/utils/stdio/read.c \ $(ATMEL_DIR)/common/utils/stdio/write.c \ $(ATMEL_DIR)/common/drivers/nvm/sam/sam_nvm.c \ $(ATMEL_DIR)/sam/boards/arduino_due_x/init.c \ $(ATMEL_DIR)/sam/boards/arduino_due_x/led.c \ $(ATMEL_DIR)/sam/drivers/dmac/dmac.c \ $(ATMEL_DIR)/sam/drivers/pdc/pdc.c \ $(ATMEL_DIR)/sam/drivers/pio/pio.c \ $(ATMEL_DIR)/sam/drivers/pio/pio_handler.c \ $(ATMEL_DIR)/sam/drivers/pmc/pmc.c \ $(ATMEL_DIR)/sam/drivers/pmc/sleep.c \ $(ATMEL_DIR)/sam/drivers/uart/uart.c \ $(ATMEL_DIR)/sam/drivers/usart/usart.c \ $(ATMEL_DIR)/sam/drivers/spi/spi.c \ $(ATMEL_DIR)/sam/drivers/efc/efc.c \ $(ATMEL_DIR)/sam/drivers/trng/trng.c \ $(ATMEL_DIR)/sam/utils/cmsis/sam3x/source/templates/exceptions.c \ $(ATMEL_DIR)/sam/utils/cmsis/sam3x/source/templates/system_sam3x.c \ $(ATMEL_DIR)/sam/utils/cmsis/sam3x/source/templates/gcc/startup_sam3x.c \ $(ATMEL_DIR)/sam/services/flash_efc/flash_efc.c \ $(ATMEL_DIR)/sam/utils/syscalls/gcc/syscalls.c \ crypto/aj_sw_crypto.c \ crypto/ecc/aj_crypto_ecc.c \ crypto/ecc/aj_crypto_sha2.c \ src/aj_about.c \ src/aj_bufio.c \ src/aj_bus.c \ src/aj_connect.c \ src/aj_cert.c \ src/aj_crc16.c \ src/aj_creds.c \ src/aj_crypto.c \ src/aj_debug.c \ src/aj_disco.c \ src/aj_guid.c \ src/aj_helper.c \ src/aj_init.c \ src/aj_introspect.c \ src/aj_keyauthentication.c \ src/aj_keyexchange.c \ src/aj_link_timeout.c \ src/aj_msg.c \ src/aj_nvram.c \ src/aj_peer.c \ src/aj_serial.c \ src/aj_serial_rx.c \ src/aj_serial_tx.c \ src/aj_std.c \ src/aj_util.c \ malloc/aj_malloc.c \ external/sha2/sha2.c \ WSL/aj_buf.c \ WSL/aj_wsl_htc.c \ WSL/aj_wsl_net.c \ WSL/aj_wsl_spi_mbox.c \ WSL/aj_wsl_unmarshal.c \ WSL/aj_wsl_wmi.c \ WSL/aj_wsl_marshal.c \ WSL/aj_wsl_tasks.c \ RTOS/main.c \ RTOS/aj_net.c \ RTOS/aj_wifi_ctrl.c \ RTOS/Alljoyn.c \ RTOS/FreeRTOS/aj_target_rtos.c \ bsp/due/aj_spi.c \ bsp/due/aj_trng.c \ bsp/due/aj_target_platform.c TEST_FILES = test/aestest.c TEST_FILES += test/mutter.c TEST_FILES += test/svclite.c TEST_FILES += test/nvramtest.c TEST_FILES += test/clientlite.c TEST_FILES += test/sessionslite.c SAMPLE_FILES = samples/basic/basic_client.c SAMPLE_FILES += samples/basic/basic_service.c SAMPLE_FILES += samples/basic/nameChange_client.c SAMPLE_FILES += samples/basic/signalConsumer_client.c SAMPLE_FILES += samples/basic/signal_service.c SAMPLE_FILES += samples/secure/SecureClient.c OBJECTS = $(SOURCE_FILES:.c=.o) TEST_OBJECTS = $(TEST_FILES:.c=.o) SAMPLE_OBJECTS = $(SAMPLE_FILES:.c=.o) DFILES = $(SOURCE_FILES:.c=.d) EXECUTABLES = $(TEST_FILES:.c=.elf) test: $(TEST_FILES) $(TEST_OBJECTS) $(OBJECTS) sample: $(SAMPLE_FILES) $(SAMPLE_OBJECTS) $(OBJECTS) Release: release #release: FLAGS += -O3 release: DEFINES += -DNDEBUG release: all Debug: debug #debug: FLAGS += -g3 debug: all # All the test elf's are linked here. Add more by using the same format as the others # $(COMPILER) -o .elf $(OBJECTS) .o $(LDFLAGS) all: test \ sample \ due_mutter \ due_svclite \ due_nvram_test \ due_clientlite \ due_sessionslite \ due_basic_client \ due_basic_service \ due_aestest: $(COMPILER) -o due_aestest.elf $(OBJECTS) test/aestest.o $(LDFLAGS) due_mutter: $(COMPILER) -o due_mutter.elf $(OBJECTS) test/mutter.o $(LDFLAGS) due_svclite: $(COMPILER) -o due_svclite.elf $(OBJECTS) test/svclite.o $(LDFLAGS) due_nvram_test: $(COMPILER) -o due_nvram_test.elf $(OBJECTS) test/nvramtest.o $(LDFLAGS) due_clientlite: $(COMPILER) -o due_clientlite.elf $(OBJECTS) test/clientlite.o $(LDFLAGS) due_sessionslite: $(COMPILER) -o due_sessionslite.elf $(OBJECTS) test/sessionslite.o $(LDFLAGS) due_samplesecureclient: $(COMPILER) -o due_samplesecureclient.elf $(OBJECTS) samples/secure/secureclient.o $(LDFLAGS) due_samplesecureservice: $(COMPILER) -o due_samplesecureservice.elf $(OBJECTS) samples/secure/secureservice.o $(LDFLAGS) due_basic_client: $(COMPILER) -o due_basic_client.elf $(OBJECTS) samples/basic/basic_client.o $(LDFLAGS) due_basic_service: $(COMPILER) -o due_basic_service.elf $(OBJECTS) samples/basic/basic_service.o $(LDFLAGS) due_nameChange_client: $(COMPILER) -o due_nameChange_client.elf $(OBJECTS) samples/basic/nameChange_client.o $(LDFLAGS) due_signalConsumer_client: $(COMPILER) -o due_signalConsumer_client.elf $(OBJECTS) samples/basic/signalConsumer_client.o $(LDFLAGS) due_signal_service: $(COMPILER) -o due_signal_service.elf $(OBJECTS) samples/basic/signal_service.o $(LDFLAGS) %.o : %.c $(COMPILER) $(DEFINES) $(INCLUDES) $(FLAGS) -o $@ $< clean: cmd /C del /S *.elf cmd /C for /r %i in (*.o, *.d, *.map) do del %i clean_c: cmd /C del /S *.o cmd /C del /S *.d cd test; cmd /C del /S *.o cd test; cmd /C del /S *.d cd ajtcl; cmd /C del /S *.o cd ajtcl; cmd /C del /S *.d ajtcl-15.04b/README.md000066400000000000000000000025231256742562600142620ustar00rootroot00000000000000Notice of Export Control Law ============================ Cryptographic software is subject to the US government export control and economic sanctions laws (“US export laws”) including the US Department of Commerce Bureau of Industry and Security’s (“BIS”) Export Administration Regulations (“EAR”, 15 CFR 730 et seq., http://www.bis.doc.gov/). You may also be subject to US export laws, including the requirements of license exception TSU in accordance with part 740.13(e) of the EAR. Software and/or technical data subject to the US export laws may not be directly or indirectly exported, reexported, transferred, or released (“exported”) to US embargoed or sanctioned destinations currently including Cuba, Iran, North Korea, Sudan, or Syria, but any amendments to this list shall apply. In addition, software and/or technical data may not be exported to any entity barred by the US government from participating in export activities. Denied persons or entities include those listed on BIS’s Denied Persons and Entities Lists, and the US Department of Treasury’s Office of Foreign Assets Control’s Specially Designated Nationals List. The country in which you are currently located may have restrictions on the import, possession, use of encryption software. You are responsible for compliance with the laws where You are located. ajtcl-15.04b/ReleaseNotes.txt000066400000000000000000000107301256742562600161340ustar00rootroot00000000000000AllJoyn Thin Core Library: Version 15.04b Release Notes ======================================================= Fully Validated Platforms ------------------------- 1) Linux Ubuntu 14.04 LTS (64 bit) 2) Windows 7 (64 bit) See the release review page for other platforms that have not been fully verified, but may work: wiki.allseenalliance.org/core/core_15.04_release_review?&#regression_test Features added in Version 15.04b -------------------------------- * Allow the setting of the UNMARSHAL_TIMEOUT (ASACORE-695). This gives applications explicit control over how long unmarshalling waits for new input before giving up. * AJTCL Router Selection (ASACORE-803). TC applications now use the rank advertised by the router to select the most desirable router. * Support for X.509 ECDSA digital certificates, which replace the X.509 RSA certificates. (ASACORE-1561) * AJTCL adds information string to reply messages (ASACORE-1824). This feature duplicates the standard library API functionality that allows information to be added to a reply message. * Add support for specifying NVRAM file location on Windows (ASACORE-1835). * EXPERIMENTAL: UDP Transport for TC <-> RN connections. Thin Client to Routing Node version of a UDP-based transport (ASACORE-1404). Issues Addressed in Version 15.04b ---------------------------------- ASACORE-1247 Thin Core Library basic samples fail under Windows ASACORE-1853 NGNS query responses for openly advertised names are sent as multicast ASACORE-1948 Debug flag left on in target/linux/aj_net.c ASACORE-1949 Don't send Probe requests when using ARDP ASACORE-1952 Double type does not work ASACORE-2008 Address issue with ECDSA authentication code ASACORE-2045 Unable to write more than 32764 bytes to an NVRAM item. ASACORE-2247 Allow little-endian CTR block counter to go past 511 ASACORE-2248 scan-n-con off by one error ASACORE-2294 Always call AJ_DisconnectWiFi() if AJ_ConnectWifi() returns AJ_OK ASACORE-2299 Validate message serial numbers ASACORE-2332 Avoid long pauses in codisco stress test ASACORE-2365 C on Win32 attempts to do discovery over IP 0.0.0.0 For a complete list of fixed issues: https://jira.allseenalliance.org/issues/?jql=project%20%3D%20ASACORE%20AND%20fixVersion%20in%20%28%2215.04b%22%2C%20%2215.04a%22%2C%20%2215.04%22%29%20AND%20component%20%3D%20%22Thin%20Core%20Library%22%20ORDER%20BY%20fixVersion%20DESC%2C%20priority%20DESC%2C%20id%20ASC Known Issues in Version 15.04b ------------------------------ ASACORE-2051 TC: Possible to write beyond the capacity using AJ_NVRAM_Write ASACORE-2053 AJ_NVRAM_Read can read beyond the item's capacity For a complete list of open issues: https://jira.allseenalliance.org/issues/?jql=project%3D%22Core%20SW%22%20and%20%20resolution%20%3D%20Unresolved%20and%20type%20not%20in%20%28task%2C%20%22New%20Feature%22%29%20and%20component%20%3D%20%22Thin%20Core%20Library%22%20order%20by%20priority%20DESC%2C%20id%20ASC Compatibility ------------- Starting in Version 15.04 * The APIs for About in the core/about_tcl repo are (still) DEPRECATED * Thin Library protocol version changed from 11 to 12. Applications that require router features of version 12 should set the minimum protocol version to 12. * Support for SPKI certificates for ECDHE_ECDSA was removed; the impact of this change is expected to be minimal as it is not believed to have been used. For details of previous releases/release families please see the release notes: 14.12: https://git.allseenalliance.org/cgit/core/ajtcl.git/tree/ReleaseNotes.txt?h=RB14.12 14.06: https://git.allseenalliance.org/cgit/core/ajtcl.git/tree/ReleaseNotes.txt?h=RB14.06 14.02: https://git.allseenalliance.org/cgit/core/ajtcl.git/tree/ReleaseNotes.txt?id=v14.02 Change history -------------- 15.05b - Critical bug fixes: ASACORE-2045, ASACORE-2247, ASACORE-2248, ASACORE-2294, ASACORE-2299, ASACORE-2332, ASACORE-2365 15.04a - Critical bug fixes: ASACORE-1948, ASACORE-1949, ASACORE-1952, ASACORE-2008 15.04 - Bug fixes, new features listed above. 14.12 - Bug fixes, major improvements to address scalability, new features listed above. 14.06a - Critical bug fixes: ASACORE-800, ASACORE-805, ASACORE-908, ASACORE-912, ASACORE-924 and ASACORE-943. 14.06 - Bug fixes, scalability and stability support, several features listed in release notes: https://git.allseenalliance.org/cgit/core/ajtcl.git/tree/ReleaseNotes.txt?id=v14.06 14.02 - Bug fixes. 3.4.1 - Bug fixes. 3.4.0 - Support for Object Level Security. ajtcl-15.04b/SConscript000066400000000000000000001207671256742562600150300ustar00rootroot00000000000000# Copyright AllSeen Alliance. All rights reserved. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import os import shutil import platform if platform.system() == 'Linux': default_target = 'linux' default_msvc_version = None elif platform.system() == 'Windows': default_target = 'win32' default_msvc_version = '11.0' elif platform.system() == 'Darwin': default_target = 'darwin' default_msvc_version = None vars = Variables() # Common build variables vars.Add(EnumVariable('TARG', 'Target platform variant', default_target, allowed_values=('win32', 'linux', 'arduino', 'bsp', 'darwin'))) vars.Add(EnumVariable('VARIANT', 'Build variant', 'debug', allowed_values=('debug', 'release'))) vars.Add(PathVariable('GTEST_DIR', 'The path to googletest sources', os.environ.get('GTEST_DIR'), PathVariable.PathIsDir)) vars.Add(EnumVariable('WS', 'Whitespace Policy Checker', 'check', allowed_values=('check', 'detail', 'fix', 'off'))) vars.Add(EnumVariable('FORCE32', 'Force building 32 bit on 64 bit architecture', 'false', allowed_values=('false', 'true'))) vars.Add(EnumVariable('NO_AUTH', 'Compile in authentication mechanism\'s to the code base', 'no', allowed_values=('no', 'yes'))) vars.Add(EnumVariable('AJWSL', 'Compile driver for the QCA4004 for a specific platform', 'off', allowed_values=('due', 'stm32', 'frdm', 'off'))) vars.Add(PathVariable('ATMEL_DIR', 'Directory for ATMEL source code', os.environ.get('ATMEL_DIR'), PathVariable.PathIsDir)) vars.Add(PathVariable('FREE_RTOS_DIR','Directory to FreeRTOS source code', os.environ.get('FREE_RTOS_DIR'), PathVariable.PathIsDir)) vars.Add(PathVariable('ARM_TOOLCHAIN_DIR', 'Path to the GNU ARM toolchain bin folder', os.environ.get('ARM_TOOLCHAIN_DIR'), PathVariable.PathIsDir)) vars.Add(PathVariable('STM_SRC_DIR', 'Path to the source code for the STM32 microcontroller', os.environ.get('STM_SRC_DIR'), PathVariable.PathIsDir)) vars.Add(PathVariable('MBED_DIR', 'Path to the mbed source code repository', os.environ.get('MBED_DIR'), PathVariable)) vars.Add(EnumVariable('RTOS', 'RTOS your using', 'mbed', allowed_values=('mbed', 'freeRTOS'))) if default_msvc_version: vars.Add(EnumVariable('MSVC_VERSION', 'MSVC compiler version - Windows', default_msvc_version, allowed_values=('8.0', '9.0', '10.0', '11.0', '11.0Exp', '12.0', '12.0Exp'))) if ARGUMENTS.get('TARG', default_target) in ['linux', 'win32']: vars.Add(EnumVariable('ARDP', 'Enable support for ARDP?', 'off', allowed_values=('on', 'off'))) if ARGUMENTS.get('TARG', default_target) == 'win32': msvc_version = ARGUMENTS.get('MSVC_VERSION') env = Environment(variables = vars, MSVC_VERSION=msvc_version, TARGET_ARCH='x86') else: env = Environment(variables = vars) Help(vars.GenerateHelpText(env)) # Allows specification of preprocessor defines on the command line # # DEFINE="FOO=1" DEFINE="BAR=2" # cppdefines = [] for key, value in ARGLIST: if key == 'define': cppdefines.append(value) env.Append(CPPDEFINES=cppdefines) # Define if compiling to use authentication if env['NO_AUTH'] == 'no': auth = '' else: auth = 'NO_SECURITY' # Set AJ_DEBUG_RESTRICT level restrict = ARGUMENTS.get('DEBUG_RESTRICT', '') if restrict != '': if restrict in ['0', '1', '2', '3', '4', '5', 'AJ_DEBUG_OFF', 'AJ_DEBUG_ERROR', 'AJ_DEBUG_WARN', 'AJ_DEBUG_INFO', 'AJ_DEBUG_DUMP', 'AJ_DEBUG_ALL']: env.Append(CPPDEFINES=['AJ_DEBUG_RESTRICT' + '=' + restrict]) else: print 'Invalid value for DEBUG_RESTRICT' Exit(0) # Define compile/link options only for win32/linux. # In case of target platforms, the compilation/linking does not take place # using SCons files. if env['TARG'] == 'win32': env['libs'] = ['wsock32', 'advapi32'] env.Append(CFLAGS=['/J', '/W3']) env.Append(CPPDEFINES=['_CRT_SECURE_NO_WARNINGS']) env.Append(LINKFLAGS=['/NODEFAULTLIB:libcmt.lib']) if env['ARDP'] == 'on': env.Append(CPPDEFINES=['AJ_ARDP']) if env['VARIANT'] == 'debug': # With a modern Microsoft compiler it is typical to use a pdb file i.e. the /Zi # or/ZI CCPDBFLAGS. However in SCons a pdb file is created for each .obj file. # To be able to use the debug information we would have to copy all of the # pdb files (one for each C++ file) into the dist. SCons documentation recommends # using the /Z7 option to solve this problem. Since another more acceptable # solution has not yet been found we are going with the recommendation from the # SCons documentation. env['CCPDBFLAGS'] = '/Z7' env.Append(CFLAGS=['/MD', '/Od']) env.Append(LINKFLAGS=['/debug']) else: env.Append(CPPDEFINES = ['NDEBUG']) env.Append(CFLAGS=['/MD', '/Gy', '/O1', '/GF']) env.Append(LINKFLAGS=['/opt:ref']) # Include paths env['includes'] = [ os.getcwd() + '/inc', os.getcwd() + '/target/${TARG}'] # Target-specific headers and sources env['aj_targ_headers'] = [Glob('target/' + env['TARG'] + '/*.h')] env['aj_targ_srcs'] = [Glob('target/' + env['TARG'] + '/*.c')] elif env['TARG'] in [ 'linux' ]: if env['ARDP'] == 'on': env.Append(CPPDEFINES=['AJ_ARDP']) if os.environ.has_key('CROSS_PREFIX'): env.Replace(CC = os.environ['CROSS_PREFIX'] + 'gcc') env.Replace(CXX = os.environ['CROSS_PREFIX'] + 'g++') env.Replace(LINK = os.environ['CROSS_PREFIX'] + 'gcc') env.Replace(AR = os.environ['CROSS_PREFIX'] + 'ar') env['ENV']['STAGING_DIR'] = os.environ.get('STAGING_DIR', '') if os.environ.has_key('CROSS_PATH'): env['ENV']['PATH'] = ':'.join([ os.environ['CROSS_PATH'], env['ENV']['PATH'] ] ) if os.environ.has_key('CROSS_CFLAGS'): env.Append(CFLAGS=os.environ['CROSS_CFLAGS'].split()) if os.environ.has_key('CROSS_LINKFLAGS'): env.Append(LINKFLAGS=os.environ['CROSS_LINKFLAGS'].split()) env['libs'] = ['rt', 'crypto', 'pthread'] env.Append(CFLAGS=['-Wall', '-pipe', '-static', '-funsigned-char', '-Wpointer-sign', '-Wimplicit-function-declaration', '-fno-strict-aliasing']) if env['VARIANT'] == 'debug': env.Append(CFLAGS='-g') else: env.Append(CPPDEFINES=['NDEBUG']) env.Append(CFLAGS='-Os') env.Append(LINKFLAGS='-s') if env['FORCE32'] == 'true': env.Append(CFLAGS='-m32') env.Append(LINKFLAGS='-m32') # Include paths env['includes'] = [ os.getcwd() + '/inc', os.getcwd() + '/target/${TARG}'] # Target-specific headers and sources env['aj_targ_headers'] = [Glob('target/' + env['TARG'] + '/*.h')] env['aj_targ_srcs'] = [Glob('target/' + env['TARG'] + '/*.c')] elif env['TARG'] == 'arduino': # Include paths env['includes'] = [ os.getcwd() + '/inc', os.getcwd() + '/target/${TARG}'] # Target-specific headers and sources env['aj_targ_headers'] = [Glob('target/' + env['TARG'] + '/*.h')] env['aj_targ_srcs'] = [Glob('target/' + env['TARG'] + '/*.c')] # Board support package target elif env['TARG'] == 'bsp': print "You are building for the bsp target" if env['AJWSL'] == 'off': print "AJWSL must be set to a platform to build for the bsp target" Exit(2) # Set the compiler env.Replace(CC = env.File('${ARM_TOOLCHAIN_DIR}/arm-none-eabi-gcc')) env.Replace(CXX = env.File('${ARM_TOOLCHAIN_DIR}/arm-none-eabi-g++')) env.Replace(LINK = env.File('${ARM_TOOLCHAIN_DIR}/arm-none-eabi-gcc')) env.Replace(AR = env.File('${ARM_TOOLCHAIN_DIR}/arm-none-eabi-ar')) env['CPPDEFPREFIX'] = '-D' env['OBJSUFFIX'] = '.o' env['SHOBJSUFFIX'] = '.os' env['CCCOM'] = '$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES' env['CXXCOM'] = '$CXX $CFLAGS $CCFLAGS $CXXFLAGS -std=gnu++98 $_CCCOMCOM -o $TARGET $SOURCES' env['INCPREFIX'] = '-I' env['CCFLAGS'] = '' env['CPPFLAGS'] = '' env['PROGSUFFIX'] = '.elf' env['PROGPREFIX'] = '' env['LDMODULEPREFIX'] = '' env['LDMODULESUFFIX'] = '' env['LIBLINKPREFIX'] = '' env['LIBPREFIX'] = '' env['PRELINKFLAGS'] = '' env['OBJPREFIX'] = '' env['LINKSCRIPT'] = '' env['LIBPATHS'] = '' env['LINKFLAGS'] = '-Xlinker -Map -Xlinker ' env['LINKCOM'] = '$LINK $PRELINKFLAGS $LINKSCRIPT $LIBPATHS -o $TARGET $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS $LINKFLAGS' env['LINK'] = '$CC' env['ASFLAGS'] = '' env['ASPPCOM'] = '$AS' env['ARFLAGS'] = 'rc' env['ARCOM'] = '$AR $ARFLAGS $TARGET $SOURCES' env['LIBDIRPREFIX'] = '' env['ASCOM'] = '$CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES' env['LIBPREFIX'] = 'lib' env['LIBSUFFIX'] = '.a' env['RANLIB'] = 'ranlib' env['RANLIBFLAGS'] = '' env['RANLIBCOM'] = '$RANLIB $RANLIBFLAGS $TARGET' env['SHLIBPREFIX'] = '' # This was done because scons creates a link file to feed into the linker # and arm-none-eabi removes '\' when interpreting a linker file. This # prevents scons from creating a link file and just feeding the command line # options directly to the compiler/linker env['MAXLINELENGTH'] = 10000 # Debug/Release Variants if env['VARIANT'] == 'debug': env.Append(CFLAGS=['-g3']) env.Append(CFLAGS=['-ggdb']) env.Append(CFLAGS=['-O0']) else: env.Append(CPPDEFINES=['NDEBUG']) env.Append(CFLAGS=['-Os']) env.Append(LINKFLAGS=['-s']) if env['AJWSL'] != 'frdm': # Set the compiler flags env['CFLAGS'] = ['-mthumb', '-fdata-sections', '-ffunction-sections', '-mlong-calls', '-g3', '-Wall', '-mcpu=cortex-m3', '-c', '-pipe', '-fno-strict-aliasing', '-Wmissing-prototypes', '-Wpointer-arith', '-std=gnu99', '-Wchar-subscripts', '-Wcomment', '-Wformat=2', '-Wimplicit-int', '-Wmain', '-Wparentheses', '-Wsequence-point', '-Wreturn-type', '-Wswitch', '-Wtrigraphs', '-Wunused', '-Wuninitialized', '-Wfloat-equal', '-Wundef', '-Wshadow', '-Wbad-function-cast', '-Wwrite-strings', '-Wsign-compare', '-Waggregate-return', '-Wmissing-declarations', '-Wformat', '-Wmissing-format-attribute', '-Wno-deprecated-declarations', '-Wpacked', '-Wlong-long', '-Wunreachable-code', '-Wcast-align', '-MD', '-MP'] # Add platform independent source files rtos_src = [Glob('RTOS/*.c') + Glob('RTOS/FreeRTOS/*.c') + Glob(env['FREE_RTOS_DIR'] + '/Source/*.c') + [env['FREE_RTOS_DIR'] + '/Source/portable/GCC/ARM_CM3/port.c']] if env['AJWSL'] == 'due': rtos_src += [env['FREE_RTOS_DIR'] + '/Source/portable/MemMang/heap_4.c'] # Add platform dependent sources due_src = [Glob('bsp/due/*.c') + [env['ATMEL_DIR'] + '/common/services/clock/sam3x/sysclk.c', env['ATMEL_DIR'] + '/common/services/spi/sam_spi/spi_master.c', env['ATMEL_DIR'] + '/common/services/freertos/sam/freertos_peripheral_control.c', env['ATMEL_DIR'] + '/common/services/freertos/sam/freertos_usart_serial.c', env['ATMEL_DIR'] + '/common/utils/interrupt/interrupt_sam_nvic.c', env['ATMEL_DIR'] + '/common/utils/stdio/read.c', env['ATMEL_DIR'] + '/common/utils/stdio/write.c', env['ATMEL_DIR'] + '/common/drivers/nvm/sam/sam_nvm.c', env['ATMEL_DIR'] + '/sam/boards/arduino_due_x/init.c', env['ATMEL_DIR'] + '/sam/boards/arduino_due_x/led.c', env['ATMEL_DIR'] + '/sam/drivers/pdc/pdc.c', env['ATMEL_DIR'] + '/sam/drivers/pio/pio.c', env['ATMEL_DIR'] + '/sam/drivers/pio/pio_handler.c', env['ATMEL_DIR'] + '/sam/drivers/pmc/pmc.c', env['ATMEL_DIR'] + '/sam/drivers/pmc/sleep.c', env['ATMEL_DIR'] + '/sam/drivers/uart/uart.c', env['ATMEL_DIR'] + '/sam/drivers/usart/usart.c', env['ATMEL_DIR'] + '/sam/drivers/spi/spi.c', env['ATMEL_DIR'] + '/sam/drivers/efc/efc.c', env['ATMEL_DIR'] + '/sam/drivers/tc/tc.c', env['ATMEL_DIR'] + '/sam/drivers/trng/trng.c', env['ATMEL_DIR'] + '/sam/drivers/rstc/rstc.c', env['ATMEL_DIR'] + '/sam/utils/cmsis/sam3x/source/templates/exceptions.c', env['ATMEL_DIR'] + '/sam/utils/cmsis/sam3x/source/templates/system_sam3x.c', env['ATMEL_DIR'] + '/sam/utils/cmsis/sam3x/source/templates/gcc/startup_sam3x.c', env['ATMEL_DIR'] + '/sam/services/flash_efc/flash_efc.c', env['ATMEL_DIR'] + '/sam/utils/syscalls/gcc/syscalls.c', env['ATMEL_DIR'] + '/sam/drivers/dmac/dmac.c']] # Add platform dependent linker flags env['LINKFLAGS'] = ['-mthumb', '-Wl,--start-group', '-larm_cortexM3l_math', '-lm', '-Wl,--end-group', '-L"' + env['ATMEL_DIR'] + '/thirdparty/CMSIS/Lib/GCC"', '-Wl,--gc-sections', '-Wl,-Map,${TARGET.base}.map', '-mcpu=cortex-m3', '-Wl,--entry=Reset_Handler', '-T' + env['ATMEL_DIR'] + '/sam/utils/linker_scripts/sam3x/sam3x8/gcc/flash.ld'] # Add platform dependent defines env.Append(CPPDEFINES = ['__SAM3X8E__', 'ARM_MATH_CM3=true', 'BOARD=ARDUINO_DUE_X', 'printf=iprintf', 'AJ_HEAP4']) # Add platform dependent include paths env['CPPPATH'] = [os.getcwd() + '/bsp', os.getcwd() + '/bsp/due', os.getcwd() + '/bsp/due/config', env['FREE_RTOS_DIR'] + '/Source/include', os.getcwd() + '/RTOS/FreeRTOS', env['FREE_RTOS_DIR'] + '/Source/portable/GCC/ARM_CM3', env['ATMEL_DIR'] + '/common/boards', env['ATMEL_DIR'] + '/common/services/clock', env['ATMEL_DIR'] + '/common/services/clock/sam3x', env['ATMEL_DIR'] + '/common/services/gpio', env['ATMEL_DIR'] + '/common/services/ioport', env['ATMEL_DIR'] + '/common/services/freertos/sam', env['ATMEL_DIR'] + '/common/services/serial/sam_uart', env['ATMEL_DIR'] + '/common/services/serial', env['ATMEL_DIR'] + '/common/services/spi', env['ATMEL_DIR'] + '/common/services/sam_spi', env['ATMEL_DIR'] + '/common/services/spi/sam_spi/module_config', env['ATMEL_DIR'] + '/common/utils', env['ATMEL_DIR'] + '/common/utils/stdio/stdio_serial', env['ATMEL_DIR'] + '/common/drivers/nvm', env['ATMEL_DIR'] + '/common/nvm/sam/module_config', env['ATMEL_DIR'] + '/sam/boards', env['ATMEL_DIR'] + '/sam/boards/arduino_due_x', env['ATMEL_DIR'] + '/sam/drivers/pio', env['ATMEL_DIR'] + '/sam/drivers/pmc', env['ATMEL_DIR'] + '/sam/drivers/tc', env['ATMEL_DIR'] + '/sam/drivers/trng', env['ATMEL_DIR'] + '/sam/drivers/pdc', env['ATMEL_DIR'] + '/sam/drivers/uart', env['ATMEL_DIR'] + '/sam/drivers/usart', env['ATMEL_DIR'] + '/sam/drivers/spi', env['ATMEL_DIR'] + '/sam/drivers/efc', env['ATMEL_DIR'] + '/sam/utils', env['ATMEL_DIR'] + '/sam/utils/cmsis/sam3x/include', env['ATMEL_DIR'] + '/sam/utils/cmsis/sam3x/source/templates', env['ATMEL_DIR'] + '/sam/utils/cmsis/sam3x/include/component', env['ATMEL_DIR'] + '/sam/utils/header_files', env['ATMEL_DIR'] + '/sam/utils/preprocessor', env['ATMEL_DIR'] + '/sam/services/flash_efc', env['ATMEL_DIR'] + '/thirdparty/CMSIS/Include', env['ATMEL_DIR'] + '/thirdparty/CMSIS/Lib/GCC', env['ATMEL_DIR'] + '/sam/boards/arduino_due_x/board_config', env['ATMEL_DIR'] + '/config', env['ATMEL_DIR'] + '/common/services/clock/sam3x/module_config', env['ATMEL_DIR'] + '/common/services/clock/sam3x', env['ATMEL_DIR'] + '/sam/drivers/dmac', env['ATMEL_DIR'] + '/sam/drivers/rstc', os.getcwd() + '/RTOS', os.getcwd() + '/crypto', os.getcwd() + '/crypto/ecc', os.getcwd() + '/external/sha2', os.getcwd() + '/malloc', os.getcwd() + '/inc', os.getcwd() + '/WSL'] elif env['AJWSL'] == 'stm32': env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS $_LIBFLAGS' rtos_src += [env['FREE_RTOS_DIR'] + '/Source/portable/MemMang/heap_4.c'] # Add platform dependent sources stm_src = [env['STM_SRC_DIR'] + 'Libraries/CMSIS/ST/STM32F4xx/Source/Templates/gcc_ride7/startup_stm32f4xx.s', env['STM_SRC_DIR'] + 'Libraries/CMSIS/ST/STM32F4xx/Source/Templates/system_stm32f4xx.c', env['STM_SRC_DIR'] + 'Libraries/STM32F4xx_StdPeriph_Driver/src/misc.c', env['STM_SRC_DIR'] + 'Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rcc.c', env['STM_SRC_DIR'] + 'Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c', env['STM_SRC_DIR'] + 'Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_gpio.c', env['STM_SRC_DIR'] + 'Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_dma.c', env['STM_SRC_DIR'] + 'Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_wwdg.c', env['STM_SRC_DIR'] + 'Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_spi.c', env['STM_SRC_DIR'] + 'Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_flash.c', env['STM_SRC_DIR'] + 'Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_rng.c', env['STM_SRC_DIR'] + 'Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_exti.c', env['STM_SRC_DIR'] + 'Libraries/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_syscfg.c', 'bsp/stm32/aj_target_platform.c', 'bsp/stm32/aj_spi.c', 'bsp/stm32/syscalls.c' ] # Add platform dependent linker flags env['LINKFLAGS'] = ['-mthumb', '-Wl,--start-group', '-lm', '-lc', '-Wl,--end-group', '-Wl,--gc-sections', '-Wl,-Map,${TARGET.base}.map', '-mcpu=cortex-m3', '-T' + env['STM_SRC_DIR'] + 'Project/Peripheral_Examples/SysTick/TrueSTUDIO/SysTick/stm32_flash.ld', '-Wl,--entry=Reset_Handler'] # Add platform dependent defines env.Append(CPPDEFINES = ['STM32F407xx', 'USE_STDPERIPH_DRIVER','HAL_UART_MODULE_ENABLED', 'HAL_RCC_MODULE_ENABLED', 'HAL_GPIO_MODULE_ENABLED', 'HAL_USART_MODULE_ENABLED', 'HAL_FLASH_MODULE_ENABLED']) # Add platform dependent include paths env['CPPPATH'] = [os.getcwd() + '/bsp', os.getcwd() + '/bsp/stm32', env['FREE_RTOS_DIR'] + '/Source/include', os.getcwd() + '/RTOS/FreeRTOS', os.getcwd() + '/bsp/stm32/config', os.getcwd() + '/RTOS', os.getcwd() + '/crypto', os.getcwd() + '/crypto/ecc', os.getcwd() + '/external/sha2', os.getcwd() + '/malloc', os.getcwd() + '/inc', os.getcwd() + '/WSL', env['FREE_RTOS_DIR'] + '/Source/portable/GCC/ARM_CM3', env['STM_SRC_DIR'] + 'Utilities/STM32F4-Discovery', env['STM_SRC_DIR'] + 'Libraries/CMSIS/ST/STM32F4xx/Include', env['STM_SRC_DIR'] + 'Libraries/CMSIS/Include', env['STM_SRC_DIR'] + 'Libraries/STM32F4xx_StdPeriph_Driver/inc'] elif env['AJWSL'] == 'frdm': if env['RTOS'] == 'freeRTOS': headers = ['RTOS/aj_target.h', 'RTOS/RTOS.h', 'RTOS/freeRTOS/aj_target_rtos.h', 'bsp/frdm/aj_target_platform.h', 'bsp/frdm/aj_target_mbed.h'] target = [Glob('bsp/frdm/*.c'), Glob('RTOS/*.c'), Glob('RTOS/FreeRTOS/*.c'), Glob('bsp/frdm/*.cpp')] env.Append(CPPPATH = [os.getcwd() + '/RTOS/FreeRTOS', os.getcwd() + '/RTOS']) elif env['RTOS'] == 'mbed': headers = ['RTOS/aj_target.h', 'RTOS/RTOS.h', 'RTOS/mbedRTOS/aj_target_rtos.h', 'bsp/frdm/aj_target_platform.h', 'bsp/frdm/aj_target_mbed.h'] target = [Glob(env['MBED_DIR'] + '/mbed-rtos/rtx/TARGET_M3/TOOLCHAIN_GCC/*.s'), Glob('bsp/frdm/*.c'), Glob('RTOS/mbedRTOS/*.cpp'), Glob('bsp/frdm/*.cpp'), Glob(env['MBED_DIR'] + '/mbed-rtos/rtx/*.c'), Glob(env['MBED_DIR'] + '/mbed-rtos/rtos/*.cpp'), Glob(env['MBED_DIR'] + '/FATFileSystem/*.cpp'), Glob(env['MBED_DIR'] + '/FATFileSystem/ChaN/*.cpp'), Glob('RTOS/*.c'), [env['MBED_DIR'] + '/SDFileSystem/SDFileSystem.cpp']] env.Append(CPPPATH = [env['MBED_DIR'] + '/mbed-rtos', env['MBED_DIR'] + '/mbed-rtos/rtx', env['MBED_DIR'] + '/mbed-rtos/rtx/TARGET_M4', env['MBED_DIR'] + '/mbed-rtos/rtx/TARGET_M4/TOOLCHAIN_GCC', env['MBED_DIR'] + '/mbed-rtos/rtos']) objects = [ env['MBED_DIR'] + '/mbed/TARGET_K64F/TOOLCHAIN_GCC_ARM/startup_MK64F12.o', env['MBED_DIR'] + '/mbed/TARGET_K64F/TOOLCHAIN_GCC_ARM/cmsis_nvic.o', env['MBED_DIR'] + '/mbed/TARGET_K64F/TOOLCHAIN_GCC_ARM/system_MK64F12.o', env['MBED_DIR'] + '/mbed/TARGET_K64F/TOOLCHAIN_GCC_ARM/mbed_overrides.o', env['MBED_DIR'] + '/mbed/TARGET_K64F/TOOLCHAIN_GCC_ARM/board.o', env['MBED_DIR'] + '/mbed/TARGET_K64F/TOOLCHAIN_GCC_ARM/retarget.o'] env['CCCOM'] = '$CC $CFLAGS $CCFLAGS $_CCCOMCOM -o $TARGET $SOURCES' if env['RTOS'] == 'freeRTOS': env.Append(CPPPATH = [env['FREE_RTOS_DIR'] + '/Source/include', env['FREE_RTOS_DIR'] + '/Source/portable/GCC/ARM_CM3']) elif env['RTOS'] == 'mbed': env.Append(CPPPATH = ['RTOS/mbedRTOS']) env.Append(CPPPATH = [os.getcwd() + '/bsp' , os.getcwd() + '/bsp/frdm', os.getcwd() + '/bsp/frdm/config', os.getcwd() + '/malloc', os.getcwd() + '/WSL', os.getcwd() + '/RTOS', os.getcwd() + '/inc', os.getcwd() + '/external/sha2', os.getcwd() + '/bsp/config', env['MBED_DIR'] + '/SDFileSystem', env['MBED_DIR'] + '/FATFileSystem', env['MBED_DIR'] + '/FATFileSystem/ChaN', env['MBED_DIR'] + '/mbed', env['MBED_DIR'] + '/mbed/TARGET_K64F', env['MBED_DIR'] + '/mbed/TARGET_K64F_Freescale', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/can', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/edma', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/sdhc', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/pit', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/flextimer', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/smc', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/uart', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/pmc', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/mcg', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/port', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/wdog', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/adc', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/osc', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/enet', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/i2c', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/gpio', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/rtc', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/dmamux', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/sim', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/sai', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/hal/dspi', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/drivers', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/drivers/pit', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/drivers/clock', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/drivers/clock/src', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/drivers/enet', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/drivers/interrupt', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/common', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/common/phyksz8081', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_MCU_K64F', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_MCU_K64F/device', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_MCU_K64F/device/MK64F12', env['MBED_DIR'] + '/mbed/TARGET_K64F/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_MCU_K64F/TARGET_FRDM', env['MBED_DIR'] + '/mbed/TARGET_K64F/TOOLCHAIN_GCC_ARM']) env['CCFLAGS'] = ['-mcpu=cortex-m4', '-mthumb', '-mfpu=fpv4-sp-d16', '-c', '-g', '-fno-common', '-fmessage-length=0', '-Wall', '-fno-exceptions', '-ffunction-sections', '-fdata-sections'] env['CXXFLAGS'] = ['-fno-rtti'] env['PRELINKFLAGS'] = ['-mcpu=cortex-m4', '-mthumb', '-Wl,--gc-sections', '--specs=nano.specs', '-u', '_printf_float', '-u', '_scanf_float'] env['LINKSCRIPT'] = ['-T' + env['MBED_DIR'] + '/mbed/TARGET_K64F/TOOLCHAIN_GCC_ARM/K64FN1M0xxx12.ld'] env['LIBPATHS'] = ['-L' + env['MBED_DIR'] + '/mbed/TARGET_K64F/TOOLCHAIN_GCC_ARM'] env['LINKFLAGS'] = ['-lstdc++', '-lgcc', '-lmbed', '-lm', '-lc', '-Wl,-Map,${TARGET.base}.map'] env.Append(CPPDEFINES = ['TARGET_K64F', 'TARGET_M4', 'TARGET_Freescale', 'TARGET_KPSDK_MCUS', 'TARGET_KPSDK_CODE', 'TARGET_MCU_K64F', 'TARGET_FRDM', 'TOOLCHAIN_GCC_ARM', 'TOOLCHAIN_GCC', '__CORTEX_M4', 'ARM_MATH_CM4', '__FPU_PRESENT=1', 'MBED_BUILD_TIMESTAMP=1411582835.22', '__MBED__=1', 'CPU_MK64FN1M0VMD12', 'FSL_RTOS_MBED', 'TARGET_FF_ARDUINO', '__CORTEX_M4', 'FSL_RTOS_MBED' 'AJ_CONFIGURE_WIFI_UPON_START', 'WIFI_SSID=\\"SEAQUIC-AP3\\"', 'WIFI_PASSPHRASE=\\"123456789\\"' ]) elif env['TARG'] in [ 'darwin' ]: if os.environ.has_key('CROSS_PREFIX'): env.Replace(CC = os.environ['CROSS_PREFIX'] + 'gcc') env.Replace(CXX = os.environ['CROSS_PREFIX'] + 'g++') env.Replace(LINK = os.environ['CROSS_PREFIX'] + 'gcc') env.Replace(AR = os.environ['CROSS_PREFIX'] + 'ar') env['ENV']['STAGING_DIR'] = os.environ.get('STAGING_DIR', '') if os.environ.has_key('CROSS_PATH'): env['ENV']['PATH'] = ':'.join([ os.environ['CROSS_PATH'], env['ENV']['PATH'] ] ) if os.environ.has_key('CROSS_CFLAGS'): env.Append(CFLAGS=os.environ['CROSS_CFLAGS'].split()) if os.environ.has_key('CROSS_LINKFLAGS'): env.Append(LINKFLAGS=os.environ['CROSS_LINKFLAGS'].split()) env['libs'] = ['crypto', 'pthread'] env.Append(CFLAGS=['-Wall', '-pipe', '-static', '-funsigned-char', '-Wpointer-sign', '-Wimplicit-function-declaration', '-fno-strict-aliasing']) if env['VARIANT'] == 'debug': env.Append(CFLAGS='-g') else: env.Append(CPPDEFINES=['NDEBUG']) env.Append(CFLAGS='-Os') env.Append(LINKFLAGS='-s') if env['FORCE32'] == 'true': env.Append(CFLAGS='-m32') env.Append(LINKFLAGS='-m32') # Include paths env['includes'] = [ os.getcwd() + '/inc', os.getcwd() + '/target/${TARG}', os.getcwd() + '/crypto/ecc', os.getcwd() + '/external/sha2'] # Target-specific headers and sources env['aj_targ_headers'] = [Glob('target/' + env['TARG'] + '/*.h')] env['aj_targ_srcs'] = [Glob('target/' + env['TARG'] + '/*.c')] # AllJoyn Thin Client headers and sources (target independent) env['aj_headers'] = [Glob('inc/*.h') + Glob('external/*/*.h')] env['aj_srcs'] = [Glob('src/*.c')] env['aj_sw_crypto'] = [Glob('crypto/*.c')] env['aj_malloc'] = [Glob('malloc/*.c')] env['aj_crypto_ecc'] = [Glob('crypto/ecc/*.c')] env['aj_external_sha2'] = [Glob('external/sha2/*.c')] wsl = [Glob('WSL/*.c')] wsl_headers = [Glob('WSL/*.h')] # Set-up the environment for Win/Linux if env['TARG'] in [ 'win32', 'linux', 'darwin' ]: # To compile, sources need access to include files env.Append(CPPPATH = [env['includes']]) # Win/Linux programs need libs to link env.Append(LIBS = [env['libs']]) # Win/Linux programs need their own 'main' function env.Append(CPPDEFINES = ['AJ_MAIN', auth]) # We have more memory on these platforms env.Append(CPPDEFINES = ['AJ_NVRAM_SIZE=64000']) env.Append(CPPDEFINES = ['AJ_NUM_REPLY_CONTEXTS=8']) # Produce shared libraries for these platforms srcs = env['aj_srcs'] + env['aj_targ_srcs'] + env['aj_crypto_ecc'] + env['aj_malloc'] + env['aj_external_sha2'] if env['TARG'] == 'win32': srcs += env['aj_sw_crypto'] env.SharedLibrary('ajtcl', srcs) env.StaticLibrary('ajtcl_st', srcs) env['aj_obj'] = env.StaticObject(srcs) env['aj_shobj'] = env.SharedObject(srcs) if env['AJWSL'] == 'due': env['aj_obj'] = env.Object(env['aj_srcs'] + env['aj_sw_crypto'] + env['aj_malloc'] + env['aj_crypto_ecc'] + env['aj_external_sha2']) env['aj_obj'] += env.Object(wsl) env['aj_obj'] += env.Object(due_src) env['aj_obj'] += env.Object(rtos_src) # Build standard ajtcl test programs env.Program('test/svclite', ['test/svclite.c'] + env['aj_obj']) env.Program('test/clientlite', ['test/clientlite.c'] + env['aj_obj']) env.Program('test/siglite', ['test/siglite.c'] + env['aj_obj']) env.Program('test/nvramtest', ['test/nvramtest.c'] + env['aj_obj']) env.Program('test/sessionslite', ['test/sessionslite.c'] + env['aj_obj']) env.Program('test/codisco', ['test/codisco.c'] + env['aj_obj']) env.Program('test/scan-n-con', ['test/scan-n-con.c'] + env['aj_obj']) elif env['AJWSL'] == 'stm32': srcs = env.Object(env['aj_srcs'] + env['aj_sw_crypto'] + env['aj_malloc'] + env['aj_crypto_ecc'] + env['aj_external_sha2']) srcs += env.Object(wsl) srcs += env.Object(rtos_src) srcs += env.Object(stm_src) stm_lib = env.StaticLibrary('ajtcl_stm32', srcs) # Build standard ajtcl test programs env.Program('test/svclite', ['test/svclite.c'], LIBS=[stm_lib]) env.Program('test/nvramtest', ['test/nvramtest.c'], LIBS=[stm_lib]) env.Program('test/clientlite', ['test/clientlite.c'], LIBS=[stm_lib]) env.Program('test/codisco', ['test/codisco.c'], LIBS=[stm_lib]) env.Program('test/scan-n-con', ['test/scan-n-con.c'], LIBS=[stm_lib]) elif env['AJWSL'] == 'frdm': srcs = [] # The freedom board has its own NVRAM implementation so remove src/aj_nvram.c for h in env['aj_srcs']: h.remove(env.File('src/aj_nvram.c')) if env['RTOS'] == 'freeRTOS': freertos = [Glob(env['FREE_RTOS_DIR'] + '/Source/*.c') + [env['FREE_RTOS_DIR'] + '/Source/portable/GCC/ARM_CM3/port.c', env['FREE_RTOS_DIR'] + '/Source/portable/MemMang/heap_4.c']] srcs += env.Object(freertos) aj_obj = env.Object(env['aj_srcs'] + env['aj_sw_crypto'] + env['aj_malloc'] + env['aj_crypto_ecc'] + env['aj_external_sha2'] + target + wsl) env.StaticLibrary('ajtcl_frdm', [objects, srcs, aj_obj]) #test_src = env.Object(['bsp/frdm/test_mbed.cpp']) env.Program('test/svclite', ['test/svclite.c'] + [objects, srcs, aj_obj]) env.Program('test/nvramtest', ['test/nvramtest.c'] + [objects, srcs, aj_obj]) env.Program('test/codisco', ['test/codisco.c'] + [objects, srcs, aj_obj]) env.Program('test/scan-n-con', ['test/scan-n-con.c'] + [objects, srcs, aj_obj]) Export('env') if env['WS'] != 'off' and not env.GetOption('clean') and not env.GetOption('help'): import sys bin_dir = os.getcwd() + '/tools' sys.path.append(bin_dir) import whitespace env['uncrustify_cfg_root'] = os.getcwd(); def wsbuild(target, source, env): print "Evaluating whitespace compliance..." print "Note: enter 'scons -h' to see whitespace (WS) options" curdir = os.path.abspath(os.path.dirname(wsbuild.func_code.co_filename)) version = whitespace.get_uncrustify_version() if (version == "0.57"): config = env['uncrustify_cfg_root'] + '/ajuncrustify.0.57.cfg' else: #use latest known version config = env['uncrustify_cfg_root'] + '/ajuncrustify.0.61.cfg' print "Config:", config print "Note: enter 'scons -h' to see whitespace (WS) options" return whitespace.main([env['WS'], config]) env.Command('#/ws_ajtcl', Dir('$DISTDIR'), wsbuild) # In case of Arduino target, package the 'SDK' suitable for development # on Arduino IDE if env['TARG'] == 'arduino': arduinoLibDir = 'build/arduino_due/libraries/AllJoyn/' # Arduino sketches need the corresponding platform-independent sources tests = [ ] tests.append('svclite') tests.append('clientlite') tests.append('siglite') tests.append('bastress2') tests.append('mutter') tests.append('sessions') tests.append('aestest') testInputs = [ ] testOutputs = [ ] # Install the generic .c files from the test directory into their # destination while changing the extension # Also install the .ino file for the test sketch for test in Flatten(tests): in_path = File('test/' + test + '.c') out_path = File('target/arduino/tests/AJ_' + test + '/' + test + '.cpp') env.Install(Dir(arduinoLibDir + 'tests/AJ_' + test + '/').abspath, File('target/arduino/tests/AJ_' + test + '/AJ_' + test + '.ino')) env.InstallAs(File(arduinoLibDir + 'tests/AJ_' + test + '/' + test + '.cpp').abspath, in_path.abspath) replaced_names = [] for x in Flatten([env['aj_srcs'], env['aj_targ_srcs'], env['aj_sw_crypto'], env['aj_external_sha2']]): replaced_names.append( File(arduinoLibDir + x.name.replace('.c', '.cpp') ) ) # change the extension install_renamed_files = env.InstallAs(Flatten(replaced_names), Flatten([env['aj_srcs'], env['aj_targ_srcs'], env['aj_sw_crypto'], env['aj_external_sha2']])) install_host_headers = env.Install(arduinoLibDir, env['aj_targ_headers']) install_headers = env.Install(arduinoLibDir, env['aj_headers']) # install the examples into their source env.Install(Dir(arduinoLibDir).abspath, 'target/arduino/examples/') # Install basic samples basicsamples = [ ] basicsamples.append('basic_service') basicsamples.append('basic_client') basicsamples.append('signal_service') basicsamples.append('signalConsumer_client') securesamples = [ ] securesamples.append('SecureClient') securesamples.append('SecureService') for sample in Flatten(basicsamples): in_path = File('samples/basic/' + sample + '.c') out_path = File('target/arduino/samples/AJ_' + sample + '/' + sample + '.cpp') env.Install(Dir(arduinoLibDir + 'samples/AJ_' + sample + '/').abspath, File('target/arduino/samples/AJ_' + sample + '/AJ_' + sample + '.ino')) env.InstallAs(File(arduinoLibDir + 'samples/AJ_' + sample + '/' + sample + '.cpp').abspath, in_path.abspath) for sample in Flatten(securesamples): in_path = File('samples/secure/' + sample + '.c') out_path = File('target/arduino/samples/AJ_' + sample + '/' + sample + '.cpp') env.Install(Dir(arduinoLibDir + 'samples/AJ_' + sample + '/').abspath, File('target/arduino/samples/AJ_' + sample + '/AJ_' + sample + '.ino')) env.InstallAs(File(arduinoLibDir + 'samples/AJ_' + sample + '/' + sample + '.cpp').abspath, in_path.abspath) Return('env') ajtcl-15.04b/SConstruct000066400000000000000000000024071256742562600150360ustar00rootroot00000000000000# Copyright AllSeen Alliance. All rights reserved. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import os env = SConscript(['SConscript']) # Add/remove projects from build env.SConscript('test/SConscript') env.SConscript('samples/SConscript') # Build googletests for VARIANT=debug and for Win/Linux only (not for embedded) if env['TARG'] == 'win32' or env['TARG'] == 'linux': if env['VARIANT'] == 'debug': if env.has_key('GTEST_DIR'): env.SConscript('unit_test/SConscript') else: print 'GTEST_DIR is not set, skipping unittest build' ajtcl-15.04b/WSL/000077500000000000000000000000001256742562600134465ustar00rootroot00000000000000ajtcl-15.04b/WSL/aj_buf.c000066400000000000000000000300151256742562600150370ustar00rootroot00000000000000/** * @file Buffer list implementation */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #ifdef __cplusplus extern "C" { #endif /** * Per-module definition of the current module for debug logging. Must be defined * prior to first inclusion of aj_debug.h */ #define AJ_MODULE BUFLIST #include "aj_target.h" #include "aj_util.h" #include "aj_buf.h" #include "aj_wsl_target.h" #include "aj_debug.h" /** * Turn on per-module debug printing by setting this variable to non-zero value * (usually in debugger). */ #ifndef NDEBUG uint8_t dbgBUFLIST = 0; #endif #ifndef NDEBUG AJ_BUFLIST_FUNC_TABLE AJ_BUFLIST_OPS; #endif void AJ_BufList_ModuleInit() { /* * Configure the indirection table with the default functions */ #ifndef NDEBUG AJ_BUFLIST_OPS.readByteFromWire = &AJ_BufListReadByteFromWire_Simulated; AJ_BUFLIST_OPS.writeToWire = &AJ_BufListWriteToWire_Simulated; #endif } #ifndef NDEBUG //DEBUG data: simulate SPI read/write using a fixed buffer AJ_BUF_WIREBUFFER toTarget; AJ_BUF_WIREBUFFER fromTarget; #endif AJ_BufList* AJ_BufListCreate(void) { AJ_BufList* list; list = (AJ_BufList*)AJ_WSL_Malloc(sizeof(AJ_BufList)); memset(list, 0, sizeof(AJ_BufList)); return list; } AJ_BufList* AJ_BufListCreateCopy(AJ_BufList* listIn) { AJ_BufList* list; AJ_BufNode* nodeA; uint16_t listInLength; list = (AJ_BufList*)AJ_WSL_Malloc(sizeof(AJ_BufList)); memset(list, 0, sizeof(AJ_BufList)); listInLength = AJ_BufListLengthOnWire(listIn); nodeA = AJ_BufListCreateNodeZero(listInLength, FALSE); AJ_BufListCopyBytes(listIn, listInLength, nodeA->bufferStart); AJ_BufListPushHead(list, nodeA); return list; } AJ_BufNode* AJ_BufListCreateNodeZero(uint16_t bufferSize, uint8_t zeroBuffer) { AJ_BufNode* newNode = (AJ_BufNode*)AJ_WSL_Malloc(sizeof(AJ_BufNode)); newNode->buffer = (uint8_t*)AJ_WSL_Malloc(bufferSize); if (zeroBuffer) { memset(newNode->buffer, 0, bufferSize); } newNode->length = bufferSize; newNode->next = NULL; newNode->bufferStart = newNode->buffer; newNode->flags = 0; return newNode; } AJ_BufNode* AJ_BufListCreateNode(uint16_t bufferSize) { return AJ_BufListCreateNodeZero(bufferSize, 1); } AJ_BufNode* AJ_BufListCreateNodeExternalZero(uint8_t* buffer, uint16_t bufferSize, uint8_t zeroBuffer) { AJ_BufNode* newNode = (AJ_BufNode*)AJ_WSL_Malloc(sizeof(AJ_BufNode)); newNode->buffer = buffer; if (zeroBuffer) { memset(newNode->buffer, 0, bufferSize); } newNode->length = bufferSize; newNode->next = NULL; newNode->bufferStart = newNode->buffer; newNode->flags = AJ_BUFNODE_EXTERNAL_BUFFER; return newNode; } AJ_BufNode* AJ_BufNodeCreateAndTakeOwnership(AJ_BufNode* giving) { AJ_BufNode* newNode = (AJ_BufNode*)AJ_WSL_Malloc(sizeof(AJ_BufNode)); memcpy(newNode, giving, sizeof(AJ_BufNode)); giving->flags = AJ_BUFNODE_EXTERNAL_BUFFER; return newNode; } AJ_BufNode* AJ_BufListCreateNodeExternalBuffer(uint8_t* buffer, uint16_t bufferSize) { return AJ_BufListCreateNodeExternalZero(buffer, bufferSize, 1); } void AJ_BufListPushHead(AJ_BufList* list, AJ_BufNode* newNode) { if (!list->head) { list->tail = newNode; list->head = newNode; } else { newNode->next = list->head; list->head = newNode; } } void AJ_BufListPushTail(AJ_BufList* list, AJ_BufNode* newNode) { if (!list->head || !list->tail) { list->tail = newNode; list->head = newNode; } else { list->tail->next = newNode; list->tail = newNode; } } void AJ_BufListCoalesce(AJ_BufNode* node) { if (node->next) { AJ_BufNode* nextNode; uint8_t* biggerBuffer; nextNode = node->next; AJ_ASSERT(!(node->flags | nextNode->flags) & AJ_BUFNODE_EXTERNAL_BUFFER); if ((node->flags | nextNode->flags) & AJ_BUFNODE_EXTERNAL_BUFFER) { /* one of the nodes has an external buffer, don't coalesce */ AJ_ASSERT((node->flags | nextNode->flags) & AJ_BUFNODE_EXTERNAL_BUFFER); } // create a new buffer with the data from two buffers biggerBuffer = (uint8_t*)AJ_WSL_Malloc(node->length + nextNode->length); memcpy(biggerBuffer, node->buffer, node->length); memcpy(biggerBuffer + node->length, nextNode->buffer, nextNode->length); AJ_WSL_Free(node->buffer); node->buffer = biggerBuffer; node->bufferStart = node->buffer; node->length += nextNode->length; // remove the following node node->next = nextNode->next; AJ_BufListFreeNodeAndBuffer(nextNode, NULL); } } AJ_EXPORT void AJ_BufNodePullBytes(AJ_BufNode* node, uint16_t count) { // while there are bytes to remove, pull bytes out of the node. // then move to the next node if needed while ((node != NULL) && (count > 0)) { // taking less than the whole buffer if (count <= node->length) { node->length -= count; node->buffer += count; count = 0; break; } else { // shorten the list and free the buffer we have now. AJ_BufNode* nodeNext = node->next; count -= node->length; AJ_BufListFreeNodeAndBuffer(node, NULL); node = nodeNext; } } // AJ_ASSERT(count == 0); } AJ_EXPORT void AJ_BufListPullBytes(AJ_BufList* list, uint16_t count) { // while there are bytes to remove, pull bytes out of the head node of the list. while ((list != NULL) && (count > 0)) { AJ_BufNode* node = list->head; // taking less than the whole buffer if (count <= node->length) { node->length -= count; node->buffer += count; count = 0; break; } else { // shorten the list and free the buffer we have now. list->head = node->next; count -= node->length; AJ_BufListFreeNodeAndBuffer(node, NULL); } } // AJ_ASSERT(count == 0); } /* * This function takes a AJ_BufList and copies it to a user buffer */ AJ_EXPORT void AJ_BufListCopyBytes(AJ_BufList* list, uint16_t count, uint8_t* userBuffer) { // while there are bytes to remove, pull bytes out of the head node of the list. if (list != NULL) { AJ_BufNode* node = list->head; while ((node != NULL) && (count > 0)) { // taking less than the whole buffer if (count <= node->length) { memcpy(userBuffer, node->buffer, count); break; } else { // copy what is in this node and advance to the next. memcpy(userBuffer, node->buffer, node->length); userBuffer += node->length; count -= node->length; node = node->next; } } } } //DEBUG function #ifndef NDEBUG void AJ_BufListWriteToWire_Simulated(AJ_BufNode* node, AJ_BUF_WIREBUFFER* target) { uint16_t iter = 0; memcpy(target->fakeWireWrite, node->buffer, node->length); target->fakeWireWrite += node->length; #ifndef NDEBUG if (AJ_DbgLevel > AJ_DEBUG_INFO) { while (iter < node->length) { AJ_AlwaysPrintf(("%02x ", node->buffer[iter])); iter++; } } #endif } //DEBUG function: simulate an SPI read using a stored data buffer // read a byte from the buffer, advance the read pointer, return the byte. uint8_t AJ_BufListReadByteFromWire_Simulated(AJ_BUF_WIREBUFFER* source) { uint8_t byteRead = *source->fakeWireRead; source->fakeWireRead++; // AJ_AlwaysPrintf(("Byte Read %02x ", byteRead)); return byteRead; } //DEBUG function: simulate an SPI read using a stored data buffer // read a byte from the buffer, advance the read pointer, return the byte. void AJ_BufListReadBytesFromWire_Simulated(uint16_t numberToRead, uint8_t* output, AJ_BUF_WIREBUFFER* source) { while (numberToRead > 0) { *output = AJ_BUFLIST_OPS.readByteFromWire(source); output++; numberToRead--; } } #endif //DEBUG function: print node header info void AJ_BufListNodePrint(AJ_BufNode* node, void* context) { AJ_AlwaysPrintf(("BufList node %p, flags %x length %d, buffer %p, bufferStart %p\n", node, node->flags, node->length, node->buffer, node->bufferStart)); } //DEBUG function: print node contents void AJ_BufListNodePrintDump(AJ_BufNode* node, void* context) { uint16_t iter = 0; AJ_BufListNodePrint(node, NULL); while (iter < node->length) { AJ_AlwaysPrintf(("%02x ", node->buffer[iter])); iter++; } AJ_AlwaysPrintf(("%s", "\n")); } // deprecate, perhaps void AJ_BufNodeIterate(AJ_BufNodeFunc nodeFunc, AJ_BufList* list, void* context) { if (list != NULL) { AJ_BufNode* node = list->head; while (node != NULL) { AJ_BufNode* nextNode = node->next; nodeFunc(node, context); node = nextNode; } } } AJ_Status AJ_BufListIterate(AJ_BufNodeFunc nodeFunc, AJ_BufList* list, void* context) { AJ_Status status = AJ_OK; if (list != NULL) { AJ_BufNode* node = list->head; while ((status == AJ_OK) && (node != NULL)) { AJ_BufNode* nextNode = node->next; nodeFunc(node, context); node = nextNode; } } return status; } void AJ_BufListPrintDump(AJ_BufList* list) { AJ_BufNode* node = list->head; while (node != NULL) { AJ_BufListNodePrintDump(node, NULL); node = node->next; } } void AJ_BufListPrintDumpContinuous(AJ_BufList* list) { int i; AJ_BufNode* node = list->head; while (node != NULL) { for (i = 0; i < node->length; i++) { AJ_AlwaysPrintf(("%02x ", *(node->buffer + i))); } //AJ_BufListNodePrintDump(node, NULL); node = node->next; } AJ_AlwaysPrintf(("\n")); } #ifndef NDEBUG //DEBUG function: print node header info void AJ_BufListIterateOnWire(AJ_BufNodeFuncWireBuf nodeFunc, AJ_BufList* list, AJ_BUF_WIREBUFFER* wire) { if (list != NULL) { AJ_BufNode* node = list->head; while (node != NULL) { AJ_BufNode* nextNode = node->next; nodeFunc(node, wire); node = nextNode; } } } #endif uint16_t AJ_BufListLengthOnWire(AJ_BufList* list) { uint16_t sum = 0; if (list != NULL) { AJ_BufNode* node = list->head; while (node != NULL) { sum += node->length; node = node->next; } } return sum; } void AJ_BufListFreeNode(AJ_BufNode* node, void* context) { AJ_WSL_Free(node); } void AJ_BufListFreeNodeAndBuffer(AJ_BufNode* node, void* context) { if (node && !(node->flags & AJ_BUFNODE_EXTERNAL_BUFFER)) { AJ_WSL_Free(node->bufferStart); } AJ_WSL_Free(node); } void AJ_BufListFree(AJ_BufList* list, uint8_t freeNodeBuffers) { AJ_BufListIterate(freeNodeBuffers ? AJ_BufListFreeNodeAndBuffer : AJ_BufListFreeNode, list, NULL); AJ_WSL_Free(list); } uint32_t AJ_BufListGetSize(AJ_BufList* list) { uint32_t size; AJ_BufNode* node; size = 0; node = list->head; while (node != NULL) { size += node->length; node = node->next; } return size; } #ifdef __cplusplus } #endif ajtcl-15.04b/WSL/aj_buf.h000066400000000000000000000132601256742562600150470ustar00rootroot00000000000000/** * @file Buffer list function declarations */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #ifndef AJ_BUF_H_ #define AJ_BUF_H_ #include "aj_target.h" #include "aj_status.h" #include "aj_wsl_target.h" #ifdef __cplusplus extern "C" { #endif #ifndef __cplusplus #pragma pack(push, 1) #endif void AJ_BufList_ModuleInit(void); typedef struct _AJ_BufNode { uint16_t length; uint8_t flags; uint8_t* buffer; //moves around when we pull data out. uint8_t* bufferStart; // stays put struct _AJ_BufNode* next; } AJ_BufNode; /* * flag indicating the buffer is allocated elsewhere */ #define AJ_BUFNODE_EXTERNAL_BUFFER (1 << 0) /* * This structure is passed down each layer of the protocol stack. * It is populated at each layer. * When data is received, each element can point to an entry in a buffer. */ typedef struct _AJ_BufList { AJ_BufNode* head; AJ_BufNode* tail; } AJ_BufList; AJ_BufList* AJ_BufListCreate(void); void AJ_BufListFree(AJ_BufList* list, uint8_t freeNodeBuffers); AJ_BufList* AJ_BufListCreateCopy(AJ_BufList* listIn); /* * Create a new node, allocate a payload buffer, and zero the memory contents */ AJ_BufNode* AJ_BufListCreateNodeZero(uint16_t bufferSize, uint8_t zeroBuffer); /* * Create a new node, allocate a buffer. * Use when the full payload will be filled with known data */ AJ_BufNode* AJ_BufListCreateNode(uint16_t bufferSize); AJ_BufNode* AJ_BufListCreateNodeExternalZero(uint8_t* buffer, uint16_t bufferSize, uint8_t zeroBuffer); AJ_BufNode* AJ_BufListCreateNodeExternalBuffer(uint8_t* buffer, uint16_t bufferSize); /* * Create a new node, and assign the buffer info from the giving node. * Use when the the underlying buffer will be used and released elsewhere */ AJ_BufNode* AJ_BufNodeCreateAndTakeOwnership(AJ_BufNode* giving); /* * Free the parameter node, (!but not the payload!) */ void AJ_BufListFreeNode(AJ_BufNode* node, void* context); /* * Free the parameter node, and the payload buffer */ void AJ_BufListFreeNodeAndBuffer(AJ_BufNode* node, void* context); /* * create a new payload of the parameter node * by combining the payloads of the parameter node and its follower */ void AJ_BufListCoalesce(AJ_BufNode* node); /* * Add a AJ_BufNode to the start of the AJ_BufList */ void AJ_BufListPushHead(AJ_BufList* list, AJ_BufNode* newNode); /* * Add a AJ_BufNode to the end of the AJ_BufList */ void AJ_BufListPushTail(AJ_BufList* list, AJ_BufNode* newNode); AJ_EXPORT void AJ_BufNodePullBytes(AJ_BufNode* node, uint16_t count); AJ_EXPORT void AJ_BufListPullBytes(AJ_BufList* list, uint16_t count); AJ_EXPORT void AJ_BufListCopyBytes(AJ_BufList* list, uint16_t count, uint8_t* userBuffer); // prototype for functions that do something with a buffer list node typedef void (*AJ_BufNodeFunc)(AJ_BufNode* node, void* context); typedef AJ_Status (*AJ_BufListFunc)(AJ_BufList* node, void* context); // perform operation on each node in a buffer list AJ_Status AJ_BufListIterate(AJ_BufNodeFunc nodeFunc, AJ_BufList* list, void* context); void AJ_BufNodeIterate(AJ_BufNodeFunc nodeFunc, AJ_BufList* list, void* context); /* * AJ_BufList Helper functions */ /* * This function returns how many bytes will be sent on the wire for this AJ_BufList. */ uint16_t AJ_BufListLengthOnWire(AJ_BufList* list); /* * This function returns the length of unconsumed data contained in the AJ_BufList. */ uint32_t AJ_BufListGetSize(AJ_BufList* list); #ifndef NDEBUG //DEBUG data: simulate SPI read/write using a fixed buffer typedef struct _AJ_BUF_WIREBUFFER { uint8_t fakeWireBuffer[512]; uint8_t* fakeWireCurr; uint8_t* fakeWireWrite; uint8_t* fakeWireRead; } AJ_BUF_WIREBUFFER; extern AJ_BUF_WIREBUFFER toTarget; extern AJ_BUF_WIREBUFFER fromTarget; // prototype for functions that do something with a buffer list node and a wirebuffer typedef void (*AJ_BufNodeFuncWireBuf)(AJ_BufNode* node, AJ_BUF_WIREBUFFER* wireBuffer); /* * Provide support for hooking the low level SPI functions */ typedef uint8_t (*AJ_BufListReadByteFromWire_Func)(AJ_BUF_WIREBUFFER* source); typedef struct _AJ_BUFLIST_FUNC_TABLE { AJ_BufNodeFuncWireBuf writeToWire; AJ_BufListReadByteFromWire_Func readByteFromWire; } AJ_BUFLIST_FUNC_TABLE; //DEBUG functions void AJ_BufListNodePrint(AJ_BufNode* node, void* context); void AJ_BufListNodePrintDump(AJ_BufNode* node, void* context); void AJ_BufListWriteToWire_Simulated(AJ_BufNode* node, AJ_BUF_WIREBUFFER* target); uint8_t AJ_BufListReadByteFromWire_Simulated(AJ_BUF_WIREBUFFER* source); void AJ_BufListReadBytesFromWire_Simulated(uint16_t numberToRead, uint8_t* output, AJ_BUF_WIREBUFFER* source); void AJ_BufListIterateOnWire(AJ_BufNodeFuncWireBuf nodeFunc, AJ_BufList* list, AJ_BUF_WIREBUFFER* wire); #endif #ifndef __cplusplus #pragma pack(pop) #endif #ifdef __cplusplus } #endif #endif /* AJ_BUF_H_ */ ajtcl-15.04b/WSL/aj_wsl_htc.c000066400000000000000000000220231256742562600157260ustar00rootroot00000000000000/** * @file HTC layer implementation */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #define AJ_MODULE WSL_HTC #include "aj_target.h" #include "aj_wsl_spi.h" #include "aj_wsl_htc.h" #include "aj_wsl_wmi.h" #include "aj_buf.h" #include "aj_debug.h" #include "aj_wsl_unmarshal.h" /** * Turn on per-module debug printing by setting this variable to non-zero value * (usually in debugger). */ #ifndef NDEBUG uint8_t dbgWSL_HTC = 0; #endif /** * global variable for WSL_HTC state */ AJ_WSL_HTC_CONTEXT AJ_WSL_HTC_Global; void AJ_WSL_HTC_ModuleInit(void) { //Initialize the credit-tracking information memset(&AJ_WSL_HTC_Global, 0, sizeof(AJ_WSL_HTC_Global)); AJ_WSL_HTC_Global.endpoints[0].txCredits = 1; AJ_WSL_HTC_Global.endpoints[1].txCredits = 2; AJ_WSL_HTC_Global.endpoints[2].txCredits = 10; AJ_WSL_HTC_Global.started = FALSE; AJ_WSL_SPI_ModuleInit(); } uint8_t AJ_WSL_IsDriverStarted() { return AJ_WSL_HTC_Global.started; } void AJ_WSL_HTC_ProcessInterruptCause(void) { uint16_t cause = 0; AJ_Status status = AJ_ERR_SPI_READ; status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_INTR_CAUSE, (uint8_t*)&cause); AJ_ASSERT(status == AJ_OK); cause = LE16_TO_CPU(cause); if (cause & AJ_WSL_SPI_REG_INTR_CAUSE_DATA_AVAILABLE) { AJ_WSL_HTC_ProcessIncoming(); cause = cause ^ AJ_WSL_SPI_REG_INTR_CAUSE_DATA_AVAILABLE; //clear the bit } if (cause & AJ_WSL_SPI_REG_INTR_CAUSE_READ_DONE) { uint16_t clearCause = CPU_TO_LE16(AJ_WSL_SPI_REG_INTR_CAUSE_READ_DONE); status = AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, clearCause); AJ_ASSERT(status == AJ_OK); cause = cause ^ AJ_WSL_SPI_REG_INTR_CAUSE_READ_DONE; } if (cause & AJ_WSL_SPI_REG_INTR_CAUSE_WRITE_DONE) { uint16_t clearCause = CPU_TO_LE16(AJ_WSL_SPI_REG_INTR_CAUSE_WRITE_DONE); status = AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, clearCause); AJ_ASSERT(status == AJ_OK); cause = cause ^ AJ_WSL_SPI_REG_INTR_CAUSE_WRITE_DONE; } if (cause & AJ_WSL_SPI_REG_INTR_CAUSE_CPU_AWAKE) { uint16_t clearCause = CPU_TO_LE16(AJ_WSL_SPI_REG_INTR_CAUSE_CPU_AWAKE); status = AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, clearCause); AJ_ASSERT(status == AJ_OK); cause = cause ^ AJ_WSL_SPI_REG_INTR_CAUSE_CPU_AWAKE; } if (cause & AJ_WSL_SPI_REG_INTR_CAUSE_COUNTER) { uint16_t clearCause = CPU_TO_LE16(AJ_WSL_SPI_REG_INTR_CAUSE_COUNTER); status = AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, clearCause); AJ_ASSERT(status == AJ_OK); cause = cause ^ AJ_WSL_SPI_REG_INTR_CAUSE_COUNTER; } if (cause & ~AJ_WSL_SPI_REG_INTR_CAUSE_DATA_AVAILABLE) { //AJ_InfoPrintf(("Some other interrupt cause as well %x\n", cause)); } } /* * read from the mailbox and do something useful with the HTC message. */ void AJ_WSL_HTC_ProcessIncoming(void) { uint16_t lenRead; uint8_t* bufRead; AJ_BufNode* pNodeHTCBody; uint8_t endpointID; uint8_t flags; uint16_t payloadLength; uint8_t controlBytes[2]; AJ_Status status; status = AJ_WSL_ReadFromMBox(AJ_WSL_SPI_MBOX_0, &lenRead, &bufRead); AJ_ASSERT(status == AJ_OK); // now create a AJ_BufList from the data we read pNodeHTCBody = AJ_BufListCreateNodeExternalZero(bufRead, lenRead, FALSE); pNodeHTCBody->flags = 0; // reset the AJ_BUFNODE_EXTERNAL_BUFFER flag, because I own this now. WMI_Unmarshal(pNodeHTCBody->buffer, "yyqyy", &endpointID, &flags, &payloadLength, &controlBytes[0], &controlBytes[1]); AJ_BufNodePullBytes(pNodeHTCBody, 6); //AJ_WSL_WMI_PrintMessage(pNodeHTCBody); AJ_DumpBytes("HTC_CONTROL", pNodeHTCBody->buffer, pNodeHTCBody->length); /* examine the endpoint of the HTC message*/ if ((flags & AJ_WSL_HTC_RECV_TRAILER_PRESENT) && ((payloadLength - controlBytes[0]) > 0)) { switch (endpointID) { case AJ_WSL_HTC_CONTROL_ENDPOINT: { uint16_t* messageID = (uint16_t*)pNodeHTCBody->buffer; AJ_InfoPrintf(("Read HTC control endpoint, messageID %x\n", *messageID)); switch (*messageID) { case AJ_WSL_HTC_MSG_READY_ID: { /* process the message and change state */ uint16_t readyMessageID; WMI_Unmarshal(pNodeHTCBody->buffer, "qqqyyy", &readyMessageID, &AJ_WSL_HTC_Global.creditCount, &AJ_WSL_HTC_Global.creditSize, &AJ_WSL_HTC_Global.maxEndpoints, &AJ_WSL_HTC_Global.HTCVersion, &AJ_WSL_HTC_Global.maxMessagesPerBundle); /* SIDE EFFECT */ AJ_WarnPrintf(("MSG_READY, credit count %x, credit size:%d\n", AJ_WSL_HTC_Global.creditCount, AJ_WSL_HTC_Global.creditSize)); AJ_WSL_HTC_Global.endpoints[AJ_WSL_HTC_CONTROL_ENDPOINT].state = AJ_WSL_HTC_UNINITIALIZED_RECV_READY; break; } case AJ_WSL_HTC_SERVICE_CONNECT_RESPONSE_ID: { AJ_WarnPrintf(("HTC MSG AJ_WSL_HTC_SERVICE_CONNECT_RESPONSE_ID\n")); break; } default: AJ_WarnPrintf(("HTC MSG ID unknown\n")); AJ_DumpBytes("WMI_SOCKET_RESPONSE", pNodeHTCBody->buffer, pNodeHTCBody->length); break; } break; } case AJ_WSL_HTC_DATA_ENDPOINT1: { // AJ_DumpBytes("DATA ENDPOINT WMI ", pNodeHTCBody->buffer, pNodeHTCBody->length); AJ_WSL_WMI_ProcessWMIEvent(pNodeHTCBody); break; } case AJ_WSL_HTC_DATA_ENDPOINT2: case AJ_WSL_HTC_DATA_ENDPOINT3: case AJ_WSL_HTC_DATA_ENDPOINT4: { AJ_DumpBytes("DATA ENDPOINT WMI_SOCKET_RESPONSE", pNodeHTCBody->bufferStart, pNodeHTCBody->length); AJ_WSL_WMI_ProcessSocketDataResponse(pNodeHTCBody); //AJ_InfoPrintf(("Read HTC data endpoint %d\n", htcHdr.endpointID)); // TODO send the data up to the next API level //AJ_WSL_WMI_PrintMessage(pNodeHTCBody); break; } default: AJ_ErrPrintf(("UNKNOWN Endpoint %d", endpointID)); AJ_ASSERT(FALSE); break; } } /* * Trailers can come on any packet */ if (flags & AJ_WSL_HTC_RECV_TRAILER_PRESENT) { uint16_t packetLength; uint8_t trailerLength = controlBytes[0]; packetLength = payloadLength - trailerLength; //AJ_InfoPrintf(("Read HTC RX trailer, length %d\n", htcHdr.controlBytes[0])); AJ_BufNodePullBytes(pNodeHTCBody, packetLength); // consume the packet, leave the trailer /* * handle multiple trailers per HTC message */ while (trailerLength) { uint8_t trailerType; uint8_t length; //AJ_BufListNodePrintDump(pNodeHTCBody, NULL); WMI_Unmarshal(pNodeHTCBody->buffer, "yy", &trailerType, &length); AJ_BufNodePullBytes(pNodeHTCBody, 2); // consume the trailer trailerLength -= 2; switch (trailerType) { case AJ_WSL_HTC_RXTRAILER_CREDIT_REPORT: { uint8_t credits; uint8_t endpoint; WMI_Unmarshal(pNodeHTCBody->buffer, "yy", &endpoint, &credits); AJ_InfoPrintf(("Add %d credits to endpoint %d\n", credits, endpoint)); AJ_WSL_HTC_Global.endpoints[endpoint].txCredits += credits; break; } default: { AJ_InfoPrintf(("HTC trailer: type not handled %d\n", trailerType)); } } trailerLength -= length; AJ_BufNodePullBytes(pNodeHTCBody, length); // consume the trailer } } //intentionally freeing the buffer here AJ_BufListFreeNodeAndBuffer(pNodeHTCBody, NULL); } ajtcl-15.04b/WSL/aj_wsl_htc.h000066400000000000000000000046021256742562600157360ustar00rootroot00000000000000/** * @file HTC layer function declarations */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #ifndef AJ_WSL_HTC_H_ #define AJ_WSL_HTC_H_ #include "aj_target.h" #include "aj_wsl_target.h" #include "aj_wsl_spi_constants.h" #include "aj_buf.h" #include "aj_debug.h" #ifdef __cplusplus extern "C" { #endif #pragma pack(push, 1) void AJ_WSL_HTC_ModuleInit(void); uint8_t AJ_WSL_IsDriverStarted(void); /* * Endpoints can be in any of these states */ typedef enum _AJ_WSL_HTC_STATE { AJ_WSL_HTC_UNINITIALIZED, AJ_WSL_HTC_UNINITIALIZED_RECV_READY, AJ_WSL_HTC_UNINITIALIZED_SENT_CRED_REQ, AJ_WSL_HTC_INITIALIZED, AJ_WSL_HTC_NO_CREDS, /**< no credits available for this endpoint */ AJ_WSL_HTC_CREDS /**< okay to send packets to the target */ } AJ_WSL_HTC_STATE; typedef struct _WSL_HTC_EP { uint8_t endpointId; uint16_t serviceId; uint16_t txCredits; AJ_WSL_HTC_STATE state; } WSL_HTC_EP; typedef struct _WSL_HTC_CONTEXT { uint16_t creditCount; uint16_t creditSize; uint8_t maxEndpoints; uint8_t HTCVersion; uint8_t maxMessagesPerBundle; WSL_HTC_EP endpoints[AJ_WSL_HTC_ENDPOINT_COUNT_MAX]; uint8_t started; } AJ_WSL_HTC_CONTEXT; /* * HTC header flags */ #define AJ_WSL_HTC_NEED_CREDIT_UPDATE (1 << 0) #define AJ_WSL_HTC_RECV_TRAILER_PRESENT (1 << 1) void AJ_WSL_HTC_ProcessInterruptCause(void); void AJ_WSL_HTC_ProcessIncoming(void); #pragma pack(pop) #ifdef __cplusplus } #endif #endif /* AJ_WSL_HTC_H_ */ ajtcl-15.04b/WSL/aj_wsl_marshal.c000066400000000000000000000203221256742562600165770ustar00rootroot00000000000000/** * @file Marshaling implementation */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #define AJ_MODULE WSL_MARSHAL #include #include "aj_buf.h" #include "aj_wsl_marshal.h" #include "aj_wsl_target.h" #include "aj_wsl_wmi.h" #include "aj_wsl_unmarshal.h" #include "aj_msg.h" #include "aj_debug.h" #ifndef NDEBUG uint8_t dbgWSL_MARSHAL = 5; #endif static uint8_t packetId = 0; uint8_t WMI_MarshalArgsBuf(AJ_BufList* data, const char* sig, uint16_t size, va_list* argpp) { va_list argp; va_copy(argp, *argpp); AJ_BufNode* node; node = AJ_BufListCreateNode(size); uint8_t* ptr = node->buffer; while (*sig) { switch (*sig++) { case (WMI_ARG_UINT64): { uint64_t u64; u64 = (uint64_t)va_arg(argp, uint64_t); memcpy(ptr, &u64, sizeof(uint64_t)); ptr += 8; } break; case (WMI_ARG_UINT32): { uint32_t u32; u32 = (uint32_t)va_arg(argp, uint32_t); memcpy(ptr, &u32, sizeof(uint32_t)); ptr += 4; } break; case (WMI_ARG_IPV4): { uint8_t* IPv4; IPv4 = (uint8_t*)va_arg(argp, uint32_t); memcpy(ptr, IPv4, sizeof(uint8_t) * 4); ptr += 4; } break; case (WMI_ARG_IPV6): { uint16_t* IPv6; IPv6 = (uint16_t*)va_arg(argp, uint32_t); memcpy(ptr, IPv6, sizeof(uint16_t) * 8); ptr += 16; } break; case (WMI_ARG_UINT16): { uint16_t u16; u16 = (uint16_t)va_arg(argp, uint32_t); memcpy(ptr, &u16, sizeof(uint16_t)); ptr += 2; } break; case (WMI_ARG_BYTE): { uint8_t u8; u8 = (uint8_t)va_arg(argp, uint32_t); memcpy(ptr, &u8, sizeof(uint8_t)); ptr += 1; } break; case (WMI_ARG_MAC): { uint8_t* mac; mac = (uint8_t*)va_arg(argp, uint32_t); memcpy(ptr, mac, sizeof(uint8_t) * 6); ptr += 6; } break; case (WMI_ARG_SSID): { char* str; str = (char*)va_arg(argp, char*); memcpy(ptr, str, sizeof(char*) * strlen(str)); ptr += 32; } break; case (WMI_ARG_PASSPHRASE): { char* str; str = (char*)va_arg(argp, char*); memcpy(ptr, str, sizeof(char*) * strlen(str)); ptr += 64; } break; case (WMI_ARG_KEY): { uint8_t* key; key = (uint8_t*)va_arg(argp, uint32_t); memcpy(ptr, key, sizeof(uint8_t) * 32); ptr += 32; } break; default: AJ_ErrPrintf(("WMI_MarshalArgsBuf(): Unknown signature: %c\n", *sig)); return 0; } } va_end(argp); AJ_BufListPushTail(data, node); return 1; } void WMI_MarshalHeader(AJ_BufList* packet, uint8_t endpoint, uint8_t flags) { AJ_BufNode* header; uint16_t size; uint8_t trailer; header = AJ_BufListCreateNode(6); size = AJ_BufListGetSize(packet); trailer = 0x00; memcpy(header->buffer, &endpoint, sizeof(uint8_t)); memcpy(header->buffer + 1, &flags, sizeof(uint8_t)); memcpy(header->buffer + 2, &size, sizeof(uint16_t)); memcpy(header->buffer + 4, &trailer, sizeof(uint8_t)); memcpy(header->buffer + 5, &packetId, sizeof(uint8_t)); packetId++; AJ_BufListPushHead(packet, header); } void WSL_MarshalPacket(AJ_BufList* packet, wsl_wmi_command_list command, ...) { va_list args; uint16_t size; uint16_t cmd; uint32_t zero = 0; AJ_BufNode* cmdid; const char* signature; va_start(args, command); cmd = getCommandId(command); // Socket commands need to get their signature from a different map if (command == WSL_SOCKET) { cmdid = AJ_BufListCreateNode(10); memcpy(cmdid->buffer, &cmd, sizeof(uint16_t)); memcpy(cmdid->buffer + 2, &zero, sizeof(uint32_t)); uint32_t sock_cmd = (uint32_t)va_arg(args, uint32_t); memcpy(cmdid->buffer + 6, &sock_cmd, sizeof(uint32_t)); signature = (char*)getSockSignature((wsl_socket_cmds)sock_cmd); size = getSockSize((wsl_socket_cmds)sock_cmd); AJ_BufListPushTail(packet, cmdid); WMI_MarshalArgsBuf(packet, signature, size - 4, &args); } else if ((command == WSL_SEND) || (command == WSL_SENDTO) || (command == WSL_SENDTO6)) { signature = (char*)getCommandSignature(command); size = getPacketSize(command); WMI_MarshalArgsBuf(packet, signature, size, &args); } else if (command == WSL_BIND6) { signature = (char*)getCommandSignature(command); size = getPacketSize(command); cmdid = AJ_BufListCreateNode(2); uint16_t cmd_bind = 0xf08d; memcpy(cmdid->buffer, &cmd_bind, 2); AJ_BufListPushTail(packet, cmdid); WMI_MarshalArgsBuf(packet, signature, size - 2, &args); } else { cmdid = AJ_BufListCreateNode(sizeof(uint16_t)); memcpy(cmdid->buffer, &cmd, sizeof(uint16_t)); AJ_BufListPushTail(packet, cmdid); signature = (char*)getCommandSignature(command); size = getPacketSize(command); WMI_MarshalArgsBuf(packet, signature + 1, size - 2, &args); } } void WMI_MarshalSend(AJ_BufList* packet, uint32_t sock, AJ_BufNode* data, uint16_t size) { WSL_MarshalPacket(packet, WSL_SEND, 0xa0000000, 0x009c0000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sock, size); // send and sendto are marshaled differently. There packet structure is not similar to other WMI commands AJ_BufListPushTail(packet, data); WMI_MarshalHeader(packet, 2, 1); packetId++; } void WMI_MarshalSendTo(AJ_BufList* packet, uint32_t sock, AJ_BufNode* data, uint16_t size, uint32_t addr, uint16_t port) { AJ_BufNode* zero23; AJ_BufNode* whereto; whereto = AJ_BufListCreateNode(9); zero23 = AJ_BufListCreateNode(23); memset(zero23->buffer, 0, 23); WSL_MarshalPacket(packet, WSL_SENDTO, 0xa0000000, 0x009c0000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sock, size); memcpy(whereto->buffer, &port, 2); memcpy(whereto->buffer + 2, (void*)2, 2); memcpy(whereto->buffer + 4, &addr, 4); memcpy(whereto->buffer + 8, (void*)8, 1); AJ_BufListPushTail(packet, whereto); AJ_BufListPushTail(packet, zero23); AJ_BufListPushTail(packet, data); WMI_MarshalHeader(packet, 2, 1); packetId++; } void WMI_MarshalSendTo6(AJ_BufList* packet, uint32_t sock, AJ_BufNode* data, uint16_t size, uint8_t* addr, uint16_t port) { AJ_BufNode* zero6; zero6 = AJ_BufListCreateNode(6); memset(zero6->buffer, 0, 6); WSL_MarshalPacket(packet, WSL_SENDTO6, 0xa0000000, 0x00bc0000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, sock, 0x1b, 0, 0, 0, 0, 0, 0, 0, 0x03, port, 0, addr, 0, size + 1); AJ_BufListPushTail(packet, zero6); AJ_BufListPushTail(packet, data); //AJ_BufListPushTail(packet, zero6); WMI_MarshalHeader(packet, 2, 1); packetId++; } ajtcl-15.04b/WSL/aj_wsl_marshal.h000066400000000000000000000100611256742562600166030ustar00rootroot00000000000000/** * @file Marshaling function declarations */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #ifndef AJ_WSL_MARSHAL_H_ #define AJ_WSL_MARSHAL_H_ #include "aj_wsl_wmi.h" #include "aj_wsl_spi_constants.h" #include #ifdef __cplusplus extern "C" { #endif /** * Marshal a list of arguments into a AJ_BufList. * * @param data The AJ_BufList to contain the marshaled data * @param sig The signature matching the parameters following it * @param ... The arguments that will be marshaled into the AJ_BufList * in the order they appear. * * @return 1 If the data was successfully marshaled * 0 If there was an error */ uint8_t WMI_MarshalArgsBuf(AJ_BufList* data, const char* sig, uint16_t size, va_list* argpp); /** * Marshals the header onto an already existing packet. * * @param data The AJ_BufList already containing the packet data */ void WMI_MarshalHeader(AJ_BufList* packet, uint8_t endpoint, uint8_t flags); /** * Marshals an entire packet to send over SPI * * @param command The command ID you are marshaling * @param AJ_BufList An empty, malloc'ed buffer list to hold the packet data * @param ... The list of arguments to put into the packet. * (note: the list of arguments must match the signature of the * packet you are trying to marshal. This includes, starting with, * the command ID followed by a 32 bit unsigned int (usually 0), * then the arguments for the packet.) * * @return The size of the packet that was marshaled (not including header) * 0 If there was an error */ void WSL_MarshalPacket(AJ_BufList* packet, wsl_wmi_command_list command, ...); /** * Marshal a IPv6 sendTo packet. * * @param packet The buf list where the marshalled data will be stored * @param sock The socket your sending the packet over * @param data Pointer to the data your sending * @param size Size of the data your sending * @param addr Endpoint address your sending to * @param port The port your sending over */ void WMI_MarshalSendTo6(AJ_BufList* packet, uint32_t sock, AJ_BufNode* data, uint16_t size, uint8_t* addr, uint16_t port); /** * Marshal a IPv4 sendTo packet. * * @param packet The buf list where the marshalled data will be stored * @param sock The socket your sending the packet over * @param data Pointer to the data your sending * @param size Size of the data your sending * @param addr Endpoint address your sending to * @param port The port your sending over */ void WMI_MarshalSendTo(AJ_BufList* packet, uint32_t sock, AJ_BufNode* data, uint16_t size, uint32_t addr, uint16_t port); /** * Marshal a IPv4 send packet. * * @param packet The buf list where the marshalled data will be stored * @param sock The socket your sending the packet over * @param data Pointer to the data your sending * @param size Size of the data your sending */ void WMI_MarshalSend(AJ_BufList* packet, uint32_t sock, AJ_BufNode* data, uint16_t size); #ifdef __cplusplus } #endif #endif /* AJ_WSL_MARSHAL_H_ */ ajtcl-15.04b/WSL/aj_wsl_net.c000066400000000000000000001376311256742562600157520ustar00rootroot00000000000000/** * @file Network functionality implementation */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #define AJ_MODULE WSL_NET #include "aj_target.h" #include "aj_buf.h" #include "aj_wsl_target.h" #include "aj_wsl_spi_constants.h" #include "aj_wsl_wmi.h" #include "aj_wsl_htc.h" #include "aj_wsl_net.h" #include "aj_wsl_unmarshal.h" #include "aj_wsl_marshal.h" #include "aj_wifi_ctrl.h" #include "aj_debug.h" /** * Turn on per-module debug printing by setting this variable to non-zero value * (usually in debugger). */ #ifndef NDEBUG uint8_t dbgWSL_NET = 0; #endif /* * Timeout for all network calls that don't have an explicit timeout passed in */ #define AJ_NET_TIMEOUT 2000 /* * Maximum timeout for DHCP */ #define AJ_IPCONFIG_TIMEOUT 60000 #define AJ_WSL_AF_INET 2 #define AJ_WSL_TCP 1 #define AJ_WSL_UDP 2 extern uint32_t AJ_WSL_MBOX_BLOCK_SIZE; wsl_socket_context AJ_WSL_SOCKET_CONTEXT[5]; static wsl_scan_list list; static AJ_WiFiScanResult wifiCallback = NULL; static void* wifiContext; static uint8_t maxAPs; void AJ_WSL_RegisterWiFiCallback(void* context, AJ_WiFiScanResult callback) { wifiContext = context; wifiCallback = callback; } void AJ_WSL_UnregisterWiFiCallback(void) { wifiCallback = NULL; } /* * Callback function for BSSINFO packets */ void AJ_WSL_BSSINFO_Recv(AJ_BufNode* node) { wsl_scan_item* item; item = (wsl_scan_item*)WMI_UnmarshalScan(node->bufferStart, node->length); memcpy(&list.items[list.size], item, sizeof(wsl_scan_item)); if (wifiCallback) { wifiCallback(wifiContext, list.items[list.size].ssid, list.items[list.size].bssid, list.items[list.size].rssi, list.items[list.size].secType, list.items[list.size].cipherType); } AJ_WSL_Free(item); list.size++; } void WSL_ClearScanList() { int i; for (i = 0; i < list.size; i++) { AJ_WSL_Free(list.items[i].ssid); } AJ_WSL_Free(list.items); list.size = 0; } wsl_scan_item* WSL_InitScanItem(void) { wsl_scan_item* item; item = (wsl_scan_item*)AJ_WSL_Malloc(sizeof(wsl_scan_item)); return item; } void AJ_WSL_InitScanList(uint8_t maxAP) { maxAPs = maxAP; list.items = AJ_WSL_Malloc(sizeof(wsl_scan_item) * maxAPs); list.size = 0; } wsl_scan_item* AJ_WSL_GetScanList(void) { return (wsl_scan_item*)&list; } int list_compare(const void* a, const void* b) { wsl_scan_item* wsl_a = (wsl_scan_item*)a; wsl_scan_item* wsl_b = (wsl_scan_item*)b; return wsl_b->rssi - wsl_a->rssi; } void WSL_PrintScan(void) { int i; for (i = 0; i < list.size; i++) { AJ_AlwaysPrintf(("%-17.17s ", list.items[i].ssid)); AJ_AlwaysPrintf(("RSSI: %u ", list.items[i].rssi)); AJ_AlwaysPrintf(("BSSID: %02x:%02x:%02x:%02x:%02x:%02x\n", list.items[i].bssid[0], list.items[i].bssid[1], list.items[i].bssid[2], list.items[i].bssid[3], list.items[i].bssid[4], list.items[i].bssid[5])); } } void WSL_PrintScanSorted(void) { qsort(&list.items[0], list.size, sizeof(wsl_scan_item), list_compare); WSL_PrintScan(); } void AJ_WSL_WMI_PadPayload(AJ_BufList* bssfilter) { AJ_BufNode* node; uint16_t sizeTail; sizeTail = (AJ_BufListLengthOnWire(bssfilter) % AJ_WSL_MBOX_BLOCK_SIZE); if (sizeTail) { node = AJ_BufListCreateNode(AJ_WSL_MBOX_BLOCK_SIZE - sizeTail); AJ_BufListPushTail(bssfilter, node); } } void AJ_WSL_NET_BSS_FILTER(uint8_t flag) { AJ_InfoPrintf(("AJ_WSL_NET_BSS_FILTER(): SET_BSS_FILTER\n")); AJ_BufList* bssfilter; bssfilter = AJ_BufListCreate(); WSL_MarshalPacket(bssfilter, WSL_SET_BSS_FILTER, 0, flag, 0, 0, 0); WMI_MarshalHeader(bssfilter, 1, 1); AJ_WSL_WMI_PadPayload(bssfilter); AJ_WSL_WMI_QueueWorkItem(0, WSL_SET_BSS_FILTER, AJ_WSL_HTC_DATA_ENDPOINT1, bssfilter); } void AJ_WSL_SetProbedSSID(const char* ssid, uint8_t flag) { AJ_BufList* probed_ssid; probed_ssid = AJ_BufListCreate(); WSL_MarshalPacket(probed_ssid, WSL_SET_PROBED_SSID, 0, 0, flag, strlen(ssid), ssid); WMI_MarshalHeader(probed_ssid, 1, 1); AJ_WSL_WMI_PadPayload(probed_ssid); AJ_WSL_WMI_QueueWorkItem(0, WSL_SET_PROBED_SSID, AJ_WSL_HTC_DATA_ENDPOINT1, probed_ssid); } void AJ_WSL_NET_add_cipher_key(uint8_t keyIndex, uint8_t* key, uint8_t keyLength) { AJ_BufList* add_key; add_key = AJ_BufListCreate(); static const uint8_t zero_mac[6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; WSL_MarshalPacket(add_key, WSL_ADD_CIPHER_KEY, 0, 0, 0x02, 0x03, keyLength, 0, 0, key, 0x03, &zero_mac); WMI_MarshalHeader(add_key, 1, 1); AJ_WSL_WMI_PadPayload(add_key); AJ_WSL_WMI_QueueWorkItem(0, WSL_ADD_CIPHER_KEY, AJ_WSL_HTC_DATA_ENDPOINT1, add_key); } void AJ_WSL_NET_set_scan_params(void) { AJ_BufList* packet; AJ_InfoPrintf(("AJ_WSL_NET_scan(): SET_SCAN_PARAMS\n")); packet = AJ_BufListCreate(); WSL_MarshalPacket(packet, WSL_SET_SCAN_PARAMS, 0, 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00, 0x00, 0x0000, 0x2f03, 0x00000000); WMI_MarshalHeader(packet, 1, 1); AJ_WSL_WMI_PadPayload(packet); AJ_WSL_WMI_QueueWorkItem(0, WSL_SET_SCAN_PARAMS, AJ_WSL_HTC_DATA_ENDPOINT1, packet); } AJ_Status AJ_WSL_NET_scan(void) { AJ_Status status; AJ_BufList* start_scan; wsl_work_item* item; AJ_WSL_NET_BSS_FILTER(1); AJ_WSL_NET_set_scan_params(); AJ_InfoPrintf((("AJ_WSL_NET_scan(): START_SCAN\n"))); start_scan = AJ_BufListCreate(); WSL_MarshalPacket(start_scan, WSL_START_SCAN, 0, 0, 0, 0, 0, 0, 0, 0); WMI_MarshalHeader(start_scan, 1, 1); AJ_WSL_WMI_PadPayload(start_scan); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_SCAN), AJ_WSL_HTC_DATA_ENDPOINT1, start_scan); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_SCAN), &item, AJ_NET_TIMEOUT); if (item && (status == AJ_OK)) { if (item->itemType == WSL_NET_SCAN) { AJ_InfoPrintf(("AJ_WSL_NET_scan(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t toss; uint32_t error; WMI_Unmarshal(item->node->buffer, "quu", &WMIEvent, &toss, &error); if (error != 0) { AJ_ErrPrintf(("AJ_WSL_NET_scan(): Scan error, scan returned: %u", error)); status = AJ_ERR_INVALID; } } else { AJ_WarnPrintf(("AJ_WSL_NET_scan(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } return status; } void AJ_WSL_NET_scan_stop(void) { AJ_InfoPrintf(("AJ_WSL_NET_scan_stop(): SET_BSS_FILTER\n")); AJ_WSL_NET_BSS_FILTER(0); } AJ_Status AJ_WSL_NET_SetPassphrase(const char* SSID, const char* passphrase, uint32_t passLen) { AJ_Status status = AJ_OK; AJ_BufList* passphraseList; passphraseList = AJ_BufListCreate(); uint8_t* hexPassphrase = NULL; if (passLen == 64) { hexPassphrase = (uint8_t*)AJ_WSL_Malloc(32); status = AJ_HexToRaw(passphrase, 64, hexPassphrase, 32); if (status == AJ_OK) { WSL_MarshalPacket(passphraseList, WMI_SET_PMK, 0, hexPassphrase, 32); } } else { WSL_MarshalPacket(passphraseList, WSL_SET_PASSPHRASE, 0, SSID, passphrase, strlen(SSID), passLen); } if (status == AJ_OK) { WMI_MarshalHeader(passphraseList, 1, 1); AJ_InfoPrintf(("AJ_WSL_NET_SetPassphrase(): SET_PASSPHRASE\n")); AJ_WSL_WMI_PadPayload(passphraseList); //AJ_BufListPrintDumpContinuous(passphraseList); status = AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_SET_PASSPHRASE), AJ_WSL_HTC_DATA_ENDPOINT1, passphraseList); } if (hexPassphrase != NULL) { AJ_MemZeroSecure(hexPassphrase, 32); AJ_WSL_Free(hexPassphrase); } return status; } AJ_Status AJ_WSL_NET_SetHiddenAP(uint8_t hidden) { AJ_Status status; AJ_BufList* hiddenList; hiddenList = AJ_BufListCreate(); WSL_MarshalPacket(hiddenList, WSL_SET_HIDDEN_AP, 0, hidden); WMI_MarshalHeader(hiddenList, 1, 1); AJ_InfoPrintf(("AJ_WSL_NET_SetHiddenAP(): AP_HIDDEN_SSID\n")); AJ_WSL_WMI_PadPayload(hiddenList); //AJ_BufListPrintDumpContinuous(passphraseList); status = AJ_WSL_WMI_QueueWorkItem(0, WSL_SET_HIDDEN_AP, AJ_WSL_HTC_DATA_ENDPOINT1, hiddenList); return status; } AJ_Status AJ_WSL_NET_SetPowerMode(uint8_t mode) { AJ_Status status; AJ_BufList* power_mode; power_mode = AJ_BufListCreate(); WSL_MarshalPacket(power_mode, WSL_SET_POWER_MODE, 0, mode); WMI_MarshalHeader(power_mode, 1, 1); AJ_WSL_WMI_PadPayload(power_mode); //AJ_BufListPrintDumpContinuous(power_mode); status = AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_SET_POWER_MODE), AJ_WSL_HTC_DATA_ENDPOINT1, power_mode); return status; } void AJ_WSL_NET_StackInit(void) { AJ_InfoPrintf(("AJ_WSL_NET_StackInit(): STACK_INIT\n")); AJ_BufList* stack_init; stack_init = AJ_BufListCreate(); WSL_MarshalPacket(stack_init, WSL_SOCKET, WSL_SOCK_STACK_INIT, 0x04, 0x01, 0x05, 0x08, 0x1f); WMI_MarshalHeader(stack_init, 1, 1); AJ_WSL_WMI_PadPayload(stack_init); //AJ_BufListPrintDumpContinuous(stack_init); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_STACK_INIT), AJ_WSL_HTC_DATA_ENDPOINT1, stack_init); } /* * Get an AP's mac address from a SSID scan list */ static uint8_t getMacFromSSID(const char* ssid, uint8_t* mac, wsl_scan_list* list) { int i; for (i = 0; i < list->size; i++) { if (0 == strcmp(list->items[i].ssid, ssid)) { memcpy(mac, list->items[i].bssid, 6); return 1; } } return 0; } #define AJ_WSL_CONNECT_WAIT 500 #define AJ_WSL_CONNECT_TIMEOUT 20000 AJ_EXPORT AJ_Status AJ_WSL_NET_connect(const char* SSID, const char* passphrase, WSL_NET_AUTH_MODE auth, WSL_NET_CRYPTO_TYPE crypto, uint8_t softAP) { AJ_Status status = AJ_OK; wsl_scan_list* list; list = (wsl_scan_list*)AJ_WSL_GetScanList(); AJ_WSL_NET_SetPowerMode(2); uint8_t bss_mac[6]; // Open auth does not require you to explicitly set the BSSID so this secondary scan is not needed if (!softAP) { if (auth != WSL_NET_AUTH_NONE) { AJ_Time timer; uint8_t found = 0; AJ_InitTimer(&timer); while (!found) { AJ_WSL_InitScanList(AJ_WSL_SCAN_LIST_SIZE); AJ_WSL_SetProbedSSID(SSID, 1); status = AJ_WSL_NET_scan(); // Some kind of scan error if (status != AJ_OK) { WSL_ClearScanList(); continue; } AJ_WSL_NET_scan_stop(); if (AJ_GetElapsedTime(&timer, TRUE) > AJ_WSL_CONNECT_TIMEOUT) { AJ_ErrPrintf(("AJ_WSL_NET_connect() Could not find the access point %s\n", SSID)); WSL_ClearScanList(); return AJ_ERR_FAILURE; } // Find the SSID you want to connect to in the second scan list if (getMacFromSSID(SSID, bss_mac, list)) { WSL_ClearScanList(); found = 1; break; } else { WSL_ClearScanList(); AJ_Sleep(AJ_WSL_CONNECT_WAIT); continue; } } if (crypto != WSL_NET_CRYPTO_WEP) { status = AJ_WSL_NET_SetPassphrase(SSID, passphrase, strlen(passphrase)); if (status != AJ_OK) { return status; } } } } { AJ_BufList* connect; AJ_BufList* connectOut; static const uint8_t zero_mac[6] = { 0, 0, 0, 0, 0, 0 }; uint8_t connect_mac[6]; wsl_work_item* item = NULL; connect = AJ_BufListCreate(); /* Three different ways connect can be called. * 1. SoftAP: The devices mac is fetched and used * 2. Using Auth: The SSID's mac is found and used * 3. Open auth: A zero'ed mac is used */ if (softAP) { WSL_MarshalPacket(connect, WSL_SET_SOFT_AP, 0, 0x04, 0x01, auth, crypto, 0x00, crypto, 0x00, strlen(SSID), SSID, 0x0, getDeviceMac(), 0x0044, 0x0000); WMI_MarshalHeader(connect, 1, 1); } else if ((auth != WSL_NET_AUTH_NONE) && (crypto != WSL_NET_CRYPTO_WEP)) { WSL_MarshalPacket(connect, WSL_CONNECT, 0, 0x01, 0x01, auth, crypto, 0x00, crypto, 0x00, strlen(SSID), SSID, 0x0, &bss_mac, 0x0044, 0x0000); WMI_MarshalHeader(connect, 1, 1); } else { // if the auth mode is open, use zero_mac, and set flags to zero WSL_MarshalPacket(connect, WSL_CONNECT, 0, 0x01, 0x01, auth, crypto, 0x00, crypto, 0x00, strlen(SSID), SSID, 0x0, &zero_mac, 0x0000, 0x0000); WMI_MarshalHeader(connect, 1, 1); } AJ_InfoPrintf(("AJ_WSL_NET_connect(): CONNECT\n")); AJ_WSL_WMI_PadPayload(connect); //AJ_BufListPrintDumpContinuous(connect); connectOut = AJ_BufListCreateCopy(connect); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_CONNECT), AJ_WSL_HTC_DATA_ENDPOINT1, connectOut); if (softAP) { AJ_AlwaysPrintf(("Waiting for a connection to the softAP %s\n", SSID)); memcpy(&connect_mac, (uint8_t*)getDeviceMac(), sizeof(connect_mac)); while (memcmp((uint8_t*)&connect_mac, (uint8_t*)getDeviceMac(), 6) == 0) { status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_CONNECT), &item, AJ_TIMER_FOREVER); if (item && (status == AJ_OK)) { if (item->itemType == WSL_NET_CONNECT) { AJ_InfoPrintf(("AJ_WSL_NET_connect(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t toss; uint16_t channel; WMI_Unmarshal(item->node->buffer, "quqM", &WMIEvent, &toss, &channel, &connect_mac); } else { AJ_WarnPrintf(("AJ_WSL_NET_connect(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } } else { status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_CONNECT), &item, AJ_TIMER_FOREVER); if (item && (status == AJ_OK)) { AJ_WSL_WMI_FreeWorkItem(item); } } AJ_BufListFree(connect, 1); return status; } } void AJ_WSL_PrintIP(uint32_t ip) { uint8_t* ptr; ptr = (uint8_t*)&ip; AJ_AlwaysPrintf(("%i.%i.%i.%i\n", *(ptr + 3), *(ptr + 2), *(ptr + 1), *(ptr))); } AJ_Status AJ_WSL_ip6config(uint32_t mode, uint8_t* globalAddr, uint8_t* localAddr, uint8_t* gateway, uint8_t* exAddr, uint32_t linkPrefix, uint32_t globalPrefix, uint32_t gwPrefix, uint32_t glbPrefixExt) { AJ_Status status; if (mode != IPCONFIG_QUERY) { AJ_ErrPrintf(("AJ_WSL_ip6config(): Can only query IPV6, cannot use mode %lu\n", mode)); return AJ_ERR_UNEXPECTED; } AJ_BufList* ip6config; ip6config = AJ_BufListCreate(); //First zeros are for v4 WSL_MarshalPacket(ip6config, WSL_SOCKET, WSL_SOCK_IP6CONFIG, 0x60, 0, 0, 0, 0, globalAddr, localAddr, gateway, exAddr, linkPrefix, globalPrefix, gwPrefix, glbPrefixExt); WMI_MarshalHeader(ip6config, 1, 1); AJ_WSL_WMI_PadPayload(ip6config); //AJ_BufListPrintDumpContinuous(ip6config); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP6CONFIG), AJ_WSL_HTC_DATA_ENDPOINT1, ip6config); { wsl_work_item* item = NULL; status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP6CONFIG), &item, AJ_NET_TIMEOUT); if (item && (status == AJ_OK)) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP6CONFIG)) { AJ_InfoPrintf(("AJ_WSL_ip6config(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t reserved; uint32_t _command; uint32_t _handle; uint32_t _error; uint32_t _mode; uint32_t _ipv4 = 0; uint32_t _ipv4mask = 0; uint32_t _ipv4gateway = 0; WMI_Unmarshal(item->node->buffer, "quuuuuuuu6666uuuu", &WMIEvent, &reserved, &_command, &_handle, &_error, &_mode, &_ipv4, &_ipv4mask, &_ipv4gateway, localAddr, globalAddr, gateway, exAddr, &linkPrefix, &globalPrefix, &gwPrefix, &glbPrefixExt); //AJ_DumpBytes("IPV6", item->node->buffer, 0x60); } else { AJ_WarnPrintf(("AJ_WSL_ip6config(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } return status; } AJ_Status AJ_WSL_ipconfig(uint32_t mode, uint32_t* ip, uint32_t* mask, uint32_t* gateway) { AJ_Status status = AJ_ERR_DHCP; uint16_t ipv6[8] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; wsl_work_item* item = NULL; switch (mode) { case (IPCONFIG_QUERY): { AJ_InfoPrintf(("AJ_WSL_ipconfig(): IPCONFIG_QUERY\n")); AJ_BufList* ipconfig; ipconfig = AJ_BufListCreate(); WSL_MarshalPacket(ipconfig, WSL_SOCKET, WSL_SOCK_IPCONFIG, 0x60, 0, ip, mask, gateway, &ipv6, &ipv6, &ipv6, &ipv6, 0, 0, 0, 0); WMI_MarshalHeader(ipconfig, 1, 1); AJ_WSL_WMI_PadPayload(ipconfig); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), AJ_WSL_HTC_DATA_ENDPOINT1, ipconfig); { status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), &item, AJ_IPCONFIG_TIMEOUT); if (item && (status == AJ_OK)) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG)) { AJ_InfoPrintf(("AJ_WSL_ipconfig(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t reserved; uint32_t _command; uint32_t _handle; uint32_t _error; uint32_t _mode; WMI_Unmarshal(item->node->buffer, "quuuuuuuu", &WMIEvent, &reserved, &_command, &_handle, &_error, &_mode, ip, mask, gateway); if (ip != 0) { status = AJ_OK; } } else { AJ_WarnPrintf(("AJ_WSL_ipconfig(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } } break; case (IPCONFIG_STATIC): AJ_InfoPrintf(("AJ_WSL_ipconfig(): IPCONFIG_STATIC\n")); AJ_BufList* ipconfig_dhcp_static; ipconfig_dhcp_static = AJ_BufListCreate(); WSL_MarshalPacket(ipconfig_dhcp_static, WSL_SOCKET, WSL_SOCK_IPCONFIG, 0x60, 1, ip, mask, gateway, &ipv6, &ipv6, &ipv6, &ipv6, 0, 0, 0, 0); WMI_MarshalHeader(ipconfig_dhcp_static, 1, 1); AJ_WSL_WMI_PadPayload(ipconfig_dhcp_static); //AJ_BufListPrintDumpContinuous(ipconfig_dhcp_static); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), AJ_WSL_HTC_DATA_ENDPOINT1, ipconfig_dhcp_static); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), &item, AJ_IPCONFIG_TIMEOUT); if (item && (status == AJ_OK)) { AJ_WSL_WMI_FreeWorkItem(item); } AJ_Sleep(1000); break; case (IPCONFIG_DHCP): AJ_InfoPrintf(("AJ_WSL_ipconfig(): IPCONFIG_DHCP\n")); AJ_BufList* ipconfig_dhcp; ipconfig_dhcp = AJ_BufListCreate(); WSL_MarshalPacket(ipconfig_dhcp, WSL_SOCKET, WSL_SOCK_IPCONFIG, 0x60, 2, ip, mask, gateway, &ipv6, &ipv6, &ipv6, &ipv6, 0, 0, 0, 0); WMI_MarshalHeader(ipconfig_dhcp, 1, 1); AJ_WSL_WMI_PadPayload(ipconfig_dhcp); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), AJ_WSL_HTC_DATA_ENDPOINT1, ipconfig_dhcp); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), &item, AJ_IPCONFIG_TIMEOUT); if (item && (status == AJ_OK)) { AJ_WSL_WMI_FreeWorkItem(item); } AJ_Sleep(100); break; } return status; } #define DHCP_WAIT 100 /* * create the WMI request to open a socket on the target device */ int8_t AJ_WSL_NET_socket_open(uint16_t domain, uint16_t type, uint16_t protocol) { AJ_Status status; int8_t handle = INVALID_SOCKET; AJ_BufList* open; open = AJ_BufListCreate(); WSL_MarshalPacket(open, WSL_SOCKET, WSL_SOCK_OPEN, 0x0c, domain, type, protocol); WMI_MarshalHeader(open, 1, 1); AJ_WSL_WMI_PadPayload(open); //AJ_BufListPrintDumpContinuous(open); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_OPEN), AJ_WSL_HTC_DATA_ENDPOINT1, open); // wait until the command completes { wsl_work_item* item = NULL; status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_OPEN), &item, AJ_NET_TIMEOUT); if (status != AJ_OK) { //AJ_WSL_WMI_FreeWorkItem(item); return -1; } if (item && (status == AJ_OK)) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_OPEN)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_open(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t reserved; uint32_t _command; uint32_t _handle; uint32_t _error; uint32_t _mode; WMI_Unmarshal(item->node->buffer, "quuuuu", &WMIEvent, &reserved, &_command, &_handle, &_error, &_mode); AJ_InfoPrintf((" Socket Open: handle %08lx error %08lx\n", _handle, _error)); handle = AJ_WSL_FindOpenSocketContext(); if (handle != INVALID_SOCKET) { AJ_WSL_SOCKET_CONTEXT[handle].targetHandle = _handle; AJ_WSL_SOCKET_CONTEXT[handle].valid = TRUE; AJ_WSL_SOCKET_CONTEXT[handle].domain = domain; AJ_WSL_SOCKET_CONTEXT[handle].type = type; AJ_WSL_SOCKET_CONTEXT[handle].protocol = protocol; } } else { AJ_WarnPrintf(("AJ_WSL_NET_socket_open(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } AJ_Sleep(100); return handle; } /* * create the WMI request to close a socket on the target device */ AJ_Status AJ_WSL_NET_socket_close(AJ_WSL_SOCKNUM sock) { AJ_Status status; AJ_BufList* close; if (AJ_WSL_SOCKET_CONTEXT[sock].valid == TRUE) { close = AJ_BufListCreate(); WSL_MarshalPacket(close, WSL_SOCKET, WSL_SOCK_CLOSE, 0x0, AJ_WSL_SOCKET_CONTEXT[sock].targetHandle); WMI_MarshalHeader(close, 1, 1); AJ_WSL_WMI_PadPayload(close); //AJ_BufListPrintDumpContinuous(close); AJ_WSL_WMI_QueueWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE), AJ_WSL_HTC_DATA_ENDPOINT1, close); // wait until the command completes do { wsl_work_item* item = NULL; status = AJ_WSL_WMI_WaitForWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE), &item, AJ_NET_TIMEOUT); if (item && (status == AJ_OK)) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_close(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t reserved; uint32_t _command; uint32_t _handle; uint32_t _error; uint32_t _mode; WMI_Unmarshal(item->node->buffer, "quuuuu", &WMIEvent, &reserved, &_command, &_handle, &_error, &_mode); AJ_InfoPrintf((" Socket close: handle %08lx error %08lx\n", _handle, _error)); if (_handle == AJ_WSL_SOCKET_CONTEXT[sock].targetHandle) { AJ_WSL_SOCKET_CONTEXT[sock].targetHandle = UINT32_MAX; AJ_WSL_SOCKET_CONTEXT[sock].valid = FALSE; } AJ_WSL_WMI_FreeWorkItem(item); break; // waited until close command completed } else { AJ_InfoPrintf(("AJ_WSL_NET_socket_close(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } while (1); } return status; } /* * create the WMI request to bind a socket on the target device to an address and port */ AJ_Status AJ_WSL_NET_socket_bind(AJ_WSL_SOCKNUM sock, uint32_t addr, uint16_t port) { AJ_Status status; AJ_BufList* bind; wsl_work_item* item; bind = AJ_BufListCreate(); WSL_MarshalPacket(bind, WSL_SOCKET, WSL_SOCK_BIND, 0x0, AJ_WSL_SOCKET_CONTEXT[sock].targetHandle, port, AJ_WSL_UDP, &addr, 0x8); WMI_MarshalHeader(bind, 1, 1); AJ_WSL_WMI_PadPayload(bind); //AJ_BufListPrintDumpContinuous(bind); AJ_WSL_WMI_QueueWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_BIND), AJ_WSL_HTC_DATA_ENDPOINT1, bind); status = AJ_WSL_WMI_WaitForWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_BIND), &item, AJ_NET_TIMEOUT); if (item && (status == AJ_OK)) { AJ_WSL_WMI_FreeWorkItem(item); } return status; } AJ_Status AJ_WSL_NET_socket_bind6(AJ_WSL_SOCKNUM sock, uint8_t* addr, uint16_t port) { AJ_Status status; AJ_BufList* bind; wsl_work_item* item; bind = AJ_BufListCreate(); WSL_MarshalPacket(bind, WSL_BIND6, 0x0, 0x03, 0x24, AJ_WSL_SOCKET_CONTEXT[sock].targetHandle, 0x00, port, addr, 0x00, 0x00020383, 0x0002001c); WMI_MarshalHeader(bind, 1, 1); AJ_WSL_WMI_PadPayload(bind); //AJ_BufListPrintDumpContinuous(bind); AJ_WSL_WMI_QueueWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_BIND), AJ_WSL_HTC_DATA_ENDPOINT1, bind); status = AJ_WSL_WMI_WaitForWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_BIND), &item, AJ_NET_TIMEOUT); if (item && (status == AJ_OK)) { AJ_WSL_WMI_FreeWorkItem(item); } return status; } /* * create the WMI request to connect to a socket */ AJ_Status AJ_WSL_NET_socket_connect(AJ_WSL_SOCKNUM sock, uint32_t addr, uint16_t port, uint16_t family) { AJ_Status status; AJ_BufList* connectV4; wsl_work_item* item = NULL; connectV4 = AJ_BufListCreate(); WSL_MarshalPacket(connectV4, WSL_SOCKET, WSL_SOCK_CONNECT, 0x0, AJ_WSL_SOCKET_CONTEXT[sock].targetHandle, port, family, &addr, 0x8); WMI_MarshalHeader(connectV4, 1, 1); AJ_WSL_WMI_PadPayload(connectV4); //AJ_BufListPrintDumpContinuous(connectV4); AJ_WSL_WMI_QueueWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CONNECT), AJ_WSL_HTC_DATA_ENDPOINT1, connectV4); do { status = AJ_WSL_WMI_WaitForWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CONNECT), &item, AJ_NET_TIMEOUT); if (item && (status == AJ_OK)) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CONNECT)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_connect(): WORK ITEM RECEIVED\n")); AJ_WSL_WMI_FreeWorkItem(item); break; } else { AJ_WarnPrintf(("AJ_WSL_NET_socket_connect(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } while (1); return status; } /* * Poll over a socket until there is data ready or till a timeout * * Returns -2 on timeout * -1 on interrupted * 1 on success * 0 on close * */ int16_t AJ_WSL_NET_socket_select(AJ_WSL_SOCKNUM sock, uint32_t timeout) { AJ_Time timer; wsl_work_item* peek; AJ_Status status; int16_t ret = 0; // Check if the socket is valid if ((sock >= AJ_WSL_SOCKET_MAX) || (sock < 0)) { // tried to get data from an invalid socket, return an error return ret; } if (AJ_WSL_SOCKET_CONTEXT[sock].valid == FALSE) { // tried to get data from an invalid socket, return the data read from the stash AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, 1); AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList = AJ_BufListCreate(); //flush the queue return ret; } AJ_InitTimer(&timer); // There are 5 conditions that we need to check for // 1. If we got an interrupted work item // 2. If there is data in the RX stash // 3. If there is a RX work item in the queue // 4. If there is a socket close work item in the queue // 5. If the timeout has expired while (1) { status = AJ_QueuePeek(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &peek); //AJ_AlwaysPrintf(("Item type = %u\n", peek->itemType)); if ((status == AJ_OK) && (peek->itemType == WSL_NET_INTERUPT)) { // Pull the interrupted item off because we dont need it anymore status = AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &peek, 0); if (peek && (status == AJ_OK)) { AJ_WSL_WMI_FreeWorkItem(peek); } ret = -1; break; } else if (AJ_BufListLengthOnWire(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList) > 0) { ret = 1; break; } else if ((status == AJ_OK) && (peek->itemType == WSL_NET_DATA_RX)) { ret = 1; break; } else if ((status == AJ_OK) && (peek->itemType == WSL_NET_CLOSE || peek->itemType == WSL_NET_DISCONNECT || peek->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE))) { wsl_work_item* clear; // Pull the close work item off the queue AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &peek, 0); // Socket was closed so tear down the connections AJ_WSL_SOCKET_CONTEXT[sock].valid = FALSE; // Removed any stashed data AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, 1); // Reallocate a new stash AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList = AJ_BufListCreate(); // Reset the queue, any work items are now invalid since the socket was closed while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workTxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue); AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[sock].workTxQueue); AJ_WSL_WMI_FreeWorkItem(peek); ret = 0; break; } else if (AJ_GetElapsedTime(&timer, TRUE) >= timeout) { ret = -2; break; } } return ret; } void AJ_WSL_NET_signal_interrupted(AJ_WSL_SOCKNUM sock) { wsl_work_item* item = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); item->itemType = WSL_NET_INTERUPT; item->sequenceNumber = 0; item->list = NULL; item->node = NULL; item->size = 0; item->endpoint = 0; if (AJ_WSL_SOCKET_CONTEXT[sock].valid == FALSE) { return; } // Push the interrupted work item to the front of the RX queue AJ_QueuePushFromISR(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &item); } /************************************************************************/ /* there isn't a command to recv....you have to grab data as it comes....*/ /************************************************************************/ /* * create the WMI request to bind a socket on the target device to an address and port */ int16_t AJ_WSL_NET_socket_recv(AJ_WSL_SOCKNUM sock, uint8_t* buffer, uint32_t sizeBuffer, uint32_t timeout) { // AJ_InfoPrintf(("AJ_WSL_NET_socket_recv()\n")); int16_t ret = -1; uint32_t rx = sizeBuffer; uint32_t stash = 0; // read from stash first. uint16_t stashLength; if ((sock >= AJ_WSL_SOCKET_MAX) || (sock < 0)) { // tried to get data from an invalid socket, return an error return ret; } if (AJ_WSL_SOCKET_CONTEXT[sock].valid == FALSE) { wsl_work_item* clear; // tried to get data from an invalid socket, return the data read from the stash AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, 1); AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList = AJ_BufListCreate(); //flush the queue while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue); return ret; } if (AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList) { stashLength = AJ_BufListLengthOnWire(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList); if (stashLength != 0) { stash = min(rx, stashLength); AJ_BufListCopyBytes(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, stash, buffer); AJ_BufListPullBytes(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, stash); // shift left-overs toward the start. ret = stash; sizeBuffer -= stash; } } // wait until there is data if (sizeBuffer) { wsl_work_item* item = NULL; AJ_Status status; // the stash was depleted and you want more data if (AJ_WSL_SOCKET_CONTEXT[sock].valid == FALSE) { // tried to get data from an invalid socket, return the data read from the stash return ret; } status = AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &item, timeout); if (item && (status == AJ_OK)) { if (item->itemType == WSL_NET_INTERUPT) { // At this point we dont care about the interrupted signal but we are expecting a RX packet // so we need to pull the next item off the queue AJ_WSL_WMI_FreeWorkItem(item); status = AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &item, timeout); } if ((status == AJ_OK) && (item->itemType == WSL_NET_DISCONNECT)) { AJ_InfoPrintf(("Disconnect received\n")); // Clean up the network queues int i; for (i = 0; i < AJ_WSL_SOCKET_MAX; i++) { wsl_work_item* clear; AJ_WSL_SOCKET_CONTEXT[i].valid = FALSE; // Removed any stashed data AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[i].stashedRxList, 1); // Reallocate a new stash AJ_WSL_SOCKET_CONTEXT[i].stashedRxList = AJ_BufListCreate(); // Reset the queue, any work items are now invalid since the socket was closed while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[i].workRxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[i].workRxQueue); AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue); } ret = -1; } else if ((status == AJ_OK) && (item->itemType == WSL_NET_CLOSE || item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE))) { wsl_work_item* clear; // Pull the close work item off the queue AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &item, 0); // Socket was closed so tear down the connections AJ_WSL_SOCKET_CONTEXT[sock].valid = FALSE; // Removed any stashed data AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, 1); // Reallocate a new stash AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList = AJ_BufListCreate(); // Reset the queue, any work items are now invalid since the socket was closed while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workTxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue); AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[sock].workTxQueue); ret = -1; } else if ((status == AJ_OK) && (item->itemType == WSL_NET_DATA_RX)) { //AJ_InfoPrintf(("=====DATA RX ITEM RECEIVED=====\n")); //AJ_DumpBytes("DATA RX ITEM", item->node->buffer, item->size); rx = min(sizeBuffer, item->size); memcpy(buffer + stash, item->node->buffer, rx); AJ_BufNodePullBytes(item->node, rx); // check node: if not empty assign to stash. if (item->node->length) { AJ_BufListPushTail(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, item->node); item->node = NULL; } ret = rx + stash; } else { AJ_InfoPrintf(("AJ_WSL_NET_socket_recv(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } else { ret = 0; AJ_InfoPrintf(("socket_recv timed out\n")); } } return ret; } int16_t AJ_WSL_NET_socket_send(uint32_t socket, uint8_t* data, uint16_t size, uint32_t timeout) { AJ_Status status; AJ_InfoPrintf(("AJ_WSL_NET_socket_send()\n")); AJ_BufList* send; AJ_BufNode* tx_data_node; if (AJ_WSL_SOCKET_CONTEXT[socket].valid == FALSE) { AJ_InfoPrintf(("send on invalid socket %lu\n", socket)); return -1; } send = AJ_BufListCreate(); tx_data_node = AJ_BufListCreateNodeExternalZero(data, size, FALSE); WMI_MarshalSend(send, AJ_WSL_SOCKET_CONTEXT[socket].targetHandle, tx_data_node, size); //send now contains the header info for the two part packet your sending //now write send to the MBOX then the data your sending AJ_WSL_WMI_PadPayload(send); AJ_WSL_WMI_QueueWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX), AJ_WSL_HTC_DATA_ENDPOINT2, send); /* * Because these are blocking sends, we need to wait until the data has been passed to the target. */ do { wsl_work_item* item = NULL; status = AJ_WSL_WMI_WaitForWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX), &item, timeout); if (item && (status == AJ_OK)) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_send(): WORK ITEM RECEIVED\n")); AJ_WSL_WMI_FreeWorkItem(item); break; } else { AJ_WarnPrintf(("AJ_WSL_NET_socket_send(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } while (1); return size; } int16_t AJ_WSL_NET_socket_sendto6(uint32_t socket, uint8_t* data, uint16_t size, uint8_t* addr, uint16_t port, uint32_t timeout) { AJ_Status status; AJ_InfoPrintf(("AJ_WSL_NET_socket_sendto()\n")); AJ_BufList* send; AJ_BufNode* tx_data_node; if (AJ_WSL_SOCKET_CONTEXT[socket].valid == FALSE) { AJ_InfoPrintf(("sendto on invalid socket %ld\n", socket)); return -1; } send = AJ_BufListCreate(); tx_data_node = AJ_BufListCreateNodeExternalZero(data, size, FALSE); WMI_MarshalSendTo6(send, AJ_WSL_SOCKET_CONTEXT[socket].targetHandle, tx_data_node, size, addr, port); //send now contains the header info for the two part packet your sending //now write send to the MBOX then the data your sending AJ_WSL_WMI_PadPayload(send); //AJ_BufListPrintDumpContinuous(send); AJ_WSL_WMI_QueueWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX), AJ_WSL_HTC_DATA_ENDPOINT2, send); wsl_work_item* item = NULL; /* * Because these are blocking sends, we need to wait until the data has been passed to the target. */ do { status = AJ_WSL_WMI_WaitForWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX), &item, timeout); if (item && (status == AJ_OK)) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_send(): WORK ITEM RECEIVED\n")); AJ_WSL_WMI_FreeWorkItem(item); break; } else { AJ_InfoPrintf(("AJ_WSL_NET_socket_sendto(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } while (1); return size; } int16_t AJ_WSL_NET_socket_sendto(uint32_t socket, uint8_t* data, uint16_t size, uint32_t addr, uint16_t port, uint32_t timeout) { AJ_Status status; AJ_InfoPrintf(("AJ_WSL_NET_socket_sendto()\n")); AJ_BufList* send; AJ_BufNode* tx_data_node; if (AJ_WSL_SOCKET_CONTEXT[socket].valid == FALSE) { AJ_InfoPrintf(("sendto on invalid socket %ld\n", socket)); return -1; } send = AJ_BufListCreate(); tx_data_node = AJ_BufListCreateNodeExternalZero(data, size, FALSE); WMI_MarshalSendTo(send, AJ_WSL_SOCKET_CONTEXT[socket].targetHandle, tx_data_node, size, AJ_ByteSwap32(addr), port); //send now contains the header info for the two part packet your sending //now write send to the MBOX then the data your sending AJ_WSL_WMI_PadPayload(send); AJ_WSL_WMI_QueueWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX), AJ_WSL_HTC_DATA_ENDPOINT2, send); wsl_work_item* item = NULL; /* * Because these are blocking sends, we need to wait until the data has been passed to the target. */ do { status = AJ_WSL_WMI_WaitForWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX), &item, timeout); if (item && (status == AJ_OK)) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_send(): WORK ITEM RECEIVED\n")); AJ_WSL_WMI_FreeWorkItem(item); break; } else { AJ_InfoPrintf(("AJ_WSL_NET_socket_sendto(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } while (1); return size; } #define AJ_SOCK_OPTS_OFFSET 19 AJ_Status AJ_WSL_NET_set_sock_options(uint32_t socket, uint32_t level, uint32_t optname, uint32_t optlen, uint8_t* optval) { AJ_Status status; AJ_InfoPrintf(("AJ_WSL_NET_set_sock_options()\n")); wsl_work_item* item; AJ_BufList* opts; AJ_BufNode* trailer; uint32_t total_length; opts = AJ_BufListCreate(); total_length = AJ_SOCK_OPTS_OFFSET + optlen; WSL_MarshalPacket(opts, WSL_SOCKET, WSL_SOCK_SETSOCKOPT, total_length, AJ_WSL_SOCKET_CONTEXT[socket].targetHandle, level, optname, optlen); if (optname == WSL_JOIN_GROUP) { trailer = AJ_BufListCreateNode((optlen / 2) + 2); memcpy(opts->tail->buffer + opts->tail->length - 17, optval, (optlen / 2) + 1); memcpy(trailer->buffer, optval + 17, 15); } else { trailer = AJ_BufListCreateNode(optlen + 3); memset(trailer->buffer, 0, optlen + 3); } AJ_BufListPushTail(opts, trailer); WMI_MarshalHeader(opts, 1, 1); //AJ_BufListPrintDumpContinuous(opts); AJ_WSL_WMI_QueueWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_SETSOCKOPT), AJ_WSL_HTC_DATA_ENDPOINT1, opts); // wait until the command completes status = AJ_WSL_WMI_WaitForWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_SETSOCKOPT), &item, AJ_NET_TIMEOUT); if (item && (status == AJ_OK)) { AJ_WSL_WMI_FreeWorkItem(item); } return status; } AJ_Status AJ_WSL_NET_set_hostname(const char* hostname) { AJ_Status status; AJ_InfoPrintf(("===== SET HOSTNAME ====\n")); wsl_work_item* item; AJ_BufList* host; host = AJ_BufListCreate(); WSL_MarshalPacket(host, WSL_SOCKET, WSL_SOCK_IP_HOST_NAME, 0x21, hostname); WMI_MarshalHeader(host, 1, 1); AJ_WSL_WMI_PadPayload(host); //AJ_BufListPrintDumpContinuous(host); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP_HOST_NAME), AJ_WSL_HTC_DATA_ENDPOINT1, host); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP_HOST_NAME), &item, AJ_NET_TIMEOUT); if (item && (status == AJ_OK)) { AJ_WSL_WMI_FreeWorkItem(item); } return status; } AJ_Status AJ_WSL_NET_ip6config_router_prefix(const uint8_t* ipv6addr, uint32_t prefix_length, uint32_t lifetimePrefix, uint32_t lifetimeValid) { AJ_InfoPrintf(("===== ip6config router prefix ====\n")); AJ_BufList* prefix; prefix = AJ_BufListCreate(); WSL_MarshalPacket(prefix, WSL_SOCKET, WSL_SOCK_IP6CONFIG_ROUTER_PREFIX, 0x21, ipv6addr, prefix_length, lifetimePrefix, lifetimeValid); WMI_MarshalHeader(prefix, 1, 1); AJ_WSL_WMI_PadPayload(prefix); //AJ_BufListPrintDumpContinuous(prefix); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP6CONFIG_ROUTER_PREFIX), AJ_WSL_HTC_DATA_ENDPOINT1, prefix); return AJ_OK; } AJ_Status AJ_WSL_NET_ipconfig_dhcp_pool(const uint32_t* startIP, const uint32_t* endIP, uint32_t leaseTime) { AJ_InfoPrintf(("===== ipconfig dhcp pool ====\n")); AJ_BufList* pool; pool = AJ_BufListCreate(); WSL_MarshalPacket(pool, WSL_SOCKET, WSL_SOCK_IPCONFIG_DHCP_POOL, 0x0c, startIP, endIP, leaseTime); WMI_MarshalHeader(pool, 1, 1); AJ_WSL_WMI_PadPayload(pool); //AJ_BufListPrintDumpContinuous(pool); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_SOCK_IPCONFIG_DHCP_POOL), AJ_WSL_HTC_DATA_ENDPOINT1, pool); return AJ_OK; } AJ_Status AJ_WSL_NET_disconnect(void) { AJ_Status status; AJ_BufList* disconnect; wsl_work_item* item; AJ_InfoPrintf((("AJ_WSL_NET_disconnect(): DISCONNECT\n"))); disconnect = AJ_BufListCreate(); WSL_MarshalPacket(disconnect, WSL_DISCONNECT, 0, 0, 0, 0, 0, 0, 0, 0); WMI_MarshalHeader(disconnect, 1, 1); AJ_WSL_WMI_PadPayload(disconnect); //AJ_BufListPrintDumpContinuous(disconnect); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_DISCONNECT), AJ_WSL_HTC_DATA_ENDPOINT1, disconnect); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_DISCONNECT), &item, AJ_NET_TIMEOUT); if (item && (status == AJ_OK)) { AJ_WSL_WMI_FreeWorkItem(item); } return status; } ajtcl-15.04b/WSL/aj_wsl_net.h000066400000000000000000000336761256742562600157630ustar00rootroot00000000000000/** * @file Network functionality function declarations */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #ifndef AJ_WSL_NET_H_ #define AJ_WSL_NET_H_ #include "aj_target.h" #include "aj_wsl_target.h" #include "aj_status.h" #include "aj_wifi_ctrl.h" #ifdef __cplusplus extern "C" { #endif #ifndef __cplusplus #pragma pack(push, 1) #endif typedef int8_t AJ_WSL_SOCKNUM; #define AJ_WSL_SCAN_LIST_SIZE 32 #define INVALID_SOCKET (-1) #define AJ_WSL_SOCKET_MAX 5 typedef struct _wsl_scan_item { char* ssid; uint8_t rssi; uint8_t bssid[6]; uint8_t secType; uint8_t cipherType; } wsl_scan_item; typedef struct _wsl_scan_list { wsl_scan_item* items; uint16_t size; } wsl_scan_list; typedef enum { WSL_NET_SCAN, WSL_NET_CONNECT, WSL_NET_DISCONNECT, WSL_NET_IPCONFIG, WSL_NET_IP6CONFIG, WSL_NET_OPEN, WSL_NET_CLOSE, WSL_NET_BIND, WSL_NET_DATA_RX, WSL_NET_DATA_TX, WSL_NET_INTERUPT, WSL_NET_SETSOCKOPTS } AJ_WSL_NET_COMMAND; typedef enum { WSL_NET_AUTH_NONE = 0x01, WSL_NET_AUTH_WPA = 0x02, WSL_NET_AUTH_WPA2 = 0x04, WSL_NET_AUTH_WPA_PSK = 0x08, WSL_NET_AUTH_WPA2_PSK = 0x10, WSL_NET_AUTH_WPA_CCKM = 0x20, WSL_NET_AUTH_WPA2_CCKM = 0x40 }WSL_NET_AUTH_MODE; typedef enum { WSL_NET_CRYPTO_NONE = 0x01, WSL_NET_CRYPTO_WEP = 0x02, WSL_NET_CRYPTO_TKIP = 0x04, WSL_NET_CRYPTO_AES = 0x08 }WSL_NET_CRYPTO_TYPE; typedef enum { WSL_AF_INET6 = 3, WSL_AF_INET = 2 }WSL_SOCK_DOMAIN; typedef enum { WSL_SOCK_STREAM = 1, WSL_SOCK_DGRAM = 2 }WSL_SOCK_TYPE; typedef enum { WSL_ADD_MEMBERSHIP = 12, WSL_DROP_MEMBERSHIP = 13, WSL_JOIN_GROUP = 83, WSL_LEAVE_GROUP = 84 }WSL_MULTICAST_OPT; typedef enum { WSL_IPPROTO_IP = 0, WSL_IPPROTO_UDP = 17, WSL_IPPROTO_TCP = 6 }WSL_MCAST_LEVEL; #define AJ_IPV4_MCAST_GROUP 0xe0000071 //0x710000e0 //224.0.0.113 - Alljoyn Multicast Group #define AJ_INADDR_ANY 0x00000000 //0.0.0.0 /** * Connect to a wifi network * * @param SSID The SSID of the network * @param passphrase The access points password * @param auth The type of authentication (NONE, WPA, WPA2 ...) * @param crypto The type of cryptography used (WEP, TKIP, AES ...) */ AJ_EXPORT AJ_Status AJ_WSL_NET_connect(const char* SSID, const char* passphrase, WSL_NET_AUTH_MODE auth, WSL_NET_CRYPTO_TYPE crypto, uint8_t softAP); /** * Disconnect from the current wifi network * */ AJ_EXPORT AJ_Status AJ_WSL_NET_disconnect(void); /** * Used to configure IP parameters * * @param mode What type of configuration are you doing (QUERY, STATIC, DHCP) * @param ip IP address (either an uninitialized pointer (DHCP/QUERY) or * an actual address for static ip configuration * @param mask subnet mask * @param gateway router gateway * @param softAP Flag to start up a softAP rather than connect to an access point * * @return success code */ AJ_EXPORT AJ_Status AJ_WSL_ipconfig(uint32_t mode, uint32_t* ip, uint32_t* mask, uint32_t* gateway); /** * Send data over a socket * * @param socket The socket your sending over * @param data Pointer to the data your sending * @param size Size of the data your sending * @param timeout Max time to try to send * * @return Number of bytes sent (not done yet) */ AJ_EXPORT int16_t AJ_WSL_NET_socket_send(uint32_t socket, uint8_t* data, uint16_t size, uint32_t timeout); /** * Send to a specific address * * @param socket Socket your sending data over * @param data Pointer to the data your sending * @param size Size of the data * @param addr IP address you wish to send to * @param port Port to send over * @param timeout How long you try and send the data * * @return Number of bytes that was sent */ AJ_EXPORT int16_t AJ_WSL_NET_socket_sendto(uint32_t socket, uint8_t* data, uint16_t size, uint32_t addr, uint16_t port, uint32_t timeout); /** * Open a socket * * @param domain Domain your opening (INET, INET6) * @param type Type of socket (SOCK_STREAM_TYPE, SOCK_DGRAM_TYPE) * @param protocol Usually zero * * @return Returns a socket number */ AJ_EXPORT int8_t AJ_WSL_NET_socket_open(uint16_t domain, uint16_t type, uint16_t protocol); /** * Ping an address * * @param addr Address to send a ping to * @param size Size of the ping packet */ AJ_EXPORT void AJ_WSL_NET_ping(uint32_t addr, uint32_t size); /** * Close a socket * * @param socketHandle The handle of the socket to close * @return AJ_OK on success * AJ_ERR_LINK_DEAD if the socket didn't exist * AJ_ERR_NULL if there was an unexpected error */ AJ_EXPORT AJ_Status AJ_WSL_NET_socket_close(AJ_WSL_SOCKNUM socketHandle); /** * Connect to another socket * * @param sock The opened socket your using * @param addr The address of the machine your connecting to * @param port The open port at the address * @param family The socket family of the connection (AF_INET, AF_INET6) * * @return 1 on connection success */ AJ_EXPORT AJ_Status AJ_WSL_NET_socket_connect(AJ_WSL_SOCKNUM sock, uint32_t addr, uint16_t port, uint16_t family); /** * Bind to a port * * @param sock The socket handle your binding the port to * @param addr Address to associate to that port * @param port The port your binding to * * @return 1 on bind success * @return AJ_OK on success * AJ_ERR_LINK_DEAD if the socket didn't exist * AJ_ERR_NULL if there was an unexpected error */ AJ_EXPORT AJ_Status AJ_WSL_NET_bind(AJ_WSL_SOCKNUM sock, uint32_t addr, uint16_t port); /** * Receive bytes of data over a socket * * @param sock Socket to receive data * @param buffer Buffer to put the data into * @param size How much data is coming * @param timeout How long to try and reveive for * * @return Number of bytes received */ AJ_EXPORT int16_t AJ_WSL_NET_socket_recv(AJ_WSL_SOCKNUM sock, uint8_t* buffer, uint32_t sizeBuffer, uint32_t timeout); /** * Set custom options for an opened socket * * @param socket The socket your configuring * @param level Options are: WSL_IPPROTO_IP, WSL_IPPROTO_UDP, WSL_IPPROTO_TCP * @param optname What option your setting: WSL_ADD_MEMBERSHIP, * WSL_DROP_MEMBERSHIP, * WSL_JOIN_GROUP, * WSL_LEAVE_GROUP * @param optlen The length of the options that follow * @param optval An array of option values e.g. {AJ_IPV4_MCAST_GROUP, AJ_INADDR_ANY} * * @return success or error code */ AJ_EXPORT AJ_Status AJ_WSL_NET_set_sock_options(uint32_t socket, uint32_t level, uint32_t optname, uint32_t optlen, uint8_t* optval); /* * Set the host name on the QCA4002 */ AJ_EXPORT AJ_Status AJ_WSL_NET_set_hostname(const char* hostname); /** * Used to configure IPV6 router prefix * * @param ipv6addr IP address * @param gateway router gateway * @param softAP Flag to start up a softAP rather than connect to an access point * * @return success code */ AJ_EXPORT AJ_Status AJ_WSL_NET_ip6config_router_prefix(const uint8_t* ipv6addr, uint32_t prefix_length, uint32_t lifetimePrefix, uint32_t lifetimeValid); /** * Used to configure DHCP pool address range and lease time * * @param startIP first IP address to give out * @param endIP last IP address to give out * @param leaseTime amount of time a DHCP address is valid * * @return success code */ AJ_EXPORT AJ_Status AJ_WSL_NET_ipconfig_dhcp_pool(const uint32_t* startIP, const uint32_t* endIP, uint32_t leaseTime); /** * Get an initialized scan item * * @return A new scan item */ wsl_scan_item* WSL_InitScanItem(void); /** * Push an interrupted work item onto the front of the queue. Used to break * out of receive if needed. * * @param sock Socket to send the interrupted call to */ void AJ_WSL_NET_signal_interrupted(AJ_WSL_SOCKNUM sock); /** * Select (poll) for data over a socket. This will return when data is available. * * @param sock Socket to poll for data on * @param timeout Timeout * * @return 1 if data is avaliable * <1 if there was an error */ int16_t AJ_WSL_NET_socket_select(AJ_WSL_SOCKNUM sock, uint32_t timeout); /** * Send UDP data over IPv6 * * @param socket The socket to send over * @param data Pointer to the data your sending * @param size Size of the data your sending * @param addr Endpoint address your sending to * @param port Port your sending over * @param timeout Timeout value (unused) * * @return Number of bytes sent */ int16_t AJ_WSL_NET_socket_sendto6(uint32_t socket, uint8_t* data, uint16_t size, uint8_t* addr, uint16_t port, uint32_t timeout); /** * Bind an IPv4 address to a port * * @param sock Opened socket * @param addr Address to bind to * @param port Port to bind to * * @return AJ_OK if the port was successfully bound. */ AJ_Status AJ_WSL_NET_socket_bind(AJ_WSL_SOCKNUM sock, uint32_t addr, uint16_t port); /** * Bind an IPv6 address to a port * * @param sock Opened socket * @param addr Address to bind to * @param port Port to bind to * * @return AJ_OK if the port was successfully bound. */ AJ_Status AJ_WSL_NET_socket_bind6(AJ_WSL_SOCKNUM sock, uint8_t* addr, uint16_t port); /** * Configure your IPv6 address * * @param mode Mode (DHCP, Static) * @param globalAddr Global IPv6 address (returned if DHCP, provided if static) * @param localAddr Local IPv6 address (returned if DHCP, provided if static) * @param gateway Gateway IPv6 address (returned if DHCP, provided if static) * @param exAddr External Address (returned if DHCP, provided if static) * @param linkPrefix Link prefix * @param globalPrefix Global prefix * @param gwPrefix * @param gblPrefixExt Global prefix extension * * @return AJ_OK on success */ AJ_Status AJ_WSL_ip6config(uint32_t mode, uint8_t* globalAddr, uint8_t* localAddr, uint8_t* gateway, uint8_t* exAddr, uint32_t linkPrefix, uint32_t globalPrefix, uint32_t gwPrefix, uint32_t glbPrefixExt); /** * Add a cipher key. Used for WEP security * * @param keyIndex Index where the target will hold the key * @param key Pointer to the hex key * @param keyLength Length of the key * * @return AJ_OK on success */ void AJ_WSL_NET_add_cipher_key(uint8_t keyIndex, uint8_t* key, uint8_t keyLength); /** * Set the passphrase for WPA and WPA2 security * * @param SSID SSID for this passphrase * @param passphrase ASCII passphrase * @param passLen Length of the passphrase * * @return AJ_OK on success */ AJ_Status AJ_WSL_NET_SetPassphrase(const char* SSID, const char* passphrase, uint32_t passLen); /** * Set the power mode on the target * * @param mode Mode to set * * @return AJ_OK if the mode was set sucessfully */ AJ_Status AJ_WSL_NET_SetPowerMode(uint8_t mode); /** * Initialize the scan list for scanning SSID's * * @param maxAP Maximum number of AP's stored in the scan. */ void AJ_WSL_InitScanList(uint8_t maxAP); /** * Initiate a wifi scan. This will populate a list of SSID/RSSI/BSSID's */ AJ_Status AJ_WSL_NET_scan(void); /** * Stop an already started SSID scan */ void AJ_WSL_NET_scan_stop(void); /** * Clear and free a scan list. This function has to be called after * calling AJ_WSL_InitScanList() or it will leak memory */ void WSL_ClearScanList(); /** * Get a stored scan list. This function will not return a valid list * unless the scanning functions were called properly. * * @return A pointer to the list of SSID's */ wsl_scan_item* AJ_WSL_GetScanList(void); /** * Set the softAP to hidden * * @param hidden 1 for hidden, 0 for not hidden */ AJ_Status AJ_WSL_NET_SetHiddenAP(uint8_t hidden); /** * Print the list of scanned SSID's */ void WSL_PrintScanSorted(void); /** * Register a callback function to be called whenever a BSSINFO (scan) packet * is received over the wire. * * @param context Context pointer * @param callback Function pointer to the callback function */ void AJ_WSL_RegisterWiFiCallback(void* context, AJ_WiFiScanResult callback); /** * Unregister a BSSINFO (scan) callback function. This function should be called * after a scan has completed or else the callback will be called later on * when connecting to an access point. */ void AJ_WSL_UnregisterWiFiCallback(void); #ifndef __cplusplus #pragma pack(pop) #endif #ifdef __cplusplus } #endif #endif /* AJ_WSL_NET_H_ */ ajtcl-15.04b/WSL/aj_wsl_spi.h000066400000000000000000000103141256742562600157500ustar00rootroot00000000000000/** * @file SPI function declarations */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #ifndef AJ_WSL_SPI_H_ #define AJ_WSL_SPI_H_ #include "aj_target.h" #include "aj_status.h" #include "aj_wsl_target.h" #include "aj_wsl_spi_constants.h" #include "aj_buf.h" #ifdef __cplusplus extern "C" { #endif #pragma pack(push, 1) /* * These methods are */ void AJ_WSL_SPI_ModuleInit(void); /* * These methods are SPI module interfaces, and are target-specific implementations */ void AJ_WSL_SPI_InitializeSPIController(void); void AJ_WSL_SPI_ShutdownSPIController(void); /* * signal to the SPI hardware if more data is coming in this transaction */ #define AJ_WSL_SPI_CONTINUE 0 #define AJ_WSL_SPI_END 1 /* * Define the layout of the SPI commands between the host and target */ #define AJ_WSL_SPI_WRITE 0 #define AJ_WSL_SPI_READ 1 #define AJ_WSL_SPI_EXTERNAL 0 #define AJ_WSL_SPI_INTERNAL 1 #define AJ_WSL_SPI_REG_READ ((AJ_WSL_SPI_READ << 1) | AJ_WSL_SPI_INTERNAL) #define AJ_WSL_SPI_REG_WRITE ((AJ_WSL_SPI_WRITE << 1) | AJ_WSL_SPI_INTERNAL) #define AJ_WSL_SPI_DMA_READ ((AJ_WSL_SPI_READ << 1) | AJ_WSL_SPI_EXTERNAL) #define AJ_WSL_SPI_DMA_WRITE ((AJ_WSL_SPI_WRITE << 1) | AJ_WSL_SPI_EXTERNAL) #define AJ_WSL_SPI_REG_EXTERNAL_WRITE ((AJ_WSL_SPI_WRITE << 1) | AJ_WSL_SPI_EXTERNAL) #define AJ_WSL_SPI_HDR_REG_READ ((uint16_t) AJ_WSL_SPI_REG_READ << 14) #define AJ_WSL_SPI_HDR_REG_WRITE ((uint16_t) AJ_WSL_SPI_REG_WRITE << 14) #define AJ_WSL_SPI_HDR_DMA_READ ((uint16_t) AJ_WSL_SPI_DMA_READ << 14) #define AJ_WSL_SPI_HDR_DMA_WRITE ((uint16_t) AJ_WSL_SPI_DMA_WRITE << 14) typedef struct _wsl_spi_command { uint16_t cmd_addr : 14, cmd_reg : 1, cmd_rx : 1; } wsl_spi_command; typedef struct _wsl_spi_status { uint8_t ready : 1, wr_err : 1, rd_err : 1, addr_err : 1, res : 4; } wsl_spi_status; /* * Global definitions */ extern wsl_spi_command qsc_HOST_INT_STATUS; AJ_Status AJ_WSL_SPI_WriteByte8(uint8_t spi_data, uint8_t end); AJ_Status AJ_WSL_SPI_WriteByte16(uint16_t spi_data, uint8_t end); /* * Helper functions */ AJ_Status AJ_WSL_GetDMABufferSize(uint16_t* dmaSize); AJ_Status AJ_WSL_SetDMABufferSize(uint16_t dmaSize); AJ_Status AJ_WSL_GetWriteBufferSpaceAvailable(uint16_t* spaceAvailable); AJ_Status AJ_WSL_GetReadBufferSpaceAvailable(uint16_t* spaceAvailable); AJ_Status AJ_WSL_SPI_RegisterRead(uint16_t reg, uint8_t* spi_data); AJ_Status AJ_WSL_SPI_RegisterWrite(uint16_t reg, uint16_t spi_data); AJ_Status AJ_WSL_SPI_DMAWriteStart(uint16_t targetAddress); AJ_Status AJ_WSL_SPI_DMAWrite8(uint16_t targetAddress, uint16_t len, uint8_t* spi_data); AJ_Status AJ_WSL_SPI_DMAWrite16(uint16_t targetAddress, uint16_t len, uint16_t* spi_data); AJ_Status AJ_WSL_SPI_DMARead16(uint16_t targetAddress, uint16_t len, uint16_t* spi_data); AJ_Status AJ_WSL_SPI_HostControlRegisterWrite(uint32_t targetRegister, uint8_t increment, uint16_t cbLen, uint8_t* spi_data); AJ_Status AJ_WSL_SPI_HostControlRegisterRead(uint32_t targetRegister, uint8_t increment, uint16_t cbLen, uint8_t* spi_data); AJ_EXPORT AJ_Status AJ_WSL_ReadFromMBox(uint8_t box, uint16_t* len, uint8_t** buf); AJ_EXPORT AJ_Status AJ_WSL_WriteBufListToMBox(uint8_t box, uint8_t endpoint, uint16_t len, AJ_BufList* list); #pragma pack(pop) #ifdef __cplusplus } #endif #endif /* AJ_WSL_SPI_H_ */ ajtcl-15.04b/WSL/aj_wsl_spi_constants.h000066400000000000000000000164731256742562600200600ustar00rootroot00000000000000/** * @file Constants related to the QCA4004 wifi module */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #ifndef AJ_WSL_SPI_CONSTANTS_H_ #define AJ_WSL_SPI_CONSTANTS_H_ #pragma pack(push, 1) #define AJ_WSL_SPI_MBOX_SIZE 0xFF #define AJ_WSL_SPI_MBOX_0 0x0 #define AJ_WSL_SPI_MBOX_0_END (AJ_WSL_SPI_MBOX_0 + AJ_WSL_SPI_MBOX_SIZE) #define AJ_WSL_SPI_MBOX_0_EOM (AJ_WSL_SPI_MBOX_0_END + 1) #define AJ_WSL_SPI_MBOX_ALIAS_SIZE 0x7FF #define AJ_WSL_SPI_MBOX_0_ALIAS 0x800 #define AJ_WSL_SPI_MBOX_0_ALIAS_END (AJ_WSL_SPI_MBOX_0_ALIAS + AJ_WSL_SPI_MBOX_ALIAS_SIZE) #define AJ_WSL_SPI_MBOX_0_EOM_ALIAS (AJ_WSL_SPI_MBOX_0_ALIAS_END + 1) //Address for AHB Read Access #define AJ_WSL_SPI_HOST_INT_STATUS 0x400 //CPU Sourced Interrupt Status #define AJ_WSL_SPI_CPU_INT_STATUS 0x401 //Credit Counter Direct Access #define AJ_WSL_SPI_CREDIT_COUNT 0x420 //Data transfer value #define AJ_WSL_SPI_TARGET_VALUE 0x474 //Data transfer write from the host #define AJ_WSL_SPI_TARGET_ADDR_WRITE 0x478 //Data transfer read from the target #define AJ_WSL_SPI_TARGET_ADDR_READ 0x047C //SPI Slave Interface #define AJ_WSL_SPI_SPI_CONFIG 0x480 //SPI Status #define AJ_WSL_SPI_SPI_STATUS 0x481 /* * SPI internal registers * description followed by register address */ //DMA size ( #define AJ_WSL_SPI_REG_DMA_SIZE 0x0100 //Write buffer space available #define AJ_WSL_SPI_REG_WRBUF_SPC_AVA 0x0200 //Read buffer byte available #define AJ_WSL_SPI_REG_RDBUF_BYTE_AVA 0x0300 //SPI configuration #define AJ_WSL_SPI_REG_SPI_CONFIG 0x0400 //SPI status #define AJ_WSL_SPI_REG_SPI_STATUS 0x0500 //Host control register access byte size #define AJ_WSL_SPI_REG_HOST_CTRL_BYTE_SIZE 0x0600 //Host control register configure #define AJ_WSL_SPI_REG_HOST_CTRL_CONFIG 0x0700 //Host control register read port #define AJ_WSL_SPI_REG_HOST_CTRL_RD_PORT 0x0800 //Host control register write port #define AJ_WSL_SPI_REG_HOST_CTRL_WR_PORT 0x0A00 //Interrupt cause #define AJ_WSL_SPI_REG_INTR_CAUSE 0x0C00 #define AJ_WSL_SPI_REG_INTR_CAUSE_DATA_AVAILABLE (1 << 0) #define AJ_WSL_SPI_REG_INTR_CAUSE_READ_DONE (1 << 9) #define AJ_WSL_SPI_REG_INTR_CAUSE_WRITE_DONE (1 << 8) #define AJ_WSL_SPI_REG_INTR_CAUSE_CPU_AWAKE (1 << 6) #define AJ_WSL_SPI_REG_INTR_CAUSE_COUNTER (1 << 5) //Interrupt enable #define AJ_WSL_SPI_REG_INTR_ENABLE 0x0D00 //Write buffer Watermark #define AJ_WSL_SPI_REG_WRBUF_WATERMARK 0x1300 //Read buffer lookahead 1 #define AJ_WSL_SPI_REG_RDBUF_LOOKAHEAD1 0x1400 //Read buffer lookahead 2 #define AJ_WSL_SPI_REG_RDBUF_LOOKAHEAD2 0x1500 // magic value from driver context data #define AJ_WSL_AR4100_BUFFER_SIZE 1664 #define AJ_WSL_SPI_TARGET_CLOCK_SPEED_ADDR 0x00428878 #define AJ_WSL_SPI_TARGET_FLASH_PRESENT_ADDR 0x0042880C #define AJ_WSL_SPI_TARGET_MBOX_BLOCKSZ_ADDR 0x0042886C typedef enum { WMI_CONNECT_CMDID = 0x0001, WMI_RECONNECT_CMDID = 0x0002, WMI_DISCONNECT_CMDID = 0x0003, WMI_SYNCHRONIZE_CMDID = 0x0004, WMI_START_SCAN_CMDID = 0x0007, WMI_SET_SCAN_PARAMS_CMDID = 0x0008, WMI_SET_BSS_FILTER_CMDID = 0x0009, WMI_SET_PROBED_SSID_CMDID = 0x000a, WMI_SET_LISTEN_INT_CMDID = 0x000b, WMI_ALLOW_AGGR_CMDID = 0xf01b, WMI_SET_CHANNEL_CMDID = 0xf042, WMI_GET_PMK_CMDID = 0xf047, WMI_SET_POWER_MODE_CMDID = 0x0012, WMI_SET_PASSPHRASE_CMDID = 0xf048, WMI_STORERECALL_CONFIGURE_CMDID = 0xf05e, WMI_STORERECALL_RECALL_CMDID = 0xf05f, WMI_STORERECALL_HOST_READY_CMDID = 0xf060, /*Socket commands*/ WMI_SOCKET_CMDID = 0xf08d, WMI_SET_SOFT_AP_CMDID = 0xf00f } wsl_wmi_command_id; typedef enum _wsl_SOCKET_CMDS { WSL_SOCK_OPEN = 0x0, /*Open a socket*/ WSL_SOCK_CLOSE = 0x1, /*Close existing socket*/ WSL_SOCK_CONNECT = 0x2, /*Connect to a peer*/ WSL_SOCK_BIND = 0x3, /*Bind to interface*/ WSL_SOCK_SELECT = 0x6, /*Wait for specified file descriptors*/ WSL_SOCK_SETSOCKOPT = 0x7, /*Set specified socket option*/ WSL_SOCK_GETSOCKOPT = 0x8, /*Get socket option*/ WSL_SOCK_ERRNO, /*Get error number for last error*/ WSL_SOCK_IPCONFIG = 0xA, /*Set static IP information, or get current IP config*/ WSL_SOCK_PING, WSL_SOCK_STACK_INIT = 0xC, /*Command to initialize stack*/ WSL_SOCK_STACK_MISC, /*Used to exchanges miscellaneous info, e.g. reassembly etc*/ WSL_SOCK_PING6, WSL_SOCK_IP6CONFIG = 0xF, /*Set static IP information, or get current IP config*/ WSL_SOCK_IPCONFIG_DHCP_POOL, /*Set DHCP Pool */ WSL_SOCK_IP6CONFIG_ROUTER_PREFIX, /* Set ipv6 router prefix */ WSL_SOCK_IP_SET_TCP_EXP_BACKOFF_RETRY, /* set tcp exponential backoff retry */ WSL_SOCK_IP_SET_IP6_STATUS, /* set ip6 module status enable/disable */ WSL_SOCK_IP_DHCP_RELEASE, /* Release the DHCP IP Addres */ WSL_SOCK_IP_SET_TCP_RX_BUF, /* set tcp rx buffer space */ WSL_SOCK_IP_HOST_NAME = 0x1d /* Command to set the hostname on the QCA4002 */ } wsl_socket_cmds; typedef enum _WSL_WMI_EVENTID { WSL_WMI_READY_EVENTID = 0x1001, WSL_WMI_CONNECT_EVENTID = 0x1002, WSL_WMI_DISCONNECT_EVENTID = 0x1003, WSL_BSS_INFO_EVENTID = 0x1004, WSL_CMDERROR_EVENTID = 0x1005, WSL_REGDOMAIN_EVENTID = 0x1006, WSL_UNKNOWN1_EVENTID = 0x1008, WSL_WMI_SCAN_COMPLETE_EVENTID = 0x100A, WSL_WMI_APLIST_EVENTID = 0x1017, WSL_WMI_PEER_NODE_EVENTID = 0x101B, WSL_WMI_WLAN_VERSION_EVENTID = 0x101E, WSL_UNKNOWN2_EVENTID = 0x103b, WSL_WMI_SOCKET_RESPONSE_EVENTID = 0x9016, } WSL_WMI_EVENTID; enum AJ_WSL_HTC_ENDPOINT_COUNT { AJ_WSL_HTC_CONTROL_ENDPOINT = 0, AJ_WSL_HTC_DATA_ENDPOINT1 = 1, AJ_WSL_HTC_DATA_ENDPOINT2 = 2, AJ_WSL_HTC_DATA_ENDPOINT3 = 3, AJ_WSL_HTC_DATA_ENDPOINT4 = 4, AJ_WSL_HTC_ENDPOINT_COUNT_MAX, }; /* * RX trailer type Ids */ #define AJ_WSL_HTC_RXTRAILER_CREDIT_REPORT 1 // message id values #define AJ_WSL_HTC_MSG_READY_ID 1 #define AJ_WSL_HTC_CONNECT_SERVICE_ID 2 #define AJ_WSL_HTC_SERVICE_CONNECT_RESPONSE_ID 3 #define AJ_WSL_HTC_SETUP_COMPLETE_ID 4 #define AJ_WSL_HTC_HOST_READY_ID 5 #pragma pack(pop) #endif /* AJ_WSL_SPI_CONSTANTS_H_ */ ajtcl-15.04b/WSL/aj_wsl_spi_mbox.c000066400000000000000000000556631256742562600170100ustar00rootroot00000000000000/** * @file SPI MBOX implementation */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #define AJ_MODULE WSL_SPI_MBOX #include "aj_target.h" #include "aj_wsl_target.h" #include "aj_status.h" #include "aj_wsl_spi.h" #include "aj_wsl_htc.h" #include "aj_buf.h" #include "aj_rtos.h" #include "aj_bsp.h" /** * Turn on per-module debug printing by setting this variable to non-zero value * (usually in debugger). */ #ifndef NDEBUG uint8_t dbgWSL_SPI_MBOX = 0; #endif extern AJ_WSL_HTC_CONTEXT AJ_WSL_HTC_Global; uint32_t AJ_WSL_MBOX_BLOCK_SIZE; void AJ_WSL_SPI_ModuleInit(void) { AJ_BufList_ModuleInit(); } AJ_Status AJ_WSL_GetDMABufferSize(uint16_t* dmaSize) { AJ_Status status = AJ_ERR_SPI_READ; uint16_t size = 0; status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_DMA_SIZE, (uint8_t*)&size); *dmaSize = size & ((1 << 12) - 1); return status; } AJ_Status AJ_WSL_SetDMABufferSize(uint16_t dmaSize) { AJ_ASSERT(0 != dmaSize); dmaSize &= ((1 << 12) - 1); // mask the reserved bits return AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_DMA_SIZE, dmaSize); } AJ_Status AJ_WSL_GetWriteBufferSpaceAvailable(uint16_t* spaceAvailable) { AJ_Status status = AJ_ERR_SPI_READ; uint16_t space = 0; status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_WRBUF_SPC_AVA, (uint8_t*)&space); *spaceAvailable = space & ((1 << 12) - 1); AJ_InfoPrintf(("write buffer space available: %x %d\n", space, *spaceAvailable)); return status; } AJ_Status AJ_WSL_GetReadBufferSpaceAvailable(uint16_t* spaceAvailable) { AJ_Status status = AJ_ERR_SPI_READ; uint16_t space = 0; status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_RDBUF_BYTE_AVA, (uint8_t*)&space); *spaceAvailable = space & ((1 << 12) - 1); return status; } static void AJ_WSL_BufListIterate_DMA(AJ_BufList* list) { if (list != NULL) { AJ_BufNode* node = list->head; while (node != NULL) { AJ_BufNode* nextNode = node->next; AJ_WSL_SPI_DMATransfer(node->buffer, node->length, 1); node = nextNode; } } } AJ_EXPORT AJ_Status AJ_WSL_WriteBufListToMBox(uint8_t box, uint8_t endpoint, uint16_t len, AJ_BufList* list) { AJ_Status status = AJ_ERR_SPI_WRITE; uint16_t spaceAvailable = 0; uint16_t bytesRemaining; uint16_t cause = 0; AJ_ASSERT(0 == box); // AJ_InfoPrintf(("=HTC Credits 0:%x, 1:%x, 2:%x\n", AJ_WSL_HTC_Global.endpoints[0].txCredits, AJ_WSL_HTC_Global.endpoints[1].txCredits, AJ_WSL_HTC_Global.endpoints[2].txCredits)); AJ_Time credit_timer; AJ_InitTimer(&credit_timer); while (AJ_WSL_HTC_Global.endpoints[endpoint].txCredits < 1) { // do nothing and wait until there are credits if (AJ_GetElapsedTime(&credit_timer, TRUE) > 1500) { AJ_WSL_HTC_Global.endpoints[endpoint].txCredits++; break; } AJ_YieldCurrentTask(); } // don't let the other tasks interrupt our SPI access AJ_EnterCriticalRegion(); AJ_Time space_timer; AJ_InitTimer(&space_timer); // read space available in mbox from register do { if (AJ_GetElapsedTime(&space_timer, TRUE) > 1500) { spaceAvailable = 0xc5b; AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_SPI_CONFIG, 1 << 15); break; } status = AJ_WSL_GetWriteBufferSpaceAvailable(&spaceAvailable); } while (spaceAvailable == 0); AJ_ASSERT((status == AJ_OK) && (spaceAvailable >= len)); if ((status == AJ_OK) && (spaceAvailable >= len)) { uint16_t targetAddress; // write size to be transferred status = AJ_WSL_SetDMABufferSize(len); AJ_ASSERT(status == AJ_OK); // write the target address (where we want to send data) // the write should end up at the end of the MBox alias // example 0xFFF - len targetAddress = AJ_WSL_SPI_MBOX_0_EOM_ALIAS - len; status = AJ_WSL_SPI_DMAWriteStart(targetAddress); AJ_ASSERT(status == AJ_OK); bytesRemaining = len; // Take the AJ_BufList to write out and write it out to the SPI interface via DMA AJ_WSL_BufListIterate_DMA(list); // clear the packet available interrupt cause = 0x1f; status = AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, cause); AJ_ASSERT(status == AJ_OK); AJ_WSL_HTC_Global.endpoints[endpoint].txCredits -= 1; } else { status = AJ_ERR_SPI_NO_SPACE; } AJ_LeaveCriticalRegion(); return status; } void AJ_WSL_SPI_ReadIntoBuffer(uint16_t bytesToRead, uint8_t** buf) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_READ; uint8_t pcs = AJ_WSL_SPI_PCS; uint16_t toss; // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_READ; send.cmd_reg = AJ_WSL_SPI_EXTERNAL; send.cmd_addr = AJ_WSL_SPI_MBOX_0_EOM_ALIAS - bytesToRead; // write the register rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, (uint8_t*)&toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, (uint8_t*)&toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); AJ_WSL_SPI_DMATransfer((uint8_t*)*buf, bytesToRead, 0); } //Mailbox Read Steps: //1. Interrupt going from the QCA4002 to the SPI host. //2. INTERNAL read from INTR_CAUSE register. //3. INTERNAL read from RDBUF_BYTE_AVA register. //4. Internal read from RDBUF_LOOKAHEAD1 register //5. Internal read from RDBUF_LOOKAHEAD2 register. From the 4 bytes we have read from RDBUF_LOOKAHEAD registers, get the packet size. //6. INTERNAL write to DMA_SIZE register with the packet size. //7. Start DMA read command and start reading the data by de-asserting chip select pin. //8. The packet available will be cleared by HW at the end of the DMA read. // AJ_EXPORT AJ_Status AJ_WSL_ReadFromMBox(uint8_t box, uint16_t* len, uint8_t** buf) { AJ_Status status = AJ_ERR_SPI_READ; uint16_t cause = 0; uint16_t bytesInBuffer = 0; uint16_t bytesToRead = 0; uint16_t lookAhead; uint16_t payloadLength; AJ_ASSERT(0 == box); AJ_EnterCriticalRegion(); //2. INTERNAL read from INTR_CAUSE register. do { //3. INTERNAL read from RDBUF_BYTE_AVA register. status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_RDBUF_BYTE_AVA, (uint8_t*)&bytesInBuffer); AJ_ASSERT(status == AJ_OK); //bytesInBuffer = CPU_TO_BE16(bytesInBuffer); // The first few bytes of the packet can now be examined and the right amount of data read from the target //4. Internal read from RDBUF_LOOKAHEAD1 register //5. Internal read from RDBUF_LOOKAHEAD2 register. From the 4 bytes we have read from RDBUF_LOOKAHEAD registers, get the packet size. status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_RDBUF_LOOKAHEAD1, (uint8_t*)&lookAhead); AJ_ASSERT(status == AJ_OK); lookAhead = CPU_TO_BE16(lookAhead); status = AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_RDBUF_LOOKAHEAD2, (uint8_t*)&payloadLength); AJ_ASSERT(status == AJ_OK); payloadLength = CPU_TO_BE16(payloadLength); // calculate number of bytes to read from the lookahead info, and round up to the next block size bytesToRead = payloadLength + 6; //sizeof(header); bytesToRead = ((bytesToRead / AJ_WSL_MBOX_BLOCK_SIZE) + ((bytesToRead % AJ_WSL_MBOX_BLOCK_SIZE) ? 1 : 0)) * AJ_WSL_MBOX_BLOCK_SIZE; *buf = (uint8_t*)AJ_WSL_Malloc(bytesToRead); *len = bytesToRead; //6. INTERNAL write to DMA_SIZE register with the packet size. // write size to be transferred status = AJ_WSL_SetDMABufferSize(bytesToRead); AJ_ASSERT(status == AJ_OK); AJ_WSL_SPI_ReadIntoBuffer(bytesToRead, buf); // clear the packet available interrupt cause = 0x1; status = AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, cause); AJ_ASSERT(status == AJ_OK); break; } while (0); AJ_LeaveCriticalRegion(); return status; } AJ_Status AJ_WSL_SPI_RegisterRead(uint16_t reg, uint8_t* spi_data) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_READ; uint8_t pcs = AJ_WSL_SPI_PCS; // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_READ; send.cmd_reg = AJ_WSL_SPI_INTERNAL; send.cmd_addr = reg; /* Test write: should return OK. */ rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, pcs); // toss. AJ_ASSERT(rc == SPI_OK); // read the first byte of response rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, 0 /*xFF*/, AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); // junk to write while reading AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { /* Test read: should return OK with what is sent. */ rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, pcs); AJ_ASSERT(rc == SPI_OK); status = AJ_OK; } // read the second byte spi_data++; rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, 0 /*xFF*/, AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); // junk to write while reading AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { /* Test read: should return OK with what is sent. */ rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, pcs); AJ_ASSERT(rc == SPI_OK); status = AJ_OK; } spi_data--; // move back to the original location *(uint16_t*)spi_data = CPU_TO_BE16(*(uint16_t*)spi_data); return status; } AJ_Status AJ_WSL_SPI_RegisterWrite(uint16_t reg, uint16_t spi_data) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_WRITE; uint8_t pcs = AJ_WSL_SPI_PCS; uint8_t toss; uint8_t* bytePoint = (uint8_t*)&spi_data; // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_WRITE; send.cmd_reg = AJ_WSL_SPI_INTERNAL; send.cmd_addr = reg; // write the register, one byte at a time, in the right order rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(bytePoint + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { status = AJ_OK; } } if (rc == SPI_OK) { rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(bytePoint) & 0xFF, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { status = AJ_OK; } } return status; } // Set up a transfer: send a write command with an address AJ_Status AJ_WSL_SPI_DMAWriteStart(uint16_t targetAddress) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_WRITE; uint8_t toss; uint8_t pcs = AJ_WSL_SPI_PCS; // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_WRITE; send.cmd_reg = AJ_WSL_SPI_EXTERNAL; send.cmd_addr = targetAddress; // write the register rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { status = AJ_OK; } return status; } // Set up a transfer: send a write command with an address AJ_Status AJ_WSL_SPI_DMAWrite16(uint16_t targetAddress, uint16_t len, uint16_t* spi_data) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_WRITE; uint8_t toss; uint8_t pcs = AJ_WSL_SPI_PCS; uint8_t* bytePoint = (uint8_t*)spi_data; // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_WRITE; send.cmd_reg = AJ_WSL_SPI_EXTERNAL; send.cmd_addr = targetAddress; // write the register rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { while ((rc == SPI_OK) && (len > 1)) { /* Test read: should return OK with what is sent. */ rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *bytePoint, AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); AJ_ASSERT(rc == SPI_OK); bytePoint++; len = len - 1; } if (rc == SPI_OK) { rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *bytePoint, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); AJ_ASSERT(rc == SPI_OK); } if (rc == SPI_OK) { status = AJ_OK; } } return status; } // Set up a transfer: send a write command with an address AJ_Status AJ_WSL_SPI_DMARead16(uint16_t targetAddress, uint16_t len, uint16_t* spi_data) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_READ; uint8_t pcs = AJ_WSL_SPI_PCS; uint8_t toss; uint8_t* bytePoint = (uint8_t*)spi_data; // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_READ; send.cmd_reg = AJ_WSL_SPI_EXTERNAL; send.cmd_addr = targetAddress; // write the register rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); while ((rc == SPI_OK) && (len > 1)) { /* Test read: should return OK with what is sent. */ rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, 0 /*xFF*/, AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, bytePoint, pcs); AJ_ASSERT(rc == SPI_OK); bytePoint++; len = len - 1; } if (rc == SPI_OK) { rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, 0 /*xFF*/, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, bytePoint, pcs); AJ_ASSERT(rc == SPI_OK); } if (rc == SPI_OK) { status = AJ_OK; } return status; } /* * @remarks SPI mode is not being changed here. */ AJ_Status AJ_WSL_SPI_WriteByte8(uint8_t spi_data, uint8_t end) { aj_spi_status rc; AJ_Status status = AJ_ERR_SPI_WRITE; uint8_t pcs = AJ_WSL_SPI_PCS; uint8_t toss; rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, (uint16_t)spi_data, AJ_WSL_SPI_PCS, end); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { status = AJ_OK; } return status; } /* * @remarks SPI mode is not being changed here. */ AJ_Status AJ_WSL_SPI_WriteByte16(uint16_t spi_data, uint8_t end) { aj_spi_status rc; AJ_Status status = AJ_ERR_SPI_WRITE; uint8_t pcs = AJ_WSL_SPI_PCS; uint8_t toss; rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, spi_data, AJ_WSL_SPI_PCS, end); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, spi_data & 0xFF, AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, spi_data >> 8, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { status = AJ_OK; } return status; } AJ_Status AJ_WSL_SPI_HostControlRegisterWrite(uint32_t targetRegister, uint8_t increment, uint16_t cbLen, uint8_t* spi_data) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_WRITE; uint8_t toss; uint8_t pcs = AJ_WSL_SPI_PCS; // write the size AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_HOST_CTRL_BYTE_SIZE, cbLen | (increment ? 0 : 0x40)); // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_WRITE; send.cmd_reg = AJ_WSL_SPI_INTERNAL; send.cmd_addr = AJ_WSL_SPI_REG_HOST_CTRL_WR_PORT; // write the register, one byte at a time, in the right order rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); // toss. AJ_ASSERT(rc == SPI_OK); if (rc == SPI_OK) { while ((rc == SPI_OK) && (cbLen > 1)) { rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *spi_data, AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); AJ_ASSERT(rc == SPI_OK); spi_data++; cbLen = cbLen - 1; } if (rc == SPI_OK) { rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *spi_data, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, &toss, pcs); AJ_ASSERT(rc == SPI_OK); } if (rc == SPI_OK) { status = AJ_OK; } } // now send the host_control_config register update { uint16_t externalRegister = 0; externalRegister = (1 << 15) | (1 << 14) | (targetRegister); // external access, write, counter dec externalRegister = CPU_TO_LE16(externalRegister); AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_HOST_CTRL_CONFIG, externalRegister); } // clear the rd/wr buffer interrupt { uint16_t spi_16 = 0x300; spi_16 = CPU_TO_LE16(spi_16); AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, spi_16); } return status; } AJ_Status AJ_WSL_SPI_HostControlRegisterRead(uint32_t targetRegister, uint8_t increment, uint16_t cbLen, uint8_t* spi_data) { aj_spi_status rc; wsl_spi_command send; AJ_Status status = AJ_ERR_SPI_WRITE; uint8_t pcs = AJ_WSL_SPI_PCS; // write the size AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_HOST_CTRL_BYTE_SIZE, cbLen | (increment ? 0 : 0x40)); // now send the host_control_config register update { uint16_t externalRegister = 0; externalRegister = (1 << 15) | (0 << 14) | (targetRegister); // external access, write, counter dec externalRegister = CPU_TO_LE16(externalRegister); AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_HOST_CTRL_CONFIG, externalRegister); } // get the spi status { uint16_t spi_16 = 0; AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_SPI_STATUS, (uint8_t*)&spi_16); spi_16 = LE16_TO_CPU(spi_16); } // initialize an SPI CMD structure with the register of interest send.cmd_rx = AJ_WSL_SPI_READ; send.cmd_reg = AJ_WSL_SPI_INTERNAL; send.cmd_addr = AJ_WSL_SPI_REG_HOST_CTRL_RD_PORT; // write the register, one byte at a time, in the right order rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *((uint8_t*)&send + 1), AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, pcs); // toss. AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, *(uint8_t*)&send, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, pcs); // toss. AJ_ASSERT(rc == SPI_OK); // now, read the data back if (rc == SPI_OK) { while ((rc == SPI_OK) && (cbLen > 1)) { /* Test read: should return OK with what is sent. */ rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, 0, AJ_WSL_SPI_PCS, AJ_WSL_SPI_CONTINUE); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, pcs); AJ_ASSERT(rc == SPI_OK); spi_data++; cbLen = cbLen - 1; } if (rc == SPI_OK) { rc = AJ_SPI_WRITE(AJ_WSL_SPI_DEVICE, 0, AJ_WSL_SPI_PCS, AJ_WSL_SPI_END); AJ_ASSERT(rc == SPI_OK); rc = AJ_SPI_READ(AJ_WSL_SPI_DEVICE, spi_data, pcs); AJ_ASSERT(rc == SPI_OK); } if (rc == SPI_OK) { status = AJ_OK; } } // clear the rd/wr buffer interrupt { uint16_t spi_16 = 0x300; spi_16 = CPU_TO_LE16(spi_16); AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, spi_16); } return status; } ajtcl-15.04b/WSL/aj_wsl_target.h000066400000000000000000000063401256742562600164470ustar00rootroot00000000000000/** * @file WSL module header */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #ifndef AJ_WSL_TARGET_H__ #define AJ_WSL_TARGET_H__ #include "aj_target_platform.h" #include "aj_target.h" #include "aj_RTOS.h" #include "aj_status.h" #ifdef __cplusplus extern "C" { #endif void AJ_WSL_ModuleInit(void); AJ_Status AJ_WSL_DriverStart(void); AJ_Status AJ_WSL_DriverStop(void); void AJ_WSL_NET_StackInit(void); /* * Platform specific defines are here */ #define AJ_WSL_SPI_CLOCK_RATE 28000000 #define AJ_WSL_SPI_CLOCK_POLARITY 1 #define AJ_WSL_SPI_CLOCK_PHASE 0 #define AJ_WSL_SPI_DELAY_BEFORE_CLOCK 0x01 #define AJ_WSL_SPI_DELAY_BETWEEN_TRANSFERS 0x01 #ifdef AJ_WSL_USE_REGULAR_MALLOC #define AJ_WSL_Malloc AJ_Malloc #define AJ_WSL_Free AJ_Free #else /* * WSL memory allocations come from a WSL-specific heap */ void* AJ_WSL_Malloc(size_t size); void AJ_WSL_Free(void* ptr); #endif AJ_Status AJ_WSL_SPI_RegisterRead(uint16_t reg, uint8_t* spi_data); /** * global flag that indicates the target chip has SPI data available */ extern volatile uint8_t g_b_spi_interrupt_data_ready; /* * Set the native endianness */ #if HOST_IS_BIG_ENDIAN #define BE8_8_TO_CPU(v, w) (((v) << 8) | (w)) #define BE16_TO_CPU(v) (v) #define BE32_TO_CPU(v) (v) #define CPU_TO_BE16(v) (v) #define CPU_TO_BE32(v) (v) #define LE8_8_TO_CPU(v, w) ((v) | ((w) << 8)) #define LE16_TO_CPU(v) (((v) >> 8) | ((v) << 8)) #define LE32_TO_CPU(v) (((v) >> 24) | (((v) & 0xFF0000) >> 8) | (((v) & 0x00FF00) << 8) | ((v) << 24)) #define CPU_TO_LE16(v) (((v) >> 8) | ((v) << 8)) #define CPU_TO_LE32(v) (((v) >> 24) | (((v) & 0xFF0000) >> 8) | (((v) & 0x00FF00) << 8) | ((v) << 24)) #else #define BE8_8_TO_CPU(v, w) ((v) | ((w) << 8)) #ifndef LE16_TO_CPU #define BE16_TO_CPU(v) (((v) >> 8) | ((v) << 8)) #define BE32_TO_CPU(v) (((v) >> 24) | (((v) & 0xFF0000) >> 8) | (((v) & 0x00FF00) << 8) | ((v) << 24)) #define CPU_TO_BE16(v) (((v) >> 8) | ((v) << 8)) #define CPU_TO_BE32(v) (((v) >> 24) | (((v) & 0xFF0000) >> 8) | (((v) & 0x00FF00) << 8) | ((v) << 24)) #endif #define LE8_8_TO_CPU(v, w) (((v) << 8) | (w)) #ifndef LE16_TO_CPU #define LE16_TO_CPU(v) (v) #define LE32_TO_CPU(v) (v) #define CPU_TO_LE16(v) (v) #define CPU_TO_LE32(v) (v) #endif #endif #ifdef __cplusplus } #endif #endif // AJ_WSL_TARGET_H__ ajtcl-15.04b/WSL/aj_wsl_tasks.c000066400000000000000000000333561256742562600163100ustar00rootroot00000000000000/** * @file Implementation for tasks related to WSL */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #define AJ_MODULE WSL_TASKS #include "aj_target.h" #include "aj_buf.h" #include "aj_wsl_spi_constants.h" #include "aj_wsl_wmi.h" #include "aj_wsl_htc.h" #include "aj_wsl_net.h" #include "aj_wsl_spi.h" #include "aj_wsl_tasks.h" /** * Turn on per-module debug printing by setting this variable to non-zero value * (usually in debugger). */ #ifndef NDEBUG uint8_t dbgWSL_TASKS = 0; #endif extern uint32_t AJ_WSL_MBOX_BLOCK_SIZE; static void set_SPI_registers(void) { volatile uint16_t spi_API = 0; AJ_AlwaysPrintf(("\n\n**************\nTEST: %s\n\n", __FUNCTION__)); // reset the target // spi_API = (1 << 15); // AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_SPI_CONFIG, spi_API); // AJ_Sleep(1 << 22); // one extra write to force the device out of the reset state. spi_API = 0x80; AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_SPI_CONFIG, spi_API); AJ_Sleep(100); // write spi_API = 0x80; // same as capture AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_SPI_CONFIG, spi_API); // AJ_InfoPrintf(("AJ_WSL_SPI_REG_SPI_CONFIG was %04x\n", spi_API)); AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_WRBUF_SPC_AVA, (uint8_t*)&spi_API); spi_API = LE16_TO_CPU(spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_WRBUF_SPC_AVA was %04x\n", spi_API)); spi_API = 0x40; // same as capture AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_WRBUF_WATERMARK, spi_API); // AJ_InfoPrintf(("AJ_WSL_SPI_REG_SPI_CONFIG was %04x\n", spi_API)); spi_API = 0x400; // same as capture AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_CAUSE was %04x\n", spi_API)); spi_API = 0x3ff; AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_ENABLE was %04x\n", spi_API)); spi_API = 0x0e; AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_ENABLE was %04x\n", spi_API)); spi_API = 0x1e; AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_ENABLE was %04x\n", spi_API)); spi_API = 0x0; AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_ENABLE was %04x\n", spi_API)); spi_API = 0x1e; AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_ENABLE was %04x\n", spi_API)); AJ_Sleep(100); } /* * This test reads a few registers using the SPI hardware. */ /* static void examine_SPI_registers(void) { uint16_t spi_API = 0; uint16_t spi_lookahead[2]; AJ_AlwaysPrintf(("\n\n**************\nTEST: %s\n\n", __FUNCTION__)); AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_DMA_SIZE, (uint8_t*)&spi_API); spi_API = LE16_TO_CPU(spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_DMA_SIZE was %04x\n", spi_API)); AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_WRBUF_SPC_AVA, (uint8_t*)&spi_API); spi_API = LE16_TO_CPU(spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_WRBUF_SPC_AVA was %04x\n", spi_API)); AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_RDBUF_BYTE_AVA, (uint8_t*)&spi_API); spi_API = LE16_TO_CPU(spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_RDBUF_BYTE_AVA was %04x\n", spi_API)); AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_SPI_CONFIG, (uint8_t*)&spi_API); spi_API = LE16_TO_CPU(spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_SPI_CONFIG was %04x\n", spi_API)); AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_SPI_STATUS, (uint8_t*)&spi_API); spi_API = LE16_TO_CPU(spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_SPI_STATUS was %04x\n", spi_API)); AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_HOST_CTRL_BYTE_SIZE, (uint8_t*)&spi_API); spi_API = LE16_TO_CPU(spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_HOST_CTRL_BYTE_SIZE was %04x\n", spi_API)); AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_HOST_CTRL_CONFIG, (uint8_t*)&spi_API); spi_API = LE16_TO_CPU(spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_HOST_CTRL_CONFIG was %04x\n", spi_API)); AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_INTR_CAUSE, (uint8_t*)&spi_API); spi_API = LE16_TO_CPU(spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_INTR_CAUSE was %04x\n", spi_API)); AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_WRBUF_WATERMARK, (uint8_t*)&spi_API); spi_API = CPU_TO_LE16(spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_WRBUF_WATERMARK was %04x\n", spi_API)); memset(spi_lookahead, 0, sizeof(spi_lookahead)); AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_RDBUF_LOOKAHEAD1, (uint8_t*)&spi_lookahead[0]); spi_API = LE16_TO_CPU(spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_RDBUF_LOOKAHEAD1 was %04x\n", spi_lookahead[0])); AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_RDBUF_LOOKAHEAD2, (uint8_t*)&spi_lookahead[1]); spi_API = LE16_TO_CPU(spi_API); AJ_InfoPrintf(("AJ_WSL_SPI_REG_RDBUF_LOOKAHEAD2 was %04x\n", spi_lookahead[1])); } */ static void write_BOOT_PARAM(void) { uint32_t spi_API = 0; uint16_t spi_API16 = 0; AJ_AlwaysPrintf(("\n\n**************\nTEST: %s\n\n", __FUNCTION__)); // read the clock speed value spi_API = 0x88888888; AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 1, FALSE, 4, (uint8_t*)&spi_API); spi_API = 0x42424242; AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 2, FALSE, 4, (uint8_t*)&spi_API); spi_API = 0x00000000; AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 3, FALSE, 4, (uint8_t*)&spi_API); spi_API = AJ_WSL_SPI_TARGET_CLOCK_SPEED_ADDR; //0x00428878; spi_API = CPU_TO_LE32(spi_API); AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ, TRUE, 4, (uint8_t*)&spi_API); // now read back the value from the data port. AJ_WSL_SPI_HostControlRegisterRead(AJ_WSL_SPI_TARGET_VALUE, TRUE, 4, (uint8_t*)&spi_API); spi_API = LE32_TO_CPU(spi_API); //AJ_InfoPrintf(("cycles read back was %ld \n", spi_API)); // read the flash is present value { // let's try this dance of writing multiple times... spi_API = 0x88888888; AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 1, FALSE, 4, (uint8_t*)&spi_API); spi_API = 0x42424242; AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 2, FALSE, 4, (uint8_t*)&spi_API); spi_API = 0x00000000; AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 3, FALSE, 4, (uint8_t*)&spi_API); spi_API = AJ_WSL_SPI_TARGET_FLASH_PRESENT_ADDR; //0x0042880C; spi_API = CPU_TO_LE32(spi_API); AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ, TRUE, 4, (uint8_t*)&spi_API); // now read back the value from the data port. AJ_WSL_SPI_HostControlRegisterRead(AJ_WSL_SPI_TARGET_VALUE, TRUE, 4, (uint8_t*)&spi_API); spi_API = LE32_TO_CPU(spi_API); //AJ_InfoPrintf(("host if flash is present read back was %ld \n", spi_API)); } // now write out the flash_is_present value spi_API = 0x00000002; spi_API = CPU_TO_LE32(spi_API); AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_VALUE, TRUE, 4, (uint8_t*)&spi_API); spi_API = 0x88888888; AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_WRITE + 1, FALSE, 4, (uint8_t*)&spi_API); spi_API = 0x42424242; AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_WRITE + 2, FALSE, 4, (uint8_t*)&spi_API); spi_API = 0x00000000; AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_WRITE + 3, FALSE, 4, (uint8_t*)&spi_API); spi_API = AJ_WSL_SPI_TARGET_FLASH_PRESENT_ADDR; //0x0042880C; spi_API = CPU_TO_LE32(spi_API); AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_WRITE, TRUE, 4, (uint8_t*)&spi_API); // read the mbox block size spi_API = 0x88888888; AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 1, FALSE, 4, (uint8_t*)&spi_API); spi_API = 0x42424242; AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 2, FALSE, 4, (uint8_t*)&spi_API); spi_API = 0x00000000; AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ + 3, FALSE, 4, (uint8_t*)&spi_API); spi_API = AJ_WSL_SPI_TARGET_MBOX_BLOCKSZ_ADDR; //0x0042886C; spi_API = CPU_TO_LE32(spi_API); AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_TARGET_ADDR_READ, TRUE, 4, (uint8_t*)&spi_API); // now read back the value from the data port. AJ_WSL_SPI_HostControlRegisterRead(AJ_WSL_SPI_TARGET_VALUE, TRUE, 4, (uint8_t*)&spi_API); spi_API = LE32_TO_CPU(spi_API); AJ_WSL_MBOX_BLOCK_SIZE = spi_API; //AJ_InfoPrintf(("block size was %ld \n", spi_API)); spi_API16 = 0x001f; spi_API16 = CPU_TO_LE16(spi_API16); AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_ENABLE, spi_API16); // wait until the write has been processed. spi_API16 = 0; while (!(spi_API16 & 1)) { AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_SPI_STATUS, (uint8_t*)&spi_API16); spi_API16 = LE16_TO_CPU(spi_API16); uint16_t space = 0; AJ_WSL_SPI_RegisterRead(AJ_WSL_SPI_REG_WRBUF_SPC_AVA, (uint8_t*)&space); } // clear the read and write interrupt cause register spi_API = (1 << 9) | (1 << 8); spi_API = CPU_TO_LE16(spi_API); AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_INTR_CAUSE, spi_API); { spi_API16 = 0x1; spi_API16 = CPU_TO_LE16(spi_API16); AJ_WSL_SPI_RegisterWrite(AJ_WSL_SPI_REG_HOST_CTRL_BYTE_SIZE, spi_API16); // waiting seems to allow the following write to succeed and thus enable interrupts. // we need something more deterministic. AJ_Sleep(1000); spi_API16 = 0x00FF; spi_API = CPU_TO_LE16(spi_API); AJ_WSL_SPI_HostControlRegisterWrite(AJ_WSL_SPI_CPU_INT_STATUS, FALSE, 1, (uint8_t*)&spi_API16); } } extern AJ_WSL_HTC_CONTEXT AJ_WSL_HTC_Global; extern wsl_socket_context AJ_WSL_SOCKET_CONTEXT[5]; extern volatile uint8_t g_b_spi_interrupt_data_ready; void AJ_WSL_MBoxListenAndProcessTask(void* parameters) { g_b_spi_interrupt_data_ready = FALSE; AJ_WSL_SPI_InitializeSPIController(); set_SPI_registers(); write_BOOT_PARAM(); g_b_spi_interrupt_data_ready = FALSE; // loop and process all of the responses while (1) { AJ_Status status; AJ_WSL_HTC_ProcessInterruptCause(); uint8_t i; for (i = 0; i < AJ_WSL_SOCKET_MAX; i++) { do { wsl_work_item* item = NULL; // peek at the queue, then make sure we have enough credits // if we have enough, pull and send the workitem to the MBOX // otherwise, move to the next socket and then eventually out of this loop. // Credits would be available again once AJ_WSL_HTC_ProcessInterruptCause has // read any credit-adjustment trailers status = AJ_QueuePeek(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue, &item); if ((status != AJ_OK) || (AJ_WSL_HTC_Global.endpoints[item->endpoint].txCredits < 1)) { break; } // pull a work item off of a socket queue and send it status = AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue, &item, 0); if (!item || (status != AJ_OK) || !item->list) { break; } else { //AJ_AlwaysPrintf(("AJ_WSL_MBoxListenAndProcessTask: %x\n", item->itemType)); AJ_WSL_WriteBufListToMBox(0, item->endpoint, AJ_BufListLengthOnWire(item->list), item->list); /* * if this item is sending data, create a workitem indicating completion * this special check is needed because there is no socket send command in WMI, * otherwise we could handle it in AJ_WSL_WMI_ProcessWMIEvent */ if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX)) { wsl_work_item** ppWork; wsl_work_item* sockWork; sockWork = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(sockWork, 0, sizeof(wsl_work_item)); sockWork->itemType = item->itemType; sockWork->endpoint = item->endpoint; ppWork = &sockWork; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[i].workRxQueue, ppWork, AJ_TIMER_FOREVER); } AJ_WSL_WMI_FreeWorkItem(item); } } while (1); } if (!g_b_spi_interrupt_data_ready) { AJ_YieldCurrentTask(); } g_b_spi_interrupt_data_ready = FALSE; // reset the state of the interrupt signal } } ajtcl-15.04b/WSL/aj_wsl_tasks.h000066400000000000000000000026001256742562600163010ustar00rootroot00000000000000/** * @file Function declarations for tasks */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #ifndef AJ_WSL_TASKS_H_ #define AJ_WSL_TASKS_H_ #include "aj_target.h" #include "aj_wsl_target.h" #include "aj_status.h" #ifdef __cplusplus extern "C" { #endif /** * This file contains the task and structure definitions for the WSL "driver" code * */ AJ_EXPORT void AJ_WSL_MBoxListenAndProcessTask(void* parameters); #ifdef __cplusplus } #endif #endif /* AJ_WSL_TASKS_H_ */ ajtcl-15.04b/WSL/aj_wsl_unmarshal.c000066400000000000000000000133071256742562600171470ustar00rootroot00000000000000/** * @file Unmarshaling implementation */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_util.h" #include "aj_buf.h" #include #include "aj_debug.h" #include "aj_wsl_unmarshal.h" #include "aj_wsl_wmi.h" #include "aj_wifi_ctrl.h" #define str(x) # x #define xstr(x) str(x) #define PRE 0x10 #define POST 0x00 #define AJ_WSL_SSID_IE 0x00 #define AJ_WSL_RSN_IE 0x30 #define AJ_RSSI_BYTE 15 //Byte location where the signal strength is #define AJ_MAC_BYTE 16 //Byte location where the mac address is #define AJ_80211_START 36 //Byte location where the 802.11 IE section begins wsl_scan_item* WMI_UnmarshalScan(void* data, uint16_t length) { wsl_scan_item* scan; uint8_t* ptr; uint16_t i = AJ_80211_START; //start of IE section uint8_t hasSecurity = 0; ptr = (uint8_t*)data; scan = (wsl_scan_item*)WSL_InitScanItem(); /* * Get signal strength */ scan->rssi = *(ptr + AJ_RSSI_BYTE); /* * Get MAC address */ memcpy(scan->bssid, (ptr + AJ_MAC_BYTE), 6); /* * Go through each IE until the packet it over and get what we need * (SSID and RSN). */ while (i < (length - AJ_80211_START)) { uint8_t EID; uint8_t EIDlen; EID = *(ptr + i); i++; EIDlen = *(ptr + i); i++; switch (EID) { case (0x00): scan->ssid = (char*)AJ_WSL_Malloc((sizeof(char) * EIDlen) + 1); memcpy(scan->ssid, (ptr + i), EIDlen); scan->ssid[EIDlen] = '\0'; i += EIDlen; break; case (0x30): /* * 5 bytes into the RSN IE is the security information */ if (*(ptr + i + 5) == 2) { scan->secType = AJ_WIFI_SECURITY_WPA; scan->cipherType = AJ_WIFI_CIPHER_TKIP; } else if (*(ptr + i + 5) == 4) { scan->secType = AJ_WIFI_SECURITY_WPA2; scan->cipherType = AJ_WIFI_CIPHER_CCMP; } else { scan->secType = AJ_WIFI_SECURITY_WEP; scan->cipherType = AJ_WIFI_CIPHER_WEP; } hasSecurity = 1; i += EIDlen; break; default: i += EIDlen; break; } } if (!hasSecurity) { scan->secType = AJ_WIFI_SECURITY_NONE; scan->cipherType = AJ_WIFI_CIPHER_NONE; } return scan; } int32_t WMI_Unmarshal(void* data, const char* sig, ...) { va_list args; uint8_t* ptr; va_start(args, sig); ptr = (uint8_t*)data; while (*sig) { switch (*sig++) { case (WMI_ARG_UINT64): { uint64_t* u64; u64 = (uint64_t*)va_arg(args, uint64_t); memcpy(u64, ptr, sizeof(uint64_t)); ptr += 8; } break; case (WMI_ARG_UINT32): { uint32_t* u32; u32 = (uint32_t*)va_arg(args, uint32_t); memcpy(u32, ptr, sizeof(uint32_t)); ptr += 4; } break; case (WMI_ARG_UINT16): { uint16_t* u16; u16 = (uint16_t*)va_arg(args, uint32_t); memcpy(u16, ptr, sizeof(uint16_t)); ptr += 2; } break; case (WMI_ARG_MAC): { uint8_t* mac; mac = (uint8_t*)va_arg(args, uint32_t); memcpy(mac, ptr, sizeof(uint8_t) * 6); ptr += 6; } break; case (WMI_ARG_IPV4): { uint8_t* IPv4; IPv4 = (uint8_t*)va_arg(args, uint32_t); memcpy(IPv4, ptr, sizeof(uint8_t) * 4); ptr += 4; } break; case (WMI_ARG_IPV6): { uint8_t* IPv6; IPv6 = (uint8_t*)va_arg(args, uint32_t); memcpy(IPv6, ptr, sizeof(uint8_t) * 16); ptr += 16; } break; case (WMI_ARG_BYTE): { uint8_t* u8; u8 = (uint8_t*)va_arg(args, uint32_t); memcpy(u8, ptr, sizeof(uint8_t)); ptr += 1; } break; case (WMI_ARG_STRING): { char** str; uint8_t size; memcpy(&size, ptr, sizeof(uint8_t)); ptr++; str = (char**)va_arg(args, char*); *str = (char*)AJ_WSL_Malloc(sizeof(char) * size + 1); memcpy(*str, ptr, sizeof(char) * size + 1); (*str)[size] = '\0'; ptr += size; } break; } } va_end(args); return ptr - (uint8_t*)data; } ajtcl-15.04b/WSL/aj_wsl_unmarshal.h000066400000000000000000000116051256742562600171530ustar00rootroot00000000000000/** * @file Unmarshaling declarations */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_wsl_target.h" #include "aj_wsl_wmi.h" #include "aj_wsl_net.h" #ifdef __cplusplus extern "C" { #endif /* * Basic Types */ #define WMI_ARG_INVALID '\0' /**< AllJoyn invalid type */ #define WMI_ARG_ARRAY 'a' /**< AllJoyn array container type */ #define WMI_ARG_BOOLEAN 'b' /**< AllJoyn boolean basic type */ #define WMI_ARG_INT32 'i' /**< AllJoyn 32-bit signed integer basic type */ #define WMI_ARG_INT16 'n' /**< AllJoyn 16-bit signed integer basic type */ #define WMI_ARG_UINT16 'q' /**< AllJoyn 16-bit unsigned integer basic type */ #define WMI_ARG_STRING 's' /**< AllJoyn UTF-8 NULL terminated string basic type */ #define WMI_ARG_UINT32 'u' /**< AllJoyn 32-bit unsigned integer basic type */ #define WMI_ARG_UINT64 't' #define WMI_ARG_VARIANT 'v' /**< AllJoyn variant container type */ #define WMI_ARG_BYTE 'y' /**< AllJoyn 8-bit unsigned integer basic type */ #define WMI_ARG_STRUCT '(' /**< AllJoyn struct container type */ #define WMI_ARG_DICT_ENTRY '{' /**< AllJoyn dictionary or map container type - an array of key-value pairs */ /* * Specific WMI types */ #define WMI_ARG_MAC 'M' /**< MAC address */ #define WMI_ARG_IPV4 '4' /**< IPV4 Address */ #define WMI_ARG_IPV6 '6' /**< IPV6 Address */ #define WMI_ARG_SSID 'S' /**< SSID 32 byte */ #define WMI_ARG_BSSID 'B' /**< BSSID */ #define WMI_ARG_ENCRYPTION 'E' /**< Encryption type */ #define WMI_ARG_SIZE 'Z' /**< Size specifier */ #define WMI_ARG_RSSI 'R' /**< RSSI */ #define WMI_ARG_HEADER 'H' /**< WMI Header */ #define WMI_ARG_PASSPHRASE 'P' /**< 64 Byte pass phrase */ #define WMI_ARG_TAG 'T' /**< Tag identifier */ #define WMI_ARG_KEY 'K' /**< Cipher key/ Pairwise master key (32 byte) */ //#define WMI_TYPE_SCAN "HP09RMP0eS" /**< WiFi scan. [Header][RSSI][MAC][SSID] */ typedef enum { BSS_SCAN = 0x1004 }EVENT; typedef enum { TAG_SSID = 0, TAG_CHANNEL = 3, TAG_RSN = 48, TAG_VENDOR = 221 }TAG_NUMBERS; typedef struct { uint8_t length; void* data; }RSN_INFO; typedef struct { uint8_t size; void* data; }TAG_INFO; typedef struct { uint16_t channel; uint8_t frame; uint8_t rssi; uint8_t bssid[6]; uint32_t seq_num; }BSS_INFO; typedef struct _WMI_HDR_INFO { uint8_t flag; /* Flag in the header (second byte) */ uint16_t size; /* Size of the packet (bytes 3 and 4) */ uint8_t offset; /* Offset (byte 5) */ uint8_t id; /* Packet ID (byte 6) */ uint16_t event; /* Event type (bytes 7 and 8) */ }WMI_HDR_INFO; typedef struct { WMI_HDR_INFO* hdr_info; union { BSS_INFO bss; }event; uint8_t timestamp[8]; uint16_t interval; uint16_t capabilities; char* SSID; uint8_t channel; RSN_INFO rsn_info; uint8_t* vendor; }SCAN_PACKET; /** * Generic unmarshal function. This will take a block of data and fill in * the parameters byte by byte according to the signature passed in. * * @param data Pointer to a block of data * @param sig Signature string that corresponds to the subsequent parameters * @param ...[out] Variable length list of parameters that correspond to the signature. * * @return The total size of data that was unmarshalled. */ int32_t WMI_Unmarshal(void* data, const char* sig, ...); /** * Unmarshal a BSSINFO (scan) packet. * * @param data Pointer to a block of data containing the scan info * @param lenght Size of the data block * * @return Pointer to a scan item containing parsed data. */ wsl_scan_item* WMI_UnmarshalScan(void* data, uint16_t length); #ifdef __cplusplus } #endif ajtcl-15.04b/WSL/aj_wsl_wmi.c000066400000000000000000000663271256742562600157630ustar00rootroot00000000000000/** * @file WMI layer implementation */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #define AJ_MODULE WSL_WMI #include "aj_target.h" #include "aj_wsl_target.h" #include "aj_buf.h" #include "aj_wsl_spi_constants.h" #include "aj_wsl_htc.h" #include "aj_wsl_wmi.h" #include "aj_wsl_net.h" #include "aj_wsl_tasks.h" #include "aj_malloc.h" #include "aj_debug.h" #include "aj_wsl_unmarshal.h" #include #include /** * Turn on per-module debug printing by setting this variable to non-zero value * (usually in debugger). */ #ifndef NDEBUG uint8_t dbgWSL_WMI = 5; #endif extern AJ_WSL_HTC_CONTEXT AJ_WSL_HTC_Global; static uint8_t deviceMAC[6]; /* * global that holds target hardware info. */ AJ_FW_Version AJ_WSL_TargetFirmware; AJ_WifiCallbackFunc AJ_WSL_WifiConnectCallback; extern wsl_socket_context AJ_WSL_SOCKET_CONTEXT[AJ_WSL_SOCKET_MAX]; /** * globals to track open socket slots */ uint32_t AJ_WSL_SOCKET_HANDLE_INVALID = UINT32_MAX; struct AJ_TaskHandle* AJ_WSL_MBoxListenHandle; #ifndef NDEBUG const char* WSL_WorkItemText(uint32_t status); #endif /* * Maps command ID's and signatures * Use the enum "wsl_wmi_command_list" to index */ const CMDID_SIG_MAP cmd_map[] = { { 0x0001, "quyyyyyyyySqMqq", 0x3a }, //CONNECT { 0x0007, "quuuuuyyq", 0x1a }, //START_SCAN { 0x0008, "quqqqqqyyqqu", 0x1a }, //SET_SCAN_PARAMS { 0x0009, "quyyqu", 0x0e }, //SET_BSS_FILTER { 0x000a, "quyyyS", 0x29 }, //SET_PROBED_SSID { 0xf01b, "quqq", 0x0a }, //ALLOW_AGGR { 0x0012, "quy", 0x07 }, //SET_POWER_MODE { 0xf048, "quSPyy", 0x68 }, //SET_PASSPHRASE { 0xf04e, "quyy", 0x08 }, //STORECALL_CONFIGURE { 0xf08d, "", 0 }, //SOCKET { 0xf00f, "quyyyyyyyySqMqq", 0x3a }, //SET_SOFT_AP { 0, "uuyyyyyyyyyyuy", 0x52 }, //SEND { 0, "uuyyyyyyyyyyuy", 0x1e }, //SENDTO { 0x0003, "qu", 0x06 }, //DISCONNECT { 0xf00b, "quy", 0x07 }, //SET_HIDDEN_AP { 0, "uuyyyyyyyyyyuyyyyyyyyqqu6uy", 0x4c }, //SENDTO6 { 0, "uuuuqq6uuu", 0x32 }, //BIND6 { 0x0016, "quyyyyuuKyM", 0x39 }, //ADD_CIPHER_KEY { 0xf028, "quKy", 0x27 } //SET_PMK }; const uint16_t getCommandId(wsl_wmi_command_list command) { return cmd_map[command].id; } const char* getCommandSignature(wsl_wmi_command_list command) { return cmd_map[command].signature; } const uint16_t getPacketSize(wsl_wmi_command_list command) { return cmd_map[command].size; } /* * Map of socket commands to signatures * The socket id is the index in the array */ const SOCKET_SIG_MAP sock_map[] = { { "uuuu", 20 }, //OPEN { "uu", 12 }, //CLOSE { "uuqq4q", 26 }, //CONNECT { "uuqq4q", 26 }, //BIND { "", 0 }, { "", 0 }, { "", 0 }, { "uuuuu", 41 }, //SETSOCKOPT { "", 0 }, { "", 0 }, { "uu4446666uuuu", 110 }, //IP_CONFIG { "", 0 }, { "uyyyy", 12 }, //STACK_INIT { "", 0 }, { "", 0 }, { "uu4446666uuuu", 104 }, //IP6_CONFIG { "u44u", 20 }, //IPCONFIG_DHCP_POOL { "u6uuu", 36 }, //IP6_CONFIG_ROUTER_PREFIX { "", 0 }, { "", 0 }, { "", 0 }, { "", 0 }, { "", 0 }, { "", 0 }, { "", 0 }, { "", 0 }, { "", 0 }, { "", 0 }, { "", 0 }, { "uS", 46 } //SET_HOSTNAME }; const char* getSockSignature(wsl_socket_cmds command) { return sock_map[command].signature; } uint16_t getSockSize(wsl_socket_cmds command) { return sock_map[command].size; } uint8_t* getDeviceMac(void) { return (uint8_t*)&deviceMAC; } static const AJ_HeapConfig wsl_heapConfig[] = { { 8, 30, 0 }, { 16, 100, 0 }, { 20, 80, 0 }, { 24, 10, 0 }, { 32, 20, 0 }, { 48, 10, 0 }, { 64, 10, 0 }, { 84, 6, 0 }, { 100, 2, 0 }, }; #define WSL_HEAP_WORD_COUNT (7360 / 4) static uint32_t wsl_heap[WSL_HEAP_WORD_COUNT]; void* AJ_WSL_Malloc(size_t size) { void* mem = NULL; // allocate from the WSL pool first. AJ_EnterCriticalRegion(); if (size <= 100) { mem = AJ_PoolAlloc(size); } // if the pool was full or the size too big, fall back to malloc if (!mem) { mem = AJ_Malloc(size); } if (!mem) { AJ_ErrPrintf(("AJ_WSL_Malloc(): Malloc failed\n")); AJ_Reboot(); } AJ_LeaveCriticalRegion(); return mem; } void AJ_WSL_Free(void* ptr) { AJ_EnterCriticalRegion(); // if the address is within the WSL heap, free the pool entry, else fallback to free. if ((ptr > (void*)&wsl_heap) && (ptr < (void*)&wsl_heap[WSL_HEAP_WORD_COUNT])) { AJ_PoolFree(ptr); } else { AJ_Free(ptr); } AJ_LeaveCriticalRegion(); } void AJ_WSL_ModuleInit(void) { //prepare the WSL heap size_t heapSz; heapSz = AJ_PoolRequired(wsl_heapConfig, ArraySize(wsl_heapConfig)); if (heapSz > sizeof(wsl_heap)) { AJ_ErrPrintf(("Heap space is too small %d required %d\n", sizeof(wsl_heap), heapSz)); return; } AJ_InfoPrintf(("Allocated heap %d bytes\n", (int)heapSz)); AJ_PoolInit(wsl_heap, heapSz, wsl_heapConfig, ArraySize(wsl_heapConfig)); AJ_PoolDump(); AJ_WSL_SOCKNUM i; for (i = 0; i < AJ_WSL_SOCKET_MAX; i++) { memset(&AJ_WSL_SOCKET_CONTEXT[i], 0, sizeof(AJ_WSL_SOCKET_CONTEXT[0])); AJ_WSL_SOCKET_CONTEXT[i].targetHandle = AJ_WSL_SOCKET_HANDLE_INVALID; AJ_WSL_SOCKET_CONTEXT[i].stashedRxList = AJ_BufListCreate(); AJ_WSL_SOCKET_CONTEXT[i].workRxQueue = AJ_QueueCreate("RxQueue"); AJ_WSL_SOCKET_CONTEXT[i].workTxQueue = AJ_QueueCreate("TxQueue"); } AJ_WSL_WMI_ModuleInit(); } AJ_Status AJ_WSL_DriverStart(void) { AJ_CreateTask(AJ_WSL_MBoxListenAndProcessTask, (const signed char*)"AJWSLMBoxListen", 1000, NULL, 2, &AJ_WSL_MBoxListenHandle); while (!AJ_WSL_IsDriverStarted()); return AJ_OK; } AJ_Status AJ_WSL_DriverStop(void) { AJ_DestroyTask(AJ_WSL_MBoxListenHandle); return AJ_OK; } void AJ_WSL_WMI_ModuleInit() { AJ_WSL_HTC_ModuleInit(); } void AJ_WSL_WMI_PrintMessage(AJ_BufNode* pNodeWMIPacket) { AJ_AlwaysPrintf(("WMI_PrintMessage node %p, length %d, buffer %p\n", pNodeWMIPacket, pNodeWMIPacket->length, pNodeWMIPacket->buffer)); } /** * return index of matching socket or AJ_WSL_SOCKET_MAX on not found * skip the global socket context */ AJ_WSL_SOCKNUM AJ_WSL_FindOpenSocketContext(void) { AJ_WSL_SOCKNUM i; for (i = 1; i < ArraySize(AJ_WSL_SOCKET_CONTEXT); i++) { if (AJ_WSL_SOCKET_CONTEXT[i].valid == FALSE) { return i; } } return INVALID_SOCKET; } /** * return index of matching socket or AJ_WSL_SOCKET_MAX on not found */ AJ_WSL_SOCKNUM AJ_WSL_FindSocketContext(uint32_t handle) { AJ_WSL_SOCKNUM i; for (i = 0; i < ArraySize(AJ_WSL_SOCKET_CONTEXT); i++) { if (AJ_WSL_SOCKET_CONTEXT[i].targetHandle == handle) { return i; } } return INVALID_SOCKET; } void AJ_WSL_WMI_ProcessWMIEvent(AJ_BufNode* pNodeHTCBody) { uint16_t eventID; uint16_t info1; uint16_t reserved; int32_t dataUnmarshaled; dataUnmarshaled = WMI_Unmarshal(pNodeHTCBody->buffer, "qqq", &eventID, &info1, &reserved); switch (eventID) { case WSL_WMI_READY_EVENTID: { uint8_t capability; dataUnmarshaled += WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "uuMy", &AJ_WSL_TargetFirmware.target_ver, &AJ_WSL_TargetFirmware.abi_ver, &deviceMAC, &capability); AJ_InfoPrintf(("WMI_READY, version A %08lx, version B %08lx capability %x\n", AJ_WSL_TargetFirmware.target_ver, AJ_WSL_TargetFirmware.abi_ver, capability)); AJ_InfoPrintf(("Device MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", deviceMAC[0], deviceMAC[1], deviceMAC[2], deviceMAC[3], deviceMAC[4], deviceMAC[5])); AJ_WSL_HTC_Global.started = TRUE; break; } case WSL_BSS_INFO_EVENTID: { extern void AJ_WSL_BSSINFO_Recv(AJ_BufNode* node); AJ_WSL_BSSINFO_Recv(pNodeHTCBody); break; } case WSL_CMDERROR_EVENTID: { uint16_t commandId; uint8_t error; dataUnmarshaled += WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "qy", &commandId, &error); AJ_InfoPrintf(("WMI_CMDERROR, last command %04x, error code %02x \n", commandId, error)); break; } case WSL_WMI_SCAN_COMPLETE_EVENTID: { // now signal the waiting code that the scan has completed // we can do this by posting an item to the global socket context recv queue // the client will pull off a scan complete event and then continue. wsl_work_item* scanCompleteResponse; wsl_work_item** pItem; scanCompleteResponse = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(scanCompleteResponse, 0, sizeof(wsl_work_item)); scanCompleteResponse->itemType = WSL_NET_SCAN; scanCompleteResponse->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); pItem = &scanCompleteResponse; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[0].workRxQueue, pItem, AJ_TIMER_FOREVER); break; } case WSL_WMI_DISCONNECT_EVENTID: { uint16_t protocolReason; uint8_t bssid[6]; uint16_t disconnectReason; WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "qMq", &protocolReason, &bssid, &disconnectReason); AJ_InfoPrintf(("WMI_DISCONNECT event: protocolReason %x, disconnectReason %x\n", protocolReason, disconnectReason)); if (AJ_WSL_WifiConnectCallback) { (AJ_WSL_WifiConnectCallback)(0); } // now signal the waiting code that the scan has completed // we can do this by posting an item to the global socket context recv queue // the client will pull off a scan complete event and then continue. wsl_work_item* disconnectResponse; wsl_work_item** pItem; disconnectResponse = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(disconnectResponse, 0, sizeof(wsl_work_item)); disconnectResponse->itemType = WSL_NET_DISCONNECT; disconnectResponse->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); pItem = &disconnectResponse; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[0].workRxQueue, pItem, AJ_TIMER_FOREVER); break; } case WSL_WMI_CONNECT_EVENTID: { // now signal the waiting code that the scan has completed // we can do this by posting an item to the global socket context recv queue // the client will pull off a scan complete event and then continue. wsl_work_item* connectResponse; wsl_work_item** pItem; connectResponse = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(connectResponse, 0, sizeof(wsl_work_item)); connectResponse->itemType = WSL_NET_CONNECT; connectResponse->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); pItem = &connectResponse; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[0].workRxQueue, pItem, AJ_TIMER_FOREVER); if (AJ_WSL_WifiConnectCallback) { (AJ_WSL_WifiConnectCallback)(1); } break; } case WSL_WMI_SOCKET_RESPONSE_EVENTID: { uint32_t responseType; uint32_t socketHandle; uint32_t error; WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "uuu", &responseType, &socketHandle, &error); int8_t socketIndex; //AJ_BufListNodePrintDump(pNodeHTCBody, NULL); /* look for the matching handle in the global context then mark it invalid */ switch (responseType) { // some of the commands operate on the global socket context case WSL_SOCK_OPEN: case WSL_SOCK_IPCONFIG: case WSL_SOCK_IP6CONFIG: case WSL_SOCK_STACK_INIT: case WSL_SOCK_IP_HOST_NAME: socketIndex = 0; break; default: { socketIndex = AJ_WSL_FindSocketContext(socketHandle); if (socketIndex == INVALID_SOCKET) { AJ_DumpBytes("INVALID SOCKET DUMP", pNodeHTCBody->buffer, pNodeHTCBody->length); AJ_WarnPrintf(("SOCKET_PING response for invalid socket!\n")); break; } } } if (socketIndex != INVALID_SOCKET) { AJ_Status status = AJ_OK; //push a work item into the Read queue if (status == AJ_OK) { wsl_work_item** ppWork; wsl_work_item* sockResp; sockResp = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(sockResp, 0, sizeof(wsl_work_item)); sockResp->itemType = AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, responseType); //sockResp->size = payloadSize; sockResp->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); ppWork = &sockResp; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[socketIndex].workRxQueue, ppWork, AJ_TIMER_FOREVER); } if ((responseType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE)) && (socketIndex != INVALID_SOCKET)) { AJ_WSL_SOCKET_CONTEXT[socketIndex].targetHandle = UINT32_MAX; AJ_WSL_SOCKET_CONTEXT[socketIndex].valid = FALSE; } } break; } case WSL_WMI_PEER_NODE_EVENTID: { uint8_t reason; WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "q", &reason); if ((reason == 0) /*&& (AJ_WSL_connectState == AJ_WIFI_CONNECTING)*/) { /* * The 4-way handshake is complete, indicate the state has changed */ if (AJ_WSL_WifiConnectCallback) { (AJ_WSL_WifiConnectCallback)(16 /*RSNA_AUTH_SUCCESS*/); } } break; } // There are several WMI events that aren't parsed. case WSL_REGDOMAIN_EVENTID: case WSL_UNKNOWN2_EVENTID: case WSL_UNKNOWN1_EVENTID: break; default: { AJ_InfoPrintf(("Unknown WMI Event %x\n", eventID)); return; } } AJ_InfoPrintf(("Processed WMI Event: %s\n", WSL_WorkItemText(eventID))); } void AJ_WSL_WMI_ProcessSocketDataResponse(AJ_BufNode* pNodeHTCBody) { int8_t socketIndex; uint32_t u32; uint16_t lead, payloadSize, _port; uint32_t _handle, srcAddr; uint16_t ipv6addr[8]; uint16_t bufferOffset = 0; wsl_work_item** ppWork; wsl_work_item* sockResp; // AJ_DumpBytes("WMI_SOCKET_RESPONSE B", pNodeHTCBody->buffer, pNodeHTCBody->length); // Get the initial bytes of data in the packet WMI_Unmarshal(pNodeHTCBody->buffer, "quuq", &lead, &u32, &_handle, &_port); //AJ_BufNodePullBytes(pNodeHTCBody, 12); bufferOffset += 12; // look for the matching handle in the global context then mark it invalid socketIndex = AJ_WSL_FindSocketContext(_handle); if (socketIndex == INVALID_SOCKET) { AJ_WarnPrintf(("data returned for invalid socket. Handle = %lu\n", _handle)); return; } if (AJ_WSL_SOCKET_CONTEXT[socketIndex].domain == WSL_AF_INET6) { bufferOffset += 6; // Get the IPv6 address and payload size WMI_Unmarshal(pNodeHTCBody->buffer + bufferOffset, "6uq", &ipv6addr, &u32, &payloadSize); // Advance the buffer to the start of the payload bufferOffset += 28; } else { bufferOffset += 2; // Get the IPv4 address WMI_Unmarshal(pNodeHTCBody->buffer + bufferOffset, "4q", &srcAddr, &payloadSize); // Advance the buffer to the start of the payload bufferOffset += 12; } sockResp = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(sockResp, 0, sizeof(wsl_work_item)); sockResp->itemType = WSL_NET_DATA_RX; sockResp->size = payloadSize; sockResp->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); AJ_BufNodePullBytes(sockResp->node, bufferOffset); /// the length of the socket header info header sockResp->node->length = payloadSize; ppWork = &sockResp; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[socketIndex].workRxQueue, ppWork, AJ_TIMER_FOREVER); } AJ_Status AJ_WSL_WMI_QueueWorkItem(uint32_t socket, uint8_t command, uint8_t endpoint, AJ_BufList* list) { AJ_InfoPrintf(("AJ_WSL_WMI_QueueWorkItem(): %s\n", WSL_WorkItemText(command))); wsl_work_item** ppWork; wsl_work_item* sockWork; sockWork = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(sockWork, 0, sizeof(wsl_work_item)); sockWork->itemType = command; sockWork->list = list; sockWork->endpoint = endpoint; ppWork = &sockWork; AJ_ResumeTask(AJ_WSL_MBoxListenHandle, 0); // wake up the driver task so it can create space in the workTxQueue AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[socket].workTxQueue, ppWork, AJ_TIMER_FOREVER); AJ_ResumeTask(AJ_WSL_MBoxListenHandle, 0); // wake up the driver task after pushing, allowing the task to process the workitem return AJ_OK; } /* * This function just returns the work item. If there is data inside that you want * you have to unmarshal it after you receive the work item. */ AJ_Status AJ_WSL_WMI_WaitForWorkItem(uint32_t socket, uint8_t command, wsl_work_item** item, uint32_t timeout) { AJ_Status status; AJ_Time timer; AJ_InitTimer(&timer); // AJ_AlwaysPrintf(("WaitForWorkItem: %x\n", command)); //wsl_work_item* item; status = AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[socket].workRxQueue, item, timeout); timeout -= AJ_GetElapsedTime(&timer, TRUE); if ((status == AJ_OK) && item && *item) { if ((status == AJ_OK) && ((*item)->itemType == WSL_NET_INTERUPT)) { // We don't care about the interrupted signal for any calls using this function AJ_WSL_WMI_FreeWorkItem((*item)); status = AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[socket].workRxQueue, item, timeout); } if ((status == AJ_OK) && ((*item)->itemType == command)) { AJ_InfoPrintf(("AJ_WSL_WMI_WaitForWorkItem(): Received work item %s\n", WSL_WorkItemText(command))); return AJ_OK; } else if ((status == AJ_OK) && ((*item)->itemType == WSL_NET_DISCONNECT)) { AJ_InfoPrintf(("Got disconnect while waiting for %s\n", WSL_WorkItemText(command))); // Clean up the network queues int i; for (i = 0; i < AJ_WSL_SOCKET_MAX; i++) { wsl_work_item* clear; AJ_WSL_SOCKET_CONTEXT[i].valid = FALSE; // Removed any stashed data AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[i].stashedRxList, 1); // Reallocate a new stash AJ_WSL_SOCKET_CONTEXT[i].stashedRxList = AJ_BufListCreate(); // Reset the queue, any work items are now invalid since the socket was closed while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[i].workRxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[i].workRxQueue); AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue); } AJ_WSL_WMI_FreeWorkItem((*item)); return AJ_ERR_LINK_DEAD; } else if ((status == AJ_OK) && ((*item)->itemType == WSL_NET_DATA_RX)) { // If we got data we want to save it and not throw it away, its still not what we // wanted so we can free the work item as it wont be needed at a higher level AJ_InfoPrintf(("Got data while waiting for %s\n", WSL_WorkItemText(command))); if ((*item)->node->length) { AJ_BufNode* new_node = AJ_BufNodeCreateAndTakeOwnership((*item)->node); AJ_BufListPushTail(AJ_WSL_SOCKET_CONTEXT[socket].stashedRxList, new_node); AJ_WSL_WMI_FreeWorkItem((*item)); return AJ_ERR_NULL; } } else { AJ_WarnPrintf(("AJ_WSL_WMI_WaitForWorkItem(): Received incorrect work item %s, wanted %s\n", WSL_WorkItemText((*item)->itemType), WSL_WorkItemText(command))); // Wrong work item, but return NULL because we can free the item internally AJ_WSL_WMI_FreeWorkItem((*item)); return AJ_ERR_NULL; } } return AJ_ERR_NULL; } void AJ_WSL_WMI_FreeWorkItem(wsl_work_item* item) { if (item) { AJ_BufListFree(item->list, TRUE); AJ_BufListFreeNodeAndBuffer(item->node, NULL); AJ_WSL_Free(item); } } #ifndef NDEBUG #define AJ_CASE_NETWORK(_status) case AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, _status): return # _status #define AJ_CASE_SOCKET(_status) case AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, _status): return # _status #define AJ_CASE_GENERIC(_status) case _status: return # _status const char* WSL_WorkItemText(uint32_t status) { static char buf[4]; switch (status) { // Network cases AJ_CASE_NETWORK(WSL_CONNECT); AJ_CASE_NETWORK(WSL_START_SCAN); AJ_CASE_NETWORK(WSL_SET_SCAN_PARAMS); AJ_CASE_NETWORK(WSL_SET_BSS_FILTER); AJ_CASE_NETWORK(WSL_SET_PROBED_SSID); AJ_CASE_NETWORK(WSL_ALLOW_AGGR); AJ_CASE_NETWORK(WSL_SET_POWER_MODE); AJ_CASE_NETWORK(WSL_SET_PASSPHRASE); AJ_CASE_NETWORK(WSL_STORECALL_CONFIGURE); AJ_CASE_NETWORK(WSL_SOCKET); AJ_CASE_NETWORK(WSL_SET_SOFT_AP); AJ_CASE_NETWORK(WSL_SEND); AJ_CASE_NETWORK(WSL_SENDTO); AJ_CASE_NETWORK(WSL_DISCONNECT); AJ_CASE_NETWORK(WSL_SET_HIDDEN_AP); AJ_CASE_NETWORK(WSL_SENDTO6); AJ_CASE_NETWORK(WSL_BIND6); AJ_CASE_NETWORK(WSL_ADD_CIPHER_KEY); AJ_CASE_NETWORK(WMI_SET_PMK); // Socket cases AJ_CASE_SOCKET(WSL_SOCK_OPEN); AJ_CASE_SOCKET(WSL_SOCK_CLOSE); AJ_CASE_SOCKET(WSL_SOCK_CONNECT); AJ_CASE_SOCKET(WSL_SOCK_BIND); AJ_CASE_SOCKET(WSL_SOCK_SELECT); AJ_CASE_SOCKET(WSL_SOCK_SETSOCKOPT); AJ_CASE_SOCKET(WSL_SOCK_GETSOCKOPT); AJ_CASE_SOCKET(WSL_SOCK_IPCONFIG); AJ_CASE_SOCKET(WSL_SOCK_IP6CONFIG); AJ_CASE_SOCKET(WSL_SOCK_PING); AJ_CASE_SOCKET(WSL_SOCK_STACK_INIT); AJ_CASE_SOCKET(WSL_SOCK_STACK_MISC); AJ_CASE_SOCKET(WSL_NET_DATA_TX); AJ_CASE_SOCKET(WSL_SOCK_IP_HOST_NAME); AJ_CASE_SOCKET(WSL_SOCK_IP6CONFIG_ROUTER_PREFIX); // Events AJ_CASE_GENERIC(WSL_WMI_READY_EVENTID); AJ_CASE_GENERIC(WSL_WMI_CONNECT_EVENTID); AJ_CASE_GENERIC(WSL_WMI_DISCONNECT_EVENTID); AJ_CASE_GENERIC(WSL_BSS_INFO_EVENTID); AJ_CASE_GENERIC(WSL_CMDERROR_EVENTID); AJ_CASE_GENERIC(WSL_WMI_SCAN_COMPLETE_EVENTID); AJ_CASE_GENERIC(WSL_WMI_APLIST_EVENTID); AJ_CASE_GENERIC(WSL_WMI_PEER_NODE_EVENTID); AJ_CASE_GENERIC(WSL_WMI_WLAN_VERSION_EVENTID); AJ_CASE_GENERIC(WSL_WMI_SOCKET_RESPONSE_EVENTID); default: snprintf(buf, sizeof(buf), "%lu", (uint32_t)status); return buf; } } /* * Print relevant information about the drivers current state. This should * only be called upon a crash as it will corrupt the current state information * after it has been called. */ void AJ_WSL_PrintDriverTraceback(void) { int i; dbgWSL_WMI = 5; AJ_AlwaysPrintf(("Driver state: ")); if (AJ_WSL_HTC_Global.started) { AJ_AlwaysPrintf(("Started\n")); } else { AJ_AlwaysPrintf(("Not Started\n")); } for (i = 0; i < 4; i++) { AJ_AlwaysPrintf(("Endpoint %d credits: %d\n", i, AJ_WSL_HTC_Global.endpoints[i].txCredits)); } for (i = 0; i < AJ_WSL_SOCKET_MAX; i++) { uint32_t stashSz = 0; AJ_BufNode* stashNode = AJ_WSL_SOCKET_CONTEXT[i].stashedRxList->head; int j = 0; wsl_work_item* item; AJ_AlwaysPrintf(("------ SOCKET CONTEXT %d -----\n", i)); AJ_AlwaysPrintf(("\tSocket Handle: 0x%x\n", AJ_WSL_SOCKET_CONTEXT[i].targetHandle)); if (AJ_WSL_SOCKET_CONTEXT[i].domain == WSL_AF_INET) { AJ_AlwaysPrintf(("Domain: AF_INET\n")); } else { AJ_AlwaysPrintf(("Domain: AF_INET6\n")); } if (AJ_WSL_SOCKET_CONTEXT[i].type == WSL_SOCK_STREAM) { AJ_AlwaysPrintf(("Type: SOCK_STREAM\n")); } else { AJ_AlwaysPrintf(("Type: SOCK_DGRAM\n")); } if (AJ_WSL_SOCKET_CONTEXT[i].valid) { while (stashNode != NULL) { stashSz += stashNode->length; stashNode = stashNode->next; } AJ_AlwaysPrintf(("\tStash size = %u\n", stashSz)); AJ_AlwaysPrintf(("\tworkRxQueue:\n")); while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[i].workRxQueue, &item, 0) == AJ_OK) { AJ_AlwaysPrintf(("\t\tQueue Index %i:", j)); AJ_AlwaysPrintf(("\tItem Type: %s\n", WSL_WorkItemText(item->itemType))); j++; } if (j == 0) { AJ_AlwaysPrintf(("\tworkRxQueue empty\n")); } j = 0; AJ_AlwaysPrintf(("\tworkTxQueue:\n")); while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue, &item, 0) == AJ_OK) { AJ_AlwaysPrintf(("\t\tQueue Index %i:", j)); AJ_AlwaysPrintf(("\tItem Type: %s\n", WSL_WorkItemText(item->itemType))); j++; } if (j == 0) { AJ_AlwaysPrintf(("\tworkTxQueue empty\n")); } } else { AJ_AlwaysPrintf(("Socket context %d: Not valid or not open\n", i)); } AJ_AlwaysPrintf(("\n")); } } void HardFault_Handler(void) { AJ_AlwaysPrintf(("HARD FAULT OCCURED, PRINTING DRIVER TRACEBACK\n")); AJ_WSL_PrintDriverTraceback(); while (1); } #endif ajtcl-15.04b/WSL/aj_wsl_wmi.h000066400000000000000000000220521256742562600157530ustar00rootroot00000000000000/** * @file WMI layer function declarations */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #ifndef AJ_WSL_WMI_H_ #define AJ_WSL_WMI_H_ #include "aj_target.h" #include "aj_wsl_target.h" #include "aj_wsl_net.h" #include "aj_buf.h" #include "aj_target_platform.h" #include "aj_target_rtos.h" #include "aj_wsl_spi_constants.h" #ifdef __cplusplus extern "C" { #endif void AJ_WSL_WMI_ModuleInit(void); // prototype for functions that are invoked for wifi connection status typedef void (*AJ_WifiCallbackFunc)(int val); /* * Defines what byte maps to data in the header for commands/events */ #define WMI_HDR_START 0 #define WMI_HDR_FLAGS 1 #define WMI_HDR_PKT_SIZE 2 #define WMI_HDR_TRAILER_SIZE 4 #define WMI_HDR_PKT_ID 5 #define WMI_HDR_CMD_ID 6 #define IPCONFIG_QUERY 0 #define IPCONFIG_STATIC 1 #define IPCONFIG_DHCP 2 #define NUM_COMMANDS 30 #define NUM_SOCK_CMDS 29 typedef struct _CMDID_SIG_MAP { const uint16_t id; const char* signature; const uint16_t size; } CMDID_SIG_MAP; typedef struct _SOCKET_SIG_MAP { const char* signature; const uint16_t size; }SOCKET_SIG_MAP; /* * Signature definitions for various WMI Commands * Will always start with "q" (command ID) */ #define WMI_SIG_SET_SCAN_PARAMS "quqqqqqyyqqu" #define WMI_SIG_START_SCAN "quuuuuyyq" #define WMI_SIG_ALLOW_AGGR "quqq" #define WMI_SIG_CONNECT "quyyyyyyyySqMqq" #define WMI_SIG_SET_PASSPHRASE "quSPyy" #define WMI_SIG_SET_PROBED_SSID "quyyyS" #define WMI_SIG_ALLOW_AGGR "quqq" #define WMI_SIG_SET_BSS_FILTER "quyyqu" //note: on socket signatures dont add the command ID or socket command // they are marshaled in automatically #define WMI_SIG_SOCKET_IPCONFIG "uu4446666uuuu" #define WMI_SIG_SOCKET_STACK_INIT "uyyyy" #define WMI_SIG_SOCKET_OPEN "uuuu" #define WMI_SIG_SOCKET_CLOSE "uu" #define WMI_SIG_SOCKET_CONNECT "uuqq4q" #define WMI_SIG_SOCKET_BIND "uuqq4q" #define WMI_SIG_SET_POWER_MODE "quy" #define WMI_STORERECALL_CONFIG "quyy" #define WMI_SIG_IP_HOST_NAME "uS" #define WMI_SIG_SET_SOFT_AP "quyyyyyyyySqMqq" //#define WMI_SIG_CONNECT_EVENT "qMqquyyyay" #define WMI_SIG_SETSOCKOPTS "uuuuu" //ay" //Array of options is marshaled in separately typedef struct ip6_addr { uint8_t addr[16]; /* 128 bit IPv6 address */ } IP6_ADDR_T; #ifdef WIN32 typedef struct sockaddr_in SOCKADDR_T; typedef struct sockaddr_in SOCKADDR_6_T; #else typedef struct sockaddr { uint16_t sin_port; //Port number uint16_t sin_family; //ATH_AF_INET uint32_t sin_addr; //IPv4 Address } SOCKADDR_T; typedef struct sockaddr_6 { uint16_t sin6_family; // ATH_AF_INET6 uint16_t sin6_port; // transport layer port # uint32_t sin6_flowinfo; // IPv6 flow information IP6_ADDR_T sin6_addr; // IPv6 address uint32_t sin6_scope_id; // set of interfaces for a scope } SOCKADDR_6_T; #endif /* * This list is used for indexing into the CMDID_SIG_MAP */ typedef enum { WSL_CONNECT = 0, WSL_START_SCAN, WSL_SET_SCAN_PARAMS, WSL_SET_BSS_FILTER, WSL_SET_PROBED_SSID, WSL_ALLOW_AGGR, WSL_SET_POWER_MODE, WSL_SET_PASSPHRASE, WSL_STORECALL_CONFIGURE, WSL_SOCKET, WSL_SET_SOFT_AP, WSL_SEND, WSL_SENDTO, WSL_DISCONNECT, WSL_SET_HIDDEN_AP, WSL_SENDTO6, WSL_BIND6, WSL_ADD_CIPHER_KEY, WMI_SET_PMK }wsl_wmi_command_list; /* * This macro converts socket command numbers into WSL workitem numbers */ #define AJ_WSL_WORKITEM(g, c) (((uint8_t)(g) << 6) | (c)) /**< Encode a socket command into a workitem */ #define AJ_WSL_WORKITEM_NETWORK 0 #define AJ_WSL_WORKITEM_SOCKET 1 #define AJ_WSL_WORKITEM_DEVICE 2 AJ_EXPORT void AJ_WSL_WMI_PrintMessage(AJ_BufNode* pNodeWMIPacket); typedef struct _wsl_work_item { uint16_t itemType; /**< what type of work item is this*/ uint16_t sequenceNumber; /**< use this match a call with the response data */ AJ_BufList* list; /**< either the data going into or coming out of the function, direction depends on the call type */ AJ_BufNode* node; /**< either the data going into or coming out of the function, direction depends on the call type */ uint32_t size; uint8_t endpoint; /**< Which endpoint does the workitem use */ } wsl_work_item; /** * structure that maps socket handles on the target to socket handles on the host */ typedef struct _wsl_socket_context { uint32_t targetHandle; /**< holds the target-side handle value */ uint8_t valid; /**< is the socket valid? */ struct AJ_Queue* workTxQueue; /**< work items to be sent to the target are pushed here */ struct AJ_Queue* workRxQueue; /**< work items received from the target are pulled from here */ AJ_BufList* stashedRxList; /**< leftover data from a network packet waiting to be read */ uint32_t domain; /**< AF_INET or AF_INET6 */ uint32_t type; /**< SOCK_STREAM or SOCK_DGRAM*/ uint32_t protocol; /**< */ union { SOCKADDR_T name; SOCKADDR_6_T name6; }; } wsl_socket_context; /** * Find a socket number * * @param handle The socket handle * * @return The socket number with associated handle */ AJ_WSL_SOCKNUM AJ_WSL_FindSocketContext(uint32_t handle); /** * Find a socket that you can open * * @return The socket number avaliable */ AJ_WSL_SOCKNUM AJ_WSL_FindOpenSocketContext(void); /** * Process a WMI event * * @param pNodeHTCBody The buf node that was received over WMI */ AJ_EXPORT void AJ_WSL_WMI_ProcessWMIEvent(AJ_BufNode* pNodeHTCBody); /** * Process a data WMI event * * @param pNodeHTCBody The buf node that was received over WMI */ AJ_EXPORT void AJ_WSL_WMI_ProcessSocketDataResponse(AJ_BufNode* pNodeHTCBody); /** * Queue a work item to be sent to the target * * @param socket Socket to send over * @param command Enum WMI command your sending * @param endpoint Endpoint on the target to send to * @param list Buf List that your sending (must be previously marshalled) * * @return AJ_OK on success */ AJ_Status AJ_WSL_WMI_QueueWorkItem(uint32_t socket, uint8_t command, uint8_t endpoint, AJ_BufList* list); /** * Wait for a work item that was previously send on the queue * * @param socket Socket that the work item was sent to * @param command Command the was sent * @param item Address of the work item pointer * @param timeout Milliseconds to wait for this work item */ AJ_Status AJ_WSL_WMI_WaitForWorkItem(uint32_t socket, uint8_t command, wsl_work_item** item, uint32_t timeout); /** * Free a work item pointer. This frees everything inside the work item structure * * @param item Item to be freed */ void AJ_WSL_WMI_FreeWorkItem(wsl_work_item* item); /** * Get the WMI command ID from the enum command list * * @param command Enum command your getting the ID for * * @return The command ID */ const uint16_t getCommandId(wsl_wmi_command_list command); /** * Get the command signature * * @param command Command you want the signature to * * @return The signature */ const char* getCommandSignature(wsl_wmi_command_list command); /** * Get the packet size for a given command * * @param command The command you need the size for * * @return The size of the packet */ const uint16_t getPacketSize(wsl_wmi_command_list command); /** * Get the socket signature for a socket command * * @param command The SOCKET command you need the signature for * * @return The signature */ const char* getSockSignature(wsl_socket_cmds command); /** * Get the packet size for a socket command * * @param command The command you need the size for * * @return The size of the socket packet */ uint16_t getSockSize(wsl_socket_cmds command); /** * Get the devices MAC address * * @return Pointer to the MAC address data */ uint8_t* getDeviceMac(void); #ifdef __cplusplus } #endif #endif /* AJ_WSL_WMI_H_ */ ajtcl-15.04b/ajuncrustify.0.57.cfg000066400000000000000000002055111256742562600166040ustar00rootroot00000000000000# Copyright AllSeen Alliance. All rights reserved. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # # Uncrustify 0.57 # # General options # # The type of line endings newlines = auto # auto/lf/crlf/cr # The original size of tabs in the input input_tab_size = 8 # number # The size of tabs in the output (only used if align_with_tabs=true) output_tab_size = 8 # number # The ASCII value of the string escape char, usually 92 (\) or 94 (^). (Pawn) string_escape_char = 92 # number # Alternate string escape char for Pawn. Only works right before the quote char. string_escape_char2 = 0 # number # # Indenting # # The number of columns to indent per level. # Usually 2, 3, 4, or 8. # DJM # indent_columns = 8 # number indent_columns = 4 # number # The continuation indent. If non-zero, this overrides the indent of '(' and '=' continuation indents. # For FreeBSD, this is set to 4. indent_continue = 0 # number # How to use tabs when indenting code # 0=spaces only # 1=indent with tabs to brace level, align with spaces # 2=indent and align with tabs, using spaces when not on a tabstop # DJM # indent_with_tabs = 1 # number indent_with_tabs = 0 # number # Comments that are not a brace level are indented with tabs on a tabstop. # Requires indent_with_tabs=2. If false, will use spaces. indent_cmt_with_tabs = false # false/true # Whether to indent strings broken by '\' so that they line up indent_align_string = false # false/true # The number of spaces to indent multi-line XML strings. # Requires indent_align_string=True indent_xml_string = 0 # number # Spaces to indent '{' from level indent_brace = 0 # number # Whether braces are indented to the body level indent_braces = false # false/true # Disabled indenting function braces if indent_braces is true indent_braces_no_func = false # false/true # Disabled indenting class braces if indent_braces is true indent_braces_no_class = false # false/true # Disabled indenting struct braces if indent_braces is true indent_braces_no_struct = false # false/true # Indent based on the size of the brace parent, i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. indent_brace_parent = false # false/true # Whether the 'namespace' body is indented indent_namespace = false # false/true # The number of spaces to indent a namespace block indent_namespace_level = 0 # number # If the body of the namespace is longer than this number, it won't be indented. # Requires indent_namespace=true. Default=0 (no limit) indent_namespace_limit = 0 # number # Whether the 'extern "C"' body is indented indent_extern = false # false/true # Whether the 'class' body is indented # DJM # indent_class = false # false/true indent_class = true # false/true # Whether to indent the stuff after a leading class colon indent_class_colon = false # false/true # False=treat 'else\nif' as 'else if' for indenting purposes # True=indent the 'if' one level indent_else_if = false # false/true # Amount to indent variable declarations after a open brace. neg=relative, pos=absolute indent_var_def_blk = 0 # number # Indent continued variable declarations instead of aligning. indent_var_def_cont = false # false/true # True: indent continued function call parameters one indent level # False: align parameters under the open paren indent_func_call_param = false # false/true # Same as indent_func_call_param, but for function defs indent_func_def_param = false # false/true # Same as indent_func_call_param, but for function protos indent_func_proto_param = false # false/true # Same as indent_func_call_param, but for class declarations indent_func_class_param = false # false/true # Same as indent_func_call_param, but for class variable constructors indent_func_ctor_var_param = false # false/true # Same as indent_func_call_param, but for templates indent_template_param = false # false/true # Double the indent for indent_func_xxx_param options indent_func_param_double = false # false/true # Indentation column for standalone 'const' function decl/proto qualifier indent_func_const = 0 # number # Indentation column for standalone 'throw' function decl/proto qualifier indent_func_throw = 0 # number # The number of spaces to indent a continued '->' or '.' # Usually set to 0, 1, or indent_columns. indent_member = 0 # number # Spaces to indent single line ('//') comments on lines before code indent_sing_line_comments = 0 # number # If set, will indent trailing single line ('//') comments relative # to the code instead of trying to keep the same absolute column indent_relative_single_line_comments = false # false/true # Spaces to indent 'case' from 'switch' # Usually 0 or indent_columns. indent_switch_case = 0 # number # Spaces to shift the 'case' line, without affecting any other lines # Usually 0. indent_case_shift = 0 # number # Spaces to indent '{' from 'case'. # By default, the brace will appear under the 'c' in case. # Usually set to 0 or indent_columns. indent_case_brace = 4 # number # Whether to indent comments found in first column indent_col1_comment = false # false/true # How to indent goto labels # >0 : absolute column where 1 is the leftmost column # <=0 : subtract from brace indent # DJM # indent_label = 1 # number indent_label = -4 # number # Same as indent_label, but for access specifiers that are followed by a colon # DJM # indent_access_spec = 1 # number indent_access_spec = -2 # number # Indent the code after an access specifier by one level. # If set, this option forces 'indent_access_spec=0' indent_access_spec_body = false # false/true # If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended) indent_paren_nl = false # false/true # Controls the indent of a close paren after a newline. # 0: Indent to body level # 1: Align under the open paren # 2: Indent to the brace level indent_paren_close = 0 # number # Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren indent_comma_paren = false # false/true # Controls the indent of a BOOL operator when inside a paren.If TRUE, aligns under the open paren indent_bool_paren = false # false/true # If 'indent_bool_paren' is true, controls the indent of the first expression. If TRUE, aligns the first expression to the following ones indent_first_bool_expr = false # false/true # If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended) indent_square_nl = false # false/true # Don't change the relative indent of ESQL/C 'EXEC SQL' bodies indent_preserve_sql = false # false/true # Align continued statements at the '='. Default=True # If FALSE or the '=' is followed by a newline, the next line is indent one tab. indent_align_assign = true # false/true # # Spacing options # # Add or remove space around arithmetic operator '+', '-', '/', '*', etc # ASACORE-1026 we want to add space for arithmetic operators due to # a issue with uncrustify v0.57 not being able to always know the difference # between a pointer '*' and arithmetic '*' we are ignoring this rule # if uncrustify v0.57 is used. sp_arith = ignore # ignore/add/remove/force # Add or remove space around assignment operator '=', '+=', etc # DJM # sp_assign = ignore # ignore/add/remove/force sp_assign = add # ignore/add/remove/force # Add or remove space around assignment operator '=' in a prototype # DJM # sp_assign_default = ignore # ignore/add/remove/force sp_assign_default = add # ignore/add/remove/force # Add or remove space before assignment operator '=', '+=', etc. Overrides sp_assign. sp_before_assign = ignore # ignore/add/remove/force # Add or remove space after assignment operator '=', '+=', etc. Overrides sp_assign. sp_after_assign = ignore # ignore/add/remove/force # Add or remove space around assignment '=' in enum # DJM # sp_enum_assign = ignore # ignore/add/remove/force sp_enum_assign = add # ignore/add/remove/force # Add or remove space before assignment '=' in enum. Overrides sp_enum_assign. sp_enum_before_assign = ignore # ignore/add/remove/force # Add or remove space after assignment '=' in enum. Overrides sp_enum_assign. sp_enum_after_assign = ignore # ignore/add/remove/force # Add or remove space around preprocessor '##' concatenation operator. Default=Add sp_pp_concat = add # ignore/add/remove/force # Add or remove space after preprocessor '#' stringify operator. Also affects the '#@' charizing operator. Default=Add sp_pp_stringify = add # ignore/add/remove/force # Add or remove space around boolean operators '&&' and '||' # DJM # sp_bool = ignore # ignore/add/remove/force sp_bool = add # ignore/add/remove/force # Add or remove space around compare operator '<', '>', '==', etc # DJM # sp_compare = ignore # ignore/add/remove/force sp_compare = add # ignore/add/remove/force # Add or remove space inside '(' and ')' # DJM # sp_inside_paren = ignore # ignore/add/remove/force sp_inside_paren = remove # ignore/add/remove/force # Add or remove space between nested parens # DJM # sp_paren_paren = ignore # ignore/add/remove/force sp_paren_paren = remove # ignore/add/remove/force # Whether to balance spaces inside nested parens sp_balance_nested_parens = false # false/true # Add or remove space between ')' and '{' # DJM # sp_paren_brace = ignore # ignore/add/remove/force sp_paren_brace = add # ignore/add/remove/force # Add or remove space before pointer star '*' # DJM # sp_before_ptr_star = ignore # ignore/add/remove/force sp_before_ptr_star = remove # ignore/add/remove/force # Add or remove space before pointer star '*' that isn't followed by a variable name # If set to 'ignore', sp_before_ptr_star is used instead. sp_before_unnamed_ptr_star = ignore # ignore/add/remove/force # Add or remove space between pointer stars '*' sp_between_ptr_star = ignore # ignore/add/remove/force # Add or remove space after pointer star '*', if followed by a word. sp_after_ptr_star = ignore # ignore/add/remove/force # Add or remove space after a pointer star '*', if followed by a func proto/def. sp_after_ptr_star_func = ignore # ignore/add/remove/force # Add or remove space before a pointer star '*', if followed by a func proto/def. # DJM # sp_before_ptr_star_func = ignore # ignore/add/remove/force sp_before_ptr_star_func = remove # ignore/add/remove/force # Add or remove space before a reference sign '&' # DJM # sp_before_byref = ignore # ignore/add/remove/force sp_before_byref = remove # ignore/add/remove/force # Add or remove space before a reference sign '&' that isn't followed by a variable name # If set to 'ignore', sp_before_byref is used instead. sp_before_unnamed_byref = ignore # ignore/add/remove/force # Add or remove space after reference sign '&', if followed by a word. # DJM # sp_after_byref = ignore # ignore/add/remove/force sp_after_byref = add # ignore/add/remove/force # Add or remove space after a reference sign '&', if followed by a func proto/def. # DJM # sp_after_byref_func = ignore # ignore/add/remove/force sp_after_byref_func = add # ignore/add/remove/force # Add or remove space before a reference sign '&', if followed by a func proto/def. # DJM # sp_before_byref_func = ignore # ignore/add/remove/force sp_before_byref_func = remove # ignore/add/remove/force # Add or remove space between type and word. Default=Force sp_after_type = force # ignore/add/remove/force # Add or remove space in 'template <' vs 'template<'. # If set to ignore, sp_before_angle is used. # DJM # sp_template_angle = ignore # ignore/add/remove/force sp_template_angle = add # ignore/add/remove/force # Add or remove space before '<>' sp_before_angle = ignore # ignore/add/remove/force # Add or remove space inside '<' and '>' # DJM # sp_inside_angle = ignore # ignore/add/remove/force sp_inside_angle = remove # ignore/add/remove/force # Add or remove space after '<>' sp_after_angle = ignore # ignore/add/remove/force # Add or remove space between '<>' and '(' as found in 'new List();' sp_angle_paren = ignore # ignore/add/remove/force # Add or remove space between '<>' and a word as in 'List m;' # DJM # sp_angle_word = ignore # ignore/add/remove/force sp_angle_word = add # ignore/add/remove/force # Add or remove space between '>' and '>' in '>>' (template stuff C++/C# only). Default=Add sp_angle_shift = add # ignore/add/remove/force # Add or remove space before '(' of 'if', 'for', 'switch', and 'while' # DJM # sp_before_sparen = ignore # ignore/add/remove/force sp_before_sparen = add # ignore/add/remove/force # Add or remove space inside if-condition '(' and ')' # DJM # sp_inside_sparen = ignore # ignore/add/remove/force sp_inside_sparen = remove # ignore/add/remove/force # Add or remove space before if-condition ')'. Overrides sp_inside_sparen. sp_inside_sparen_close = ignore # ignore/add/remove/force # Add or remove space after ')' of 'if', 'for', 'switch', and 'while' # DJM # sp_after_sparen = ignore # ignore/add/remove/force sp_after_sparen = add # ignore/add/remove/force # Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while' # DJM # sp_sparen_brace = ignore # ignore/add/remove/force sp_sparen_brace = add # ignore/add/remove/force # Add or remove space between 'invariant' and '(' in the D language. sp_invariant_paren = ignore # ignore/add/remove/force # Add or remove space after the ')' in 'invariant (C) c' in the D language. sp_after_invariant_paren = ignore # ignore/add/remove/force # Add or remove space before empty statement ';' on 'if', 'for' and 'while' sp_special_semi = ignore # ignore/add/remove/force # Add or remove space before ';'. Default=Remove sp_before_semi = remove # ignore/add/remove/force # Add or remove space before ';' in non-empty 'for' statements sp_before_semi_for = ignore # ignore/add/remove/force # Add or remove space before a semicolon of an empty part of a for statement. sp_before_semi_for_empty = ignore # ignore/add/remove/force # Add or remove space after ';', except when followed by a comment. Default=Add sp_after_semi = ignore # ignore/add/remove/force # Add or remove space after ';' in non-empty 'for' statements. Default=Force sp_after_semi_for = force # ignore/add/remove/force # Add or remove space after the final semicolon of an empty part of a for statement: for ( ; ; ). # DJM # sp_after_semi_for_empty = ignore # ignore/add/remove/force sp_after_semi_for_empty = remove # ignore/add/remove/force # Add or remove space before '[' (except '[]') sp_before_square = ignore # ignore/add/remove/force # Add or remove space before '[]' sp_before_squares = ignore # ignore/add/remove/force # Add or remove space inside '[' and ']' sp_inside_square = ignore # ignore/add/remove/force # Add or remove space after ',' # DJM # sp_after_comma = ignore # ignore/add/remove/force sp_after_comma = add # ignore/add/remove/force # Add or remove space before ',' sp_before_comma = remove # ignore/add/remove/force # Add or remove space between an open paren and comma: '(,' vs '( ,' sp_paren_comma = force # ignore/add/remove/force # Add or remove space before the variadic '...' when preceded by a non-punctuator sp_before_ellipsis = ignore # ignore/add/remove/force # Add or remove space after class ':' # DJM # sp_after_class_colon = ignore # ignore/add/remove/force sp_after_class_colon = add # ignore/add/remove/force # Add or remove space before class ':' # DJM # sp_before_class_colon = ignore # ignore/add/remove/force sp_before_class_colon = add # ignore/add/remove/force # Add or remove space before case ':'. Default=Remove sp_before_case_colon = remove # ignore/add/remove/force # Add or remove space between 'operator' and operator sign sp_after_operator = ignore # ignore/add/remove/force # Add or remove space between the operator symbol and the open paren, as in 'operator ++(' sp_after_operator_sym = ignore # ignore/add/remove/force # Add or remove space after C/D cast, i.e. 'cast(int)a' vs 'cast(int) a' or '(int)a' vs '(int) a' sp_after_cast = ignore # ignore/add/remove/force # Add or remove spaces inside cast parens sp_inside_paren_cast = ignore # ignore/add/remove/force # Add or remove space between the type and open paren in a C++ cast, i.e. 'int(exp)' vs 'int (exp)' sp_cpp_cast_paren = ignore # ignore/add/remove/force # Add or remove space between 'sizeof' and '(' sp_sizeof_paren = ignore # ignore/add/remove/force # Add or remove space after the tag keyword (Pawn) sp_after_tag = ignore # ignore/add/remove/force # Add or remove space inside enum '{' and '}' sp_inside_braces_enum = ignore # ignore/add/remove/force # Add or remove space inside struct/union '{' and '}' sp_inside_braces_struct = ignore # ignore/add/remove/force # Add or remove space inside '{' and '}' # DJM # sp_inside_braces = ignore # ignore/add/remove/force sp_inside_braces = add # ignore/add/remove/force # Add or remove space inside '{}' # DJM # sp_inside_braces_empty = ignore # ignore/add/remove/force sp_inside_braces_empty = add # ignore/add/remove/force # Add or remove space between return type and function name # A minimum of 1 is forced except for pointer return types. sp_type_func = ignore # ignore/add/remove/force # Add or remove space between function name and '(' on function declaration # DJM # sp_func_proto_paren = ignore # ignore/add/remove/force sp_func_proto_paren = remove # ignore/add/remove/force # Add or remove space between function name and '(' on function definition # DJM # sp_func_def_paren = ignore # ignore/add/remove/force sp_func_def_paren = remove # ignore/add/remove/force # Add or remove space inside empty function '()' # DJM # sp_inside_fparens = ignore # ignore/add/remove/force sp_inside_fparens = remove # ignore/add/remove/force # Add or remove space inside function '(' and ')' # DJM # sp_inside_fparen = ignore # ignore/add/remove/force sp_inside_fparen = remove # ignore/add/remove/force # Add or remove space between ']' and '(' when part of a function call. sp_square_fparen = ignore # ignore/add/remove/force # Add or remove space between ')' and '{' of function # DJM # sp_fparen_brace = ignore # ignore/add/remove/force sp_fparen_brace = add # ignore/add/remove/force # Add or remove space between function name and '(' on function calls # DJM # sp_func_call_paren = ignore # ignore/add/remove/force sp_func_call_paren = remove # ignore/add/remove/force # Add or remove space between function name and '()' on function calls without parameters. # If set to 'ignore' (the default), sp_func_call_paren is used. sp_func_call_paren_empty = ignore # ignore/add/remove/force # Add or remove space between the user function name and '(' on function calls # You need to set a keyword to be a user function, like this: 'set func_call_user _' in the config file. sp_func_call_user_paren = ignore # ignore/add/remove/force # Add or remove space between a constructor/destructor and the open paren # DJM # sp_func_class_paren = ignore # ignore/add/remove/force sp_func_class_paren = remove # ignore/add/remove/force # Add or remove space between 'return' and '(' sp_return_paren = ignore # ignore/add/remove/force # Add or remove space between '__attribute__' and '(' sp_attribute_paren = ignore # ignore/add/remove/force # Add or remove space between 'defined' and '(' in '#if defined (FOO)' sp_defined_paren = ignore # ignore/add/remove/force # Add or remove space between 'throw' and '(' in 'throw (something)' sp_throw_paren = ignore # ignore/add/remove/force # Add or remove space between macro and value sp_macro = ignore # ignore/add/remove/force # Add or remove space between macro function ')' and value sp_macro_func = ignore # ignore/add/remove/force # Add or remove space between 'else' and '{' if on the same line # DJM # sp_else_brace = ignore # ignore/add/remove/force sp_else_brace = add # ignore/add/remove/force # Add or remove space between '}' and 'else' if on the same line # DJM # sp_brace_else = ignore # ignore/add/remove/force sp_brace_else = add # ignore/add/remove/force # Add or remove space between '}' and the name of a typedef on the same line sp_brace_typedef = ignore # ignore/add/remove/force # Add or remove space between 'catch' and '{' if on the same line sp_catch_brace = ignore # ignore/add/remove/force # Add or remove space between '}' and 'catch' if on the same line sp_brace_catch = ignore # ignore/add/remove/force # Add or remove space between 'finally' and '{' if on the same line sp_finally_brace = ignore # ignore/add/remove/force # Add or remove space between '}' and 'finally' if on the same line sp_brace_finally = ignore # ignore/add/remove/force # Add or remove space between 'try' and '{' if on the same line sp_try_brace = ignore # ignore/add/remove/force # Add or remove space between get/set and '{' if on the same line sp_getset_brace = ignore # ignore/add/remove/force # Add or remove space before the '::' operator # DJM # sp_before_dc = ignore # ignore/add/remove/force sp_before_dc = remove # ignore/add/remove/force # Add or remove space after the '::' operator # DJM # sp_after_dc = ignore # ignore/add/remove/force sp_after_dc = remove # ignore/add/remove/force # Add or remove around the D named array initializer ':' operator sp_d_array_colon = ignore # ignore/add/remove/force # Add or remove space after the '!' (not) operator. Default=Remove sp_not = remove # ignore/add/remove/force # Add or remove space after the '~' (invert) operator. Default=Remove sp_inv = remove # ignore/add/remove/force # Add or remove space after the '&' (address-of) operator. Default=Remove # This does not affect the spacing after a '&' that is part of a type. sp_addr = remove # ignore/add/remove/force # Add or remove space around the '.' or '->' operators. Default=Remove sp_member = remove # ignore/add/remove/force # Add or remove space after the '*' (dereference) operator. Default=Remove # This does not affect the spacing after a '*' that is part of a type. sp_deref = remove # ignore/add/remove/force # Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. Default=Remove sp_sign = remove # ignore/add/remove/force # Add or remove space before or after '++' and '--', as in '(--x)' or 'y++;'. Default=Remove sp_incdec = remove # ignore/add/remove/force # Add or remove space before a backslash-newline at the end of a line. Default=Add sp_before_nl_cont = add # ignore/add/remove/force # Add or remove space after the scope '+' or '-', as in '-(void) foo;' or '+(int) bar;' sp_after_oc_scope = ignore # ignore/add/remove/force # Add or remove space after the colon in message specs # '-(int) f:(int) x;' vs '-(int) f: (int) x;' sp_after_oc_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in message specs # '-(int) f: (int) x;' vs '-(int) f : (int) x;' sp_before_oc_colon = ignore # ignore/add/remove/force # Add or remove space after the colon in message specs # '[object setValue:1];' vs '[object setValue: 1];' sp_after_send_oc_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in message specs # '[object setValue:1];' vs '[object setValue :1];' sp_before_send_oc_colon = ignore # ignore/add/remove/force # Add or remove space after the (type) in message specs # '-(int)f: (int) x;' vs '-(int)f: (int)x;' sp_after_oc_type = ignore # ignore/add/remove/force # Add or remove space after the first (type) in message specs # '-(int) f:(int)x;' vs '-(int)f:(int)x;' sp_after_oc_return_type = ignore # ignore/add/remove/force # Add or remove space between '@selector' and '(' # '@selector(msgName)' vs '@selector (msgName)' # Also applies to @protocol() constructs sp_after_oc_at_sel = ignore # ignore/add/remove/force # Add or remove space between '@selector(x)' and the following word # '@selector(foo) a:' vs '@selector(foo)a:' sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force # Add or remove space inside '@selector' parens # '@selector(foo)' vs '@selector( foo )' # Also applies to @protocol() constructs sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force # Add or remove space before a block pointer caret # '^int (int arg){...}' vs. ' ^int (int arg){...}' sp_before_oc_block_caret = ignore # ignore/add/remove/force # Add or remove space after a block pointer caret # '^int (int arg){...}' vs. '^ int (int arg){...}' sp_after_oc_block_caret = ignore # ignore/add/remove/force # Add or remove space around the ':' in 'b ? t : f' # DJM # sp_cond_colon = ignore # ignore/add/remove/force sp_cond_colon = add # ignore/add/remove/force # Add or remove space around the '?' in 'b ? t : f' # DJM # sp_cond_question = ignore # ignore/add/remove/force sp_cond_question = add # ignore/add/remove/force # Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make sense here. sp_case_label = ignore # ignore/add/remove/force # Control the space around the D '..' operator. sp_range = ignore # ignore/add/remove/force # Control the space after the opening of a C++ comment '// A' vs '//A' sp_cmt_cpp_start = ignore # ignore/add/remove/force # Controls the spaces between #else or #endif and a trailing comment sp_endif_cmt = ignore # ignore/add/remove/force # # Code alignment (not left column spaces/tabs) # # Whether to keep non-indenting tabs align_keep_tabs = false # false/true # Whether to use tabs for aligning align_with_tabs = false # false/true # Whether to bump out to the next tab when aligning align_on_tabstop = false # false/true # Whether to left-align numbers align_number_left = false # false/true # Align variable definitions in prototypes and functions align_func_params = false # false/true # Align parameters in single-line functions that have the same name. # The function names must already be aligned with each other. align_same_func_call_params = false # false/true # The span for aligning variable definitions (0=don't align) align_var_def_span = 0 # number # How to align the star in variable definitions. # 0=Part of the type 'void * foo;' # 1=Part of the variable 'void *foo;' # 2=Dangling 'void *foo;' align_var_def_star_style = 0 # number # How to align the '&' in variable definitions. # 0=Part of the type # 1=Part of the variable # 2=Dangling align_var_def_amp_style = 0 # number # The threshold for aligning variable definitions (0=no limit) align_var_def_thresh = 0 # number # The gap for aligning variable definitions align_var_def_gap = 0 # number # Whether to align the colon in struct bit fields align_var_def_colon = false # false/true # Whether to align any attribute after the variable name align_var_def_attribute = false # false/true # Whether to align inline struct/enum/union variable definitions align_var_def_inline = false # false/true # The span for aligning on '=' in assignments (0=don't align) align_assign_span = 0 # number # The threshold for aligning on '=' in assignments (0=no limit) align_assign_thresh = 0 # number # The span for aligning on '=' in enums (0=don't align) align_enum_equ_span = 0 # number # The threshold for aligning on '=' in enums (0=no limit) align_enum_equ_thresh = 0 # number # The span for aligning struct/union (0=don't align) align_var_struct_span = 0 # number # The threshold for aligning struct/union member definitions (0=no limit) align_var_struct_thresh = 0 # number # The gap for aligning struct/union member definitions align_var_struct_gap = 0 # number # The span for aligning struct initializer values (0=don't align) align_struct_init_span = 0 # number # The minimum space between the type and the synonym of a typedef align_typedef_gap = 0 # number # The span for aligning single-line typedefs (0=don't align) align_typedef_span = 0 # number # How to align typedef'd functions with other typedefs # 0: Don't mix them at all # 1: align the open paren with the types # 2: align the function type name with the other type names align_typedef_func = 0 # number # Controls the positioning of the '*' in typedefs. Just try it. # 0: Align on typedef type, ignore '*' # 1: The '*' is part of type name: typedef int *pint; # 2: The '*' is part of the type, but dangling: typedef int *pint; align_typedef_star_style = 0 # number # Controls the positioning of the '&' in typedefs. Just try it. # 0: Align on typedef type, ignore '&' # 1: The '&' is part of type name: typedef int &pint; # 2: The '&' is part of the type, but dangling: typedef int &pint; align_typedef_amp_style = 0 # number # The span for aligning comments that end lines (0=don't align) align_right_cmt_span = 0 # number # If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment align_right_cmt_mix = false # false/true # If a trailing comment is more than this number of columns away from the text it follows, # it will qualify for being aligned. This has to be > 0 to do anything. align_right_cmt_gap = 0 # number # Align trailing comment at or beyond column N; 'pulls in' comments as a bonus side effect (0=ignore) align_right_cmt_at_col = 0 # number # The span for aligning function prototypes (0=don't align) align_func_proto_span = 0 # number # Minimum gap between the return type and the function name. align_func_proto_gap = 0 # number # Align function protos on the 'operator' keyword instead of what follows align_on_operator = false # false/true # Whether to mix aligning prototype and variable declarations. # If true, align_var_def_XXX options are used instead of align_func_proto_XXX options. align_mix_var_proto = false # false/true # Align single-line functions with function prototypes, uses align_func_proto_span align_single_line_func = false # false/true # Aligning the open brace of single-line functions. # Requires align_single_line_func=true, uses align_func_proto_span align_single_line_brace = false # false/true # Gap for align_single_line_brace. align_single_line_brace_gap = 0 # number # The span for aligning ObjC msg spec (0=don't align) align_oc_msg_spec_span = 0 # number # Whether to align macros wrapped with a backslash and a newline. # This will not work right if the macro contains a multi-line comment. align_nl_cont = false # false/true # The minimum space between label and value of a preprocessor define align_pp_define_gap = 0 # number # The span for aligning on '#define' bodies (0=don't align) align_pp_define_span = 0 # number # Align lines that start with '<<' with previous '<<'. Default=true align_left_shift = true # false/true # Span for aligning parameters in an Obj-C message call on the ':' (0=don't align) align_oc_msg_colon_span = 0 # number # Aligning parameters in an Obj-C '+' or '-' declaration on the ':' align_oc_decl_colon = false # false/true # # Newline adding and removing options # # Whether to collapse empty blocks between '{' and '}' nl_collapse_empty_body = false # false/true # Don't split one-line braced assignments - 'foo_t f = { 1, 2 };' nl_assign_leave_one_liners = false # false/true # Don't split one-line braced statements inside a class xx { } body # DJM # nl_class_leave_one_liners = false # false/true nl_class_leave_one_liners = true # false/true # Don't split one-line enums: 'enum foo { BAR = 15 };' nl_enum_leave_one_liners = false # false/true # Don't split one-line get or set functions nl_getset_leave_one_liners = false # false/true # Don't split one-line function definitions - 'int foo() { return 0; }' nl_func_leave_one_liners = false # false/true # Don't split one-line if/else statements - 'if(a) b++;' nl_if_leave_one_liners = false # false/true # Add or remove newlines at the start of the file nl_start_of_file = ignore # ignore/add/remove/force # The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force' nl_start_of_file_min = 0 # number # Add or remove newline at the end of the file nl_end_of_file = ignore # ignore/add/remove/force # The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force') nl_end_of_file_min = 0 # number # Add or remove newline between '=' and '{' nl_assign_brace = ignore # ignore/add/remove/force # Add or remove newline between '=' and '[' (D only) nl_assign_square = ignore # ignore/add/remove/force # Add or remove newline after '= [' (D only). Will also affect the newline before the ']' nl_after_square_assign = ignore # ignore/add/remove/force # The number of blank lines after a block of variable definitions nl_func_var_def_blk = 0 # number # Add or remove newline between a function call's ')' and '{', as in: # list_for_each(item, &list) { } nl_fcall_brace = ignore # ignore/add/remove/force # Add or remove newline between 'enum' and '{' # DJM # nl_enum_brace = ignore # ignore/add/remove/force nl_enum_brace = remove # ignore/add/remove/force # Add or remove newline between 'struct and '{' # DJM # nl_struct_brace = ignore # ignore/add/remove/force nl_struct_brace = remove # ignore/add/remove/force # Add or remove newline between 'union' and '{' # DJM # nl_union_brace = ignore # ignore/add/remove/force nl_union_brace = remove # ignore/add/remove/force # Add or remove newline between 'if' and '{' # DJM # nl_if_brace = ignore # ignore/add/remove/force nl_if_brace = remove # ignore/add/remove/force # Add or remove newline between '}' and 'else' # DJM # nl_brace_else = ignore # ignore/add/remove/force nl_brace_else = remove # ignore/add/remove/force # Add or remove newline between 'else if' and '{' # If set to ignore, nl_if_brace is used instead nl_elseif_brace = ignore # ignore/add/remove/force # Add or remove newline between 'else' and '{' # DJM # nl_else_brace = ignore # ignore/add/remove/force nl_else_brace = remove # ignore/add/remove/force # Add or remove newline between 'else' and 'if' nl_else_if = ignore # ignore/add/remove/force # Add or remove newline between '}' and 'finally' # DJM # nl_brace_finally = ignore # ignore/add/remove/force nl_brace_finally = remove # ignore/add/remove/force # Add or remove newline between 'finally' and '{' # DJM # nl_finally_brace = ignore # ignore/add/remove/force nl_finally_brace = remove # ignore/add/remove/force # Add or remove newline between 'try' and '{' # DJM # nl_try_brace = ignore # ignore/add/remove/force nl_try_brace = remove # ignore/add/remove/force # Add or remove newline between get/set and '{' # DJM # nl_getset_brace = ignore # ignore/add/remove/force nl_getset_brace = remove # ignore/add/remove/force # Add or remove newline between 'for' and '{' # DJM # nl_for_brace = ignore # ignore/add/remove/force nl_for_brace = remove # ignore/add/remove/force # Add or remove newline between 'catch' and '{' # DJM # nl_catch_brace = ignore # ignore/add/remove/force nl_catch_brace = remove # ignore/add/remove/force # Add or remove newline between '}' and 'catch' # DJM # nl_brace_catch = ignore # ignore/add/remove/force nl_brace_catch = remove # ignore/add/remove/force # Add or remove newline between 'while' and '{' # DJM # nl_while_brace = ignore # ignore/add/remove/force nl_while_brace = remove # ignore/add/remove/force # Add or remove newline between 'using' and '{' nl_using_brace = ignore # ignore/add/remove/force # Add or remove newline between two open or close braces. # Due to general newline/brace handling, REMOVE may not work. nl_brace_brace = ignore # ignore/add/remove/force # Add or remove newline between 'do' and '{' # DJM # nl_do_brace = ignore # ignore/add/remove/force nl_do_brace = remove # ignore/add/remove/force # Add or remove newline between '}' and 'while' of 'do' statement # DJM # nl_brace_while = ignore # ignore/add/remove/force nl_brace_while = remove # ignore/add/remove/force # Add or remove newline between 'switch' and '{' # DJM # nl_switch_brace = ignore # ignore/add/remove/force nl_switch_brace = remove # ignore/add/remove/force # Add a newline between ')' and '{' if the ')' is on a different line than the if/for/etc. # Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch, and nl_catch_brace. nl_multi_line_cond = false # false/true # Force a newline in a define after the macro name for multi-line defines. nl_multi_line_define = false # false/true # Whether to put a newline before 'case' statement # DJM # nl_before_case = false # false/true nl_before_case = true # false/true # Add or remove newline between ')' and 'throw' nl_before_throw = ignore # ignore/add/remove/force # Whether to put a newline after 'case' statement nl_after_case = false # false/true # Newline between namespace and { # DJM # nl_namespace_brace = ignore # ignore/add/remove/force nl_namespace_brace = remove # ignore/add/remove/force # Add or remove newline between 'template<>' and whatever follows. nl_template_class = ignore # ignore/add/remove/force # Add or remove newline between 'class' and '{' # DJM # nl_class_brace = ignore # ignore/add/remove/force nl_class_brace = remove # ignore/add/remove/force # Add or remove newline after each ',' in the constructor member initialization nl_class_init_args = ignore # ignore/add/remove/force # Add or remove newline between return type and function name in a function definition # DJM nl_func_type_name = ignore # ignore/add/remove/force # nl_func_type_name = remove # ignore/add/remove/force # Add or remove newline between return type and function name inside a class {} # Uses nl_func_type_name or nl_func_proto_type_name if set to ignore. # DJM nl_func_type_name_class = ignore # ignore/add/remove/force # nl_func_type_name_class = remove # ignore/add/remove/force # Add or remove newline between function scope and name in a definition # Controls the newline after '::' in 'void A::f() { }' nl_func_scope_name = ignore # ignore/add/remove/force # Add or remove newline between return type and function name in a prototype # DJM # nl_func_proto_type_name = ignore # ignore/add/remove/force nl_func_proto_type_name = remove # ignore/add/remove/force # Add or remove newline between a function name and the opening '(' # DJM # nl_func_paren = ignore # ignore/add/remove/force nl_func_paren = remove # ignore/add/remove/force # Add or remove newline between a function name and the opening '(' in the definition # DJM # nl_func_def_paren = ignore # ignore/add/remove/force nl_func_def_paren = remove # ignore/add/remove/force # Add or remove newline after '(' in a function declaration nl_func_decl_start = ignore # ignore/add/remove/force # Add or remove newline after '(' in a function definition nl_func_def_start = ignore # ignore/add/remove/force # Overrides nl_func_decl_start when there is only one parameter. nl_func_decl_start_single = ignore # ignore/add/remove/force # Overrides nl_func_def_start when there is only one parameter. nl_func_def_start_single = ignore # ignore/add/remove/force # Add or remove newline after each ',' in a function declaration nl_func_decl_args = ignore # ignore/add/remove/force # Add or remove newline after each ',' in a function definition nl_func_def_args = ignore # ignore/add/remove/force # Add or remove newline before the ')' in a function declaration nl_func_decl_end = ignore # ignore/add/remove/force # Add or remove newline before the ')' in a function definition nl_func_def_end = ignore # ignore/add/remove/force # Overrides nl_func_decl_end when there is only one parameter. nl_func_decl_end_single = ignore # ignore/add/remove/force # Overrides nl_func_def_end when there is only one parameter. nl_func_def_end_single = ignore # ignore/add/remove/force # Add or remove newline between '()' in a function declaration. nl_func_decl_empty = ignore # ignore/add/remove/force # Add or remove newline between '()' in a function definition. nl_func_def_empty = ignore # ignore/add/remove/force # Add or remove newline between function signature and '{' nl_fdef_brace = ignore # ignore/add/remove/force # Whether to put a newline after 'return' statement nl_after_return = false # false/true # Add or remove a newline between the return keyword and return expression. nl_return_expr = ignore # ignore/add/remove/force # Whether to put a newline after semicolons, except in 'for' statements nl_after_semicolon = false # false/true # Whether to put a newline after brace open. # This also adds a newline before the matching brace close. nl_after_brace_open = false # false/true # If nl_after_brace_open and nl_after_brace_open_cmt are true, a newline is # placed between the open brace and a trailing single-line comment. nl_after_brace_open_cmt = false # false/true # Whether to put a newline after a virtual brace open with a non-empty body. # These occur in un-braced if/while/do/for statement bodies. nl_after_vbrace_open = false # false/true # Whether to put a newline after a virtual brace open with an empty body. # These occur in un-braced if/while/do/for statement bodies. nl_after_vbrace_open_empty = false # false/true # Whether to put a newline after a brace close. # Does not apply if followed by a necessary ';'. nl_after_brace_close = false # false/true # Whether to put a newline after a virtual brace close. # Would add a newline before return in: 'if (foo) a++; return;' nl_after_vbrace_close = false # false/true # Whether to alter newlines in '#define' macros nl_define_macro = false # false/true # Whether to not put blanks after '#ifxx', '#elxx', or before '#endif' nl_squeeze_ifdef = false # false/true # Add or remove blank line before 'if' nl_before_if = ignore # ignore/add/remove/force # Add or remove blank line after 'if' statement nl_after_if = ignore # ignore/add/remove/force # Add or remove blank line before 'for' nl_before_for = ignore # ignore/add/remove/force # Add or remove blank line after 'for' statement nl_after_for = ignore # ignore/add/remove/force # Add or remove blank line before 'while' nl_before_while = ignore # ignore/add/remove/force # Add or remove blank line after 'while' statement nl_after_while = ignore # ignore/add/remove/force # Add or remove blank line before 'switch' nl_before_switch = ignore # ignore/add/remove/force # Add or remove blank line after 'switch' statement nl_after_switch = ignore # ignore/add/remove/force # Add or remove blank line before 'do' nl_before_do = ignore # ignore/add/remove/force # Add or remove blank line after 'do/while' statement nl_after_do = ignore # ignore/add/remove/force # Whether to double-space commented-entries in struct/enum nl_ds_struct_enum_cmt = false # false/true # Whether to double-space before the close brace of a struct/union/enum # (lower priority than 'eat_blanks_before_close_brace') nl_ds_struct_enum_close_brace = false # false/true # Add or remove a newline around a class colon. # Related to pos_class_colon, nl_class_init_args, and pos_comma. nl_class_colon = ignore # ignore/add/remove/force # Change simple unbraced if statements into a one-liner # 'if(b)\n i++;' => 'if(b) i++;' nl_create_if_one_liner = false # false/true # Change simple unbraced for statements into a one-liner # 'for (i=0;i<5;i++)\n foo(i);' => 'for (i=0;i<5;i++) foo(i);' nl_create_for_one_liner = false # false/true # Change simple unbraced while statements into a one-liner # 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);' nl_create_while_one_liner = false # false/true # # Positioning options # # The position of arithmetic operators in wrapped expressions pos_arith = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of assignment in wrapped expressions. # Do not affect '=' followed by '{' pos_assign = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of boolean operators in wrapped expressions pos_bool = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of comparison operators in wrapped expressions pos_compare = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of conditional (b ? t : f) operators in wrapped expressions pos_conditional = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of the comma in wrapped expressions pos_comma = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of the comma in the constructor initialization list pos_class_comma = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of colons between constructor and member initialization pos_class_colon = ignore # ignore/lead/lead_break/lead_force/trail/trail_break/trail_force # # Line Splitting options # # Try to limit code width to N number of columns code_width = 0 # number # Whether to fully split long 'for' statements at semi-colons ls_for_split_full = false # false/true # Whether to fully split long function protos/calls at commas ls_func_split_full = false # false/true # # Blank line options # # The maximum consecutive newlines nl_max = 0 # number # The number of newlines after a function prototype, if followed by another function prototype nl_after_func_proto = 0 # number # The number of newlines after a function prototype, if not followed by another function prototype nl_after_func_proto_group = 0 # number # The number of newlines after '}' of a multi-line function body nl_after_func_body = 0 # number # The number of newlines after '}' of a single line function body nl_after_func_body_one_liner = 0 # number # The minimum number of newlines before a multi-line comment. # Doesn't apply if after a brace open or another multi-line comment. nl_before_block_comment = 0 # number # The minimum number of newlines before a single-line C comment. # Doesn't apply if after a brace open or other single-line C comments. nl_before_c_comment = 0 # number # The minimum number of newlines before a CPP comment. # Doesn't apply if after a brace open or other CPP comments. nl_before_cpp_comment = 0 # number # Whether to force a newline after a multi-line comment. nl_after_multiline_comment = false # false/true # The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. # Will not change the newline count if after a brace open. # 0 = No change. nl_before_access_spec = 0 # number # The number of newlines after a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. # 0 = No change. nl_after_access_spec = 0 # number # The number of newlines between a function def and the function comment. # 0 = No change. nl_comment_func_def = 0 # number # The number of newlines after a try-catch-finally block that isn't followed by a brace close. # 0 = No change. nl_after_try_catch_finally = 0 # number # The number of newlines before and after a property, indexer or event decl. # 0 = No change. nl_around_cs_property = 0 # number # The number of newlines between the get/set/add/remove handlers in C#. # 0 = No change. nl_between_get_set = 0 # number # Whether to remove blank lines after '{' eat_blanks_after_open_brace = false # false/true # Whether to remove blank lines before '}' eat_blanks_before_close_brace = false # false/true # # Code modifying options (non-whitespace) # # Add or remove braces on single-line 'do' statement mod_full_brace_do = ignore # ignore/add/remove/force # Add or remove braces on single-line 'for' statement mod_full_brace_for = ignore # ignore/add/remove/force # Add or remove braces on single-line function definitions. (Pawn) mod_full_brace_function = ignore # ignore/add/remove/force # Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'. mod_full_brace_if = add # ignore/add/remove/force # Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if. # If any must be braced, they are all braced. If all can be unbraced, then the braces are removed. mod_full_brace_if_chain = false # false/true # Don't remove braces around statements that span N newlines mod_full_brace_nl = 0 # number # Add or remove braces on single-line 'while' statement mod_full_brace_while = ignore # ignore/add/remove/force # Add or remove braces on single-line 'using ()' statement mod_full_brace_using = ignore # ignore/add/remove/force # Add or remove unnecessary paren on 'return' statement mod_paren_on_return = ignore # ignore/add/remove/force # Whether to change optional semicolons to real semicolons mod_pawn_semicolon = false # false/true # Add parens on 'while' and 'if' statement around bools mod_full_paren_if_bool = false # false/true # Whether to remove superfluous semicolons mod_remove_extra_semicolon = false # false/true # If a function body exceeds the specified number of newlines and doesn't have a comment after # the close brace, a comment will be added. mod_add_long_function_closebrace_comment = 0 # number # If a switch body exceeds the specified number of newlines and doesn't have a comment after # the close brace, a comment will be added. mod_add_long_switch_closebrace_comment = 0 # number # If an #ifdef body exceeds the specified number of newlines and doesn't have a comment after # the #else, a comment will be added. mod_add_long_ifdef_endif_comment = 0 # number # If an #ifdef or #else body exceeds the specified number of newlines and doesn't have a comment after # the #endif, a comment will be added. mod_add_long_ifdef_else_comment = 0 # number # If TRUE, will sort consecutive single-line 'import' statements [Java, D] mod_sort_import = false # false/true # If TRUE, will sort consecutive single-line 'using' statements [C#] mod_sort_using = false # false/true # If TRUE, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C] # This is generally a bad idea, as it may break your code. mod_sort_include = false # false/true # If TRUE, it will move a 'break' that appears after a fully braced 'case' before the close brace. mod_move_case_break = false # false/true # Will add or remove the braces around a fully braced case statement. # Will only remove the braces if there are no variable declarations in the block. mod_case_brace = ignore # ignore/add/remove/force # If TRUE, it will remove a void 'return;' that appears as the last statement in a function. mod_remove_empty_return = false # false/true # # Comment modifications # # Try to wrap comments at cmt_width columns cmt_width = 0 # number # Set the comment reflow mode (default: 0) # 0: no reflowing (apart from the line wrapping due to cmt_width) # 1: no touching at all # 2: full reflow cmt_reflow_mode = 0 # number # If false, disable all multi-line comment changes, including cmt_width. keyword substitution, and leading chars. # Default is true. cmt_indent_multi = true # false/true # Whether to group c-comments that look like they are in a block cmt_c_group = false # false/true # Whether to put an empty '/*' on the first line of the combined c-comment cmt_c_nl_start = false # false/true # Whether to put a newline before the closing '*/' of the combined c-comment cmt_c_nl_end = false # false/true # Whether to group cpp-comments that look like they are in a block cmt_cpp_group = false # false/true # Whether to put an empty '/*' on the first line of the combined cpp-comment cmt_cpp_nl_start = false # false/true # Whether to put a newline before the closing '*/' of the combined cpp-comment cmt_cpp_nl_end = false # false/true # Whether to change cpp-comments into c-comments cmt_cpp_to_c = false # false/true # Whether to put a star on subsequent comment lines cmt_star_cont = false # false/true # The number of spaces to insert at the start of subsequent comment lines cmt_sp_before_star_cont = 0 # number # The number of spaces to insert after the star on subsequent comment lines # DJM # cmt_sp_after_star_cont = 0 # number cmt_sp_after_star_cont = 1 # number # For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of # the comment are the same length. Default=True # DJM # cmt_multi_check_last = true # false/true cmt_multi_check_last = false # false/true # The filename that contains text to insert at the head of a file if the file doesn't start with a C/C++ comment. # Will substitute $(filename) with the current file's name. cmt_insert_file_header = "" # string # The filename that contains text to insert at the end of a file if the file doesn't end with a C/C++ comment. # Will substitute $(filename) with the current file's name. cmt_insert_file_footer = "" # string # The filename that contains text to insert before a function implementation if the function isn't preceded with a C/C++ comment. # Will substitute $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff. # Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... } cmt_insert_func_header = "" # string # The filename that contains text to insert before a class if the class isn't preceded with a C/C++ comment. # Will substitute $(class) with the class name. cmt_insert_class_header = "" # string # If a preprocessor is encountered when stepping backwards from a function name, then # this option decides whether the comment should be inserted. # Affects cmt_insert_func_header and cmt_insert_class_header. cmt_insert_before_preproc = false # false/true # # Preprocessor options # # Control indent of preprocessors inside #if blocks at brace level 0 pp_indent = ignore # ignore/add/remove/force # Whether to indent #if/#else/#endif at the brace level (true) or from column 1 (false) pp_indent_at_level = false # false/true # If pp_indent_at_level=false, specifies the number of columns to indent per level. Default=1. pp_indent_count = 1 # number # Add or remove space after # based on pp_level of #if blocks pp_space = ignore # ignore/add/remove/force # Sets the number of spaces added with pp_space pp_space_count = 0 # number # The indent for #region and #endregion in C# and '#pragma region' in C/C++ pp_indent_region = 0 # number # Whether to indent the code between #region and #endregion pp_region_indent_code = false # false/true # If pp_indent_at_level=true, sets the indent for #if, #else, and #endif when not at file-level pp_indent_if = 0 # number # Control whether to indent the code between #if, #else and #endif when not at file-level pp_if_indent_code = false # false/true # Whether to indent '#define' at the brace level (true) or from column 1 (false) pp_define_at_level = false # false/true # You can force a token to be a type with the 'type' option. # Example: # type myfoo1 myfoo2 # # You can create custom macro-based indentation using macro-open, # macro-else and macro-close. # Example: # macro-open BEGIN_TEMPLATE_MESSAGE_MAP # macro-open BEGIN_MESSAGE_MAP # macro-close END_MESSAGE_MAP # # You can assign any keyword to any type with the set option. # set func_call_user _ N_ # # The full syntax description of all custom definition config entries # is shown below: # # define custom tokens as: # - embed whitespace in token using '' escape character, or # put token in quotes # - these: ' " and ` are recognized as quote delimiters # # type token1 token2 token3 ... # ^ optionally specify multiple tokens on a single line # define def_token output_token # ^ output_token is optional, then NULL is assumed # macro-open token # macro-close token # macro-else token # set id token1 token2 ... # ^ optionally specify multiple tokens on a single line # ^ id is one of the names in token_enum.h sans the CT_ prefix, # e.g. PP_PRAGMA # # all tokens are separated by any mix of ',' commas, '=' equal signs # and whitespace (space, tab) # ajtcl-15.04b/ajuncrustify.0.61.cfg000066400000000000000000002453651256742562600166120ustar00rootroot00000000000000# Copyright AllSeen Alliance. All rights reserved. # # Permission to use, copy, modify, and/or distribute this software for any # purpose with or without fee is hereby granted, provided that the above # copyright notice and this permission notice appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # Uncrustify 0.61 # # General options # # The type of line endings newlines = auto # auto/lf/crlf/cr # The original size of tabs in the input input_tab_size = 8 # number # The size of tabs in the output (only used if align_with_tabs=true) output_tab_size = 8 # number # The ASCII value of the string escape char, usually 92 (\) or 94 (^). (Pawn) string_escape_char = 92 # number # Alternate string escape char for Pawn. Only works right before the quote char. string_escape_char2 = 0 # number # Allow interpreting '>=' and '>>=' as part of a template in 'void f(list>=val);'. # If true (default), 'assert(x<0 && y>=3)' will be broken. # Improvements to template detection may make this option obsolete. tok_split_gte = false # false/true # Control what to do with the UTF-8 BOM (recommend 'remove') utf8_bom = remove # ignore/add/remove/force # If the file contains bytes with values between 128 and 255, but is not UTF-8, then output as UTF-8 utf8_byte = false # false/true # Force the output encoding to UTF-8 utf8_force = false # false/true # # Indenting # # The number of columns to indent per level. # Usually 2, 3, 4, or 8. # DJM # indent_columns = 8 # number indent_columns = 4 # number # The continuation indent. If non-zero, this overrides the indent of '(' and '=' continuation indents. # For FreeBSD, this is set to 4. Negative value is absolute and not increased for each ( level indent_continue = 0 # number # How to use tabs when indenting code # 0=spaces only # 1=indent with tabs to brace level, align with spaces # 2=indent and align with tabs, using spaces when not on a tabstop # DJM # indent_with_tabs = 1 # number indent_with_tabs = 0 # number # Comments that are not a brace level are indented with tabs on a tabstop. # Requires indent_with_tabs=2. If false, will use spaces. indent_cmt_with_tabs = false # false/true # Whether to indent strings broken by '\' so that they line up indent_align_string = false # false/true # The number of spaces to indent multi-line XML strings. # Requires indent_align_string=True indent_xml_string = 0 # number # Spaces to indent '{' from level indent_brace = 0 # number # Whether braces are indented to the body level indent_braces = false # false/true # Disabled indenting function braces if indent_braces is true indent_braces_no_func = false # false/true # Disabled indenting class braces if indent_braces is true indent_braces_no_class = false # false/true # Disabled indenting struct braces if indent_braces is true indent_braces_no_struct = false # false/true # Indent based on the size of the brace parent, i.e. 'if' => 3 spaces, 'for' => 4 spaces, etc. indent_brace_parent = false # false/true # Indent based on the paren open instead of the brace open in '({\n', default is to indent by brace. indent_paren_open_brace = false # false/true # Whether the 'namespace' body is indented indent_namespace = false # false/true # Only indent one namespace and no sub-namepaces. # Requires indent_namespace=true. indent_namespace_single_indent = false # false/true # The number of spaces to indent a namespace block indent_namespace_level = 0 # number # If the body of the namespace is longer than this number, it won't be indented. # Requires indent_namespace=true. Default=0 (no limit) indent_namespace_limit = 0 # number # Whether the 'extern "C"' body is indented indent_extern = false # false/true # Whether the 'class' body is indented # DJM # indent_class = false # false/true indent_class = true # false/true # Whether to indent the stuff after a leading base class colon indent_class_colon = false # false/true # Whether to indent the stuff after a leading class initializer colon indent_constr_colon = false # false/true # Virtual indent from the ':' for member initializers. Default is 2 indent_ctor_init_leading = 2 # number # Additional indenting for constructor initializer list indent_ctor_init = 0 # number # False=treat 'else\nif' as 'else if' for indenting purposes # True=indent the 'if' one level indent_else_if = false # false/true # Amount to indent variable declarations after a open brace. neg=relative, pos=absolute indent_var_def_blk = 0 # number # Indent continued variable declarations instead of aligning. indent_var_def_cont = false # false/true # True: force indentation of function definition to start in column 1 # False: use the default behavior indent_func_def_force_col1 = false # false/true # True: indent continued function call parameters one indent level # False: align parameters under the open paren indent_func_call_param = false # false/true # Same as indent_func_call_param, but for function defs indent_func_def_param = false # false/true # Same as indent_func_call_param, but for function protos indent_func_proto_param = false # false/true # Same as indent_func_call_param, but for class declarations indent_func_class_param = false # false/true # Same as indent_func_call_param, but for class variable constructors indent_func_ctor_var_param = false # false/true # Same as indent_func_call_param, but for templates indent_template_param = false # false/true # Double the indent for indent_func_xxx_param options indent_func_param_double = false # false/true # Indentation column for standalone 'const' function decl/proto qualifier indent_func_const = 0 # number # Indentation column for standalone 'throw' function decl/proto qualifier indent_func_throw = 0 # number # The number of spaces to indent a continued '->' or '.' # Usually set to 0, 1, or indent_columns. indent_member = 0 # number # Spaces to indent single line ('//') comments on lines before code indent_sing_line_comments = 0 # number # If set, will indent trailing single line ('//') comments relative # to the code instead of trying to keep the same absolute column indent_relative_single_line_comments = false # false/true # Spaces to indent 'case' from 'switch' # Usually 0 or indent_columns. indent_switch_case = 0 # number # Spaces to shift the 'case' line, without affecting any other lines # Usually 0. indent_case_shift = 0 # number # Spaces to indent '{' from 'case'. # By default, the brace will appear under the 'c' in case. # Usually set to 0 or indent_columns. indent_case_brace = 4 # number # Whether to indent comments found in first column indent_col1_comment = false # false/true # How to indent goto labels # >0 : absolute column where 1 is the leftmost column # <=0 : subtract from brace indent # DJM # indent_label = 1 # number indent_label = -4 # number # Same as indent_label, but for access specifiers that are followed by a colon # DJM # indent_access_spec = 1 # number indent_access_spec = -2 # number # Indent the code after an access specifier by one level. # If set, this option forces 'indent_access_spec=0' indent_access_spec_body = false # false/true # If an open paren is followed by a newline, indent the next line so that it lines up after the open paren (not recommended) indent_paren_nl = false # false/true # Controls the indent of a close paren after a newline. # 0: Indent to body level # 1: Align under the open paren # 2: Indent to the brace level indent_paren_close = 0 # number # Controls the indent of a comma when inside a paren.If TRUE, aligns under the open paren indent_comma_paren = false # false/true # Controls the indent of a BOOL operator when inside a paren.If TRUE, aligns under the open paren indent_bool_paren = false # false/true # If 'indent_bool_paren' is true, controls the indent of the first expression. If TRUE, aligns the first expression to the following ones indent_first_bool_expr = false # false/true # If an open square is followed by a newline, indent the next line so that it lines up after the open square (not recommended) indent_square_nl = false # false/true # Don't change the relative indent of ESQL/C 'EXEC SQL' bodies indent_preserve_sql = false # false/true # Align continued statements at the '='. Default=True # If FALSE or the '=' is followed by a newline, the next line is indent one tab. indent_align_assign = true # false/true # Indent OC blocks at brace level instead of usual rules. indent_oc_block = false # false/true # Indent OC blocks in a message relative to the parameter name. # 0=use indent_oc_block rules, 1+=spaces to indent indent_oc_block_msg = 0 # number # Minimum indent for subsequent parameters indent_oc_msg_colon = 0 # number # If true, prioritize aligning with initial colon (and stripping spaces from lines, if necessary). # Default is true. indent_oc_msg_prioritize_first_colon = true # false/true # If indent_oc_block_msg and this option are on, blocks will be indented the way that Xcode does by default (from keyword if the parameter is on its own line; otherwise, from the previous indentation level). indent_oc_block_msg_xcode_style = false # false/true # If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is relative to a msg keyword. indent_oc_block_msg_from_keyword = false # false/true # If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is relative to a msg colon. indent_oc_block_msg_from_colon = false # false/true # If indent_oc_block_msg and this option are on, blocks will be indented from where the block caret is. indent_oc_block_msg_from_caret = false # false/true # If indent_oc_block_msg and this option are on, blocks will be indented from where the brace is. indent_oc_block_msg_from_brace = false # false/true # # Spacing options # # Add or remove space around arithmetic operator '+', '-', '/', '*', etc # DJM # sp_arith = ignore # ignore/add/remove/force sp_arith = add # ignore/add/remove/force # Add or remove space around assignment operator '=', '+=', etc # DJM # sp_assign = ignore # ignore/add/remove/force sp_assign = add # ignore/add/remove/force # Add or remove space around '=' in C++11 lambda capture specifications. Overrides sp_assign sp_cpp_lambda_assign = ignore # ignore/add/remove/force # Add or remove space after the capture specification in C++11 lambda. sp_cpp_lambda_paren = ignore # ignore/add/remove/force # Add or remove space around assignment operator '=' in a prototype # DJM # sp_assign_default = ignore # ignore/add/remove/force sp_assign_default = add # ignore/add/remove/force # Add or remove space before assignment operator '=', '+=', etc. Overrides sp_assign. sp_before_assign = ignore # ignore/add/remove/force # Add or remove space after assignment operator '=', '+=', etc. Overrides sp_assign. sp_after_assign = ignore # ignore/add/remove/force # Add or remove space in 'NS_ENUM (' sp_enum_paren = ignore # ignore/add/remove/force # Add or remove space around assignment '=' in enum # DJM # sp_enum_assign = ignore # ignore/add/remove/force sp_enum_assign = add # ignore/add/remove/force # Add or remove space before assignment '=' in enum. Overrides sp_enum_assign. sp_enum_before_assign = ignore # ignore/add/remove/force # Add or remove space after assignment '=' in enum. Overrides sp_enum_assign. sp_enum_after_assign = ignore # ignore/add/remove/force # Add or remove space around preprocessor '##' concatenation operator. Default=Add sp_pp_concat = add # ignore/add/remove/force # Add or remove space after preprocessor '#' stringify operator. Also affects the '#@' charizing operator. sp_pp_stringify = add # ignore/add/remove/force # Add or remove space before preprocessor '#' stringify operator as in '#define x(y) L#y'. sp_before_pp_stringify = ignore # ignore/add/remove/force # Add or remove space around boolean operators '&&' and '||' # DJM # sp_bool = ignore # ignore/add/remove/force sp_bool = add # ignore/add/remove/force # Add or remove space around compare operator '<', '>', '==', etc # DJM # sp_compare = ignore # ignore/add/remove/force sp_compare = add # ignore/add/remove/force # Add or remove space inside '(' and ')' # DJM # sp_inside_paren = ignore # ignore/add/remove/force sp_inside_paren = remove # ignore/add/remove/force # Add or remove space between nested parens: '((' vs ') )' # DJM # sp_paren_paren = ignore # ignore/add/remove/force sp_paren_paren = remove # ignore/add/remove/force # Add or remove space between back-to-back parens: ')(' vs ') (' sp_cparen_oparen = ignore # ignore/add/remove/force # Whether to balance spaces inside nested parens sp_balance_nested_parens = false # false/true # Add or remove space between ')' and '{' # DJM # sp_paren_brace = ignore # ignore/add/remove/force sp_paren_brace = add # ignore/add/remove/force # Add or remove space before pointer star '*' # DJM # sp_before_ptr_star = ignore # ignore/add/remove/force sp_before_ptr_star = remove # ignore/add/remove/force # Add or remove space before pointer star '*' that isn't followed by a variable name # If set to 'ignore', sp_before_ptr_star is used instead. sp_before_unnamed_ptr_star = ignore # ignore/add/remove/force # Add or remove space between pointer stars '*' sp_between_ptr_star = ignore # ignore/add/remove/force # Add or remove space after pointer star '*', if followed by a word. sp_after_ptr_star = ignore # ignore/add/remove/force # Add or remove space after pointer star '*', if followed by a qualifier. sp_after_ptr_star_qualifier = ignore # ignore/add/remove/force # Add or remove space after a pointer star '*', if followed by a func proto/def. sp_after_ptr_star_func = ignore # ignore/add/remove/force # Add or remove space after a pointer star '*', if followed by an open paren (function types). sp_ptr_star_paren = ignore # ignore/add/remove/force # Add or remove space before a pointer star '*', if followed by a func proto/def. # DJM # sp_before_ptr_star_func = ignore # ignore/add/remove/force sp_before_ptr_star_func = remove # ignore/add/remove/force # Add or remove space before a reference sign '&' # DJM # sp_before_byref = ignore # ignore/add/remove/force sp_before_byref = remove # ignore/add/remove/force # Add or remove space before a reference sign '&' that isn't followed by a variable name # If set to 'ignore', sp_before_byref is used instead. sp_before_unnamed_byref = ignore # ignore/add/remove/force # Add or remove space after reference sign '&', if followed by a word. # DJM # sp_after_byref = ignore # ignore/add/remove/force sp_after_byref = add # ignore/add/remove/force # Add or remove space after a reference sign '&', if followed by a func proto/def. # DJM # sp_after_byref_func = ignore # ignore/add/remove/force sp_after_byref_func = add # ignore/add/remove/force # Add or remove space before a reference sign '&', if followed by a func proto/def. # DJM # sp_before_byref_func = ignore # ignore/add/remove/force sp_before_byref_func = remove # ignore/add/remove/force # Add or remove space between type and word. Default=Force sp_after_type = force # ignore/add/remove/force # Add or remove space before the paren in the D constructs 'template Foo(' and 'class Foo('. sp_before_template_paren = ignore # ignore/add/remove/force # Add or remove space in 'template <' vs 'template<'. # If set to ignore, sp_before_angle is used. # DJM # sp_template_angle = ignore # ignore/add/remove/force sp_template_angle = add # ignore/add/remove/force # Add or remove space before '<>' sp_before_angle = ignore # ignore/add/remove/force # Add or remove space inside '<' and '>' # DJM # sp_inside_angle = ignore # ignore/add/remove/force sp_inside_angle = remove # ignore/add/remove/force # Add or remove space after '<>' sp_after_angle = ignore # ignore/add/remove/force # Add or remove space between '<>' and '(' as found in 'new List();' sp_angle_paren = ignore # ignore/add/remove/force # Add or remove space between '<>' and a word as in 'List m;' # DJM # sp_angle_word = ignore # ignore/add/remove/force sp_angle_word = add # ignore/add/remove/force # Add or remove space between '>' and '>' in '>>' (template stuff C++/C# only). Default=Add sp_angle_shift = add # ignore/add/remove/force # Permit removal of the space between '>>' in 'foo >' (C++11 only). Default=False # sp_angle_shift cannot remove the space without this option. sp_permit_cpp11_shift = false # false/true # Add or remove space before '(' of 'if', 'for', 'switch', and 'while' # DJM # sp_before_sparen = ignore # ignore/add/remove/force sp_before_sparen = add # ignore/add/remove/force # Add or remove space inside if-condition '(' and ')' # DJM # sp_inside_sparen = ignore # ignore/add/remove/force sp_inside_sparen = remove # ignore/add/remove/force # Add or remove space before if-condition ')'. Overrides sp_inside_sparen. sp_inside_sparen_close = ignore # ignore/add/remove/force # Add or remove space before if-condition '('. Overrides sp_inside_sparen. sp_inside_sparen_open = ignore # ignore/add/remove/force # Add or remove space after ')' of 'if', 'for', 'switch', and 'while' # DJM # sp_after_sparen = ignore # ignore/add/remove/force sp_after_sparen = add # ignore/add/remove/force # Add or remove space between ')' and '{' of 'if', 'for', 'switch', and 'while' # DJM # sp_sparen_brace = ignore # ignore/add/remove/force sp_sparen_brace = add # ignore/add/remove/force # Add or remove space between 'invariant' and '(' in the D language. sp_invariant_paren = ignore # ignore/add/remove/force # Add or remove space after the ')' in 'invariant (C) c' in the D language. sp_after_invariant_paren = ignore # ignore/add/remove/force # Add or remove space before empty statement ';' on 'if', 'for' and 'while' sp_special_semi = ignore # ignore/add/remove/force # Add or remove space before ';'. Default=Remove sp_before_semi = remove # ignore/add/remove/force # Add or remove space before ';' in non-empty 'for' statements sp_before_semi_for = ignore # ignore/add/remove/force # Add or remove space before a semicolon of an empty part of a for statement. sp_before_semi_for_empty = ignore # ignore/add/remove/force # Add or remove space after ';', except when followed by a comment. Default=Add sp_after_semi = add # ignore/add/remove/force # Add or remove space after ';' in non-empty 'for' statements. Default=Force sp_after_semi_for = force # ignore/add/remove/force # Add or remove space after the final semicolon of an empty part of a for statement: for ( ; ; ). # DJM # sp_after_semi_for_empty = ignore # ignore/add/remove/force sp_after_semi_for_empty = remove # ignore/add/remove/force # Add or remove space before '[' (except '[]') sp_before_square = ignore # ignore/add/remove/force # Add or remove space before '[]' sp_before_squares = ignore # ignore/add/remove/force # Add or remove space inside a non-empty '[' and ']' sp_inside_square = ignore # ignore/add/remove/force # Add or remove space after ',' # DJM # sp_after_comma = ignore # ignore/add/remove/force sp_after_comma = add # ignore/add/remove/force # Add or remove space before ',' sp_before_comma = remove # ignore/add/remove/force # Add or remove space between an open paren and comma: '(,' vs '( ,' sp_paren_comma = force # ignore/add/remove/force # Add or remove space before the variadic '...' when preceded by a non-punctuator sp_before_ellipsis = ignore # ignore/add/remove/force # Add or remove space after class ':' # DJM # sp_after_class_colon = ignore # ignore/add/remove/force sp_after_class_colon = add # ignore/add/remove/force # Add or remove space before class ':' # DJM # sp_before_class_colon = ignore # ignore/add/remove/force sp_before_class_colon = add # ignore/add/remove/force # Add or remove space after class constructor ':' sp_after_constr_colon = ignore # ignore/add/remove/force # Add or remove space before class constructor ':' sp_before_constr_colon = ignore # ignore/add/remove/force # Add or remove space before case ':'. Default=Remove sp_before_case_colon = remove # ignore/add/remove/force # Add or remove space between 'operator' and operator sign sp_after_operator = ignore # ignore/add/remove/force # Add or remove space between the operator symbol and the open paren, as in 'operator ++(' sp_after_operator_sym = ignore # ignore/add/remove/force # Add or remove space after C/D cast, i.e. 'cast(int)a' vs 'cast(int) a' or '(int)a' vs '(int) a' sp_after_cast = ignore # ignore/add/remove/force # Add or remove spaces inside cast parens sp_inside_paren_cast = ignore # ignore/add/remove/force # Add or remove space between the type and open paren in a C++ cast, i.e. 'int(exp)' vs 'int (exp)' sp_cpp_cast_paren = ignore # ignore/add/remove/force # Add or remove space between 'sizeof' and '(' sp_sizeof_paren = ignore # ignore/add/remove/force # Add or remove space after the tag keyword (Pawn) sp_after_tag = ignore # ignore/add/remove/force # Add or remove space inside enum '{' and '}' sp_inside_braces_enum = ignore # ignore/add/remove/force # Add or remove space inside struct/union '{' and '}' sp_inside_braces_struct = ignore # ignore/add/remove/force # Add or remove space inside '{' and '}' # DJM # sp_inside_braces = ignore # ignore/add/remove/force sp_inside_braces = add # ignore/add/remove/force # Add or remove space inside '{}' # sp_inside_braces_empty = ignore # ignore/add/remove/force sp_inside_braces_empty = add # ignore/add/remove/force # Add or remove space between return type and function name # A minimum of 1 is forced except for pointer return types. sp_type_func = ignore # ignore/add/remove/force # Add or remove space between function name and '(' on function declaration # DJM # sp_func_proto_paren = ignore # ignore/add/remove/force sp_func_proto_paren = remove # ignore/add/remove/force # Add or remove space between function name and '(' on function definition # DJM # sp_func_def_paren = ignore # ignore/add/remove/force sp_func_def_paren = remove # ignore/add/remove/force # Add or remove space inside empty function '()' # DJM # sp_inside_fparens = ignore # ignore/add/remove/force sp_inside_fparens = remove # ignore/add/remove/force # Add or remove space inside function '(' and ')' # DJM # sp_inside_fparen = ignore # ignore/add/remove/force sp_inside_fparen = remove # ignore/add/remove/force # Add or remove space inside the first parens in the function type: 'void (*x)(...)' sp_inside_tparen = ignore # ignore/add/remove/force # Add or remove between the parens in the function type: 'void (*x)(...)' sp_after_tparen_close = ignore # ignore/add/remove/force # Add or remove space between ']' and '(' when part of a function call. sp_square_fparen = ignore # ignore/add/remove/force # Add or remove space between ')' and '{' of function # DJM # sp_fparen_brace = ignore # ignore/add/remove/force sp_fparen_brace = add # ignore/add/remove/force # Java: Add or remove space between ')' and '{{' of double brace initializer. sp_fparen_dbrace = ignore # ignore/add/remove/force # Add or remove space between function name and '(' on function calls # DJM # sp_func_call_paren = ignore # ignore/add/remove/force sp_func_call_paren = remove # ignore/add/remove/force # Add or remove space between function name and '()' on function calls without parameters. # If set to 'ignore' (the default), sp_func_call_paren is used. sp_func_call_paren_empty = ignore # ignore/add/remove/force # Add or remove space between the user function name and '(' on function calls # You need to set a keyword to be a user function, like this: 'set func_call_user _' in the config file. sp_func_call_user_paren = ignore # ignore/add/remove/force # Add or remove space between a constructor/destructor and the open paren # DJM # sp_func_class_paren = ignore # ignore/add/remove/force sp_func_class_paren = remove # ignore/add/remove/force # Add or remove space between 'return' and '(' sp_return_paren = ignore # ignore/add/remove/force # Add or remove space between '__attribute__' and '(' sp_attribute_paren = ignore # ignore/add/remove/force # Add or remove space between 'defined' and '(' in '#if defined (FOO)' sp_defined_paren = ignore # ignore/add/remove/force # Add or remove space between 'throw' and '(' in 'throw (something)' sp_throw_paren = ignore # ignore/add/remove/force # Add or remove space between 'throw' and anything other than '(' as in '@throw [...];' sp_after_throw = ignore # ignore/add/remove/force # Add or remove space between 'catch' and '(' in 'catch (something) { }' # If set to ignore, sp_before_sparen is used. sp_catch_paren = ignore # ignore/add/remove/force # Add or remove space between 'version' and '(' in 'version (something) { }' (D language) # If set to ignore, sp_before_sparen is used. sp_version_paren = ignore # ignore/add/remove/force # Add or remove space between 'scope' and '(' in 'scope (something) { }' (D language) # If set to ignore, sp_before_sparen is used. sp_scope_paren = ignore # ignore/add/remove/force # Add or remove space between macro and value sp_macro = ignore # ignore/add/remove/force # Add or remove space between macro function ')' and value sp_macro_func = ignore # ignore/add/remove/force # Add or remove space between 'else' and '{' if on the same line # DJM # sp_else_brace = ignore # ignore/add/remove/force sp_else_brace = add # ignore/add/remove/force # Add or remove space between '}' and 'else' if on the same line # DJM # sp_brace_else = ignore # ignore/add/remove/force sp_brace_else = add # ignore/add/remove/force # Add or remove space between '}' and the name of a typedef on the same line sp_brace_typedef = ignore # ignore/add/remove/force # Add or remove space between 'catch' and '{' if on the same line sp_catch_brace = ignore # ignore/add/remove/force # Add or remove space between '}' and 'catch' if on the same line sp_brace_catch = ignore # ignore/add/remove/force # Add or remove space between 'finally' and '{' if on the same line sp_finally_brace = ignore # ignore/add/remove/force # Add or remove space between '}' and 'finally' if on the same line sp_brace_finally = ignore # ignore/add/remove/force # Add or remove space between 'try' and '{' if on the same line sp_try_brace = ignore # ignore/add/remove/force # Add or remove space between get/set and '{' if on the same line sp_getset_brace = ignore # ignore/add/remove/force # Add or remove space between a variable and '{' for C++ uniform initialization sp_word_brace = add # ignore/add/remove/force # Add or remove space between a variable and '{' for a namespace sp_word_brace_ns = add # ignore/add/remove/force # Add or remove space before the '::' operator # DJM # sp_before_dc = ignore # ignore/add/remove/force sp_before_dc = remove # ignore/add/remove/force # Add or remove space after the '::' operator # DJM # sp_after_dc = ignore # ignore/add/remove/force sp_after_dc = remove # ignore/add/remove/force # Add or remove around the D named array initializer ':' operator sp_d_array_colon = ignore # ignore/add/remove/force # Add or remove space after the '!' (not) operator. Default=Remove sp_not = remove # ignore/add/remove/force # Add or remove space after the '~' (invert) operator. Default=Remove sp_inv = remove # ignore/add/remove/force # Add or remove space after the '&' (address-of) operator. Default=Remove # This does not affect the spacing after a '&' that is part of a type. sp_addr = remove # ignore/add/remove/force # Add or remove space around the '.' or '->' operators. Default=Remove sp_member = remove # ignore/add/remove/force # Add or remove space after the '*' (dereference) operator. Default=Remove # This does not affect the spacing after a '*' that is part of a type. sp_deref = remove # ignore/add/remove/force # Add or remove space after '+' or '-', as in 'x = -5' or 'y = +7'. Default=Remove sp_sign = remove # ignore/add/remove/force # Add or remove space before or after '++' and '--', as in '(--x)' or 'y++;'. Default=Remove sp_incdec = remove # ignore/add/remove/force # Add or remove space before a backslash-newline at the end of a line. Default=Add sp_before_nl_cont = add # ignore/add/remove/force # Add or remove space after the scope '+' or '-', as in '-(void) foo;' or '+(int) bar;' sp_after_oc_scope = ignore # ignore/add/remove/force # Add or remove space after the colon in message specs # '-(int) f:(int) x;' vs '-(int) f: (int) x;' sp_after_oc_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in message specs # '-(int) f: (int) x;' vs '-(int) f : (int) x;' sp_before_oc_colon = ignore # ignore/add/remove/force # Add or remove space after the colon in immutable dictionary expression # 'NSDictionary *test = @{@"foo" :@"bar"};' sp_after_oc_dict_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in immutable dictionary expression # 'NSDictionary *test = @{@"foo" :@"bar"};' sp_before_oc_dict_colon = ignore # ignore/add/remove/force # Add or remove space after the colon in message specs # '[object setValue:1];' vs '[object setValue: 1];' sp_after_send_oc_colon = ignore # ignore/add/remove/force # Add or remove space before the colon in message specs # '[object setValue:1];' vs '[object setValue :1];' sp_before_send_oc_colon = ignore # ignore/add/remove/force # Add or remove space after the (type) in message specs # '-(int)f: (int) x;' vs '-(int)f: (int)x;' sp_after_oc_type = ignore # ignore/add/remove/force # Add or remove space after the first (type) in message specs # '-(int) f:(int)x;' vs '-(int)f:(int)x;' sp_after_oc_return_type = ignore # ignore/add/remove/force # Add or remove space between '@selector' and '(' # '@selector(msgName)' vs '@selector (msgName)' # Also applies to @protocol() constructs sp_after_oc_at_sel = ignore # ignore/add/remove/force # Add or remove space between '@selector(x)' and the following word # '@selector(foo) a:' vs '@selector(foo)a:' sp_after_oc_at_sel_parens = ignore # ignore/add/remove/force # Add or remove space inside '@selector' parens # '@selector(foo)' vs '@selector( foo )' # Also applies to @protocol() constructs sp_inside_oc_at_sel_parens = ignore # ignore/add/remove/force # Add or remove space before a block pointer caret # '^int (int arg){...}' vs. ' ^int (int arg){...}' sp_before_oc_block_caret = ignore # ignore/add/remove/force # Add or remove space after a block pointer caret # '^int (int arg){...}' vs. '^ int (int arg){...}' sp_after_oc_block_caret = ignore # ignore/add/remove/force # Add or remove space between the receiver and selector in a message. # '[receiver selector ...]' sp_after_oc_msg_receiver = ignore # ignore/add/remove/force # Add or remove space after @property. sp_after_oc_property = ignore # ignore/add/remove/force # Add or remove space around the ':' in 'b ? t : f' #DJM # sp_cond_colon = ignore # ignore/add/remove/force sp_cond_colon = add # ignore/add/remove/force # Add or remove space before the ':' in 'b ? t : f'. Overrides sp_cond_colon. sp_cond_colon_before = ignore # ignore/add/remove/force # Add or remove space after the ':' in 'b ? t : f'. Overrides sp_cond_colon. sp_cond_colon_after = ignore # ignore/add/remove/force # Add or remove space around the '?' in 'b ? t : f' # DJM # sp_cond_question = ignore # ignore/add/remove/force sp_cond_question = add # ignore/add/remove/force # Add or remove space before the '?' in 'b ? t : f'. Overrides sp_cond_question. sp_cond_question_before = ignore # ignore/add/remove/force # Add or remove space after the '?' in 'b ? t : f'. Overrides sp_cond_question. sp_cond_question_after = ignore # ignore/add/remove/force # In the abbreviated ternary form (a ?: b), add/remove space between ? and :.'. Overrides all other sp_cond_* options. sp_cond_ternary_short = ignore # ignore/add/remove/force # Fix the spacing between 'case' and the label. Only 'ignore' and 'force' make sense here. sp_case_label = ignore # ignore/add/remove/force # Control the space around the D '..' operator. sp_range = ignore # ignore/add/remove/force # Control the spacing after ':' in 'for (TYPE VAR : EXPR)' (Java) sp_after_for_colon = ignore # ignore/add/remove/force # Control the spacing before ':' in 'for (TYPE VAR : EXPR)' (Java) sp_before_for_colon = ignore # ignore/add/remove/force # Control the spacing in 'extern (C)' (D) sp_extern_paren = ignore # ignore/add/remove/force # Control the space after the opening of a C++ comment '// A' vs '//A' sp_cmt_cpp_start = ignore # ignore/add/remove/force # Controls the spaces between #else or #endif and a trailing comment sp_endif_cmt = ignore # ignore/add/remove/force # Controls the spaces after 'new', 'delete', and 'delete[]' sp_after_new = ignore # ignore/add/remove/force # Controls the spaces before a trailing or embedded comment sp_before_tr_emb_cmt = ignore # ignore/add/remove/force # Number of spaces before a trailing or embedded comment sp_num_before_tr_emb_cmt = 0 # number # Control space between a Java annotation and the open paren. sp_annotation_paren = ignore # ignore/add/remove/force # # Code alignment (not left column spaces/tabs) # # Whether to keep non-indenting tabs align_keep_tabs = false # false/true # Whether to use tabs for aligning align_with_tabs = false # false/true # Whether to bump out to the next tab when aligning align_on_tabstop = false # false/true # Whether to left-align numbers align_number_left = false # false/true # Whether to keep whitespace not required for alignment. align_keep_extra_space = false # false/true # Align variable definitions in prototypes and functions align_func_params = false # false/true # Align parameters in single-line functions that have the same name. # The function names must already be aligned with each other. align_same_func_call_params = false # false/true # The span for aligning variable definitions (0=don't align) align_var_def_span = 0 # number # How to align the star in variable definitions. # 0=Part of the type 'void * foo;' # 1=Part of the variable 'void *foo;' # 2=Dangling 'void *foo;' align_var_def_star_style = 0 # number # How to align the '&' in variable definitions. # 0=Part of the type # 1=Part of the variable # 2=Dangling align_var_def_amp_style = 0 # number # The threshold for aligning variable definitions (0=no limit) align_var_def_thresh = 0 # number # The gap for aligning variable definitions align_var_def_gap = 0 # number # Whether to align the colon in struct bit fields align_var_def_colon = false # false/true # Whether to align any attribute after the variable name align_var_def_attribute = false # false/true # Whether to align inline struct/enum/union variable definitions align_var_def_inline = false # false/true # The span for aligning on '=' in assignments (0=don't align) align_assign_span = 0 # number # The threshold for aligning on '=' in assignments (0=no limit) align_assign_thresh = 0 # number # The span for aligning on '=' in enums (0=don't align) align_enum_equ_span = 0 # number # The threshold for aligning on '=' in enums (0=no limit) align_enum_equ_thresh = 0 # number # The span for aligning struct/union (0=don't align) align_var_struct_span = 0 # number # The threshold for aligning struct/union member definitions (0=no limit) align_var_struct_thresh = 0 # number # The gap for aligning struct/union member definitions align_var_struct_gap = 0 # number # The span for aligning struct initializer values (0=don't align) align_struct_init_span = 0 # number # The minimum space between the type and the synonym of a typedef align_typedef_gap = 0 # number # The span for aligning single-line typedefs (0=don't align) align_typedef_span = 0 # number # How to align typedef'd functions with other typedefs # 0: Don't mix them at all # 1: align the open paren with the types # 2: align the function type name with the other type names align_typedef_func = 0 # number # Controls the positioning of the '*' in typedefs. Just try it. # 0: Align on typedef type, ignore '*' # 1: The '*' is part of type name: typedef int *pint; # 2: The '*' is part of the type, but dangling: typedef int *pint; align_typedef_star_style = 0 # number # Controls the positioning of the '&' in typedefs. Just try it. # 0: Align on typedef type, ignore '&' # 1: The '&' is part of type name: typedef int &pint; # 2: The '&' is part of the type, but dangling: typedef int &pint; align_typedef_amp_style = 0 # number # The span for aligning comments that end lines (0=don't align) align_right_cmt_span = 0 # number # If aligning comments, mix with comments after '}' and #endif with less than 3 spaces before the comment align_right_cmt_mix = false # false/true # If a trailing comment is more than this number of columns away from the text it follows, # it will qualify for being aligned. This has to be > 0 to do anything. align_right_cmt_gap = 0 # number # Align trailing comment at or beyond column N; 'pulls in' comments as a bonus side effect (0=ignore) align_right_cmt_at_col = 0 # number # The span for aligning function prototypes (0=don't align) align_func_proto_span = 0 # number # Minimum gap between the return type and the function name. align_func_proto_gap = 0 # number # Align function protos on the 'operator' keyword instead of what follows align_on_operator = false # false/true # Whether to mix aligning prototype and variable declarations. # If true, align_var_def_XXX options are used instead of align_func_proto_XXX options. align_mix_var_proto = false # false/true # Align single-line functions with function prototypes, uses align_func_proto_span align_single_line_func = false # false/true # Aligning the open brace of single-line functions. # Requires align_single_line_func=true, uses align_func_proto_span align_single_line_brace = false # false/true # Gap for align_single_line_brace. align_single_line_brace_gap = 0 # number # The span for aligning ObjC msg spec (0=don't align) align_oc_msg_spec_span = 0 # number # Whether to align macros wrapped with a backslash and a newline. # This will not work right if the macro contains a multi-line comment. align_nl_cont = false # false/true # # Align macro functions and variables together align_pp_define_together = false # false/true # The minimum space between label and value of a preprocessor define align_pp_define_gap = 0 # number # The span for aligning on '#define' bodies (0=don't align, other=number of lines including comments between blocks) align_pp_define_span = 0 # number # Align lines that start with '<<' with previous '<<'. Default=true align_left_shift = true # false/true # Span for aligning parameters in an Obj-C message call on the ':' (0=don't align) align_oc_msg_colon_span = 0 # number # If true, always align with the first parameter, even if it is too short. align_oc_msg_colon_first = false # false/true # Aligning parameters in an Obj-C '+' or '-' declaration on the ':' align_oc_decl_colon = false # false/true # # Newline adding and removing options # # Whether to collapse empty blocks between '{' and '}' nl_collapse_empty_body = false # false/true # Don't split one-line braced assignments - 'foo_t f = { 1, 2 };' nl_assign_leave_one_liners = false # false/true # Don't split one-line braced statements inside a class xx { } body # DJM # nl_class_leave_one_liners = false # false/true nl_class_leave_one_liners = true # false/true # Don't split one-line enums: 'enum foo { BAR = 15 };' nl_enum_leave_one_liners = false # false/true # Don't split one-line get or set functions nl_getset_leave_one_liners = false # false/true # Don't split one-line function definitions - 'int foo() { return 0; }' nl_func_leave_one_liners = false # false/true # Don't split one-line C++11 lambdas - '[]() { return 0; }' nl_cpp_lambda_leave_one_liners = false # false/true # Don't split one-line if/else statements - 'if(a) b++;' nl_if_leave_one_liners = false # false/true # Don't split one-line OC messages nl_oc_msg_leave_one_liner = false # false/true # Add or remove newlines at the start of the file nl_start_of_file = ignore # ignore/add/remove/force # The number of newlines at the start of the file (only used if nl_start_of_file is 'add' or 'force' nl_start_of_file_min = 0 # number # Add or remove newline at the end of the file nl_end_of_file = ignore # ignore/add/remove/force # The number of newlines at the end of the file (only used if nl_end_of_file is 'add' or 'force') nl_end_of_file_min = 0 # number # Add or remove newline between '=' and '{' nl_assign_brace = ignore # ignore/add/remove/force # Add or remove newline between '=' and '[' (D only) nl_assign_square = ignore # ignore/add/remove/force # Add or remove newline after '= [' (D only). Will also affect the newline before the ']' nl_after_square_assign = ignore # ignore/add/remove/force # The number of blank lines after a block of variable definitions at the top of a function body # 0 = No change (default) nl_func_var_def_blk = 0 # number # The number of newlines before a block of typedefs # 0 = No change (default) nl_typedef_blk_start = 0 # number # The number of newlines after a block of typedefs # 0 = No change (default) nl_typedef_blk_end = 0 # number # The maximum consecutive newlines within a block of typedefs # 0 = No change (default) nl_typedef_blk_in = 0 # number # The number of newlines before a block of variable definitions not at the top of a function body # 0 = No change (default) nl_var_def_blk_start = 0 # number # The number of newlines after a block of variable definitions not at the top of a function body # 0 = No change (default) nl_var_def_blk_end = 0 # number # The maximum consecutive newlines within a block of variable definitions # 0 = No change (default) nl_var_def_blk_in = 0 # number # Add or remove newline between a function call's ')' and '{', as in: # list_for_each(item, &list) { } nl_fcall_brace = ignore # ignore/add/remove/force # Add or remove newline between 'enum' and '{' # DJM # nl_enum_brace = ignore # ignore/add/remove/force nl_enum_brace = remove # ignore/add/remove/force # Add or remove newline between 'struct and '{' # DJM # nl_struct_brace = ignore # ignore/add/remove/force nl_struct_brace = remove # ignore/add/remove/force # Add or remove newline between 'union' and '{' # DJM # nl_union_brace = ignore # ignore/add/remove/force nl_union_brace = remove # ignore/add/remove/force # Add or remove newline between 'if' and '{' # DJM # nl_if_brace = ignore # ignore/add/remove/force nl_if_brace = remove # ignore/add/remove/force # Add or remove newline between '}' and 'else' # DJM # nl_brace_else = ignore # ignore/add/remove/force nl_brace_else = remove # ignore/add/remove/force # Add or remove newline between 'else if' and '{' # If set to ignore, nl_if_brace is used instead nl_elseif_brace = ignore # ignore/add/remove/force # Add or remove newline between 'else' and '{' # DJM # nl_else_brace = ignore # ignore/add/remove/force nl_else_brace = remove # ignore/add/remove/force # Add or remove newline between 'else' and 'if' nl_else_if = ignore # ignore/add/remove/force # Add or remove newline between '}' and 'finally' # DJM # nl_brace_finally = ignore # ignore/add/remove/force nl_brace_finally = remove # ignore/add/remove/force # Add or remove newline between 'finally' and '{' # DJM # nl_finally_brace = ignore # ignore/add/remove/force nl_finally_brace = remove # ignore/add/remove/force # Add or remove newline between 'try' and '{' # DJM # nl_try_brace = ignore # ignore/add/remove/force nl_try_brace = remove # ignore/add/remove/force # Add or remove newline between get/set and '{' # DJM # nl_getset_brace = ignore # ignore/add/remove/force nl_getset_brace = remove # ignore/add/remove/force # Add or remove newline between 'for' and '{' # DJM # nl_for_brace = ignore # ignore/add/remove/force nl_for_brace = remove # ignore/add/remove/force # Add or remove newline between 'catch' and '{' # DJM # nl_catch_brace = ignore # ignore/add/remove/force nl_catch_brace = remove # ignore/add/remove/force # Add or remove newline between '}' and 'catch' # DJM # nl_brace_catch = ignore # ignore/add/remove/force nl_brace_catch = remove # ignore/add/remove/force # Add or remove newline between '}' and ']' nl_brace_square = ignore # ignore/add/remove/force # Add or remove newline between '}' and ')' in a function invocation nl_brace_fparen = ignore # ignore/add/remove/force # Add or remove newline between 'while' and '{' # DJM # nl_while_brace = ignore # ignore/add/remove/force nl_while_brace = remove # ignore/add/remove/force # Add or remove newline between 'scope (x)' and '{' (D) nl_scope_brace = ignore # ignore/add/remove/force # Add or remove newline between 'unittest' and '{' (D) nl_unittest_brace = ignore # ignore/add/remove/force # Add or remove newline between 'version (x)' and '{' (D) nl_version_brace = ignore # ignore/add/remove/force # Add or remove newline between 'using' and '{' nl_using_brace = ignore # ignore/add/remove/force # Add or remove newline between two open or close braces. # Due to general newline/brace handling, REMOVE may not work. nl_brace_brace = ignore # ignore/add/remove/force # Add or remove newline between 'do' and '{' # DJM # nl_do_brace = ignore # ignore/add/remove/force nl_do_brace = remove # ignore/add/remove/force # Add or remove newline between '}' and 'while' of 'do' statement # DJM # nl_brace_while = ignore # ignore/add/remove/force nl_brace_while = remove # ignore/add/remove/force # Add or remove newline between 'switch' and '{' # DJM # nl_switch_brace = ignore # ignore/add/remove/force nl_switch_brace = remove # ignore/add/remove/force # Add a newline between ')' and '{' if the ')' is on a different line than the if/for/etc. # Overrides nl_for_brace, nl_if_brace, nl_switch_brace, nl_while_switch, and nl_catch_brace. nl_multi_line_cond = false # false/true # Force a newline in a define after the macro name for multi-line defines. nl_multi_line_define = false # false/true # Whether to put a newline before 'case' statement # DJM # nl_before_case = false # false/true nl_before_case = true # false/true # Add or remove newline between ')' and 'throw' nl_before_throw = ignore # ignore/add/remove/force # Whether to put a newline after 'case' statement nl_after_case = false # false/true # Add or remove a newline between a case ':' and '{'. Overrides nl_after_case. nl_case_colon_brace = ignore # ignore/add/remove/force # Newline between namespace and { # DJM # nl_namespace_brace = ignore # ignore/add/remove/force nl_namespace_brace = remove # ignore/add/remove/force # Add or remove newline between 'template<>' and whatever follows. nl_template_class = ignore # ignore/add/remove/force # Add or remove newline between 'class' and '{' # DJM # nl_class_brace = ignore # ignore/add/remove/force nl_class_brace = remove # ignore/add/remove/force # Add or remove newline after each ',' in the class base list nl_class_init_args = ignore # ignore/add/remove/force # Add or remove newline after each ',' in the constructor member initialization nl_constr_init_args = ignore # ignore/add/remove/force # Add or remove newline between return type and function name in a function definition # DJM # nl_func_type_name = ignore # ignore/add/remove/force nl_func_type_name = remove # ignore/add/remove/force # Add or remove newline between return type and function name inside a class {} # Uses nl_func_type_name or nl_func_proto_type_name if set to ignore. # DJM # nl_func_type_name_class = ignore # ignore/add/remove/force nl_func_type_name_class = remove # ignore/add/remove/force # Add or remove newline between function scope and name in a definition # Controls the newline after '::' in 'void A::f() { }' nl_func_scope_name = ignore # ignore/add/remove/force # Add or remove newline between return type and function name in a prototype # DJM # nl_func_proto_type_name = ignore # ignore/add/remove/force nl_func_proto_type_name = remove # ignore/add/remove/force # Add or remove newline between a function name and the opening '(' # DJM # nl_func_paren = ignore # ignore/add/remove/force nl_func_paren = remove # ignore/add/remove/force # Add or remove newline between a function name and the opening '(' in the definition # DJM # nl_func_def_paren = ignore # ignore/add/remove/force nl_func_def_paren = remove # ignore/add/remove/force # Add or remove newline after '(' in a function declaration nl_func_decl_start = ignore # ignore/add/remove/force # Add or remove newline after '(' in a function definition nl_func_def_start = ignore # ignore/add/remove/force # Overrides nl_func_decl_start when there is only one parameter. nl_func_decl_start_single = ignore # ignore/add/remove/force # Overrides nl_func_def_start when there is only one parameter. nl_func_def_start_single = ignore # ignore/add/remove/force # Add or remove newline after each ',' in a function declaration nl_func_decl_args = ignore # ignore/add/remove/force # Add or remove newline after each ',' in a function definition nl_func_def_args = ignore # ignore/add/remove/force # Add or remove newline before the ')' in a function declaration nl_func_decl_end = ignore # ignore/add/remove/force # Add or remove newline before the ')' in a function definition nl_func_def_end = ignore # ignore/add/remove/force # Overrides nl_func_decl_end when there is only one parameter. nl_func_decl_end_single = ignore # ignore/add/remove/force # Overrides nl_func_def_end when there is only one parameter. nl_func_def_end_single = ignore # ignore/add/remove/force # Add or remove newline between '()' in a function declaration. nl_func_decl_empty = ignore # ignore/add/remove/force # Add or remove newline between '()' in a function definition. nl_func_def_empty = ignore # ignore/add/remove/force # Whether to put each OC message parameter on a separate line # See nl_oc_msg_leave_one_liner nl_oc_msg_args = false # false/true # Add or remove newline between function signature and '{' nl_fdef_brace = ignore # ignore/add/remove/force # Add or remove newline between C++11 lambda signature and '{' nl_cpp_ldef_brace = ignore # ignore/add/remove/force # Add or remove a newline between the return keyword and return expression. nl_return_expr = ignore # ignore/add/remove/force # Whether to put a newline after semicolons, except in 'for' statements nl_after_semicolon = false # false/true # Java: Control the newline between the ')' and '{{' of the double brace initializer. nl_paren_dbrace_open = ignore # ignore/add/remove/force # Whether to put a newline after brace open. # This also adds a newline before the matching brace close. nl_after_brace_open = false # false/true # If nl_after_brace_open and nl_after_brace_open_cmt are true, a newline is # placed between the open brace and a trailing single-line comment. nl_after_brace_open_cmt = false # false/true # Whether to put a newline after a virtual brace open with a non-empty body. # These occur in un-braced if/while/do/for statement bodies. nl_after_vbrace_open = false # false/true # Whether to put a newline after a virtual brace open with an empty body. # These occur in un-braced if/while/do/for statement bodies. nl_after_vbrace_open_empty = false # false/true # Whether to put a newline after a brace close. # Does not apply if followed by a necessary ';'. nl_after_brace_close = false # false/true # Whether to put a newline after a virtual brace close. # Would add a newline before return in: 'if (foo) a++; return;' nl_after_vbrace_close = false # false/true # Control the newline between the close brace and 'b' in: 'struct { int a; } b;' # Affects enums, unions, and structures. If set to ignore, uses nl_after_brace_close nl_brace_struct_var = ignore # ignore/add/remove/force # Whether to alter newlines in '#define' macros nl_define_macro = false # false/true # Whether to not put blanks after '#ifxx', '#elxx', or before '#endif' nl_squeeze_ifdef = false # false/true # Add or remove blank line before 'if' nl_before_if = ignore # ignore/add/remove/force # Add or remove blank line after 'if' statement nl_after_if = ignore # ignore/add/remove/force # Add or remove blank line before 'for' nl_before_for = ignore # ignore/add/remove/force # Add or remove blank line after 'for' statement nl_after_for = ignore # ignore/add/remove/force # Add or remove blank line before 'while' nl_before_while = ignore # ignore/add/remove/force # Add or remove blank line after 'while' statement nl_after_while = ignore # ignore/add/remove/force # Add or remove blank line before 'switch' nl_before_switch = ignore # ignore/add/remove/force # Add or remove blank line after 'switch' statement nl_after_switch = ignore # ignore/add/remove/force # Add or remove blank line before 'do' nl_before_do = ignore # ignore/add/remove/force # Add or remove blank line after 'do/while' statement nl_after_do = ignore # ignore/add/remove/force # Whether to double-space commented-entries in struct/enum nl_ds_struct_enum_cmt = false # false/true # Whether to double-space before the close brace of a struct/union/enum # (lower priority than 'eat_blanks_before_close_brace') nl_ds_struct_enum_close_brace = false # false/true # Add or remove a newline around a class colon. # Related to pos_class_colon, nl_class_init_args, and pos_class_comma. nl_class_colon = ignore # ignore/add/remove/force # Add or remove a newline around a class constructor colon. # Related to pos_constr_colon, nl_constr_init_args, and pos_constr_comma. nl_constr_colon = ignore # ignore/add/remove/force # Change simple unbraced if statements into a one-liner # 'if(b)\n i++;' => 'if(b) i++;' nl_create_if_one_liner = false # false/true # Change simple unbraced for statements into a one-liner # 'for (i=0;i<5;i++)\n foo(i);' => 'for (i=0;i<5;i++) foo(i);' nl_create_for_one_liner = false # false/true # Change simple unbraced while statements into a one-liner # 'while (i<5)\n foo(i++);' => 'while (i<5) foo(i++);' nl_create_while_one_liner = false # false/true # # Positioning options # # The position of arithmetic operators in wrapped expressions pos_arith = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of assignment in wrapped expressions. # Do not affect '=' followed by '{' pos_assign = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of boolean operators in wrapped expressions pos_bool = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of comparison operators in wrapped expressions pos_compare = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of conditional (b ? t : f) operators in wrapped expressions pos_conditional = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of the comma in wrapped expressions pos_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of the comma in the class base list pos_class_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of the comma in the constructor initialization list pos_constr_comma = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of colons between class and base class list pos_class_colon = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # The position of colons between constructor and member initialization pos_constr_colon = ignore # ignore/join/lead/lead_break/lead_force/trail/trail_break/trail_force # # Line Splitting options # # Try to limit code width to N number of columns code_width = 0 # number # Whether to fully split long 'for' statements at semi-colons ls_for_split_full = false # false/true # Whether to fully split long function protos/calls at commas ls_func_split_full = false # false/true # Whether to split lines as close to code_width as possible and ignore some groupings ls_code_width = false # false/true # # Blank line options # # The maximum consecutive newlines nl_max = 0 # number # The number of newlines after a function prototype, if followed by another function prototype nl_after_func_proto = 0 # number # The number of newlines after a function prototype, if not followed by another function prototype nl_after_func_proto_group = 0 # number # The number of newlines after '}' of a multi-line function body nl_after_func_body = 0 # number # The number of newlines after '}' of a multi-line function body in a class declaration nl_after_func_body_class = 0 # number # The number of newlines after '}' of a single line function body nl_after_func_body_one_liner = 0 # number # The minimum number of newlines before a multi-line comment. # Doesn't apply if after a brace open or another multi-line comment. nl_before_block_comment = 0 # number # The minimum number of newlines before a single-line C comment. # Doesn't apply if after a brace open or other single-line C comments. nl_before_c_comment = 0 # number # The minimum number of newlines before a CPP comment. # Doesn't apply if after a brace open or other CPP comments. nl_before_cpp_comment = 0 # number # Whether to force a newline after a multi-line comment. nl_after_multiline_comment = false # false/true # The number of newlines after '}' or ';' of a struct/enum/union definition nl_after_struct = 0 # number # The number of newlines after '}' or ';' of a class definition nl_after_class = 0 # number # The number of newlines before a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. # Will not change the newline count if after a brace open. # 0 = No change. nl_before_access_spec = 0 # number # The number of newlines after a 'private:', 'public:', 'protected:', 'signals:', or 'slots:' label. # 0 = No change. nl_after_access_spec = 0 # number # The number of newlines between a function def and the function comment. # 0 = No change. nl_comment_func_def = 0 # number # The number of newlines after a try-catch-finally block that isn't followed by a brace close. # 0 = No change. nl_after_try_catch_finally = 0 # number # The number of newlines before and after a property, indexer or event decl. # 0 = No change. nl_around_cs_property = 0 # number # The number of newlines between the get/set/add/remove handlers in C#. # 0 = No change. nl_between_get_set = 0 # number # Add or remove newline between C# property and the '{' nl_property_brace = ignore # ignore/add/remove/force # Whether to remove blank lines after '{' eat_blanks_after_open_brace = false # false/true # Whether to remove blank lines before '}' eat_blanks_before_close_brace = false # false/true # How aggressively to remove extra newlines not in preproc. # 0: No change # 1: Remove most newlines not handled by other config # 2: Remove all newlines and reformat completely by config nl_remove_extra_newlines = 0 # number # Whether to put a blank line before 'return' statements, unless after an open brace. nl_before_return = false # false/true # Whether to put a blank line after 'return' statements, unless followed by a close brace. nl_after_return = false # false/true # Whether to put a newline after a Java annotation statement. # Only affects annotations that are after a newline. nl_after_annotation = ignore # ignore/add/remove/force # Controls the newline between two annotations. nl_between_annotation = ignore # ignore/add/remove/force # # Code modifying options (non-whitespace) # # Add or remove braces on single-line 'do' statement mod_full_brace_do = ignore # ignore/add/remove/force # Add or remove braces on single-line 'for' statement mod_full_brace_for = ignore # ignore/add/remove/force # Add or remove braces on single-line function definitions. (Pawn) mod_full_brace_function = ignore # ignore/add/remove/force # Add or remove braces on single-line 'if' statement. Will not remove the braces if they contain an 'else'. # GLN # mod_full_brace_if = ignore # ignore/add/remove/force mod_full_brace_if = add # ignore/add/remove/force # Make all if/elseif/else statements in a chain be braced or not. Overrides mod_full_brace_if. # If any must be braced, they are all braced. If all can be unbraced, then the braces are removed. mod_full_brace_if_chain = false # false/true # Don't remove braces around statements that span N newlines mod_full_brace_nl = 0 # number # Add or remove braces on single-line 'while' statement mod_full_brace_while = ignore # ignore/add/remove/force # Add or remove braces on single-line 'using ()' statement mod_full_brace_using = ignore # ignore/add/remove/force # Add or remove unnecessary paren on 'return' statement mod_paren_on_return = ignore # ignore/add/remove/force # Whether to change optional semicolons to real semicolons mod_pawn_semicolon = false # false/true # Add parens on 'while' and 'if' statement around bools mod_full_paren_if_bool = false # false/true # Whether to remove superfluous semicolons mod_remove_extra_semicolon = false # false/true # If a function body exceeds the specified number of newlines and doesn't have a comment after # the close brace, a comment will be added. mod_add_long_function_closebrace_comment = 0 # number # If a namespace body exceeds the specified number of newlines and doesn't have a comment after # the close brace, a comment will be added. mod_add_long_namespace_closebrace_comment = 0 # number # If a switch body exceeds the specified number of newlines and doesn't have a comment after # the close brace, a comment will be added. mod_add_long_switch_closebrace_comment = 0 # number # If an #ifdef body exceeds the specified number of newlines and doesn't have a comment after # the #endif, a comment will be added. mod_add_long_ifdef_endif_comment = 0 # number # If an #ifdef or #else body exceeds the specified number of newlines and doesn't have a comment after # the #else, a comment will be added. mod_add_long_ifdef_else_comment = 0 # number # If TRUE, will sort consecutive single-line 'import' statements [Java, D] mod_sort_import = false # false/true # If TRUE, will sort consecutive single-line 'using' statements [C#] mod_sort_using = false # false/true # If TRUE, will sort consecutive single-line '#include' statements [C/C++] and '#import' statements [Obj-C] # This is generally a bad idea, as it may break your code. mod_sort_include = false # false/true # If TRUE, it will move a 'break' that appears after a fully braced 'case' before the close brace. mod_move_case_break = false # false/true # Will add or remove the braces around a fully braced case statement. # Will only remove the braces if there are no variable declarations in the block. mod_case_brace = ignore # ignore/add/remove/force # If TRUE, it will remove a void 'return;' that appears as the last statement in a function. mod_remove_empty_return = false # false/true # # Comment modifications # # Try to wrap comments at cmt_width columns cmt_width = 0 # number # Set the comment reflow mode (default: 0) # 0: no reflowing (apart from the line wrapping due to cmt_width) # 1: no touching at all # 2: full reflow cmt_reflow_mode = 0 # number # Whether to convert all tabs to spaces in comments. Default is to leave tabs inside comments alone, unless used for indenting. cmt_convert_tab_to_spaces = false # false/true # If false, disable all multi-line comment changes, including cmt_width. keyword substitution, and leading chars. # Default is true. cmt_indent_multi = true # false/true # Whether to group c-comments that look like they are in a block cmt_c_group = false # false/true # Whether to put an empty '/*' on the first line of the combined c-comment cmt_c_nl_start = false # false/true # Whether to put a newline before the closing '*/' of the combined c-comment cmt_c_nl_end = false # false/true # Whether to group cpp-comments that look like they are in a block cmt_cpp_group = false # false/true # Whether to put an empty '/*' on the first line of the combined cpp-comment cmt_cpp_nl_start = false # false/true # Whether to put a newline before the closing '*/' of the combined cpp-comment cmt_cpp_nl_end = false # false/true # Whether to change cpp-comments into c-comments cmt_cpp_to_c = false # false/true # Whether to put a star on subsequent comment lines cmt_star_cont = false # false/true # The number of spaces to insert at the start of subsequent comment lines cmt_sp_before_star_cont = 0 # number # The number of spaces to insert after the star on subsequent comment lines # DJM # cmt_sp_after_star_cont = 0 # number cmt_sp_after_star_cont = 1 # number # For multi-line comments with a '*' lead, remove leading spaces if the first and last lines of # the comment are the same length. Default=True # DJM # cmt_multi_check_last = true # false/true cmt_multi_check_last = false # false/true # The filename that contains text to insert at the head of a file if the file doesn't start with a C/C++ comment. # Will substitute $(filename) with the current file's name. cmt_insert_file_header = "" # string # The filename that contains text to insert at the end of a file if the file doesn't end with a C/C++ comment. # Will substitute $(filename) with the current file's name. cmt_insert_file_footer = "" # string # The filename that contains text to insert before a function implementation if the function isn't preceded with a C/C++ comment. # Will substitute $(function) with the function name and $(javaparam) with the javadoc @param and @return stuff. # Will also substitute $(fclass) with the class name: void CFoo::Bar() { ... } cmt_insert_func_header = "" # string # The filename that contains text to insert before a class if the class isn't preceded with a C/C++ comment. # Will substitute $(class) with the class name. cmt_insert_class_header = "" # string # The filename that contains text to insert before a Obj-C message specification if the method isn't preceded with a C/C++ comment. # Will substitute $(message) with the function name and $(javaparam) with the javadoc @param and @return stuff. cmt_insert_oc_msg_header = "" # string # If a preprocessor is encountered when stepping backwards from a function name, then # this option decides whether the comment should be inserted. # Affects cmt_insert_oc_msg_header, cmt_insert_func_header and cmt_insert_class_header. cmt_insert_before_preproc = false # false/true # # Preprocessor options # # Control indent of preprocessors inside #if blocks at brace level 0 (file-level) pp_indent = ignore # ignore/add/remove/force # Whether to indent #if/#else/#endif at the brace level (true) or from column 1 (false) pp_indent_at_level = false # false/true # Specifies the number of columns to indent preprocessors per level at brace level 0 (file-level). # If pp_indent_at_level=false, specifies the number of columns to indent preprocessors per level at brace level > 0 (function-level). # Default=1. pp_indent_count = 1 # number # Add or remove space after # based on pp_level of #if blocks pp_space = ignore # ignore/add/remove/force # Sets the number of spaces added with pp_space pp_space_count = 0 # number # The indent for #region and #endregion in C# and '#pragma region' in C/C++ pp_indent_region = 0 # number # Whether to indent the code between #region and #endregion pp_region_indent_code = false # false/true # If pp_indent_at_level=true, sets the indent for #if, #else, and #endif when not at file-level. # 0: indent preprocessors using output_tab_size. # >0: column at which all preprocessors will be indented. pp_indent_if = 0 # number # Control whether to indent the code between #if, #else and #endif. pp_if_indent_code = false # false/true # Whether to indent '#define' at the brace level (true) or from column 1 (false) pp_define_at_level = false # false/true # You can force a token to be a type with the 'type' option. # Example: # type myfoo1 myfoo2 # # You can create custom macro-based indentation using macro-open, # macro-else and macro-close. # Example: # macro-open BEGIN_TEMPLATE_MESSAGE_MAP # macro-open BEGIN_MESSAGE_MAP # macro-close END_MESSAGE_MAP # # You can assign any keyword to any type with the set option. # set func_call_user _ N_ # # The full syntax description of all custom definition config entries # is shown below: # # define custom tokens as: # - embed whitespace in token using '' escape character, or # put token in quotes # - these: ' " and ` are recognized as quote delimiters # # type token1 token2 token3 ... # ^ optionally specify multiple tokens on a single line # define def_token output_token # ^ output_token is optional, then NULL is assumed # macro-open token # macro-close token # macro-else token # set id token1 token2 ... # ^ optionally specify multiple tokens on a single line # ^ id is one of the names in token_enum.h sans the CT_ prefix, # e.g. PP_PRAGMA # # all tokens are separated by any mix of ',' commas, '=' equal signs # and whitespace (space, tab) # # You can add support for other file extensions using the 'file_ext' command. # The first arg is the language name used with the '-l' option. # The remaining args are file extensions, matched with 'endswith'. # file_ext CPP .ch .cxx .cpp.in # ajtcl-15.04b/crypto/000077500000000000000000000000001256742562600143215ustar00rootroot00000000000000ajtcl-15.04b/crypto/aj_sw_crypto.c000066400000000000000000000252421256742562600171750ustar00rootroot00000000000000/** * @file */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_crypto.h" #define MAX_SCHEDULE_LEN 48 typedef struct { uint32_t fkey[MAX_SCHEDULE_LEN]; } AES_CTX; static AES_CTX aes_context; #define ROTL8(x) ((((uint32_t)(x)) << 8) | (((uint32_t)(x)) >> 24)) #define ROTL16(x) ((((uint32_t)(x)) << 16) | (((uint32_t)(x)) >> 16)) #define ROTL24(x) ((((uint32_t)(x)) << 24) | (((uint32_t)(x)) >> 8)) #define SHFL8(x) (((uint32_t)(x)) << 8) #define SHFL16(x) (((uint32_t)(x)) << 16) #define SHFL24(x) (((uint32_t)(x)) << 24) #define ROW_0(x) (uint8_t)(x) #define ROW_1(x) (uint8_t)((x) >> 8) #define ROW_2(x) (uint8_t)((x) >> 16) #define ROW_3(x) (uint8_t)((x) >> 24) /* The Rijndael S-box matrix */ static const uint8_t sbox[256] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; static const uint32_t ftable[256] = { 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c }; static const uint32_t Rconst[12] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8 }; #define round_column(x0, x1, x2, x3) \ ftable[ROW_0(x0)] ^ ROTL8(ftable[ROW_1(x1)]) ^ ROTL16(ftable[ROW_2(x2)]) ^ ROTL24(ftable[ROW_3(x3)]) /* * yn are inputs xn are outputs */ #define round(y0, y1, y2, y3, x0, x1, x2, x3, key) \ y0 = round_column(x0, x1, x2, x3) ^ *key++; \ y1 = round_column(x1, x2, x3, x0) ^ *key++; \ y2 = round_column(x2, x3, x0, x1) ^ *key++; \ y3 = round_column(x3, x0, x1, x2) ^ *key++; #define lastround_column(x0, x1, x2, x3) \ (uint32_t)sbox[ROW_0(x0)] ^ SHFL8(sbox[ROW_1(x1)]) ^ SHFL16(sbox[ROW_2(x2)]) ^ SHFL24(sbox[ROW_3(x3)]) /* * yn are inputs xn are outputs */ #define lastround(y0, y1, y2, y3, x0, x1, x2, x3, key) \ y0 = lastround_column(x0, x1, x2, x3) ^ *key++; \ y1 = lastround_column(x1, x2, x3, x0) ^ *key++; \ y2 = lastround_column(x2, x3, x0, x1) ^ *key++; \ y3 = lastround_column(x3, x0, x1, x2) ^ *key++; static void Pack32(uint32_t* u32, const uint8_t* u8) { #if HOST_IS_LITTLE_ENDIAN memcpy(u32, u8, 16); #else int i; for (i = 0; i < 4; ++i, ++u32, u8 += 4) { *u32 = (uint32_t)u8[0] | (u8[1] << 8) | (u8[2] << 16) | (u8[3] << 24); } #endif } static void Unpack32(uint8_t* u8, const uint32_t* u32) { #if HOST_IS_LITTLE_ENDIAN memcpy(u8, u32, 16); #else int i; for (i = 0; i < 4; ++i, ++u32) { *u8++ = (uint8_t)(*u32); *u8++ = (uint8_t)(*u32 >> 8); *u8++ = (uint8_t)(*u32 >> 16); *u8++ = (uint8_t)(*u32 >> 24); } #endif } static uint32_t SubBytes(uint32_t a) { return (uint32_t)sbox[(uint8_t)(a)] | (sbox[(uint8_t)(a >> 8)] << 8) | (sbox[(uint8_t)(a >> 16)] << 16) | (sbox[(uint8_t)(a >> 24)] << 24); } #define ROUNDS 10 static void EncryptRounds(uint32_t* out, uint32_t* in, uint32_t* key) { int i; uint32_t x0 = in[0]; uint32_t x1 = in[1]; uint32_t x2 = in[2]; uint32_t x3 = in[3]; uint32_t y0; uint32_t y1; uint32_t y2; uint32_t y3; for (i = 0; i < 4; i++) { round(y0, y1, y2, y3, x0, x1, x2, x3, key); round(x0, x1, x2, x3, y0, y1, y2, y3, key); } round(y0, y1, y2, y3, x0, x1, x2, x3, key); lastround(x0, x1, x2, x3, y0, y1, y2, y3, key); out[0] = x0; out[1] = x1; out[2] = x2; out[3] = x3; } void AJ_AES_Enable(const uint8_t* key) { int i; uint32_t* fkey = aes_context.fkey; Pack32(fkey, key); for (i = 0; i <= ROUNDS; ++i, fkey += 4) { fkey[4] = fkey[0] ^ SubBytes(ROTL24(fkey[3])) ^ Rconst[i]; fkey[5] = fkey[1] ^ fkey[4]; fkey[6] = fkey[2] ^ fkey[5]; fkey[7] = fkey[3] ^ fkey[6]; } } void AJ_AES_Disable(void) { memset(&aes_context, 0, sizeof(aes_context)); } void AJ_AES_CTR_128(const uint8_t* key, const uint8_t* in, uint8_t* out, uint32_t len, uint8_t* ctr) { uint32_t counter[4]; Pack32(counter, ctr); while (len) { uint32_t tmp[4]; uint32_t i; uint32_t n = min(len, 16); uint8_t* p = (uint8_t*)tmp; for (i = 0; i < 4; ++i) { tmp[i] = counter[i] ^ aes_context.fkey[i]; } EncryptRounds(tmp, tmp, &aes_context.fkey[4]); len -= n; while (n--) { *out++ = *p++ ^ *in++; } /* * The counter field is big-endian */ #if HOST_IS_LITTLE_ENDIAN counter[3] = AJ_ByteSwap32(1 + AJ_ByteSwap32(counter[3])); #else counter[3] += 1; #endif } Unpack32(ctr, counter); } void AJ_AES_CBC_128_ENCRYPT(const uint8_t* key, const uint8_t* in, uint8_t* out, uint32_t len, uint8_t* iv) { uint32_t xorbuf[4]; uint32_t ivt[4]; AJ_ASSERT((len % 16) == 0); Pack32(ivt, iv); while (len) { int i; Pack32(xorbuf, in); for (i = 0; i < 4; ++i) { xorbuf[i] ^= ivt[i] ^ aes_context.fkey[i]; } EncryptRounds(ivt, xorbuf, &aes_context.fkey[4]); Unpack32(out, ivt); out += 16; in += 16; len -= 16; } Unpack32(iv, ivt); } void AJ_AES_ECB_128_ENCRYPT(const uint8_t* key, const uint8_t* in, uint8_t* out) { uint32_t in32[4]; uint32_t out32[4]; Pack32(in32, in); EncryptRounds(out32, in32, &aes_context.fkey[4]); Unpack32(out, out32); } ajtcl-15.04b/crypto/ecc/000077500000000000000000000000001256742562600150535ustar00rootroot00000000000000ajtcl-15.04b/crypto/ecc/aj_crypto_ecc.c000066400000000000000000001450631256742562600200340ustar00rootroot00000000000000/** * @file aj_crypto_ecc.cc * * Class for Elliptic Curve Cryptography */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include #include "aj_crypto_ecc.h" #include "aj_crypto_sha2.h" /* P256 is tested directly with known answer tests from example in ANSI X9.62 Annex L.4.2. (See item in pt_mpy_testcases below.) Mathematica code, written in a non-curve-specific way, was also tested on the ANSI example, then used to generate both P192 and P256 test cases. */ /* * This file exports the functions ECDH_generate, ECDH_derive, and * optionally, ECDSA_sign and ECDSA_verify. It depends on a function * get_random_bytes, which is expected to be of cryptographic quality. */ /* * References: * * [KnuthV2] is D.E. Knuth, The Art of Computer Programming, Volume 2: * Seminumerical Algorithms, 1969. * * [HMV] is D. Hankerson, A. Menezes, and S. Vanstone, Guide to * Elliptic Curve Cryptography, 2004. * * [Wallace] is C.S. Wallace, "A suggestion for a Fast Multiplier", * IEEE Transactions on Electronic Computers, EC-13 no. 1, pp 14-17, * 1964. * * [ANSIX9.62] is ANSI X9.62-2005, "Public Key Cryptography for the Financial * Services Industry The Elliptic Curve Digital Signature Algorithm * (ECDSA)". */ /* * The vast majority of cycles in programs like this are spent in * modular multiplication. The usual approach is Montgomery * multiplication, which effectively does two multiplications in place * of one multiplication and one reduction. However, this program is * dedicated to the NIST standard curves P256 and P192. Most of the * NIST curves have the property that they can be expressed as a_i * * 2^(32*i), where a_i is -1, 0, or +1. For example P192 is 2^(6*32) * - 2^(2*32) - 2^(0*32). This allows easy word-oriented reduction * (32 bit words): The word at position 6 can just be subtracted from * word 6 (i.e. word 6 zeroed), and added to words 2 and 0. This is * faster than Montgomery multiplication. * * Two problems with the naive implementation suggested above are carry * propagation and getting the reduction precise. * * Every time you do an add or subtract you have to propagate carries. * The result might come out between the modulus and 2^192 or 2^256, * in which case you subtract the modulus. Most carry propagation is avoided * by using 64 bit words during computation, even though the radix is only * 2^32. A carry propagation is done once in the multiplication * and once again after the reduction step. (This idea comes from the carry * save adder used in hardware designs.) * * Exact reduction is required for only a few operations: comparisons, * and halving. The multiplier for point multiplication must also be * exactly reduced. So we do away with the requirement for exact * reduction in most operations. Thus, any reduced value, X, can may * represented by X + k * modulus, for any integer k, as long as the * result is representable in the data structure. Typically k is * between -1 and 1. (A bigval_t has one more 32 bit word than is * required to hold the modulus, and is interpreted as 2's complement * binary, little endian by word, native endian within words.) * * An exact reduction function is supplied, and must be called as necessary. */ /* * The external function get_random_bytes is expected to be avaiable. * It must return 0 on success, and -1 on error. Feel free to raname * this function, if necessary. */ static int get_random_bytes(uint8_t* buf, int len); /* * CONFIGURATION STUFF * * All these values are undefined. It seems better to set the * preprocessor variables in the makefile, and thus avoid * generating many different versions of the code. * This may not be practical with ECC_P192 and ECC_P256, but at * least that is only in the ecc.h file. */ /* define ECDSA to include ECDSA functions */ #define ECDSA /* define ECC_TEST to rename the the exported symbols to avoid name collisions with openSSL, and a few other things necessary for linking with the test program ecctest.c */ /* define ARM7_ASM to use assembly code specially for the ARM7 processor */ // #define ARM7_ASM /* define SMALL_CODE to skip unrolling loops */ // #define SMALL_CODE /* define SPECIAL_SQUARE to generate a special case for squaring. Special squaring should just about halve the number of multiplies, but on Windows machines and if loops are unrolled (SMALL_CODE not defined) actually causes slight slowing. */ #define SPECIAL_SQUARE /* define MPY2BITS to consume the multiplier two bits at a time. */ #define MPY2BITS #ifdef ECC_TEST /* rename to avoid conflicts with OpenSSL in ecctest.c code. */ #define ECDSA_sign TEST_ECDSA_sign #define ECDSA_verify TEST_ECDSA_verify #define COND_STATIC #else /* ECC_TEST not defined */ #define COND_STATIC static #endif /* ECC_TEST not defined */ typedef struct { int64_t data[2 * BIGLEN]; } dblbigval_t; /* These values describe why the verify failed. This simplifies testing. */ typedef enum {V_SUCCESS = 0, V_R_ZERO, V_R_BIG, V_S_ZERO, V_S_BIG, V_INFINITY, V_UNEQUAL} verify_res_t; typedef enum {MOD_MODULUS = 0, MOD_ORDER} modulus_val_t; #define MSW (BIGLEN - 1) static void big_adjustP(bigval_t* tgt, bigval_t const* a, int64_t k); static void big_1wd_mpy(bigval_t* tgt, bigval_t const* a, int32_t k); static void big_sub(bigval_t* tgt, bigval_t const* a, bigval_t const* b); static void big_precise_reduce(bigval_t* tgt, bigval_t const* a, bigval_t const* modulus); #define big_is_negative(a) ((int32_t)(a)->data[MSW] < 0) /* * Does approximate reduction. Subtracts most significant word times * modulus from src. The double cast is important to get sign * extension right. */ #define big_approx_reduceP(tgt, src) \ big_adjustP(tgt, src, -(int64_t)(int32_t)(src)->data[MSW]) /* if tgt is a modular value, it must be precisely reduced */ #define big_is_odd(tgt) ((tgt)->data[0] & 1) // Squares, always modulo the modulus #define big_sqrP(tgt, a) big_mpyP(tgt, a, a, MOD_MODULUS) #define m1 0xffffffffU #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define OVERFLOWCHECK(sum, a, b) ((((a) > 0) && ((b) > 0) && ((sum) <= 0)) || \ (((a) < 0) && ((b) < 0) && ((sum) >= 0))) /* NOTE WELL! The Z component must always be precisely reduced. */ typedef struct { bigval_t X; bigval_t Y; bigval_t Z; } jacobian_point_t; static bigval_t const big_zero = { { 0, 0, 0, 0, 0, 0, 0 } }; static bigval_t const big_one = { { 1, 0, 0, 0, 0, 0, 0 } }; static affine_point_t const affine_infinity = { { { 0, 0, 0, 0, 0, 0, 0 } }, { { 0, 0, 0, 0, 0, 0, 0 } }, B_TRUE }; static jacobian_point_t const jacobian_infinity = { { { 1, 0, 0, 0, 0, 0, 0 } }, { { 1, 0, 0, 0, 0, 0, 0 } }, { { 0, 0, 0, 0, 0, 0, 0 } } }; static bigval_t const modulusP256 = { { m1, m1, m1, 0, 0, 0, 1, m1, 0 } }; static bigval_t const b_P256 = { { 0x27d2604b, 0x3bce3c3e, 0xcc53b0f6, 0x651d06b0, 0x769886bc, 0xb3ebbd55, 0xaa3a93e7, 0x5ac635d8, 0x00000000 } }; static bigval_t const orderP256 = { { 0xfc632551, 0xf3b9cac2, 0xa7179e84, 0xbce6faad, 0xffffffff, 0xffffffff, 0x00000000, 0xffffffff, 0x00000000 } }; #ifdef ECDSA static dblbigval_t const orderDBL256 = { { 0xfc632551LL - 0x100000000LL, 0xf3b9cac2LL - 0x100000000LL + 1LL, 0xa7179e84LL - 0x100000000LL + 1LL, 0xbce6faadLL - 0x100000000LL + 1LL, 0xffffffffLL - 0x100000000LL + 1LL, 0xffffffffLL - 0x100000000LL + 1LL, 0x00000000LL + 0x1LL, 0xffffffffLL - 0x100000000LL, 0x00000000LL + 1LL } }; #endif /* ECDSA */ static affine_point_t const baseP256 = { { { 0xd898c296, 0xf4a13945, 0x2deb33a0, 0x77037d81, 0x63a440f2, 0xf8bce6e5, 0xe12c4247, 0x6b17d1f2 } }, { { 0x37bf51f5, 0xcbb64068, 0x6b315ece, 0x2bce3357, 0x7c0f9e16, 0x8ee7eb4a, 0xfe1a7f9b, 0x4fe342e2 } }, B_FALSE }; #define modulusP modulusP256 #define orderP orderP256 #define orderDBL orderDBL256 #define base_point baseP256 #define curve_b b_P256 #ifdef ARM7_ASM #define MULACC(a, b) \ __asm \ { \ UMULL tmpr0, tmpr1, a, b; \ ADDS sum0, sum0, tmpr0; \ ADCS sum1, sum1, tmpr1; \ ADC cum_carry, cum_carry, 0x0; \ } // cumcarry: 32-bit word that accumulates carries // sum0: lower half 32-bit word of sum // sum1: higher half 32-bit word of sum // a : 32-bit operand to be multiplied // b : 32-bit operand to be multiplied // tmpr0, tmpr1: two temporary words // sum = sum + A*B where cout may contain carry info from previous operations #define MULACC_DOUBLE(a, b) \ __asm \ { \ UMULL tmpr0, tmpr1, a, b; \ ADDS sum0, sum0, tmpr0; \ ADCS sum1, sum1, tmpr1; \ ADC cum_carry, cum_carry, 0x0; \ ADDS sum0, sum0, tmpr0; \ ADCS sum1, sum1, tmpr1; \ ADC cum_carry, cum_carry, 0x0; \ } #define ACCUM(ap, bp) MULACC(*(ap), *(bp)) #define ACCUMDBL(ap, bp) MULACC_DOUBLE(*(ap), *(bp)) #else /* ARM7_ASM, below is platform independent */ /* (sum, carry) += a * b */ static void mpy_accum(int* cumcarry, uint64_t* sum, uint32_t a, uint32_t b) { uint64_t product = (uint64_t)a * (uint64_t)b; uint64_t lsum = *sum; lsum += product; if (lsum < product) { *cumcarry += 1; } *sum = lsum; } #ifdef SPECIAL_SQUARE /* (sum, carry += 2 * a * b. Attempts to reduce writes to memory and branches caused slowdown on windows machines. */ static void mpy_accum_dbl(int* cumcarry, uint64_t* sum, uint32_t a, uint32_t b) { uint64_t product = (uint64_t)a * (uint64_t)b; uint64_t lsum = *sum; lsum += product; if (lsum < product) { *cumcarry += 1; } lsum += product; if (lsum < product) { *cumcarry += 1; } *sum = lsum; } #endif /* SPECIAL_SQUARE */ /* ap and bp are pointers to the words to be multiplied and accumulated */ #define ACCUM(ap, bp) mpy_accum(&cum_carry, &u_accum, *(ap), *(bp)) #define ACCUMDBL(ap, bp) mpy_accum_dbl(&cum_carry, &u_accum, *(ap), *(bp)) #endif /* !ARM7_ASM, ie platform independent */ /* * The big_mpyP algorithm first multiplies the two arguments, with the * outer loop indexing over output words, and the inner "loop" * (unrolled unless SMALL_CODE is defined), collecting all the terms * that contribute to that output word. * * The impementation is inspired by the Wallace Tree often used in * hardware [Wallace], where (0, 1) terms of the same weight are * collected together into a sequence values each of which can be on * the order of the number of bits in a word, and then the sequence is * turned into a binary number with a carry save adder. This is * generized from base 2 to base 2^32. * * The first part of the algorithm sums together products of equal * weight. The outer loop does carry propagation and makes each value * at most 32 bits. * * Then corrections are applied for negative arguments. (The first * part essentially does unsigned multiplication.) * * The reduction proceeds in 2 steps. The first treats the 32 bit * values (in 64 bit words) from above as though they were * polynomials, and reduces by the paper and pencil method. Carries * are propagated and the result collapsed to a sequence of 32 bit * words (in the target). The second step subtracts MSW * modulus * from the result. This usually (but not always) results in the MSW * being zero. (And that makes subsequent mutliplications faster.) * * The modselect parameter chooses whether reduction is mod the modulus * or the order of the curve. If ECDSA is not defined, this parameter * is ignored, and the curve modulus is used. */ /* * Computes a * b, approximately reduced mod modulusP or orderP, * depending on the modselect flag. */ static void big_mpyP(bigval_t* tgt, bigval_t const* a, bigval_t const* b, modulus_val_t modselect) { int64_t w[2 * BIGLEN]; int64_t s_accum; /* signed */ int i, minj, maxj, a_words, b_words, cum_carry; #ifdef SMALL_CODE int j; #else uint32_t const* ap; uint32_t const* bp; #endif #ifdef ARM7_ASM uint32_t tmpr0, tmpr1, sum0, sum1; #else uint64_t u_accum; #endif #ifdef ECDSA #define MODSELECT modselect #else #define MODSELECT MOD_MODULUS #endif a_words = BIGLEN; while (a_words > 0 && a->data[a_words - 1] == 0) { --a_words; } /* * i is target index. The j (in comments only) indexes * through the multiplier. */ #ifdef ARM7_ASM sum0 = 0; sum1 = 0; cum_carry = 0; #else u_accum = 0; cum_carry = 0; #endif #ifndef SPECIAL_SQUARE #define NO_SPECIAL_SQUARE 1 #else #define NO_SPECIAL_SQUARE 0 #endif if (NO_SPECIAL_SQUARE || a != b) { /* normal multiply */ /* compute length of b */ b_words = BIGLEN; while (b_words > 0 && b->data[b_words - 1] == 0) { --b_words; } /* iterate over words of output */ for (i = 0; i < a_words + b_words - 1; ++i) { /* Run j over all possible values such that 0 <= j < b_words && 0 <= i-j < a_words. Hence j >= 0 and j > i - a_words and j < b_words and j <= i (j exists only in the mind of the reader.) */ maxj = MIN(b_words - 1, i); minj = MAX(0, i - a_words + 1); /* ACCUM accumlates into . */ #ifdef SMALL_CODE for (j = minj; j <= maxj; ++j) { ACCUM(a->data + i - j, b->data + j); } #else /* SMALL_CODE not defined */ /* * The inner loop (over j, running from minj to maxj) is * unrolled. Sequentially increasing case values in the code * are intended to coax the compiler into emitting a jump * table. Here j runs from maxj to minj, but addition is * commutative, so it doesn't matter. */ ap = &a->data[i - minj]; bp = &b->data[minj]; /* the order is opposite the loop, but addition is commutative */ switch (8 - (maxj - minj)) { case 0: ACCUM(ap - 8, bp + 8); /* j = 8 */ case 1: ACCUM(ap - 7, bp + 7); case 2: ACCUM(ap - 6, bp + 6); case 3: ACCUM(ap - 5, bp + 5); case 4: ACCUM(ap - 4, bp + 4); case 5: ACCUM(ap - 3, bp + 3); case 6: ACCUM(ap - 2, bp + 2); case 7: ACCUM(ap - 1, bp + 1); case 8: ACCUM(ap - 0, bp + 0); /* j = 0 */ } #endif /* SMALL_CODE not defined */ /* The total value is w + u_accum << (32 *i) + cum_carry << (32 * i + 64). The steps from here to the end of the i-loop (not counting squaring branch) and the increment of i by the loop maintain the invariant that the value is constant. (Assume w had been initialized to zero, even though we really didn't.) */ #ifdef ARM7_ASM w[i] = sum0; sum0 = sum1; sum1 = cum_carry; cum_carry = 0; #else w[i] = u_accum & 0xffffffffULL; u_accum = (u_accum >> 32) + ((uint64_t)cum_carry << 32); cum_carry = 0; #endif } } else { /* squaring */ #ifdef SPECIAL_SQUARE /* a[i] * a[j] + a[j] * a[i] == 2 * (a[i] * a[j]), so we can cut the number of multiplies nearly in half. */ for (i = 0; i < 2 * a_words - 1; ++i) { /* Run j over all possible values such that 0 <= j < a_words && 0 <= i-j < a_words && j < i-j Hence j >= 0 and j > i - a_words and j < a_words and 2*j < i */ maxj = MIN(a_words - 1, i); /* Only go half way. Must use (i-1)>> 1, not (i-1)/ 2 */ maxj = MIN(maxj, (i - 1) >> 1); minj = MAX(0, i - a_words + 1); #ifdef SMALL_CODE for (j = minj; j <= maxj; ++j) { ACCUMDBL(a->data + i - j, a->data + j); } /* j live */ if ((i & 1) == 0) { ACCUM(a->data + j, a->data + j); } #else /* SMALL_CODE not defined */ ap = &a->data[i - minj]; bp = &a->data[minj]; switch (8 - (maxj - minj)) { case 0: ACCUMDBL(ap - 8, bp + 8); /* j = 8 */ case 1: ACCUMDBL(ap - 7, bp + 7); case 2: ACCUMDBL(ap - 6, bp + 6); case 3: ACCUMDBL(ap - 5, bp + 5); case 4: ACCUMDBL(ap - 4, bp + 4); case 5: ACCUMDBL(ap - 3, bp + 3); case 6: ACCUMDBL(ap - 2, bp + 2); case 7: ACCUMDBL(ap - 1, bp + 1); case 8: ACCUMDBL(ap - 0, bp + 0); /* j = 0 */ } /* Even numbered columns (zero based) have a middle element. */ if ((i & 1) == 0) { ACCUM(a->data + maxj + 1, a->data + maxj + 1); } #endif /* SMALL_CODE not defined */ /* The total value is w + u_accum << (32 *i) + cum_carry << (32 * i + 64). The steps from here to the end of i-loop and the increment of i by the loop maintain the invariant that the total value is unchanged. (Assume w had been initialized to zero, even though we really didn't.) */ #ifdef ARM7_ASM w[i] = sum0; sum0 = sum1; sum1 = cum_carry; cum_carry = 0; #else /* ARM7_ASM not defined */ w[i] = u_accum & 0xffffffffULL; u_accum = (u_accum >> 32) + ((uint64_t)cum_carry << 32); cum_carry = 0; #endif /* ARM7_ASM not defined */ } #endif /* SPECIAL_SQUARE */ } /* false branch of NO_SPECIAL_SQUARE || (a != b) */ /* The total value as indicated above is maintained invariant down to the approximate reduction code below. */ /* propagate any residual to next to end of array */ for (; i < 2 * BIGLEN - 1; ++i) { #ifdef ARM7_ASM w[i] = sum0; sum0 = sum1; sum1 = 0; #else w[i] = u_accum & 0xffffffffULL; u_accum >>= 32; #endif } /* i is still live */ /* from here on, think of w as containing signed values */ /* Last value of the array, still using i. We store the entire 64 bits. There are two reasons for this. The pedantic one is that this clearly maintains our invariant that the value has not changed. The other one is that this makes w[BIGNUM-1] negative if the result was negative, and reduction depends on this. */ #ifdef ARM7_ASM w[i] = ((uint64_t)sum1 << 32) | sum0; /* sum1 = sum0 = 0; maintain invariant */ #else w[i] = u_accum; /* u_accum = 0; maintain invariant */ #endif /* * Apply correction if a or b are negative. It would be nice to * put this inside the i-loop to reduce memory bandwidth. Later... * * signvedval(a) = unsignedval(a) - 2^(32*BIGLEN)*isneg(a). * * so signval(a) * signedval(b) = unsignedval(a) * unsignedval[b] - * isneg(a) * unsignedval(b) * 2^(32*BIGLEN) - * isneg(b) * unsingedval(a) * 2^ (32*BIGLEN) + * isneg(a) * isneg(b) * 2 ^(2 * 32 * BIGLEN) * * If one arg is zero and the other is negative, obviously no * correction is needed, but we do not make a special case, since * the "correction" only adds in zero. */ if (big_is_negative(a)) { for (i = 0; i < BIGLEN; ++i) { w[i + BIGLEN] -= b->data[i]; } } if (big_is_negative(b)) { for (i = 0; i < BIGLEN; ++i) { w[i + BIGLEN] -= a->data[i]; } if (big_is_negative(a)) { /* both negative */ w[2 * BIGLEN - 1] += 1ULL << 32; } } /* * The code from here to the end of the function maintains w mod * modulusP constant, even though it changes the value of w. */ /* reduce (approximate) */ if (MODSELECT == MOD_MODULUS) { for (i = 2 * BIGLEN - 1; i >= MSW; --i) { int64_t v; v = w[i]; if (v != 0) { w[i] = 0; w[i - 1] += v; w[i - 2] -= v; w[i - 5] -= v; w[i - 8] += v; } } } else { /* modulo order. Not performance critical */ #ifdef ECDSA int64_t carry; /* convert to 32 bit values, except for most signifiant word */ carry = 0; for (i = 0; i < 2 * BIGLEN - 1; ++i) { w[i] += carry; carry = w[i] >> 32; w[i] -= carry << 32; } /* i is live */ w[i] += carry; /* each iteration knocks off word i */ for (i = 2 * BIGLEN - 1; i >= MSW; --i) { /* most to least significant */ int64_t v; int64_t tmp; int64_t tmp2; int j; int k; for (k = 0; w[i] != 0 && k < 3; ++k) { v = w[i]; carry = 0; for (j = i - MSW; j < 2 * BIGLEN; ++j) { if (j <= i) { tmp2 = -(v * orderDBL.data[j - i + MSW]); tmp = w[j] + tmp2 + carry; } else { tmp = w[j] + carry; } if (j < 2 * BIGLEN - 1) { carry = tmp >> 32; tmp -= carry << 32; } else { carry = 0; } w[j] = tmp; } } } #endif /* ECDSA */ } /* propagate carries and copy out to tgt in 32 bit chunks. */ s_accum = 0; for (i = 0; i < BIGLEN; ++i) { s_accum += w[i]; tgt->data[i] = (uint32_t)s_accum; s_accum >>= 32; /* signed, so sign bit propagates */ } /* final approximate reduction */ if (MODSELECT == MOD_MODULUS) { big_approx_reduceP(tgt, tgt); } else { #ifdef ECDSA if (tgt->data[MSW]) { /* Keep it simple! At one time all this was done in place, and was totally unobvious. */ bigval_t tmp; /* The most significant word is signed, even though the whole array has declared uint32_t. */ big_1wd_mpy(&tmp, &orderP, (int32_t)tgt->data[MSW]); big_sub(tgt, tgt, &tmp); } #endif /* ECDSA */ } } /* * Adds k * modulusP to a and stores into target. -2^62 <= k <= 2^62 . * (This is conservative.) */ static void big_adjustP(bigval_t* tgt, bigval_t const* a, int64_t k) { #define RDCSTEP(i, adj) \ w += a->data[i]; \ w += (adj); \ tgt->data[i] = (uint32_t)(int32_t)w; \ w >>= 32; /* add k * modulus */ if (k != 0) { int64_t w = 0; RDCSTEP(0, -k); RDCSTEP(1, 0); RDCSTEP(2, 0); RDCSTEP(3, k); RDCSTEP(4, 0); RDCSTEP(5, 0); RDCSTEP(6, k); RDCSTEP(7, -k); RDCSTEP(8, k); } else if (tgt != a) { *tgt = *a; } } /* * Computes k * a and stores into target. Conditions: product must * be representable in bigval_t. */ static void big_1wd_mpy(bigval_t* tgt, bigval_t const* a, int32_t k) { int64_t w = 0; int64_t tmp; int64_t prod; int j; for (j = 0; j <= MSW; ++j) { prod = (int64_t)k * (int64_t)a->data[j]; tmp = w + prod; w = tmp; tgt->data[j] = (uint32_t)w; w -= tgt->data[j]; w >>= 32; } } /* * Adds a to b as signed (2's complement) numbers. Ok to use for * modular values if you don't let the sum overflow. */ COND_STATIC void big_add(bigval_t* tgt, bigval_t const* a, bigval_t const* b) { uint64_t v; int i; v = 0; for (i = 0; i < BIGLEN; ++i) { v += a->data[i]; v += b->data[i]; tgt->data[i] = (uint32_t)v; v >>= 32; } } /* * modulo modulusP addition with approximate reduction. */ static void big_addP(bigval_t* tgt, bigval_t const* a, bigval_t const* b) { big_add(tgt, a, b); big_approx_reduceP(tgt, tgt); } /* 2's complement subtraction */ static void big_sub(bigval_t* tgt, bigval_t const* a, bigval_t const* b) { uint64_t v; int i; /* negation is equivalent to 1's complement and increment */ v = 1; /* increment */ for (i = 0; i < BIGLEN; ++i) { v += a->data[i]; v += ~b->data[i]; /* 1's complement */ tgt->data[i] = (uint32_t)v; v >>= 32; } } /* * modulo modulusP subtraction with approximate reduction. */ static void big_subP(bigval_t* tgt, bigval_t const* a, bigval_t const* b) { big_sub(tgt, a, b); big_approx_reduceP(tgt, tgt); } /* returns 1 if a > b, -1 if a < b, and 0 if a == b. a and b are 2's complement. When applied to modular values, args must be precisely reduced. */ static int big_cmp(bigval_t const* a, bigval_t const* b) { int i; /* most significant word is treated as 2's complement */ if ((int32_t)a->data[MSW] > (int32_t)b->data[MSW]) { return (1); } else if ((int32_t)a->data[MSW] < (int32_t)b->data[MSW]) { return (-1); } /* remainder treated as unsigned */ for (i = MSW - 1; i >= 0; --i) { if (a->data[i] > b->data[i]) { return (1); } else if (a->data[i] < b->data[i]) { return (-1); } } return (0); } /* * Computes tgt = a mod modulus. Only works with modluii slightly * less than 2**(32*(BIGLEN-1)). Both modulusP and orderP qualify. */ static void big_precise_reduce(bigval_t* tgt, bigval_t const* a, bigval_t const* modulus) { /* * src is a trick to avoid an extra copy of a to arg a to a * temporary. Every statement uses src as the src and tgt as the * destination, and it executes src = tgt, so all subsequent * operations affect the modified data, not the original. There is * a case to handle the situation of no modifications having been * made. */ bigval_t const* src = a; /* If tgt < 0, a positive value gets added in, so eventually tgt will be >= 0. If tgt > 0 and the MSW is non-zero, a non-zero value smaller than tgt gets subtracted, so eventually target becomes < 1 * 2**(32*MSW), but not negative, i.e. tgt->data[MSW] == 0, and thus loop termination is guaranteed. */ while ((int32_t)src->data[MSW] != 0) { if (modulus != &modulusP) { /* General case. Keep it simple! */ bigval_t tmp; /* The most significant word is signed, even though the whole array has been declared uint32_t. */ big_1wd_mpy(&tmp, modulus, (int32_t)src->data[MSW]); big_sub(tgt, src, &tmp); } else { /* just an optimization. The other branch would work, but slower. */ big_adjustP(tgt, src, -(int64_t)(int32_t)src->data[MSW]); } src = tgt; } while (big_cmp(src, modulus) >= 0) { big_sub(tgt, src, modulus); src = tgt; } while ((int32_t)src->data[MSW] < 0) { big_add(tgt, src, modulus); src = tgt; } /* copy src to tgt if not already done */ if (src != tgt) { *tgt = *src; } } /* computes floor(a / 2), 2's complement. */ static void big_halve(bigval_t* tgt, bigval_t const* a) { uint32_t shiftval; uint32_t new_shiftval; int i; /* most significant word is 2's complement. Do it separately. */ shiftval = a->data[MSW] & 1; tgt->data[MSW] = (uint32_t)((int32_t)a->data[MSW] >> 1); for (i = MSW - 1; i >= 0; --i) { new_shiftval = a->data[i] & 1; tgt->data[i] = (a->data[i] >> 1) | (shiftval << 31); shiftval = new_shiftval; } } /* * computes tgt, such that 2 * tgt === a, (mod modulusP). NOTE WELL: * arg a must be precisely reduced. This function could do that, but * in some cases, arg a is known to already be reduced and we don't * want to waste cycles. The code could be written more cleverly to * avoid passing over the data twice in the case of an odd value. */ static void big_halveP(bigval_t* tgt, bigval_t const* a) { if (a->data[0] & 1) { /* odd */ big_adjustP(tgt, a, 1); big_halve(tgt, tgt); } else { /* even */ big_halve(tgt, a); } } /* returns B_TRUE if a is zero */ boolean_t big_is_zero(bigval_t const* a) { int i; for (i = 0; i < BIGLEN; ++i) { if (a->data[i] != 0) { return (B_FALSE); } } return (B_TRUE); } /* returns B_TRUE if a is one */ static boolean_t big_is_one(bigval_t const* a) { int i; if (a->data[0] != 1) { return (B_FALSE); } for (i = 1; i < BIGLEN; ++i) { if (a->data[i] != 0) { return (B_FALSE); } } return (B_TRUE); } /* * This uses the extended binary GCD (Greatest Common Divisor) * algorithm. The binary GCD algorithm is presented in [KnuthV2] as * Algorithm X. The extension to do division is presented in Homework * Problem 15 and its solution in the back of the book. * * The implementation here follows the presentation in [HMV] Algorithm * 2.22. * * If the denominator is zero, it will loop forever. Be careful! * Modulus must be odd. num and den must be positive. */ static void big_divide(bigval_t* tgt, bigval_t const* num, bigval_t const* den, bigval_t const* modulus) { bigval_t u, v, x1, x2; u = *den; v = *modulus; x1 = *num; x2 = big_zero; while (!big_is_one(&u) && !big_is_one(&v)) { while (!big_is_odd(&u)) { big_halve(&u, &u); if (big_is_odd(&x1)) { big_add(&x1, &x1, modulus); } big_halve(&x1, &x1); } while (!big_is_odd(&v)) { big_halve(&v, &v); if (big_is_odd(&x2)) { big_add(&x2, &x2, modulus); } big_halve(&x2, &x2); } if (big_cmp(&u, &v) >= 0) { big_sub(&u, &u, &v); big_sub(&x1, &x1, &x2); } else { big_sub(&v, &v, &u); big_sub(&x2, &x2, &x1); } } if (big_is_one(&u)) { big_precise_reduce(tgt, &x1, modulus); } else { big_precise_reduce(tgt, &x2, modulus); } } static void big_triple(bigval_t* tgt, bigval_t const* a) { int i; uint64_t accum = 0; /* technically, the lower significance words should be treated as unsigned and the most significant word treated as signed (arithmetic right shift instead of logical right shift), but accum can never get negative during processing the lower significance words, and the most significant word is the last word processed, so what is left in the accum after the final shift does not matter. */ for (i = 0; i < BIGLEN; ++i) { accum += a->data[i]; accum += a->data[i]; accum += a->data[i]; tgt->data[i] = (uint32_t)accum; accum >>= 32; } } /* * The point add and point double algorithms use mixed Jacobian * and affine coordinates. The affine point (x,y) corresponds * to the Jacobian point (X, Y, Z), for any non-zero Z, with X = Z^2 * x * and Y = Z^3 * y. The infinite point is represented in Jacobian * coordinates as (1, 1, 0). */ #define jacobian_point_is_infinity(P) (big_is_zero(&(P)->Z)) static void toJacobian(jacobian_point_t* tgt, affine_point_t const* a) { tgt->X = a->x; tgt->Y = a->y; tgt->Z = big_one; } /* a->Z must be precisely reduced */ static void toAffine(affine_point_t* tgt, jacobian_point_t const* a) { bigval_t zinv, zinvpwr; if (big_is_zero(&a->Z)) { *tgt = affine_infinity; return; } big_divide(&zinv, &big_one, &a->Z, &modulusP); big_sqrP(&zinvpwr, &zinv); /* Zinv^2 */ big_mpyP(&tgt->x, &a->X, &zinvpwr, MOD_MODULUS); big_mpyP(&zinvpwr, &zinvpwr, &zinv, MOD_MODULUS); /* Zinv^3 */ big_mpyP(&tgt->y, &a->Y, &zinvpwr, MOD_MODULUS); big_precise_reduce(&tgt->x, &tgt->x, &modulusP); big_precise_reduce(&tgt->y, &tgt->y, &modulusP); tgt->infinity = B_FALSE; } /* * From [HMV] Algorithm 3.21. */ /* tgt = 2 * P. P->Z must be precisely reduced and tgt->Z will be precisely reduced */ static void pointDouble(jacobian_point_t* tgt, jacobian_point_t const* P) { bigval_t x3loc, y3loc, z3loc, t1, t2, t3; #define x1 (&P->X) #define y1 (&P->Y) #define z1 (&P->Z) #define x3 (&x3loc) #define y3 (&y3loc) #define z3 (&z3loc) /* This requires P->Z be precisely reduced */ if (jacobian_point_is_infinity(P)) { *tgt = jacobian_infinity; return; } big_sqrP(&t1, z1); big_subP(&t2, x1, &t1); big_addP(&t1, x1, &t1); big_mpyP(&t2, &t2, &t1, MOD_MODULUS); big_triple(&t2, &t2); big_addP(y3, y1, y1); big_mpyP(z3, y3, z1, MOD_MODULUS); big_sqrP(y3, y3); big_mpyP(&t3, y3, x1, MOD_MODULUS); big_sqrP(y3, y3); big_halveP(y3, y3); big_sqrP(x3, &t2); big_addP(&t1, &t3, &t3); /* x1 not used after this point. Safe to store to tgt, even if aliased */ big_subP(&tgt->X /* x3 */, x3, &t1); #undef x3 #define x3 (&tgt->X) big_subP(&t1, &t3, x3); big_mpyP(&t1, &t1, &t2, MOD_MODULUS); big_subP(&tgt->Y, &t1, y3); /* Z components of returned Jacobian points must be precisely reduced */ big_precise_reduce(&tgt->Z, z3, &modulusP); #undef x1 #undef y1 #undef z1 #undef x3 #undef y3 #undef z3 } /* From [HMV] Algorithm 3.22 */ /* tgt = P + Q. P->Z must be precisely reduced. tgt->Z will be precisely reduced. tgt and P can be aliased. */ static void pointAdd(jacobian_point_t* tgt, jacobian_point_t const* P, affine_point_t const* Q) { bigval_t t1, t2, t3, t4, x3loc; if (Q->infinity) { if (tgt != P) { *tgt = *P; } return; } /* This requires that P->Z be precisely reduced */ if (jacobian_point_is_infinity(P)) { toJacobian(tgt, Q); return; } #define x1 (&P->X) #define y1 (&P->Y) #define z1 (&P->Z) #define x2 (&Q->x) #define y2 (&Q->y) #define x3 (&x3loc) #define y3 (&y3loc) #define z3 (&tgt->Z) big_sqrP(&t1, z1); big_mpyP(&t2, &t1, z1, MOD_MODULUS); big_mpyP(&t1, &t1, x2, MOD_MODULUS); big_mpyP(&t2, &t2, y2, MOD_MODULUS); big_subP(&t1, &t1, x1); big_subP(&t2, &t2, y1); /* big_is_zero requires precisely reduced arg */ big_precise_reduce(&t1, &t1, &modulusP); if (big_is_zero(&t1)) { big_precise_reduce(&t2, &t2, &modulusP); if (big_is_zero(&t2)) { toJacobian(tgt, Q); pointDouble(tgt, tgt); } else { *tgt = jacobian_infinity; } return; } /* store into target. okay, even if tgt is aliased with P, as z1 is not subsequently used */ big_mpyP(z3, z1, &t1, MOD_MODULUS); /* z coordinates of returned jacobians must be precisely reduced. */ big_precise_reduce(z3, z3, &modulusP); big_sqrP(&t3, &t1); big_mpyP(&t4, &t3, &t1, MOD_MODULUS); big_mpyP(&t3, &t3, x1, MOD_MODULUS); big_addP(&t1, &t3, &t3); big_sqrP(x3, &t2); big_subP(x3, x3, &t1); big_subP(&tgt->X /* x3 */, x3, &t4); /* switch x3 to tgt */ #undef x3 #define x3 (&tgt->X) big_subP(&t3, &t3, x3); big_mpyP(&t3, &t3, &t2, MOD_MODULUS); big_mpyP(&t4, &t4, y1, MOD_MODULUS); /* switch y3 to tgt */ #undef y3 #define y3 (&tgt->Y) big_subP(y3, &t3, &t4); #undef x1 #undef y1 #undef z1 #undef x2 #undef y2 #undef x3 #undef y3 #undef z3 } /* pointMpyP uses a left-to-right binary double-and-add method, which * is an exact analogy to the left-to-right binary meethod for * exponentiation described in [KnuthV2] Section 4.6.3. */ /* returns bit i of bignum n. LSB of n is bit 0. */ #define big_get_bit(n, i) (((n)->data[(i) / 32] >> ((i) % 32)) & 1) /* returns bits i+1 and i of bignum n. LSB of n is bit 0; i <= 30 */ #define big_get_2bits(n, i) (((n)->data[(i) / 32] >> ((i) % 32)) & 3) /* k must be non-negative. Negative values (incorrectly) return the infinite point */ static void pointMpyP(affine_point_t* tgt, bigval_t const* k, affine_point_t const* P) { int i; jacobian_point_t Q; #ifdef MPY2BITS affine_point_t const* mpyset[4]; affine_point_t twoP, threeP; #endif /* MPY2BITS */ if (big_is_negative(k)) { /* This should never happen.*/ *tgt = affine_infinity; return; } Q = jacobian_infinity; /* faster */ if (big_is_zero(k) || big_is_negative(k)) { *tgt = affine_infinity; return; } #ifndef MPY2BITS /* Classical high-to-low method */ /* discard high order zeros */ for (i = BIGLEN * 32 - 1; i >= 0; --i) { if (big_get_bit(k, i)) { break; } } /* Can't fall through since k is non-zero. We get here only via the break */ /* discard highest order 1 bit */ --i; toJacobian(&Q, P); for (; i >= 0; --i) { pointDouble(&Q, &Q); if (big_get_bit(k, i)) { pointAdd(&Q, &Q, P); } } #else /* MPY2BITS defined */ /* multiply 2 bits at a time */ /* precompute 1P, 2P, and 3P */ mpyset[0] = (affine_point_t*)0; mpyset[1] = P; toJacobian(&Q, P); /* Q = P */ pointDouble(&Q, &Q); /* now Q = 2P */ toAffine(&twoP, &Q); mpyset[2] = &twoP; pointAdd(&Q, &Q, P); /* now Q = 3P */ toAffine(&threeP, &Q); mpyset[3] = &threeP; /* discard high order zeros (in pairs) */ for (i = BIGLEN * 32 - 2; i >= 0; i -= 2) { if (big_get_2bits(k, i)) { break; } } Q = jacobian_infinity; for (; i >= 0; i -= 2) { int mbits = big_get_2bits(k, i); pointDouble(&Q, &Q); pointDouble(&Q, &Q); if (mpyset[mbits] != (affine_point_t*)0) { pointAdd(&Q, &Q, mpyset[mbits]); } } #endif /* MPY2BITS */ toAffine(tgt, &Q); } COND_STATIC boolean_t in_curveP(affine_point_t const* P) { bigval_t sum, product; if (P->infinity) { return (B_TRUE); } big_sqrP(&product, &P->x); big_mpyP(&sum, &product, &P->x, MOD_MODULUS); /* x^3 */ big_triple(&product, &P->x); /* 3 x */ big_subP(&sum, &sum, &product); /* x^3 -3x */ big_addP(&sum, &sum, &curve_b); /* x^3 -3x + b */ big_sqrP(&product, &P->y); /* y^2 */ big_subP(&sum, &sum, &product); /* -y^2 + x^3 -3x + b */ big_precise_reduce(&sum, &sum, &modulusP); return(big_is_zero(&sum)); } /* returns a bigval between 0 or 1 (depending on allow_zero) and order-1, inclusive. Returns 0 on success, -1 otherwise */ COND_STATIC int big_get_random_n(bigval_t* tgt, boolean_t allow_zero) { int rv; tgt->data[BIGLEN - 1] = 0; do { rv = get_random_bytes((uint8_t*) tgt, sizeof (uint32_t) * (BIGLEN - 1)); if (rv < 0) { return (-1); } } while ((!allow_zero && big_is_zero(tgt)) || (big_cmp(tgt, &orderP) >= 0)); return (0); } /* * computes a secret value, k, and a point, P1, to send to the other * party. Returns 0 on success, -1 on failure (of the RNG). */ int ECDH_generate(affine_point_t* P1, bigval_t* k) { int rv; rv = big_get_random_n(k, B_FALSE); if (rv < 0) { return (-1); } pointMpyP(P1, k, &base_point); return (0); } /* takes the point sent by the other party, and verifies that it is a valid point. If 1 <= k < orderP and the point is valid, it stores the resuling point *tgt and returns B_TRUE. If the point is invalid it returns B_FALSE. The behavior with k out of range is unspecified, but safe. */ COND_STATIC boolean_t ECDH_derive_pt(affine_point_t* tgt, bigval_t const* k, affine_point_t const* Q) { if (Q->infinity) { return (B_FALSE); } if (big_is_negative(&Q->x)) { return (B_FALSE); } if (big_cmp(&Q->x, &modulusP) >= 0) { return (B_FALSE); } if (big_is_negative(&Q->y)) { return (B_FALSE); } if (big_cmp(&Q->y, &modulusP) >= 0) { return (B_FALSE); } if (!in_curveP(Q)) { return (B_FALSE); } /* [HMV] Section 4.3 states that the above steps, combined with the * fact the h=1 for the curves used here, implies that order*Q = * Infinity, which is required by ANSI X9.63. */ pointMpyP(tgt, k, Q); /* Q2 can't be infinity if 1 <= k < orderP, which is supposed to be the case, but the test is so cheap, we just do it. */ if (tgt->infinity) { return (B_FALSE); } return (B_TRUE); } void AJ_BigvalEncode(const bigval_t* src, uint8_t* tgt, size_t tgtlen) { size_t i; uint8_t v; uint8_t highbytes = big_is_negative(src) ? 0xff : 0; /* LSbyte to MS_byte */ for (i = 0; i < 4 * BIGLEN; ++i) { if (i < tgtlen) { v = src->data[i / 4] >> (8 * (i % 4)); ((uint8_t*)tgt)[tgtlen - 1 - i] = v; } } /* i is live */ for (; i < tgtlen; ++i) { ((uint8_t*)tgt)[tgtlen - 1 - i] = highbytes; } } void AJ_BigvalDecode(const uint8_t* src, bigval_t* tgt, size_t srclen) { size_t i; uint8_t v; /* zero the bigval_t */ memset(tgt, 0, sizeof (bigval_t)); /* scan from LSbyte to MSbyte */ for (i = 0; i < srclen && i < 4 * BIGLEN; ++i) { v = ((uint8_t*)src)[srclen - 1 - i]; tgt->data[i / 4] |= (uint32_t)v << (8 * (i % 4)); } } #ifdef ECDSA /* * This function sets the r and s fields of sig. The implementation * follows HMV Algorithm 4.29. */ static int ECDSA_sign(bigval_t const* msgdgst, bigval_t const* privkey, ECDSA_sig_t* sig) { int rv; affine_point_t P1; bigval_t k; bigval_t t; startpoint: rv = ECDH_generate(&P1, &k); if (rv) { return (rv); } big_precise_reduce(&sig->r, &P1.x, &orderP); if (big_is_zero(&sig->r)) { goto startpoint; } big_mpyP(&t, privkey, &sig->r, MOD_ORDER); big_add(&t, &t, msgdgst); big_precise_reduce(&t, &t, &orderP); /* may not be necessary */ big_divide(&sig->s, &t, &k, &orderP); if (big_is_zero(&sig->s)) { goto startpoint; } return (0); } /* * Returns B_TRUE if the signature is valid. * The implementation follow HMV Algorithm 4.30. */ static verify_res_t ECDSA_verify_inner(bigval_t const* msgdgst, affine_point_t const* pubkey, ECDSA_sig_t const* sig) { /* We could reuse variables and save stack space. If stack space is tight, u1 and u2 could be the same variable by interleaving the big multiplies and the point multiplies. P2 and X could be the same variable. X.x could be reduced in place, eliminating v. And if you really wanted to get tricky, I think one could use unions between the affine and jacobian versions of points. But check that out before doing it. */ bigval_t v; bigval_t w; bigval_t u1; bigval_t u2; affine_point_t P1; affine_point_t P2; affine_point_t X; jacobian_point_t P2Jacobian; jacobian_point_t XJacobian; if (big_cmp(&sig->r, &big_one) < 0) { return (V_R_ZERO); } if (big_cmp(&sig->r, &orderP) >= 0) { return(V_R_BIG); } if (big_cmp(&sig->s, &big_one) < 0) { return (V_S_ZERO); } if (big_cmp(&sig->s, &orderP) >= 0) { return(V_S_BIG); } big_divide(&w, &big_one, &sig->s, &orderP); big_mpyP(&u1, msgdgst, &w, MOD_ORDER); big_precise_reduce(&u1, &u1, &orderP); big_mpyP(&u2, &sig->r, &w, MOD_ORDER); big_precise_reduce(&u2, &u2, &orderP); pointMpyP(&P1, &u1, &base_point); pointMpyP(&P2, &u2, pubkey); toJacobian(&P2Jacobian, &P2); pointAdd(&XJacobian, &P2Jacobian, &P1); toAffine(&X, &XJacobian); if (X.infinity) { return (V_INFINITY); } big_precise_reduce(&v, &X.x, &orderP); if (big_cmp(&v, &sig->r) != 0) { return (V_UNEQUAL); } return (V_SUCCESS); } boolean_t ECDSA_verify(bigval_t const* msgdgst, affine_point_t const* pubkey, ECDSA_sig_t const* sig) { if (ECDSA_verify_inner(msgdgst, pubkey, sig) == V_SUCCESS) { return B_TRUE; } return B_FALSE; } /* * Converts a hash value to a bigval_t. The rules for this in * ANSIX9.62 are strange. Let b be the number of octets necessary to * represent the modulus. If the size of the hash is less than or * equal to b, the hash is interpreted directly as a number. * Otherwise the left most b octets of the hash are converted to a * number. The hash must be big-endian by byte. There is no alignment * requirement on hashp. */ void ECC_hash_to_bigval(bigval_t* tgt, void const* hashp, unsigned int hashlen) { unsigned int i; /* The "4"s in the rest of this function are the number of bytes in a uint32_t (what bigval_t's are made of). The "8" is the number of bits in a byte. */ /* reduce hashlen to modulus size, if necessary */ if (hashlen > 4 * (BIGLEN - 1)) { hashlen = 4 * (BIGLEN - 1); } *tgt = big_zero; /* move one byte at a time starting with least significant byte */ for (i = 0; i < hashlen; ++i) { tgt->data[i / 4] |= ((uint8_t*)hashp)[hashlen - 1 - i] << (8 * (i % 4)); } } #endif /* ECDSA */ #ifdef ECC_TEST char* ECC_feature_list(void) { return ("ECC_P256" #ifdef ECDSA " ECDSA" #endif #ifdef SPECIAL_SQUARE " SPECIAL_SQUARE" #endif #ifdef SMALL_CODE " SMALL_CODE" #endif #ifdef MPY2BITS " MPY2BITS" #endif #ifdef ARM7_ASM " ARM7_ASM" #endif ); } #endif /* ECC_TEST */ static int get_random_bytes(uint8_t* buf, int len) { AJ_RandBytes(buf, len); return 0; } /** * Generates the Ephemeral Diffie-Hellman key pair. * * @param publicKey The output public key * @param privateKey The output private key * * @return - AJ_OK if the key pair is successfully generated. * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_GenerateDHKeyPair(ecc_publickey* publicKey, ecc_privatekey* privateKey) { if (ECDH_generate(publicKey, privateKey) == 0) { return AJ_OK; } return AJ_ERR_SECURITY; } /** * Generates the Diffie-Hellman share secret. * * @param peerPublicKey The peer's public key * @param privateKey The private key * @param secret The output share secret * * @return - AJ_OK if the share secret is successfully generated. * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_GenerateShareSecret(ecc_publickey* peerPublicKey, ecc_privatekey* privateKey, ecc_secret* secret) { boolean_t derive_rv; derive_rv = ECDH_derive_pt(secret, privateKey, peerPublicKey); if (!derive_rv) { return AJ_ERR_SECURITY; /* bad */ } if (derive_rv) { if (!in_curveP(secret)) { return AJ_ERR_SECURITY; /* bad */ } } return AJ_OK; } /** * Generates the DSA key pair. * * @param publicKey The output public key * @param privateKey The output private key * @return - AJ_OK if the key pair is successfully generated * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_GenerateDSAKeyPair(ecc_publickey* publicKey, ecc_privatekey* privateKey) { if (ECDH_generate(publicKey, privateKey) == 0) { return AJ_OK; } return AJ_ERR_SECURITY; } /** * Sign a digest using the DSA key * @param digest The digest to sign * @param signingPrivateKey The signing private key * @param sig The output signature * @return - AJ_OK if the signing process succeeds * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_DSASignDigest(const uint8_t* digest, const ecc_privatekey* signingPrivateKey, ecc_signature* sig) { bigval_t source; ECC_hash_to_bigval(&source, digest, SHA256_DIGEST_LENGTH); if (ECDSA_sign(&source, signingPrivateKey, sig) == 0) { return AJ_OK; } return AJ_ERR_SECURITY; } /** * Sign a buffer using the DSA key * @param buf The buffer to sign * @param len The buffer len * @param signingPrivateKey The signing private key * @param sig The output signature * @return - AJ_OK if the signing process succeeds * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_DSASign(const uint8_t* buf, uint16_t len, const ecc_privatekey* signingPrivateKey, ecc_signature* sig) { AJ_SHA256_Context ctx; uint8_t digest[SHA256_DIGEST_LENGTH]; AJ_SHA256_Init(&ctx); AJ_SHA256_Update(&ctx, (const uint8_t*) buf, (size_t) len); AJ_SHA256_Final(&ctx, digest); return AJ_DSASignDigest(digest, signingPrivateKey, sig); } /** * Verify DSA signature of a digest * @param digest The digest to sign * @param sig The signature * @param pubKey The signing public key * @return - AJ_OK if the signature verification succeeds * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_DSAVerifyDigest(const uint8_t* digest, const ecc_signature* sig, const ecc_publickey* pubKey) { bigval_t source; ECC_hash_to_bigval(&source, digest, SHA256_DIGEST_LENGTH); if (ECDSA_verify(&source, pubKey, sig) == B_TRUE) { return AJ_OK; } return AJ_ERR_SECURITY; } /** * Verify DSA signature of a buffer * @param buf The buffer to sign * @param len The buffer len * @param sig The signature * @param pubKey The signing public key * @return - AJ_OK if the signature verification succeeds * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_DSAVerify(const uint8_t* buf, uint16_t len, const ecc_signature* sig, const ecc_publickey* pubKey) { AJ_SHA256_Context ctx; uint8_t digest[SHA256_DIGEST_LENGTH]; AJ_SHA256_Init(&ctx); AJ_SHA256_Update(&ctx, (const uint8_t*) buf, (size_t) len); AJ_SHA256_Final(&ctx, digest); return AJ_DSAVerifyDigest(digest, sig, pubKey); } ajtcl-15.04b/crypto/ecc/aj_crypto_sha2.c000066400000000000000000000130241256742562600201260ustar00rootroot00000000000000/** * @file aj_crypto_sha2.c * * Class for SHA-256 */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include #include "aj_crypto_sha2.h" #include "aj_util.h" /** * Initialize the hash context * @param context the hash context * @return AJ_OK if successful */ void AJ_SHA256_Init(AJ_SHA256_Context* context) { SHA256_Init(context); } /** * Update the digest using the specific bytes * @param context the hash context * @param buf the bytes to digest * @param bufSize the number of bytes to digest */ void AJ_SHA256_Update(AJ_SHA256_Context* context, const uint8_t* buf, size_t bufSize) { SHA256_Update(context, buf, bufSize); } /** * Retrieve the digest * @param context the hash context * @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH * @param keepAlive keep the digest process alive for continuing digest */ void AJ_SHA256_GetDigest(AJ_SHA256_Context* context, uint8_t* digest, const uint8_t keepAlive) { AJ_SHA256_Context savedCtx; if (keepAlive != 0) { memcpy(&savedCtx, context, sizeof(AJ_SHA256_Context)); } SHA256_Final(digest, context); if (keepAlive != 0) { memcpy(context, &savedCtx, sizeof(AJ_SHA256_Context)); } } /** * Retrieve the final digest * @param context the hash context * @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH */ void AJ_SHA256_Final(AJ_SHA256_Context* context, uint8_t* digest) { AJ_SHA256_GetDigest(context, digest, 0); } AJ_Status AJ_HMAC_SHA256_Init(AJ_HMAC_SHA256_CTX* ctx, const uint8_t* key, size_t keyLen) { int cnt; memset(ctx->ipad, 0, HMAC_SHA256_BLOCK_LENGTH); memset(ctx->opad, 0, HMAC_SHA256_BLOCK_LENGTH); /* if keyLen > 64, hash it and use it as key */ if (keyLen > HMAC_SHA256_BLOCK_LENGTH) { uint8_t digest[SHA256_DIGEST_LENGTH]; AJ_SHA256_Init(&ctx->hashCtx); AJ_SHA256_Update(&ctx->hashCtx, key, keyLen); AJ_SHA256_Final(&ctx->hashCtx, digest); keyLen = SHA256_DIGEST_LENGTH; memcpy(ctx->ipad, digest, SHA256_DIGEST_LENGTH); memcpy(ctx->opad, digest, SHA256_DIGEST_LENGTH); } else { memcpy(ctx->ipad, key, keyLen); memcpy(ctx->opad, key, keyLen); } /* * the HMAC_SHA256 process * * SHA256(K XOR opad, SHA256(K XOR ipad, msg)) * * K is the key * ipad is filled with 0x36 * opad is filled with 0x5c * msg is the message */ /* * prepare inner hash SHA256(K XOR ipad, msg) * K XOR ipad */ for (cnt = 0; cnt < HMAC_SHA256_BLOCK_LENGTH; cnt++) { ctx->ipad[cnt] ^= 0x36; } AJ_SHA256_Init(&ctx->hashCtx); AJ_SHA256_Update(&ctx->hashCtx, ctx->ipad, HMAC_SHA256_BLOCK_LENGTH); return AJ_OK; } AJ_Status AJ_HMAC_SHA256_Update(AJ_HMAC_SHA256_CTX* ctx, const uint8_t* data, size_t dataLen) { AJ_SHA256_Update(&ctx->hashCtx, data, dataLen); return AJ_OK; } AJ_Status AJ_HMAC_SHA256_Final(AJ_HMAC_SHA256_CTX* ctx, uint8_t* digest) { int cnt; /* complete inner hash SHA256(K XOR ipad, msg) */ AJ_SHA256_Final(&ctx->hashCtx, digest); /* * perform outer hash SHA256(K XOR opad, SHA256(K XOR ipad, msg)) */ for (cnt = 0; cnt < HMAC_SHA256_BLOCK_LENGTH; cnt++) { ctx->opad[cnt] ^= 0x5c; } AJ_SHA256_Init(&ctx->hashCtx); AJ_SHA256_Update(&ctx->hashCtx, ctx->opad, HMAC_SHA256_BLOCK_LENGTH); AJ_SHA256_Update(&ctx->hashCtx, digest, SHA256_DIGEST_LENGTH); AJ_SHA256_Final(&ctx->hashCtx, digest); return AJ_OK; } AJ_Status AJ_Crypto_PRF_SHA256(const uint8_t** inputs, const uint8_t* lengths, uint32_t count, uint8_t* out, uint32_t outLen) { uint32_t cnt; AJ_HMAC_SHA256_CTX msgHash; uint8_t digest[SHA256_DIGEST_LENGTH]; uint32_t len = 0; if (count < 2) { return AJ_ERR_INVALID; } while (outLen) { /* * Initialize SHA256 in HMAC mode with the secret */ AJ_HMAC_SHA256_Init(&msgHash, inputs[0], lengths[0]); /* * If this is not the first iteration hash in the digest from the previous iteration. */ if (len) { AJ_HMAC_SHA256_Update(&msgHash, digest, sizeof(digest)); } for (cnt = 1; cnt < count; cnt++) { AJ_HMAC_SHA256_Update(&msgHash, inputs[cnt], lengths[cnt]); } AJ_HMAC_SHA256_Final(&msgHash, digest); if (outLen < sizeof(digest)) { len = outLen; } else { len = sizeof(digest); } memcpy(out, digest, len); outLen -= len; out += len; } return AJ_OK; } ajtcl-15.04b/external/000077500000000000000000000000001256742562600146235ustar00rootroot00000000000000ajtcl-15.04b/external/sha2/000077500000000000000000000000001256742562600154605ustar00rootroot00000000000000ajtcl-15.04b/external/sha2/sha2.c000066400000000000000000001012051256742562600164600ustar00rootroot00000000000000/* * FILE: sha2.c * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ * * Copyright (c) 2000-2001, Aaron D. Gifford * 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. Neither the name of the copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 THE AUTHOR OR CONTRIBUTOR(S) 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. * */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include /* memcpy()/memset() or bcopy()/bzero() */ #include /* assert() */ #include "sha2.h" /* * ASSERT NOTE: * Some sanity checking code is included using assert(). On my FreeBSD * system, this additional code can be removed by compiling with NDEBUG * defined. Check your own systems manpage on assert() to see how to * compile WITHOUT the sanity checking code on your system. * * UNROLLED TRANSFORM LOOP NOTE: * You can define SHA2_UNROLL_TRANSFORM to use the unrolled transform * loop version for the hash transform rounds (defined using macros * later in this file). Either define on the command line, for example: * * cc -DSHA2_UNROLL_TRANSFORM -o sha2 sha2.c sha2prog.c * * or define below: * * #define SHA2_UNROLL_TRANSFORM * */ /*** SHA-256/384/512 Machine Architecture Definitions *****************/ /* * BYTE_ORDER NOTE: * * Please make sure that your system defines BYTE_ORDER. If your * architecture is little-endian, make sure it also defines * LITTLE_ENDIAN and that the two (BYTE_ORDER and LITTLE_ENDIAN) are * equivilent. * * If your system does not define the above, then you can do so by * hand like this: * * #define LITTLE_ENDIAN 1234 * #define BIG_ENDIAN 4321 * * And for little-endian machines, add: * * #define BYTE_ORDER LITTLE_ENDIAN * * Or for big-endian machines: * * #define BYTE_ORDER BIG_ENDIAN * * The FreeBSD machine this was written on defines BYTE_ORDER * appropriately by including (which in turn includes * where the appropriate definitions are actually * made). */ #if !defined(BYTE_ORDER) || (BYTE_ORDER != LITTLE_ENDIAN && BYTE_ORDER != BIG_ENDIAN) #define LITTLE_ENDIAN 1234 #define BIG_ENDIAN 4321 #if HOST_IS_LITTLE_ENDIAN #define BYTE_ORDER LITTLE_ENDIAN #else #define BYTE_ORDER BIG_ENDIAN #endif #endif /* * Define the followingsha2_* types to types of the correct length on * the native archtecture. Most BSD systems and Linux define u_intXX_t * types. Machines with very recent ANSI C headers, can use the * uintXX_t definintions from inttypes.h by defining SHA2_USE_INTTYPES_H * during compile or in the sha.h header file. * * Machines that support neither u_intXX_t nor inttypes.h's uintXX_t * will need to define these three typedefs below (and the appropriate * ones in sha.h too) by hand according to their system architecture. * * Thank you, Jun-ichiro itojun Hagino, for suggesting using u_intXX_t * types and pointing out recent ANSI C support for uintXX_t in inttypes.h. */ #ifdef SHA2_USE_INTTYPES_H typedef uint8_t sha2_byte; /* Exactly 1 byte */ typedef uint32_t sha2_word32; /* Exactly 4 bytes */ typedef uint64_t sha2_word64; /* Exactly 8 bytes */ #else /* SHA2_USE_INTTYPES_H */ typedef u_int8_t sha2_byte; /* Exactly 1 byte */ typedef u_int32_t sha2_word32; /* Exactly 4 bytes */ typedef u_int64_t sha2_word64; /* Exactly 8 bytes */ #endif /* SHA2_USE_INTTYPES_H */ /*** SHA-256/384/512 Various Length Definitions ***********************/ /* NOTE: Most of these are in sha2.h */ #define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) #define SHA384_SHORT_BLOCK_LENGTH (SHA384_BLOCK_LENGTH - 16) #define SHA512_SHORT_BLOCK_LENGTH (SHA512_BLOCK_LENGTH - 16) /*** ENDIAN REVERSAL MACROS *******************************************/ #if BYTE_ORDER == LITTLE_ENDIAN #if !defined(ALIGNED_ACCESS_REQUIRED) #define REVERSE32(w,x) { \ sha2_word32 tmp = (w); \ tmp = (tmp >> 16) | (tmp << 16); \ (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ } #else #define REVERSE32(w,x) { \ sha2_byte *b = (sha2_byte*) &w; \ sha2_word32 tmp = 0; \ tmp = ((sha2_word32)*b++); \ tmp = (tmp << 8) | ((sha2_word32)*b++); \ tmp = (tmp << 8) | ((sha2_word32)*b++); \ tmp = (tmp << 8) | ((sha2_word32)*b++); \ (x) = tmp; \ } #endif /* ALIGNED_ACCESS_REQUIRED */ #define REVERSE64(w,x) { \ sha2_word64 tmp = (w); \ tmp = (tmp >> 32) | (tmp << 32); \ tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ ((tmp & 0x0000ffff0000ffffULL) << 16); \ } #endif /* BYTE_ORDER == LITTLE_ENDIAN */ /* * Macro for incrementally adding the unsigned 64-bit integer n to the * unsigned 128-bit integer (represented using a two-element array of * 64-bit words): */ #define ADDINC128(w,n) { \ (w)[0] += (sha2_word64)(n); \ if ((w)[0] < (n)) { \ (w)[1]++; \ } \ } /* * Macros for copying blocks of memory and for zeroing out ranges * of memory. Using these macros makes it easy to switch from * using memset()/memcpy() and using bzero()/bcopy(). * * Please define either SHA2_USE_MEMSET_MEMCPY or define * SHA2_USE_BZERO_BCOPY depending on which function set you * choose to use: */ #if !defined(SHA2_USE_MEMSET_MEMCPY) && !defined(SHA2_USE_BZERO_BCOPY) /* Default to memset()/memcpy() if no option is specified */ #define SHA2_USE_MEMSET_MEMCPY 1 #endif #if defined(SHA2_USE_MEMSET_MEMCPY) && defined(SHA2_USE_BZERO_BCOPY) /* Abort with an error if BOTH options are defined */ #error Define either SHA2_USE_MEMSET_MEMCPY or SHA2_USE_BZERO_BCOPY, not both! #endif #ifdef SHA2_USE_MEMSET_MEMCPY #define MEMSET_BZERO(p,l) memset((p), 0, (l)) #define MEMCPY_BCOPY(d,s,l) memcpy((d), (s), (l)) #endif #ifdef SHA2_USE_BZERO_BCOPY #define MEMSET_BZERO(p,l) bzero((p), (l)) #define MEMCPY_BCOPY(d,s,l) bcopy((s), (d), (l)) #endif /*** THE SIX LOGICAL FUNCTIONS ****************************************/ /* * Bit shifting and rotation (used by the six SHA-XYZ logical functions: * * NOTE: The naming of R and S appears backwards here (R is a SHIFT and * S is a ROTATION) because the SHA-256/384/512 description document * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this * same "backwards" definition. */ /* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ #define R(b,x) ((x) >> (b)) /* 32-bit Rotate-right (used in SHA-256): */ #define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) /* 64-bit Rotate-right (used in SHA-384 and SHA-512): */ #define S64(b,x) (((x) >> (b)) | ((x) << (64 - (b)))) /* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ #define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) #define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) /* Four of six logical functions used in SHA-256: */ #define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) #define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) #define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) #define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) /* Four of six logical functions used in SHA-384 and SHA-512: */ #define Sigma0_512(x) (S64(28, (x)) ^ S64(34, (x)) ^ S64(39, (x))) #define Sigma1_512(x) (S64(14, (x)) ^ S64(18, (x)) ^ S64(41, (x))) #define sigma0_512(x) (S64( 1, (x)) ^ S64( 8, (x)) ^ R( 7, (x))) #define sigma1_512(x) (S64(19, (x)) ^ S64(61, (x)) ^ R( 6, (x))) /*** INTERNAL FUNCTION PROTOTYPES *************************************/ /* NOTE: These should not be accessed directly from outside this * library -- they are intended for private internal visibility/use * only. */ void SHA512_Last(SHA512_CTX*); void SHA256_Transform(SHA256_CTX*, const sha2_word32*); void SHA512_Transform(SHA512_CTX*, const sha2_word64*); /*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ /* Hash constant words K for SHA-256: */ const static sha2_word32 K256[64] = { 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL }; /* Initial hash value H for SHA-256: */ const static sha2_word32 sha256_initial_hash_value[8] = { 0x6a09e667UL, 0xbb67ae85UL, 0x3c6ef372UL, 0xa54ff53aUL, 0x510e527fUL, 0x9b05688cUL, 0x1f83d9abUL, 0x5be0cd19UL }; /* Hash constant words K for SHA-384 and SHA-512: */ const static sha2_word64 K512[80] = { 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL }; /* Initial hash value H for SHA-384 */ const static sha2_word64 sha384_initial_hash_value[8] = { 0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL, 0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL, 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL }; /* Initial hash value H for SHA-512 */ const static sha2_word64 sha512_initial_hash_value[8] = { 0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL, 0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL }; /* * Constant used by SHA256/384/512_End() functions for converting the * digest to a readable hexadecimal character string: */ static const char *sha2_hex_digits = "0123456789abcdef"; /*** SHA-256: *********************************************************/ void SHA256_Init(SHA256_CTX* context) { if (context == (SHA256_CTX*)0) { return; } MEMCPY_BCOPY(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); MEMSET_BZERO(context->buffer, SHA256_BLOCK_LENGTH); context->bitcount = 0; } #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-256 round macros: */ #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ REVERSE32(*data++, W256[j]); \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + W256[j]; \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ K256[j] + (W256[j] = *data++); \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND256(a,b,c,d,e,f,g,h) \ s0 = W256[(j+1)&0x0f]; \ s0 = sigma0_256(s0); \ s1 = W256[(j+14)&0x0f]; \ s1 = sigma1_256(s1); \ T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ (d) += T1; \ (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ j++ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { sha2_word32 a, b, c, d, e, f, g, h, s0, s1; sha2_word32 T1, *W256; int j; W256 = (sha2_word32*)context->buffer; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { /* Rounds 0 to 15 (unrolled): */ ROUND256_0_TO_15(a,b,c,d,e,f,g,h); ROUND256_0_TO_15(h,a,b,c,d,e,f,g); ROUND256_0_TO_15(g,h,a,b,c,d,e,f); ROUND256_0_TO_15(f,g,h,a,b,c,d,e); ROUND256_0_TO_15(e,f,g,h,a,b,c,d); ROUND256_0_TO_15(d,e,f,g,h,a,b,c); ROUND256_0_TO_15(c,d,e,f,g,h,a,b); ROUND256_0_TO_15(b,c,d,e,f,g,h,a); } while (j < 16); /* Now for the remaining rounds to 64: */ do { ROUND256(a,b,c,d,e,f,g,h); ROUND256(h,a,b,c,d,e,f,g); ROUND256(g,h,a,b,c,d,e,f); ROUND256(f,g,h,a,b,c,d,e); ROUND256(e,f,g,h,a,b,c,d); ROUND256(d,e,f,g,h,a,b,c); ROUND256(c,d,e,f,g,h,a,b); ROUND256(b,c,d,e,f,g,h,a); } while (j < 64); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) { sha2_word32 a, b, c, d, e, f, g, h, s0, s1; sha2_word32 T1, T2, *W256; int j; W256 = (sha2_word32*)context->buffer; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { #if BYTE_ORDER == LITTLE_ENDIAN /* Copy data while converting to host byte order */ REVERSE32(*data++,W256[j]); /* Apply the SHA-256 compression function to update a..h */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + W256[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ /* Apply the SHA-256 compression function to update a..h with copy */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ T2 = Sigma0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 16); do { /* Part of the message block expansion: */ s0 = W256[(j+1)&0x0f]; s0 = sigma0_256(s0); s1 = W256[(j+14)&0x0f]; s1 = sigma1_256(s1); /* Apply the SHA-256 compression function to update a..h */ T1 = h + Sigma1_256(e) + Ch(e, f, g) + K256[j] + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); T2 = Sigma0_256(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 64); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA256_Update(SHA256_CTX* context, const sha2_byte *data, size_t len) { unsigned int freespace, usedspace; if (len == 0) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ assert(context != (SHA256_CTX*)0 && data != (sha2_byte*)0); usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA256_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); context->bitcount += freespace << 3; len -= freespace; data += freespace; SHA256_Transform(context, (sha2_word32*)context->buffer); } else { /* The buffer is not yet full */ MEMCPY_BCOPY(&context->buffer[usedspace], data, len); context->bitcount += len << 3; /* Clean up: */ usedspace = freespace = 0; return; } } while (len >= SHA256_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ SHA256_Transform(context, (sha2_word32*)data); context->bitcount += SHA256_BLOCK_LENGTH << 3; len -= SHA256_BLOCK_LENGTH; data += SHA256_BLOCK_LENGTH; } if (len > 0) { /* There's left-overs, so save 'em */ MEMCPY_BCOPY(context->buffer, data, len); context->bitcount += len << 3; } /* Clean up: */ usedspace = freespace = 0; } void SHA256_Final(sha2_byte digest[], SHA256_CTX* context) { sha2_word32 *d = (sha2_word32*)digest; unsigned int usedspace; /* Sanity check: */ assert(context != (SHA256_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount,context->bitcount); #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { /* Set-up for the last transform: */ MEMSET_BZERO(&context->buffer[usedspace], SHA256_SHORT_BLOCK_LENGTH - usedspace); } else { if (usedspace < SHA256_BLOCK_LENGTH) { MEMSET_BZERO(&context->buffer[usedspace], SHA256_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ SHA256_Transform(context, (sha2_word32*)context->buffer); /* And set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); } } else { /* Set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA256_SHORT_BLOCK_LENGTH); /* Begin padding with a 1 bit: */ *context->buffer = 0x80; } /* Set the bit count: */ *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = context->bitcount; /* Final transform: */ SHA256_Transform(context, (sha2_word32*)context->buffer); #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 8; j++) { REVERSE32(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else MEMCPY_BCOPY(d, context->state, SHA256_DIGEST_LENGTH); #endif } /* Clean up state data: */ MEMSET_BZERO(context, sizeof(SHA256_CTX)); usedspace = 0; } char *SHA256_End(SHA256_CTX* context, char buffer[]) { sha2_byte digest[SHA256_DIGEST_LENGTH], *d = digest; int i; /* Sanity check: */ assert(context != (SHA256_CTX*)0); if (buffer != (char*)0) { SHA256_Final(digest, context); for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { MEMSET_BZERO(context, sizeof(SHA256_CTX)); } MEMSET_BZERO(digest, SHA256_DIGEST_LENGTH); return buffer; } char* SHA256_Data(const sha2_byte* data, size_t len, char digest[SHA256_DIGEST_STRING_LENGTH]) { SHA256_CTX context; SHA256_Init(&context); SHA256_Update(&context, data, len); return SHA256_End(&context, digest); } /*** SHA-512: *********************************************************/ void SHA512_Init(SHA512_CTX* context) { if (context == (SHA512_CTX*)0) { return; } MEMCPY_BCOPY(context->state, sha512_initial_hash_value, SHA512_DIGEST_LENGTH); MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH); context->bitcount[0] = context->bitcount[1] = 0; } #ifdef SHA2_UNROLL_TRANSFORM /* Unrolled SHA-512 round macros: */ #if BYTE_ORDER == LITTLE_ENDIAN #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ REVERSE64(*data++, W512[j]); \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + W512[j]; \ (d) += T1, \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)), \ j++ #else /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512_0_TO_15(a,b,c,d,e,f,g,h) \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + \ K512[j] + (W512[j] = *data++); \ (d) += T1; \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ j++ #endif /* BYTE_ORDER == LITTLE_ENDIAN */ #define ROUND512(a,b,c,d,e,f,g,h) \ s0 = W512[(j+1)&0x0f]; \ s0 = sigma0_512(s0); \ s1 = W512[(j+14)&0x0f]; \ s1 = sigma1_512(s1); \ T1 = (h) + Sigma1_512(e) + Ch((e), (f), (g)) + K512[j] + \ (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); \ (d) += T1; \ (h) = T1 + Sigma0_512(a) + Maj((a), (b), (c)); \ j++ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { sha2_word64 a, b, c, d, e, f, g, h, s0, s1; sha2_word64 T1, *W512 = (sha2_word64*)context->buffer; int j; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { ROUND512_0_TO_15(a,b,c,d,e,f,g,h); ROUND512_0_TO_15(h,a,b,c,d,e,f,g); ROUND512_0_TO_15(g,h,a,b,c,d,e,f); ROUND512_0_TO_15(f,g,h,a,b,c,d,e); ROUND512_0_TO_15(e,f,g,h,a,b,c,d); ROUND512_0_TO_15(d,e,f,g,h,a,b,c); ROUND512_0_TO_15(c,d,e,f,g,h,a,b); ROUND512_0_TO_15(b,c,d,e,f,g,h,a); } while (j < 16); /* Now for the remaining rounds up to 79: */ do { ROUND512(a,b,c,d,e,f,g,h); ROUND512(h,a,b,c,d,e,f,g); ROUND512(g,h,a,b,c,d,e,f); ROUND512(f,g,h,a,b,c,d,e); ROUND512(e,f,g,h,a,b,c,d); ROUND512(d,e,f,g,h,a,b,c); ROUND512(c,d,e,f,g,h,a,b); ROUND512(b,c,d,e,f,g,h,a); } while (j < 80); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = 0; } #else /* SHA2_UNROLL_TRANSFORM */ void SHA512_Transform(SHA512_CTX* context, const sha2_word64* data) { sha2_word64 a, b, c, d, e, f, g, h, s0, s1; sha2_word64 T1, T2, *W512 = (sha2_word64*)context->buffer; int j; /* Initialize registers with the prev. intermediate value */ a = context->state[0]; b = context->state[1]; c = context->state[2]; d = context->state[3]; e = context->state[4]; f = context->state[5]; g = context->state[6]; h = context->state[7]; j = 0; do { #if BYTE_ORDER == LITTLE_ENDIAN /* Convert TO host byte order */ REVERSE64(*data++, W512[j]); /* Apply the SHA-512 compression function to update a..h */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + W512[j]; #else /* BYTE_ORDER == LITTLE_ENDIAN */ /* Apply the SHA-512 compression function to update a..h with copy */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j] = *data++); #endif /* BYTE_ORDER == LITTLE_ENDIAN */ T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 16); do { /* Part of the message block expansion: */ s0 = W512[(j+1)&0x0f]; s0 = sigma0_512(s0); s1 = W512[(j+14)&0x0f]; s1 = sigma1_512(s1); /* Apply the SHA-512 compression function to update a..h */ T1 = h + Sigma1_512(e) + Ch(e, f, g) + K512[j] + (W512[j&0x0f] += s1 + W512[(j+9)&0x0f] + s0); T2 = Sigma0_512(a) + Maj(a, b, c); h = g; g = f; f = e; e = d + T1; d = c; c = b; b = a; a = T1 + T2; j++; } while (j < 80); /* Compute the current intermediate hash value */ context->state[0] += a; context->state[1] += b; context->state[2] += c; context->state[3] += d; context->state[4] += e; context->state[5] += f; context->state[6] += g; context->state[7] += h; /* Clean up */ a = b = c = d = e = f = g = h = T1 = T2 = 0; } #endif /* SHA2_UNROLL_TRANSFORM */ void SHA512_Update(SHA512_CTX* context, const sha2_byte *data, size_t len) { unsigned int freespace, usedspace; if (len == 0) { /* Calling with no data is valid - we do nothing */ return; } /* Sanity check: */ assert(context != (SHA512_CTX*)0 && data != (sha2_byte*)0); usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; if (usedspace > 0) { /* Calculate how much free space is available in the buffer */ freespace = SHA512_BLOCK_LENGTH - usedspace; if (len >= freespace) { /* Fill the buffer completely and process it */ MEMCPY_BCOPY(&context->buffer[usedspace], data, freespace); ADDINC128(context->bitcount, freespace << 3); len -= freespace; data += freespace; SHA512_Transform(context, (sha2_word64*)context->buffer); } else { /* The buffer is not yet full */ MEMCPY_BCOPY(&context->buffer[usedspace], data, len); ADDINC128(context->bitcount, len << 3); /* Clean up: */ usedspace = freespace = 0; return; } } while (len >= SHA512_BLOCK_LENGTH) { /* Process as many complete blocks as we can */ SHA512_Transform(context, (sha2_word64*)data); ADDINC128(context->bitcount, SHA512_BLOCK_LENGTH << 3); len -= SHA512_BLOCK_LENGTH; data += SHA512_BLOCK_LENGTH; } if (len > 0) { /* There's left-overs, so save 'em */ MEMCPY_BCOPY(context->buffer, data, len); ADDINC128(context->bitcount, len << 3); } /* Clean up: */ usedspace = freespace = 0; } void SHA512_Last(SHA512_CTX* context) { unsigned int usedspace; usedspace = (context->bitcount[0] >> 3) % SHA512_BLOCK_LENGTH; #if BYTE_ORDER == LITTLE_ENDIAN /* Convert FROM host byte order */ REVERSE64(context->bitcount[0],context->bitcount[0]); REVERSE64(context->bitcount[1],context->bitcount[1]); #endif if (usedspace > 0) { /* Begin padding with a 1 bit: */ context->buffer[usedspace++] = 0x80; if (usedspace <= SHA512_SHORT_BLOCK_LENGTH) { /* Set-up for the last transform: */ MEMSET_BZERO(&context->buffer[usedspace], SHA512_SHORT_BLOCK_LENGTH - usedspace); } else { if (usedspace < SHA512_BLOCK_LENGTH) { MEMSET_BZERO(&context->buffer[usedspace], SHA512_BLOCK_LENGTH - usedspace); } /* Do second-to-last transform: */ SHA512_Transform(context, (sha2_word64*)context->buffer); /* And set-up for the last transform: */ MEMSET_BZERO(context->buffer, SHA512_BLOCK_LENGTH - 2); } } else { /* Prepare for final transform: */ MEMSET_BZERO(context->buffer, SHA512_SHORT_BLOCK_LENGTH); /* Begin padding with a 1 bit: */ *context->buffer = 0x80; } /* Store the length of input data (in bits): */ *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH] = context->bitcount[1]; *(sha2_word64*)&context->buffer[SHA512_SHORT_BLOCK_LENGTH+8] = context->bitcount[0]; /* Final transform: */ SHA512_Transform(context, (sha2_word64*)context->buffer); } void SHA512_Final(sha2_byte digest[], SHA512_CTX* context) { sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ assert(context != (SHA512_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { SHA512_Last(context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 8; j++) { REVERSE64(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else MEMCPY_BCOPY(d, context->state, SHA512_DIGEST_LENGTH); #endif } /* Zero out state data */ MEMSET_BZERO(context, sizeof(SHA512_CTX)); } char *SHA512_End(SHA512_CTX* context, char buffer[]) { sha2_byte digest[SHA512_DIGEST_LENGTH], *d = digest; int i; /* Sanity check: */ assert(context != (SHA512_CTX*)0); if (buffer != (char*)0) { SHA512_Final(digest, context); for (i = 0; i < SHA512_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { MEMSET_BZERO(context, sizeof(SHA512_CTX)); } MEMSET_BZERO(digest, SHA512_DIGEST_LENGTH); return buffer; } char* SHA512_Data(const sha2_byte* data, size_t len, char digest[SHA512_DIGEST_STRING_LENGTH]) { SHA512_CTX context; SHA512_Init(&context); SHA512_Update(&context, data, len); return SHA512_End(&context, digest); } /*** SHA-384: *********************************************************/ void SHA384_Init(SHA384_CTX* context) { if (context == (SHA384_CTX*)0) { return; } MEMCPY_BCOPY(context->state, sha384_initial_hash_value, SHA512_DIGEST_LENGTH); MEMSET_BZERO(context->buffer, SHA384_BLOCK_LENGTH); context->bitcount[0] = context->bitcount[1] = 0; } void SHA384_Update(SHA384_CTX* context, const sha2_byte* data, size_t len) { SHA512_Update((SHA512_CTX*)context, data, len); } void SHA384_Final(sha2_byte digest[], SHA384_CTX* context) { sha2_word64 *d = (sha2_word64*)digest; /* Sanity check: */ assert(context != (SHA384_CTX*)0); /* If no digest buffer is passed, we don't bother doing this: */ if (digest != (sha2_byte*)0) { SHA512_Last((SHA512_CTX*)context); /* Save the hash data for output: */ #if BYTE_ORDER == LITTLE_ENDIAN { /* Convert TO host byte order */ int j; for (j = 0; j < 6; j++) { REVERSE64(context->state[j],context->state[j]); *d++ = context->state[j]; } } #else MEMCPY_BCOPY(d, context->state, SHA384_DIGEST_LENGTH); #endif } /* Zero out state data */ MEMSET_BZERO(context, sizeof(SHA384_CTX)); } char *SHA384_End(SHA384_CTX* context, char buffer[]) { sha2_byte digest[SHA384_DIGEST_LENGTH], *d = digest; int i; /* Sanity check: */ assert(context != (SHA384_CTX*)0); if (buffer != (char*)0) { SHA384_Final(digest, context); for (i = 0; i < SHA384_DIGEST_LENGTH; i++) { *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; *buffer++ = sha2_hex_digits[*d & 0x0f]; d++; } *buffer = (char)0; } else { MEMSET_BZERO(context, sizeof(SHA384_CTX)); } MEMSET_BZERO(digest, SHA384_DIGEST_LENGTH); return buffer; } char* SHA384_Data(const sha2_byte* data, size_t len, char digest[SHA384_DIGEST_STRING_LENGTH]) { SHA384_CTX context; SHA384_Init(&context); SHA384_Update(&context, data, len); return SHA384_End(&context, digest); } ajtcl-15.04b/external/sha2/sha2.h000066400000000000000000000137461256742562600165010ustar00rootroot00000000000000/* * FILE: sha2.h * AUTHOR: Aaron D. Gifford - http://www.aarongifford.com/ * * Copyright (c) 2000-2001, Aaron D. Gifford * 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. Neither the name of the copyright holder nor the names of contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTOR(S) ``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 THE AUTHOR OR CONTRIBUTOR(S) 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. * * $Id: sha2.h,v 1.1 2001/11/08 00:02:01 adg Exp adg $ */ #ifndef __SHA2_H__ #define __SHA2_H__ #define SHA2_USE_INTTYPES_H #include "aj_target.h" /*** SHA-256/384/512 Various Length Definitions ***********************/ #define SHA256_BLOCK_LENGTH 64 #define SHA256_DIGEST_LENGTH 32 #define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) #define SHA384_BLOCK_LENGTH 128 #define SHA384_DIGEST_LENGTH 48 #define SHA384_DIGEST_STRING_LENGTH (SHA384_DIGEST_LENGTH * 2 + 1) #define SHA512_BLOCK_LENGTH 128 #define SHA512_DIGEST_LENGTH 64 #define SHA512_DIGEST_STRING_LENGTH (SHA512_DIGEST_LENGTH * 2 + 1) /*** SHA-256/384/512 Context Structures *******************************/ /* NOTE: If your architecture does not define either u_intXX_t types or * uintXX_t (from inttypes.h), you may need to define things by hand * for your system: */ #if 0 typedef unsigned char u_int8_t; /* 1-byte (8-bits) */ typedef unsigned int u_int32_t; /* 4-bytes (32-bits) */ typedef unsigned long long u_int64_t; /* 8-bytes (64-bits) */ #endif /* * Most BSD systems already define u_intXX_t types, as does Linux. * Some systems, however, like Compaq's Tru64 Unix instead can use * uintXX_t types defined by very recent ANSI C standards and included * in the file: * * #include * * If you choose to use then please define: * * #define SHA2_USE_INTTYPES_H * * Or on the command line during compile: * * cc -DSHA2_USE_INTTYPES_H ... */ #ifdef SHA2_USE_INTTYPES_H typedef struct _SHA256_CTX { uint32_t state[8]; uint64_t bitcount; uint8_t buffer[SHA256_BLOCK_LENGTH]; } SHA256_CTX; typedef struct _SHA512_CTX { uint64_t state[8]; uint64_t bitcount[2]; uint8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; #else /* SHA2_USE_INTTYPES_H */ typedef struct _SHA256_CTX { u_int32_t state[8]; u_int64_t bitcount; u_int8_t buffer[SHA256_BLOCK_LENGTH]; } SHA256_CTX; typedef struct _SHA512_CTX { u_int64_t state[8]; u_int64_t bitcount[2]; u_int8_t buffer[SHA512_BLOCK_LENGTH]; } SHA512_CTX; #endif /* SHA2_USE_INTTYPES_H */ typedef SHA512_CTX SHA384_CTX; /*** SHA-256/384/512 Function Prototypes ******************************/ #ifndef NOPROTO #ifdef SHA2_USE_INTTYPES_H void SHA256_Init(SHA256_CTX *); void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); char* SHA256_Data(const uint8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); void SHA384_Init(SHA384_CTX*); void SHA384_Update(SHA384_CTX*, const uint8_t*, size_t); void SHA384_Final(uint8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); char* SHA384_Data(const uint8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); void SHA512_Init(SHA512_CTX*); void SHA512_Update(SHA512_CTX*, const uint8_t*, size_t); void SHA512_Final(uint8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); char* SHA512_Data(const uint8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); #else /* SHA2_USE_INTTYPES_H */ void SHA256_Init(SHA256_CTX *); void SHA256_Update(SHA256_CTX*, const u_int8_t*, size_t); void SHA256_Final(u_int8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); char* SHA256_End(SHA256_CTX*, char[SHA256_DIGEST_STRING_LENGTH]); char* SHA256_Data(const u_int8_t*, size_t, char[SHA256_DIGEST_STRING_LENGTH]); void SHA384_Init(SHA384_CTX*); void SHA384_Update(SHA384_CTX*, const u_int8_t*, size_t); void SHA384_Final(u_int8_t[SHA384_DIGEST_LENGTH], SHA384_CTX*); char* SHA384_End(SHA384_CTX*, char[SHA384_DIGEST_STRING_LENGTH]); char* SHA384_Data(const u_int8_t*, size_t, char[SHA384_DIGEST_STRING_LENGTH]); void SHA512_Init(SHA512_CTX*); void SHA512_Update(SHA512_CTX*, const u_int8_t*, size_t); void SHA512_Final(u_int8_t[SHA512_DIGEST_LENGTH], SHA512_CTX*); char* SHA512_End(SHA512_CTX*, char[SHA512_DIGEST_STRING_LENGTH]); char* SHA512_Data(const u_int8_t*, size_t, char[SHA512_DIGEST_STRING_LENGTH]); #endif /* SHA2_USE_INTTYPES_H */ #else /* NOPROTO */ void SHA256_Init(); void SHA256_Update(); void SHA256_Final(); char* SHA256_End(); char* SHA256_Data(); void SHA384_Init(); void SHA384_Update(); void SHA384_Final(); char* SHA384_End(); char* SHA384_Data(); void SHA512_Init(); void SHA512_Update(); void SHA512_Final(); char* SHA512_End(); char* SHA512_Data(); #endif /* NOPROTO */ #endif /* __SHA2_H__ */ ajtcl-15.04b/footer.html000066400000000000000000000024201256742562600151630ustar00rootroot00000000000000
$projectname $projectnumber ($datetime)
Copyright AllSeen Alliance, Inc. All Rights Reserved.
AllSeen, AllSeen Alliance, and AllJoyn are trademarks of the AllSeen Alliance, Inc in the United States and other jurisdictions.
THIS DOCUMENT AND ALL INFORMATION CONTAIN HEREIN ARE PROVIDED ON AN "AS-IS" BASIS WITHOUT WARRANTY OF ANY KIND.
MAY CONTAIN U.S. AND INTERNATIONAL EXPORT CONTROLLED INFORMATION
ajtcl-15.04b/inc/000077500000000000000000000000001256742562600135525ustar00rootroot00000000000000ajtcl-15.04b/inc/aj_about.h000066400000000000000000000361531256742562600155170ustar00rootroot00000000000000#ifndef _AJ_ABOUT_H #define _AJ_ABOUT_H /** * @file aj_about.h * @defgroup aj_about Bus Attachment * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_status.h" #include "aj_util.h" #include "aj_config.h" #ifdef __cplusplus extern "C" { #endif /** * Prototype for a function provided by the property store for getting ANNOUNCE and ABOUT properties * * @param reply The message to marshal the property values into. The getter can also figure out * from the msgId in the reply message if the reply is for ANNOUNCE or ABOUT. * * @param language The language to use to return the string properties. If this is NULL the default * language will be used. * * @return Return AJ_OK if the properties were succesfully marshaled into the reply. * */ typedef AJ_Status (*AJ_AboutPropGetter)(AJ_Message* reply, const char* language); /** * Called by the property store to register the about property getter. Functionality will be limited * if there is not property store. * * @param propGetter The property getter function being registered. */ void AJ_AboutRegisterPropStoreGetter(AJ_AboutPropGetter propGetter); /** * Initialize About and send the initial announcement. * * @param bus The bus attachment * @param boundPort Session port the application has bound */ AJ_Status AJ_AboutInit(AJ_BusAttachment* bus, uint16_t boundPort); /** * Emit an announcement if one has been scheduled. * * @param bus The bus attachment context. */ AJ_Status AJ_AboutAnnounce(AJ_BusAttachment* bus); /** * Cancel an about announcement * * @param bus The bus attachment context * * @return AJ_OK if canceled successfully */ AJ_Status AJ_AboutUnannounce(AJ_BusAttachment* bus); /** * Set a device icon to be returned by About * * @param icon Pointer to the icon data blob. This pointer must remain live until the next time this * function is called. Can be NULL if there is not icon data. * @param size The size of the icon data blob. * @param mime The mime type for the icon * @param url Optional URL for an icon */ void AJ_AboutSetIcon(const uint8_t* icon, uint16_t size, const char* mimeType, const char* url); /** * Handle a GET_PROP method call * * @param msg The GET_PROP message * * @return Return AJ_Status * - AJ_OK if successfully handled * - AJ_ERR_WRITE if there was a write failure */ AJ_Status AJ_AboutHandleGetProp(AJ_Message* msg); /** * Handle a GET_ABOUT_DATA method call * * @param msg The GET_ABOUT_DATA message * @param reply The GET_ABOUT_DATA reply message * * @return Return AJ_Status * - AJ_OK if successfully handled * - AJ_ERR_WRITE if there was a write failure */ AJ_Status AJ_AboutHandleGetAboutData(AJ_Message* msg, AJ_Message* reply); /** * Handle a GET_ABOUT_OBJECT_DESCRIPTION method call * * @param msg The GET_ABOUT_OBJECT_DESCRIPTION message * @param reply The GET_ABOUT_OBJECT_DESCRIPTION reply message * * @return Return AJ_Status * - AJ_OK if successfully handled * - AJ_ERR_WRITE if there was a write failure */ AJ_Status AJ_AboutHandleGetObjectDescription(AJ_Message* msg, AJ_Message* reply); /** * Handle a GET_PROP method call * * @param msg The GET_PROP message * * @return Return AJ_Status * - AJ_OK if successfully handled * - AJ_ERR_WRITE if there was a write failure */ AJ_Status AJ_AboutIconHandleGetProp(AJ_Message* msg); /** * Handle a GET_ABOUT_ICON_GET_URL method call * * @param msg The GET_ABOUT_ICON_GET_URL message * @param reply The GET_ABOUT_ICON_GET_URL reply message * * @return Return AJ_Status * - AJ_OK if successfully handled * - AJ_ERR_WRITE if there was a write failure */ AJ_Status AJ_AboutIconHandleGetURL(AJ_Message* msg, AJ_Message* reply); /** * Handle a GET_ABOUT_ICON_GET_CONTENT method call * * @param msg The GET_ABOUT_ICON_GET_CONTENT message * @param reply The GET_ABOUT_ICON_GET_CONTENT reply message * * @return Return AJ_Status * - AJ_OK if successfully handled * - AJ_ERR_WRITE if there was a write failure */ AJ_Status AJ_AboutIconHandleGetContent(AJ_Message* msg, AJ_Message* reply); /** * Function called by the application and other services when there are changes that warrant sending * of a new announcement. The announce condition is cleared after all AJ_AboutAnnounce() is called. */ void AJ_AboutSetShouldAnnounce(); /** * Sets the announce flag on a list of objects * * @param objList The object list to set. */ void AJ_AboutSetAnnounceObjects(AJ_Object* objList); #ifdef ANNOUNCE_BASED_DISCOVERY /** * Type for received object description * * This structure is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ typedef struct _AJ_AboutObjectDescription { const char* path; /**< the object path in an Announcement's ObjectDescription */ const char* interfaces[AJ_MAX_NUM_OF_INTERFACES]; /**< array of interface names in an Announcement's ObjectDescription */ uint8_t interfacesCount; /**< number of interface names in an Announcement's ObjectDescription */ } AJ_AboutObjectDescription; /** * Unmarshal an Announcement message ObjectDescription section. * * @param announcement The received Announcement message. * @param objDescs[out] An array of AJ_AboutObjectDescriptions that points at the Announcement message. * @param objDescsCount[out] The number of AJ_AboutObjectDescriptions in the objDescs array. * * @return Return AJ_Status * * This function is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ AJ_Status AJ_AboutUnmarshalObjectDescriptions(AJ_Message* announcement, AJ_AboutObjectDescription* objDescs, uint16_t* objDescsCount); /** * About found peer function prototype for indicating an Annoucement from a peer with matching interfaces was received. * * @param version The org.alljoyn.About interface version * @param port The application session port that is used by About * @param peerName The peer bus unique name * @param objPath The object path of the queried interface or "/" otherwise * * @return continueProcessing TRUE to continue processing the Announcement properties. * * Important: functions which implement this prototype MUST copy the input strings * (i.e. peerName and objPath) if they need to use it later! * * This function is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ typedef uint8_t (*AJ_AboutPeerDescriptionMatched)(uint16_t version, uint16_t port, const char* peerName, const char* objPath); /** * About peer's object description prototype for retrieving an Annoucement object description. * * @param peerName The peer bus unique name * @param aboutObjectDescription The object description * * Important: functions which implement this prototype MUST copy the input strings * (i.e. peerName and objPath) if they need to use it later! * * This function is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ typedef void (*AJ_AboutHandleObjectDescription)(const char* peerName, const AJ_AboutObjectDescription* aboutObjectDescription); /** * About peer's mandatory properties function prototype for retrieving an Annoucement mandatory properties. * * @param peerName The peer bus unique name * @param appId The string value of the peer's AppId * @param appName The string value of the peer's AppName * @param deviceId The string value of the peer's DeviceId * @param deviceName The string value of the peer's DeviceName * @param manufacturer The string value of the peer's Manufacturer * @param modelNumber The string value of the peer's ModelNumber * @param defaultLanguage The string value of the peer's DefaultLanguage * * Important: functions which implement this prototype MUST copy the input strings * (e.g. appId, deviceName etc.) if they need to use it later! * * This function is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ typedef void (*AJ_AboutHandleMandatoryProps)(const char* peerName, const char* appId, const char* appName, const char* deviceId, const char* deviceName, const char* manufacturer, const char* modelNumber, const char* defaultLanguage); /** * About peer's optional property function prototype for retrieving an Annoucement optional property. * * @param peerName The peer bus unique name * @param key The optional property key name * @param sig The optional property value signature * @param value The optional property value variant AJ_Arg of a basic type! * * Important: functions which implement this prototype MUST copy the input key * and unmarshal as variant the value if they need to use it later! * * This function is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ typedef void (*AJ_AboutHandleOptionalProperty)(const char* peerName, const char* key, const char* sig, const AJ_Arg* value); /** * About peer isRelevant function prototype for indicating the peer is relevant for engagement. * * @param peerName The peer bus name * * @return relevant TRUE to indicate the Announcement is from a relevant peer. * * Important: functions which implement this prototype MUST copy the input strings * (i.e. peerName and objPath) if they need to use it later! * * This function is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ typedef uint8_t (*AJ_AboutPeerIsRelevant)(const char* peerName); /** * Type for a peer Announcement filter criterion * * This structure is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ typedef struct _AJ_AboutPeerDescription { const char** implementsInterfaces; /**< interface names to resolve in peer Announcement */ uint16_t numberInterfaces; /**< number of interface names */ AJ_AboutPeerDescriptionMatched handleMatch; /**< handleMatched called when a peer with a matching description is found. The callee returns whether to continue to process this description */ AJ_AboutPeerIsRelevant handleIsRelevant; /**< handleIsRelevant called when the Announcement message was unmarshalled entirely. The callee returns whether the peer is relevant for enagement */ AJ_AboutHandleObjectDescription handleObjectDescription; /**< handleObjectDescription called when an object description is found. */ AJ_AboutHandleMandatoryProps handleMandatoryProps; /**< handleMandatoryProps called when mandatory props are found. */ AJ_AboutHandleOptionalProperty handleOptionalProperty; /**< handleOptionalProperty called when an optional property is found. This may be called prior to handleMandatoryProps */ } AJ_AboutPeerDescription; /** * Register Announce signal handlers matching each provided peer description. * * @param peerDescs An array of peer description structs. * @param peerDescsCount The number of AJ_AboutPeerDescriptions in the peerDescs array. * * This function is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ void AJ_AboutRegisterAnnounceHandlers(AJ_AboutPeerDescription* peerDescs, uint16_t peerDescsCount); /** * Unmarshal an Announcement message AboutData section. * * @param announcement The received Announcement message. * @param onMandatoryProps A callback function to return the unmarshalled mandatory properties. * @param onOptionalProperty A callback function to return each unmarshalled optional property. * * @return Return AJ_Status * * This function is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ AJ_Status AJ_AboutUnmarshalProps(AJ_Message* announcement, AJ_AboutHandleMandatoryProps onMandatoryProps, AJ_AboutHandleOptionalProperty onOptionalProperty); /** * Unmarshal the AppId variant from an Announcement message AboutData section. * * @param announcement The received Announcement message. * @param appIdBuf[out] A buffer to store the AppId string value. * @param appIdBufLen The length of the appIdBuf. * * @return Return AJ_Status * * This function is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ AJ_Status AJ_AboutUnmarshalAppIdFromVariant(AJ_Message* announcement, char* appIdBuf, size_t appIdBufLen); /** * Handle an ANNOUNCE signal * * @param announcement The received Announcement message. * @param version[out] The org.alljoyn.About interface version in the Announcenment * @param port[out] The application session port in the Annoucnement * @param peerName[out] The peer bus unique name of the Announcement sender (supply array of size AJ_MAX_NAME_SIZE+1) * @param handled[out] One of the registered Announce handlers indicated this peer is relevant for engagement * * @return Return AJ_Status * * This function is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ AJ_Status AJ_AboutHandleAnnounce(AJ_Message* announcement, uint16_t* version, uint16_t* port, char* peerName, uint8_t* relevant); #endif #ifdef __cplusplus } #endif /** End of insert */ /** * @} */ #endif ajtcl-15.04b/inc/aj_ardp.h000066400000000000000000000161621256742562600153310ustar00rootroot00000000000000/** * @file ArdpProtocol is an implementation of the Reliable Datagram Protocol * (RDP) adapted to AllJoyn. */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #ifndef _ALLJOYN_ARDP_PROTOCOL_H #define _ALLJOYN_ARDP_PROTOCOL_H #ifdef AJ_ARDP #ifdef __cplusplus extern "C" { #endif #include "aj_bufio.h" #include "aj_net.h" #include "aj_status.h" #include "aj_target.h" /** * @brief Per-protocol-instance (global) configuration variables. */ #define UDP_CONNECT_TIMEOUT 1000 /**< How long before we expect a connection to complete */ #define UDP_CONNECT_RETRIES 10 /**< How many times do we retry a connection before giving up */ #define UDP_INITIAL_DATA_TIMEOUT 1000 /**< Initial value for how long do we wait before retrying sending data */ #define UDP_TOTAL_DATA_RETRY_TIMEOUT 30000 /**< Initial total amount of time to try and send data before giving up */ #define UDP_MIN_DATA_RETRIES 5 /**< Minimum number of times to try and send data before giving up */ #define UDP_PERSIST_INTERVAL 1000 /**< How long do we wait before pinging the other side due to a zero window */ #define UDP_TOTAL_APP_TIMEOUT 30000 /**< How long to we try to ping for window opening before deciding app is not pulling data */ #define UDP_LINK_TIMEOUT 30000 /**< How long before we decide a link is down (with no reponses to keepalive probes */ #define UDP_KEEPALIVE_RETRIES 5 /**< How many times do we try to probe on an idle link before terminating the connection */ #define UDP_FAST_RETRANSMIT_ACK_COUNTER 1 /**< How many duplicate acknowledgements to we need to trigger a data retransmission */ #define UDP_DELAYED_ACK_TIMEOUT 100 /**< How long do we wait until acknowledging received segments */ #define UDP_TIMEWAIT 1000 /**< How long do we stay in TIMWAIT state before releasing the per-connection resources */ #define UDP_MINIMUM_TIMEOUT 100 /**< The minimum amount of time between calls to ARDP_Recv */ #define UDP_BACKPRESSURE_TIMEOUT 100 /**< How long can backpressure block the program before a disconnect is triggered? */ #define UDP_DISCONNECT_TIMEOUT 1000 /**< How long can disconnect block the program waiting for TX queue to drain */ #define UDP_SEGBMAX 1472 /**< Maximum size of an ARDP segment (quantum of reliable transmission) */ #define UDP_SEGMAX 2 /**< Maximum number of ARDP segment in-flight (bandwidth-delay product sizing) */ /* Protocol specific values */ #define UDP_HEADER_SIZE 8 #define ARDP_HEADER_SIZE 36 #define ARDP_TTL_INFINITE 0 /* * SEGMAX and SEGBMAX on both send and receive sides are inidcted by SYN header in Connection request: * the acceptor cannot modify these parameters, only reject in case the request cannot be accomodated. * No EACKs: only acknowledge segments received in sequence. */ #define ARDP_FLAG_SIMPLE_MODE 2 struct _AJ_IOBuffer; /* * ARDP onnection request. Connect begins the SYN, * SYN-ACK, ACK thre-way handshake. * * Returns error code: * AJ_OK - all is good, connection transitioned to SYN_SENT state; * fail error code otherwise */ AJ_Status AJ_ARDP_Connect(uint8_t* data, uint16_t dataLen, void* context, AJ_NetSocket* netSock); /* * Disconnect is used to actively close the connection. * forced (IN) - if set to TRUE, the connection should be torn down regardless * of whether there are pending data retransmits. Otherwise, the * callee should check the value of returned error code. */ void AJ_ARDP_Disconnect(uint8_t forced); /* * StartMsgSend informs the ARDP protocol that next chunk of data to be sent * is a beginning of anew message with a specified TTL. * Returns error code: * AJ_OK - all is good * AJ_ERR_ARDP_TTL_EXPIRED - Discard this message. TTL is less than 1/2 estimated roundtrip time. * AJ_ERR_ARDP_INVALID_CONNECTION - Connection does not exist (efffectively connection record is NULL) */ AJ_Status AJ_ARDP_StartMsgSend(uint32_t ttl); /** * AJ_ARDP_Send will attempt to send the data in buf. It will attempt to send the message, waiting for * backpressure to clear if necessary. It can potentially block for as long as is necessary * for the backpressure to be cleared. * * returns: * AJ_OK - if we sent successfully * AJ_ERR_WRITE - if we were unable to send. */ AJ_Status AJ_ARDP_Send(struct _AJ_IOBuffer* buf); /* * ARDP_Recv: data are being read, buffered, and timers are checked. * rxBuf - (IN) app buffer to be filled * len - (IN) the number of bytes the app wants * timeout - (IN) the longest time period we can spend here * Returns error code: * AJ_OK; * AJ_ERR_ARDP_RECV_EXPIRED; * AJ_ERR_ARDP_REMOTE_DISCONNECT; * AJ_ERR_TIMEOUT; * AJ_ERR_INTERRUPTED; * AJ_ERR_READ; * AJ_ERR_PROBE_TIMEOUT * */ AJ_Status AJ_ARDP_Recv(struct _AJ_IOBuffer* rxBuf, uint32_t len, uint32_t timeout); /** * A pointer to the function used by ARDP to receive from a socket * * @param context - (IN) The context pointer * @param buf - (OUT) A pointer to the underlying data that was received * @param recved - (OUT) The number of bytes received into buf * @param timeout - (IN) The timeout * * @return error code * AJ_OK if data was recived * AJ_ERR_TIMEOUT if no data was received by msec * AJ_ERR_INTERRUPTED if the receive operation was interrupted by AJ_Net_Interrupt * AJ_ERR_READ if an error has occured */ typedef AJ_Status (*ReceiveFunction)(void* context, uint8_t** buf, uint32_t* recved, uint32_t timeout); /** * A pointer to the function used by ARDP to send raw data to a socket * * @param context - (IN) The context pointer * @param buf - (IN) A pointer to the buffer to send * @param recved - (IN) The number of bytes to send * @param timeout - (OUT) The number of bytes actually sent * * @return error code * AJ_OK if data was sent * AJ_ERR_READ if an error has occured */ typedef AJ_Status (*SendFunction)(void* context, uint8_t* buf, size_t len, size_t* sent); void AJ_ARDP_InitFunctions(ReceiveFunction recv, SendFunction send); #ifdef __cplusplus } #endif #endif // AJ_ARDP #endif // _ALLJOYN_ARDP_PROTOCOL_H ajtcl-15.04b/inc/aj_auth_listener.h000066400000000000000000000036241256742562600172500ustar00rootroot00000000000000#ifndef _AJ_AUTH_LISTENER_H #define _AJ_AUTH_LISTENER_H /** * @file aj_auth_listener.h * @defgroup aj_auth_listener Authentication Listener * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_net.h" #include "aj_status.h" #include "aj_util.h" #ifdef __cplusplus extern "C" { #endif /* * Command for auth listener callback */ #define AJ_CRED_PRV_KEY 0x0001 /**< private key */ #define AJ_CRED_PUB_KEY 0x0002 /**< public key */ #define AJ_CRED_CERT_CHAIN 0x0003 /**< certificate chain */ #define AJ_CRED_REQUEST 0 #define AJ_CRED_RESPONSE 1 /* * Type for a Credential entry for the auth listener callback */ typedef struct _AJ_Credential { uint8_t direction; /**< request or response */ uint32_t expiration; /**< auth listener to set key expiration value */ uint8_t* data; /**< data to or from the auth listener */ size_t len; /**< length of data */ } AJ_Credential; #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_authentication.h000066400000000000000000000115721256742562600174220ustar00rootroot00000000000000#ifndef _AJ_AUTHENTICATION_H #define _AJ_AUTHENTICATION_H /** * @file aj_authentication.h * @defgroup aj_authentication Implementation of Authentication mechanisms * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_bus.h" #include "aj_config.h" #include "aj_target.h" #include "aj_crypto_ecc.h" #include "aj_crypto_sha2.h" #ifdef __cplusplus extern "C" { #endif /* The key exchange is in the 16 MSB */ #define AUTH_KEYX_ECDHE 0x00400000 /* The key authentication suite is in the 16 LSB */ #define AUTH_SUITE_ECDHE_NULL (AUTH_KEYX_ECDHE | 0x0001) #define AUTH_SUITE_ECDHE_PSK (AUTH_KEYX_ECDHE | 0x0002) #define AUTH_SUITE_ECDHE_ECDSA (AUTH_KEYX_ECDHE | 0x0004) #define AJ_AUTH_SUITES_NUM 3 /**< Number of supported authentication suites */ #define AUTH_CLIENT 0 #define AUTH_SERVER 1 typedef struct _KeyExchangeContext { ecc_publickey pub; ecc_privatekey prv; } KeyExchangeContext; /** * Context for PSK authentication * Memory is not allocated and copied * The pointer addresses memory that exists in the lifetime of its usage */ typedef struct _PSKContext { uint8_t* hint; /**< PSK hint */ size_t size; /**< Size of PSK hint */ } PSKContext; typedef struct _KeyAuthenticationContext { PSKContext psk; /**< Context for PSK authentication */ } KeyAuthenticationContext; /** * Authentication context */ typedef struct _AJ_AuthenticationContext { AJ_BusAttachment* bus; /**< Bus attachement - required for auth callbacks */ uint8_t role; /**< Role (client or server) */ uint32_t suite; /**< Authentication suite */ uint32_t version; /**< Protocol version */ AJ_SHA256_Context hash; /**< Running hash of exchanged messages */ KeyExchangeContext kectx; /**< Context for key exchange step */ KeyAuthenticationContext kactx; /**< Context for key authentication step */ uint8_t mastersecret[AJ_MASTER_SECRET_LEN]; /**< Master secret */ uint32_t expiration; /**< Master secret expiration */ } AJ_AuthenticationContext; /** * Marshal a key exchange message * * @param ctx The authentication context * @param msg The outgoing message * * @return * - AJ_OK on success * - An error status otherwise */ AJ_Status AJ_KeyExchangeMarshal(AJ_AuthenticationContext* ctx, AJ_Message* msg); /** * Unmarshal a key exchange message * * @param ctx The authentication context * @param msg The incoming message * * @return * - AJ_OK on success * - An error status otherwise */ AJ_Status AJ_KeyExchangeUnmarshal(AJ_AuthenticationContext* ctx, AJ_Message* msg); /** * Marshal a key authentication message * * @param ctx The authentication context * @param msg The outgoing message * * @return * - AJ_OK on success * - An error status otherwise */ AJ_Status AJ_KeyAuthenticationMarshal(AJ_AuthenticationContext* ctx, AJ_Message* msg); /** * Unmarshal a key authentication message * * @param ctx The authentication context * @param msg The incoming message * * @return * - AJ_OK on success * - An error status otherwise */ AJ_Status AJ_KeyAuthenticationUnmarshal(AJ_AuthenticationContext* ctx, AJ_Message* msg); /** * Check if an authentication suite is available * * @param suite The authentication suite to check * @param version The authentication protocol version * * @return Return true or false */ uint8_t AJ_IsSuiteEnabled(uint32_t suite, uint32_t version); /** * Enable an authentication suite * * @param suite The authentication suite to enable */ void AJ_EnableSuite(uint32_t suite); #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_bufio.h000066400000000000000000000110201256742562600154730ustar00rootroot00000000000000#ifndef _AJ_BUFIO_H #define _AJ_BUFIO_H /** * @file aj_bufio.h * @defgroup aj_bufio Buffer Input/Output * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_status.h" #ifdef __cplusplus extern "C" { #endif /* * Forward declaration */ struct _AJ_IOBuffer; /** * Function pointer type for an abstracted transmit function */ typedef AJ_Status (*AJ_TxFunc)(struct _AJ_IOBuffer* buf); /** * Function pointer type for an abstracted receive function * * @param buf The buffer to read into * @param len The requested number of bytes to read. More or fewer bytes may actually be read into * the buffer. * @param timeout A timeout in milliseconds after which the read will return with an error status if * there is not data to read. * * @return * - AJ_OK if some data was read * - AJ_ERR_TIMEOUT if the read timedout * - AJ_ERR_RESOURCES if there isn't enough room in the buffer to read len bytes. The buffer * will contain the bytes actually read so this is not a fatal error. * - AJ_ERR_READ the read failed irrecoverably * - AJ_ERR_LINK_DEAD the network link is dead */ typedef AJ_Status (*AJ_RxFunc)(struct _AJ_IOBuffer* buf, uint32_t len, uint32_t timeout); #define AJ_IO_BUF_RX 1 /**< I/O direction is receive */ #define AJ_IO_BUF_TX 2 /**< I/O direction is send */ #define AJ_IO_BUF_AJ 1 /**< send/receive data to/from AJ */ #define AJ_IO_BUF_MDNS 2 /**< send/receive data to/from mDNS */ /** * A type for managing a receive or transmit buffer */ typedef struct _AJ_IOBuffer { uint8_t direction; /**< I/O buffer is either a Tx buffer or an Rx buffer */ uint8_t flags; /**< ports to send to or receive on */ uint16_t bufSize; /**< Size of the data buffer */ uint8_t* bufStart; /**< Start for the data buffer */ uint8_t* readPtr; /**< Current position in buf for reading data */ uint8_t* writePtr; /**< Current position in buf for writing data */ /* * Function pointer to send or recv function */ union { AJ_TxFunc send; AJ_RxFunc recv; }; void* context; /**< Abstracted context for managing I/O */ } AJ_IOBuffer; /** * How much data is available to read from the buffer */ #define AJ_IO_BUF_AVAIL(iobuf) (uint32_t)(((iobuf)->writePtr - (iobuf)->readPtr)) /** * How much space is available to write to the buffer */ #define AJ_IO_BUF_SPACE(iobuf) ((uint32_t)((iobuf)->bufSize - ((iobuf)->writePtr - (iobuf)->bufStart))) /** * How much data has been consumed from the buffer */ #define AJ_IO_BUF_CONSUMED(iobuf) (uint32_t)(((iobuf)->readPtr - (iobuf)->bufStart)) /** * Reset and IO buffer */ #define AJ_IO_BUF_RESET(iobuf) \ do { \ (iobuf)->readPtr = (iobuf)->bufStart; \ (iobuf)->writePtr = (iobuf)->bufStart; \ (iobuf)->flags = 0; \ } while (0) /** * Initialize an I/O Buffer. * * @param ioBuf The I/O buffer to initialize * @param buffer The data buffer to use * @param bufLen The size of the data buffer * @param direction Indicates if the buffer is being used for sending or receiving data * @param context Abstracted context for managing I/O */ void AJ_IOBufInit(AJ_IOBuffer* ioBuf, uint8_t* buffer, uint32_t bufLen, uint8_t direction, void* context); /** * Move any unconsumed data to the start of the buffer. * * @param ioBuf An RX I/O buf that may contain unconsumed data * @param preserve Data (if any) at front of buffer that must be preserved */ void AJ_IOBufRebase(AJ_IOBuffer* ioBuf, size_t preserve); #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_bus.h000066400000000000000000000546131256742562600151770ustar00rootroot00000000000000#ifndef _AJ_BUS_H #define _AJ_BUS_H /** * @file aj_bus.h * @defgroup aj_bus Bus Attachment * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_net.h" #include "aj_status.h" #include "aj_util.h" #include "aj_auth_listener.h" #ifdef __cplusplus extern "C" { #endif /** * Forward declarations */ typedef struct _AJ_Message AJ_Message; typedef struct _AJ_Arg AJ_Arg; /** * Callback function prototype for requesting a password or pincode from an application. * * @param buffer The buffer to receive the password. * @param bufLen The size of the buffer * * @return Returns the length of the password. If the length is zero this will be * treated as a rejected password request. */ typedef uint32_t (*AJ_AuthPwdFunc)(uint8_t* buffer, uint32_t bufLen); /** * Callback function prototype for authentication listener * * @param authmechansim The authentication mechanism used * @param command The listener command * @param creds The credentials * * @return Returns true if authorized; false otherwise. */ typedef AJ_Status (*AJ_AuthListenerFunc)(uint32_t authmechanism, uint32_t command, AJ_Credential* creds); #define AJ_MAX_NAME_SIZE 20 /**< Maximum length for a bus unique name */ /** * Type for a bus attachment */ typedef struct _AJ_BusAttachment { uint16_t aboutPort; /**< The port to use in announcements */ char uniqueName[AJ_MAX_NAME_SIZE + 1]; /**< The unique name returned by the hello message */ AJ_NetSocket sock; /**< Abstracts a network socket */ uint32_t serial; /**< Next outgoing message serial number */ AJ_AuthPwdFunc pwdCallback; /**< Callback for obtaining passwords */ AJ_AuthListenerFunc authListenerCallback; /**< Callback for obtaining passwords */ uint8_t isAuthenticated; /**< Has authentication already occured? */ uint32_t aboutSerial; /**< Serial number for About announcement */ uint8_t isProbeRequired; /**< Are probe requests required for the live transport? */ } AJ_BusAttachment; /** * Get the unique name for the bus * * @return The unique name or NULL if the bus is not connected. */ const char* AJ_GetUniqueName(AJ_BusAttachment* bus); #define AJ_NAME_REQ_ALLOW_REPLACEMENT 0x01 /**< Allow others to take ownership of this name */ #define AJ_NAME_REQ_REPLACE_EXISTING 0x02 /**< Attempt to take ownership of name if already taken */ #define AJ_NAME_REQ_DO_NOT_QUEUE 0x04 /**< Fail if name cannot be immediately obtained */ /** * Make a method call to request a well known name * * @param bus The bus attachment * @param name The name being requested * @param flags An XOR of the name request flags * * @return * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusRequestName(AJ_BusAttachment* bus, const char* name, uint32_t flags); #define AJ_TRANSPORT_NONE 0x0000 /**< no transports */ #define AJ_TRANSPORT_LOCAL 0x0001 /**< Local (same device) transport */ #define AJ_TRANSPORT_TCP 0x0004 /**< TCP/IP transport */ #define AJ_TRANSPORT_UDP 0x0100 /**< UDP/IP transport */ #define AJ_TRANSPORT_EXPERIMENTAL 0x8000 /**< Placeholder for an experimental transport */ #define AJ_TRANSPORT_IP (AJ_TRANSPORT_TCP | AJ_TRANSPORT_UDP) /**< Any IP-based transport */ #define AJ_TRANSPORT_ANY (AJ_TRANSPORT_LOCAL | AJ_TRANSPORT_IP) /**< ANY non-experimental transport */ #define AJ_TRANSPORT_BLUETOOTH (attempted_use_of_deprecated_definition = 0x0002) /**< Bluetooth transport */ #define AJ_TRANSPORT_WLAN (attempted_use_of_deprecated_definition = 0x0004) /**< Wireless local-area network transport */ #define AJ_TRANSPORT_WWAN (attempted_use_of_deprecated_definition = 0x0008) /**< Wireless wide-area network transport */ #define AJ_TRANSPORT_LAN (attempted_use_of_deprecated_definition = 0x0010) /**< Wired local-area network transport */ /** * Make a method call to release a previously requested well known name. * * @param bus The bus attachment * @param name The name being released * * @return * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusReleaseName(AJ_BusAttachment* bus, const char* name); #define AJ_BUS_START_ADVERTISING 0 /**< start advertising */ #define AJ_BUS_STOP_ADVERTISING 1 /**< stop advertising */ /** * Make a method call to start or stop advertising a name * * @param bus The bus attachment * @param name The name to be advertised * @param transportMask Restricts the transports the advertisement will be stopped/started on. * @param op Either AJ_BUS_START_ADVERTISING or AJ_BUS_STOP_ADVERTISING * @param flags Flags to pass into AJ_MarshalMsg * * @return Return AJ_Status * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusAdvertiseName(AJ_BusAttachment* bus, const char* name, uint16_t transportMask, uint8_t op, uint8_t flags); #define AJ_BUS_START_FINDING 0 /**< Start finding advertised name */ #define AJ_BUS_STOP_FINDING 1 /**< Stop finding advertised name */ #define AJ_FIND_NAME_STARTED 0x1 /**< Started to find the name as requested */ #define AJ_FIND_NAME_ALREADY 0x2 /**< Was already finding the requested name */ #define AJ_FIND_NAME_FAILURE 0x3 /**< Attempt to find the name failed */ /** * Register interest in a well-known name prefix for the purpose of discovery. * * @param bus The bus attachment * @param namePrefix Well-known name prefix that application is interested in receiving * FoundAdvertisedName notifications about. * @param op Either AJ_BUS_START_FINDING or AJ_BUS_STOP_FINDING * @param flags Flags being passed in * * @return Return AJ_Status * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusFindAdvertisedName(AJ_BusAttachment* bus, const char* namePrefix, uint8_t op); /** * Register interest in a well-known name prefix for the purpose of discovery. * * @param bus The bus attachment * @param namePrefix Well-known name prefix that application is interested in receiving * @param transport Transports by which for well-known name discovery * FoundAdvertisedName notifications about. * @param op Either AJ_BUS_START_FINDING or AJ_BUS_STOP_FINDING * * @return Return AJ_Status * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusFindAdvertisedNameByTransport(AJ_BusAttachment* bus, const char* namePrefix, uint16_t transport, uint8_t op); #define AJ_SESSION_PROXIMITY_ANY 0xFF /**< No proximity restrictions */ #define AJ_SESSION_PROXIMITY_PHYSICAL 0x01 /**< Limit to services that are physically proximal */ #define AJ_SESSION_PROXIMITY_NETWORK 0x02 /**< Allow services that are on the same subnet */ #define AJ_SESSION_TRAFFIC_MESSAGES 0x01 /**< Session carries message traffic */ #define AJ_SESSION_TRAFFIC_RAW_UNRELIABLE 0x02 /**< Not supported by this implementation */ #define AJ_SESSION_TRAFFIC_RAW_RELIABLE 0x04 /**< Not supported by this implementation */ #define AJ_SESSION_PORT_ANY 0x00 /**< Use a daemon assigned ephemeral session port */ /** * Type for describing session options */ typedef struct _AJ_SessionOpts { uint8_t traffic; /**< traffic type */ uint8_t proximity; /**< proximity */ uint16_t transports; /**< allowed transports */ uint32_t isMultipoint; /**< multi-point session capable */ } AJ_SessionOpts; /** * Make a method call to bind a session port. * * @param bus The bus attachment * @param port The port to bind, if AJ_SESSION_PORT_ANY is passed in, the daemon * will assign an ephemeral session port * @param opts Options for establishing a session, if NULL defaults are used. * @param flags Flags to pass into AJ_MarshalMsg * * @return Return AJ_Status * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusBindSessionPort(AJ_BusAttachment* bus, uint16_t port, const AJ_SessionOpts* opts, uint8_t flags); /** * Make a method call to unbind a session port. * * @param bus The bus attachment * @param port The port the session is associated with * @param flags The flags associated with binding a port * * @return Return AJ_Status * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusUnbindSession(AJ_BusAttachment* bus, uint16_t port); /** * Make a method call to cancel a sessionless signal * * @param bus The bus attachment * @param serialNum The serial number of the signal to cancel * * @return * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusCancelSessionless(AJ_BusAttachment* bus, uint32_t serialNum); /** * Possible response codes for AJ_BusCancelSessionless */ #define AJ_CANCELSESSIONLESS_REPLY_SUCCESS 1 /**< Cancel Sessionless: reply success */ #define AJ_CANCELSESSIONLESS_REPLY_NO_SUCH_MSG 2 /**< Cancel Sessionless: no such msg */ #define AJ_CANCELSESSIONLESS_REPLY_NOT_ALLOWED 3 /**< Cancel Sessionless: not allowed */ #define AJ_CANCELSESSIONLESS_REPLY_FAILED 4 /**< Cancel Sessionless: reply failed */ /** * Send a reply to an accept session method call * * @param msg The AcceptSession method call * @param accept TRUE to accept the session, FALSE to reject it. * * @return Return AJ_Status * - AJ_OK if the message was succesfully delivered * - AJ_ERR_MARSHAL if the message arguments were incompletely marshaled */ AJ_EXPORT AJ_Status AJ_BusReplyAcceptSession(AJ_Message* msg, uint32_t accept); /** * Make a method call join a session. * * @param bus The bus attachment * @param sessionHost Bus name of attachment that is hosting the session to be joined. * @param port The session port to join * @param opts Options for establishing a session, if NULL defaults are used. * * @return Return AJ_Status * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusJoinSession(AJ_BusAttachment* bus, const char* sessionHost, uint16_t port, const AJ_SessionOpts* opts); /** * Make a method call join a session. * * @param bus The bus attachment * @param sessionId The Id of the session joined * * @return Return AJ_Status * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusLeaveSession(AJ_BusAttachment* bus, uint32_t sessionId); #define AJ_BUS_SIGNAL_ALLOW 0 /**< Allow signals */ #define AJ_BUS_SIGNAL_DENY 1 /**< Deny signals */ /** * Add a SIGNAL match rule. A rule must be added for every non-session signal that the application * is interested in receiving. * * @param bus The bus attachment * @param ruleString Match rule to be added/removed * @param rule Either AJ_BUS_SIGNAL_ALLOW or AJ_BUS_SIGNAL_DENY * * @return Return AJ_Status * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusSetSignalRule(AJ_BusAttachment* bus, const char* ruleString, uint8_t rule); /** * Add a SIGNAL match rule. A rule must be added for every non-session signal that the application * is interested in receiving. * * @param bus The bus attachment * @param ruleString Match rule to be added/removed * @param rule Either AJ_BUS_SIGNAL_ALLOW or AJ_BUS_SIGNAL_DENY * @param flags Flags associated with the new rule * @param[out] serialNum The serial number of the method call * * @return Return AJ_Status * - AJ_OK if the request was sent * - An error status otherwise */ AJ_Status AJ_BusSetSignalRuleSerial(AJ_BusAttachment* bus, const char* ruleString, uint8_t rule, uint8_t flags, uint32_t* serialNum); /** * Add a SIGNAL match rule. A rule must be added for every non-session signal that the application * is interested in receiving. * * @param bus The bus attachment * @param signalName The name of the signal. * @param interfaceName The name of the interface. * @param rule Either AJ_BUS_SIGNAL_ALLOW or AJ_BUS_SIGNAL_DENY * * @return Return AJ_Status * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusAddSignalRule(AJ_BusAttachment* bus, const char* signalName, const char* interfaceName, uint8_t rule); /** * Add a SIGNAL match rule. A rule must be added for every non-session signal that the application * is interested in receiving. * * @param bus The bus attachment * @param ruleString Match rule to be added/removed * @param rule Either AJ_BUS_SIGNAL_ALLOW or AJ_BUS_SIGNAL_DENY * @param flags Flags associated with the new rule * * @return Return AJ_Status * - AJ_OK if the request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusSetSignalRuleFlags(AJ_BusAttachment* bus, const char* ruleString, uint8_t rule, uint8_t flags); #define AJ_SETLINKTIMEOUT_SUCCESS 1 /**< SetLinkTimeout reply: Success */ #define AJ_SETLINKTIMEOUT_NO_DEST_SUPPORT 2 /**< SetLinkTimeout reply: Destination endpoint does not support link monitoring */ #define AJ_SETLINKTIMEOUT_NO_SESSION 3 /**< SetLinkTimeout reply: Session with given id does not exist */ #define AJ_SETLINKTIMEOUT_FAILED 4 /**< SetLinkTimeout reply: Failed */ /** * Set a link timeout on a session. This will ensure that a session lost signal is reported by the * daemon within the specified timeout period if the session peer unexpectedly leaves the bus, for * example because the peer moved out of range. The application may want to handle to reply to * this method call to determine if the request succeeded. * * @param bus The bus attachment * @param sessionId The session id for the session to set the timeout on. * @param linkTimeout The link timeout value to set specified in milliseconds * * @return Return AJ_Status * - AJ_OK if the link timwout request was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusSetLinkTimeout(AJ_BusAttachment* bus, uint32_t sessionId, uint32_t linkTimeout); /* * Use to remove a member from the session * * @param bus The bus attachment your on * @param sessionId The session ID for the session your removing the member from * @param member The unique ID of the member you wish to remove from the session * * @return Return AJ_Status * - AJ_OK if the member was removed successfully * - An error if not removed */ AJ_EXPORT AJ_Status AJ_BusRemoveSessionMember(AJ_BusAttachment* bus, uint32_t sessionId, const char* member); /* * Is the bus name reachable? * * @param bus The bus attachment * @param name The unique or well-known name of the object to ping * @param timeout Timeout (in milliseconds) to wait for a reply * * @return Return AJ_Status * - AJ_OK if ping was sent * - An error status otherwise */ AJ_EXPORT AJ_Status AJ_BusPing(AJ_BusAttachment* bus, const char* name, uint32_t timeout); #define AJ_PING_SUCCESS 1 /**< Ping reply: Success */ #define AJ_PING_FAILED 2 /**< Ping reply: Failed */ #define AJ_PING_TIMEOUT 3 /**< Ping reply: Timed out */ /** * Invoke a built-in handler for standard bus messages. Signals passed to this function that are * not bus messages are silently ignored. Method calls passed to this function that are not * recognized bus messages are rejected with an error response. * * Method calls that currently have built-in handlers are: * * - AJ_BUS_METHOD_PING * - AJ_BUS_METHOD_GET_MACHINE_ID * - AJ_BUS_METHOD_INTROSPECT * - AJ_BUS_METHOD_EXCHANGE_GUIDS * - AJ_BUS_METHOD_GEN_SESSION_KEY * - AJ_BUS_METHOD_EXCHANGE_GROUP_KEYS * - AJ_BUS_METHOD_AUTH_CHALLENGE * * @param msg The message to handle * * @return Return AJ_Status * - AJ_OK if the message was handled or ingored */ AJ_EXPORT AJ_Status AJ_BusHandleBusMessage(AJ_Message* msg); /** * Set a callback for returning passwords for peer authentication. Authentication is not enabled * until a password callback function has been set. * * @param bus The bus attachment struct * @param pwdCallback The password callback function. */ AJ_EXPORT void AJ_BusSetPasswordCallback(AJ_BusAttachment* bus, AJ_AuthPwdFunc pwdCallback); /** * Set a callback for auth listener * until a password callback function has been set. * * @param bus The bus attachment struct * @param authListenerCallback The auth listener callback function. */ void AJ_BusSetAuthListenerCallback(AJ_BusAttachment* bus, AJ_AuthListenerFunc authListenerCallback); /** * Callback function prototype for the function called when an authentication completes or fails. * * @param context The context provided when AJ_PeerAuthenticate() was called. * @param status A status code indicating if the authentication was succesful * - AJ_OK indicates the authentication succeeded * - AJ_ERR_SECURITY indicates the authentication failed * - AJ_ERR_TIMEOUT indciates the authentication timed-out */ typedef void (*AJ_BusAuthPeerCallback)(const void* context, AJ_Status status); /** * Initiate a secure connection to a remote peer authenticating if necessary. * * @param bus The bus attachment * @param peerBusName The bus name of the remove peer to secure. * @param callback A function to be called when the authentication completes * @param cbContext A caller provided context to pass to the callback function * * @return Return AJ_Status * - AJ_OK if the request was sent * - An error status otherwise */ AJ_Status AJ_BusAuthenticatePeer(AJ_BusAttachment* bus, const char* peerBusName, AJ_BusAuthPeerCallback callback, void* cbContext); /** * Callback function prototype for a callback function to GET a property. All this function has to * do is marshal the property value. * * @param replyMsg The GET_PROPERTY or GET_ALL_PROPERTIES reply message * @param propId The property identifier * @param context The caller provided context that was passed into AJ_BusPropGet() * * @return Return AJ_Status * - AJ_OK if the property was read and marshaled * - An error status if the property could not be returned for any reason. */ typedef AJ_Status (*AJ_BusPropGetCallback)(AJ_Message* replyMsg, uint32_t propId, void* context); /** * Helper function that provides all the boilerplate for responding to a GET_PROPERTY. All the * application has to do is marshal the property value. * * @param msg An unmarshalled GET_PROPERTY message * @param callback The function called to request the application to marshal the property value. * @param context A caller provided context that is passed into the callback function * * @return Return AJ_Status */ AJ_EXPORT AJ_Status AJ_BusPropGet(AJ_Message* msg, AJ_BusPropGetCallback callback, void* context); /** * Helper function that provides all the boilerplate for responding to a GET_ALL_PROPERTIES. All the * application has to do is marshal each of the property values. * * @param msg An unmarshalled GET_ALL_PROPERTIES message * @param callback The function called to request the application to marshal the property value. * @param context A caller provided context that is passed into the callback function * * @return Return AJ_Status */ AJ_EXPORT AJ_Status AJ_BusPropGetAll(AJ_Message* msg, AJ_BusPropGetCallback callback, void* context); /** * Callback function prototype for a callback function to SET an application property. All this * function has to do is unmarshal the property value. * * @param replyMsg The SET_PROPERTY reply message * @param propId The property identifier * @param context The caller provided context that was passed into AJ_BusPropSet() * * @return Return AJ_Status * - AJ_OK if the property was unmarshaled * - An error status if the property could not be set for any reason. */ typedef AJ_Status (*AJ_BusPropSetCallback)(AJ_Message* replyMsg, uint32_t propId, void* context); /** * Helper function that provides all the boilerplate for responding to a SET_PROPERTY. All the * application has to do is unmarshal the property value. * * @param msg An unmarshalled SET_PROPERTY message * @param callback The function called to request the application to marshal the property value. * @param context A caller provided context that is passed into the callback function * * @return Return AJ_Status */ AJ_EXPORT AJ_Status AJ_BusPropSet(AJ_Message* msg, AJ_BusPropSetCallback callback, void* context); /** * Function to specify which authentication suites are available. * * @param bus The bus attachment struct * @param suites The authentication suites to enable * @param numsuites The number of authentication suites * * @return Return AJ_Status */ AJ_Status AJ_BusEnableSecurity(AJ_BusAttachment* bus, const uint32_t* suites, size_t numsuites); #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_cert.h000066400000000000000000000173411256742562600153400ustar00rootroot00000000000000#ifndef _AJ_CERT_H #define _AJ_CERT_H /** * @file aj_cert.h * @defgroup aj_cert Certificate Utilities * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_status.h" #include "aj_crypto_ecc.h" #ifdef __cplusplus extern "C" { #endif /** * DER encoding types. */ #define ASN_BOOLEAN 0x01 #define ASN_INTEGER 0x02 #define ASN_BITS 0x03 #define ASN_OCTETS 0x04 #define ASN_NULL 0x05 #define ASN_OID 0x06 #define ASN_UTF8 0x0C #define ASN_SEQ 0x10 #define ASN_SET_OF 0x11 #define ASN_PRINTABLE 0x13 #define ASN_ASCII 0x16 #define ASN_UTC_TIME 0x17 #define ASN_GEN_TIME 0x18 #define ASN_CONTEXT_SPECIFIC 0xA0 /** * Structure for a DER encoded element. */ typedef struct _DER_Element { size_t size; uint8_t* data; } DER_Element; /** * Decode one element from a DER encoded blob. * * @param der The input DER encoded blob. * @param tag The expected element type. * @param out The output decoded element. * * @return Return AJ_Status * - AJ_OK on success * - AJ_ERR_INVALID on all failures */ AJ_Status AJ_ASN1DecodeElement(DER_Element* der, uint8_t tag, DER_Element* out); /** * Decode many elements from a DER encoded blob. * This is a non-recursive decoder. * Only a depth of one may be decoded in one call. * * @param der The input DER encoded blob. * @param tags The expected element types. * @param len The number of types to decode. * @param ... The output decoded elements. * * @return Return AJ_Status * - AJ_OK on success * - AJ_ERR_INVALID on all failures */ AJ_Status AJ_ASN1DecodeElements(DER_Element* der, const uint8_t* tags, size_t len, ...); /** * OIDs used in X.509 certificates. */ extern const uint8_t OID_SIG_ECDSA_SHA256[]; extern const uint8_t OID_KEY_ECC[]; extern const uint8_t OID_CRV_PRIME256V1[]; extern const uint8_t OID_DN_OU[]; extern const uint8_t OID_DN_CN[]; extern const uint8_t OID_BASIC_CONSTRAINTS[]; typedef struct _X509Validity { uint64_t from; uint64_t to; } X509Validity; typedef struct _X509DistinguishedName { DER_Element ou; /**< Organizational Unit name */ DER_Element cn; /**< Common name */ } X509DistinguishedName; typedef struct _X509Extensions { uint32_t ca; /**< Certificate authority */ } X509Extensions; typedef struct _X509TbsCertificate { DER_Element serial; /**< The serial number */ X509DistinguishedName issuer; /**< The issuer's identity */ X509Validity validity; /**< The validity period */ X509DistinguishedName subject; /**< The subject's identity */ ecc_publickey publickey; /**< The subject's public key */ X509Extensions extensions; /**< The certificate extensions */ } X509TbsCertificate; /** * Structure for X.509 certificate. * Only useful for NISTP256 ECDSA signed certificates at the moment. * Can be modified to handle other types in the future. */ typedef struct _X509Certificate { DER_Element der; /**< Certificate DER encoding */ DER_Element raw; /**< The raw tbs section */ X509TbsCertificate tbs; /**< The TBS section of the certificate */ ecc_signature signature; /**< The certificate signature */ } X509Certificate; /** * Certificate chain: linked list of certificates */ typedef struct _X509CertificateChain { X509Certificate certificate; /**< The certificate */ struct _X509CertificateChain* next; /**< Linked list pointer */ } X509CertificateChain; /** * Decode a PEM encoded private key * * @param key The output decoded key. * @param pem The input PEM. * * @return Return AJ_Status * - AJ_OK on success * - AJ_ERR_INVALID on all failures */ AJ_Status AJ_DecodePrivateKeyPEM(ecc_privatekey* key, const char* pem); /** * Decode a ASN.1 DER encoded X.509 certificate. * * @param certificate The output decoded certificate. * @param der The input encoded DER blob. * * @return Return AJ_Status * - AJ_OK on success * - AJ_ERR_INVALID on all failures */ AJ_Status AJ_X509DecodeCertificateDER(X509Certificate* certificate, DER_Element* der); /** * Decode a PEM encoded X.509 certificate. * * @param certificate The output decoded certificate. * @param pem The input PEM. * @param len The input PEM length. * * @return Return AJ_Status * - AJ_OK on success * - AJ_ERR_RESOURCES on failure */ AJ_Status AJ_X509DecodeCertificatePEM(X509Certificate* certificate, const char* pem, size_t len); /** * Decode a PEM encoded X.509 certificate chain. * The order of certificates is important. * This puts the child first, then parents follow. * That is the same order that should be in the pem. * * @param pem The input PEM. * * @return Return chain on success, NULL on failure */ X509CertificateChain* AJ_X509DecodeCertificateChainPEM(const char* pem); /** * Verify a self-signed X.509 certificate. * * @param certificate The input certificate. * * @return Return AJ_Status * - AJ_OK on success * - AJ_ERR_SECURITY on failure */ AJ_Status AJ_X509SelfVerify(const X509Certificate* certificate); /** * Verify a signed X.509 certificate. * * @param certificate The input certificate. * @param key The verification key. * * @return Return AJ_Status * - AJ_OK on success * - AJ_ERR_SECURITY on failure */ AJ_Status AJ_X509Verify(const X509Certificate* certificate, const ecc_publickey* key); /** * Verify a chain of X.509 certificates. * Root certificate is first. * * @param chain The input certificate chain. * @param key The verification key of the root. If this is NULL, don't verify the root. * * @return Return AJ_Status * - AJ_OK on success * - AJ_ERR_SECURITY on failure */ AJ_Status AJ_X509VerifyChain(const X509CertificateChain* chain, const ecc_publickey* key); /** * Convert unsigned 32-bit int array to network order (big endian) bytes. * * @param u32 Unsigned 32-bit array * @param len Length of 32-bit array * @param u8 Unsigned 8-bit array * */ void HostU32ToBigEndianU8(uint32_t* u32, size_t len, uint8_t* u8); /** * Old encoding of native public key. * * @param publickey The ECC public key * @param[out] b8 Big endian byte array * */ void AJ_BigEndianEncodePublicKey(ecc_publickey* publickey, uint8_t* b8); /** * Old decoding of native public key. * * @param[out] publickey The ECC public key * @param b8 Big endian byte array * */ void AJ_BigEndianDecodePublicKey(ecc_publickey* publickey, uint8_t* b8); #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_config.h000066400000000000000000000125221256742562600156440ustar00rootroot00000000000000#ifndef _AJ_CONFIG_H #define _AJ_CONFIG_H /** * @file aj_config.h * @defgroup aj_config Configuration * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_debug.h" #ifdef __cplusplus extern "C" { #endif /* Debug options */ #define _AJ_AUTH_DEBUG 0 //Enable for authentication debugging #ifndef AJ_DEBUG_RESTRICT #define AJ_DEBUG_RESTRICT AJ_DEBUG_WARN //Debug output level (aj_debug.h) #endif #define AJ_DUMP_MSG_RAW 0 //set to see raw msg bytes #define AJ_DUMP_BYTE_SIZE 16 //aj_debug.c /* Network options */ #define AJ_CONNECT_LOCALHOST 0 //Enable to bypass discovery and connect locally #define AJ_MAX_TIMERS 4 //maximum number of timers (aj_helper.c) #define AJ_ROUTING_NODE_BLACKLIST_SIZE 16 // maximum number of blacklisted routing nodes #define AJ_ROUTING_NODE_RESPONSELIST_SIZE 3 // maximum number of routing node responses to track /* Auth options */ #define AJ_NONCE_LEN 28 //Length of the nonce. #define AJ_VERIFIER_LEN 12 //Length of the verifier string #define AJ_PINX_MASTER_SECRET_LEN 24 //Length of the master secret PINX #define AJ_MASTER_SECRET_LEN 48 //Length of the master secret - RFC 5246 #define AJ_ADHOC_LEN 16 //AD-HOC maximal passcode length (aj_auth.h) #define AJ_NAME_MAP_GUID_SIZE 4 //aj_guid.c #define AJ_MAX_CREDS 40 //Max number of credentials that can store credentials (aj_creds.h) #define AJ_LOCAL_GUID_NV_ID 1 #define AJ_CREDS_NV_ID_BEGIN (AJ_LOCAL_GUID_NV_ID + 1) #define AJ_CREDS_NV_ID_END (AJ_CREDS_NV_ID_BEGIN + AJ_MAX_CREDS) /* Timeouts */ #define AJ_UNMARSHAL_TIMEOUT (100 * 1000) //unmarshal timeout (aj_helper.c + aj_msg.c) #define AJ_CONNECT_TIMEOUT (60 * 1000) //connection timeout (aj_helper.c) #define AJ_SELECTION_TIMEOUT (5 * 1000) //selection timeout (aj_helper.c) #define AJ_CONNECT_PAUSE (10 * 1000) //how long to pause between failed connects (aj_helper.c) #define AJ_DEFAULT_REPLY_TIMEOUT (1000 * 20) //reply timeout (aj_introspect.c) #define AJ_MIN_BUS_LINK_TIMEOUT (40) //min link timeout for the bus (aj_link_timeout.c) #define AJ_BUS_LINK_PING_TIMEOUT (5 * 1000) //time period in which probe requests sb acked (aj_link_timeout.c) #define AJ_MAX_LINK_PING_PACKETS (3) //max number of outstanding probe requests (aj_link_timeout.c) #define AJ_METHOD_TIMEOUT (1000 * 3) //timeout for method calls (aj_bus.c) #define AJ_MAX_AUTH_TIME (5 * 60 * 1000ul) //max time for incomplete authentication (aj_peer.c) #define AJ_AUTH_CALL_TIMEOUT (2 * 60 * 1000ul) //long timeout for method calls w/ user input (aj_peer.c) #define AJ_CALL_TIMEOUT (1000ul * 5) //default timout for method calls (aj_peer.c) #define AJ_UDP_CONNECT_TIMEOUT 5000 //UDP connection timeout (aj_connect.c) /* Message identification related */ #if !defined(AJ_NUM_REPLY_CONTEXTS) #define AJ_NUM_REPLY_CONTEXTS (3) //number of concurrent method calls (aj_introspect.c) #endif #if !(defined(AJ_MAX_OBJECT_LISTS)) #define AJ_MAX_OBJECT_LISTS (9) //maximum number of object lists (aj_introspect.c) #endif /* Crypto */ #define AJ_CCM_TRACE 0 //Enables fine-grained tracing for debugging new implementations. #define _SO_REUSEPORT 0 //Linux target /* About client Announcement buffer */ #define AJ_MAX_NUM_OF_OBJ_DESC (32) //number of object descriptions in an Announcement payload (aj_about.c) #define AJ_MAX_NUM_OF_INTERFACES (16) //number of interfaces per object description in an Annoucement payload (aj_about.c) /* Below sets the actual #define's based on values above */ #if _AJ_AUTH_DEBUG #define AUTH_DEBUG #endif #if _SO_REUSEPORT #define SO_REUSEPORT #endif #if HOST_IS_LITTLE_ENDIAN #define HOST_ENDIANESS AJ_LITTLE_ENDIAN #elif HOST_IS_BIG_ENDIAN #define HOST_ENDIANESS AJ_BIG_ENDIAN #endif #ifdef __cplusplus } #endif /** * @} */ #endif //AJ_CONFIG_H ajtcl-15.04b/inc/aj_connect.h000066400000000000000000000122531256742562600160310ustar00rootroot00000000000000#ifndef _AJ_CONNECT_H #define _AJ_CONNECT_H /** * @file aj_connect.h * @defgroup aj_connect Bus Connection Management * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_status.h" #include "aj_bus.h" #include "aj_disco.h" #ifdef __cplusplus extern "C" { #endif /** * Set the minimum acceptable routing node protocol version. * * @param min Minimum acceptable protocol version */ void AJ_SetMinProtoVersion(uint8_t min); /** * Set the amount of time to wait for routing node responses. * * @param selection time for selecting routing node responses */ void AJ_SetSelectionTimeout(uint32_t selection); /** * Get the minimum acceptable routing node protocol version. * * @return Minimum acceptable protocol version */ uint8_t AJ_GetMinProtoVersion(); /** * Get the routing nodes protocol version * * @return The routing nodes protocol version * 0 if not connected to a routing node */ AJ_EXPORT uint8_t AJ_GetRoutingProtoVersion(void); /** * Authenticate with the daemon * * @param bus The bus attachment to authenticate * * @return Return AJ_Status */ AJ_Status AJ_Authenticate(AJ_BusAttachment* bus); /** * Establish an AllJoyn connection. * * @param bus The bus attachment to connect. * @param serviceName Name of a specific service to connect to, NULL for the default name. * @param timeout How long to spend attempting to connect * * @return * - AJ_OK if the connection was succesfully established * - AJ_ERR_TIMEOUT if the connection attempt timed out */ AJ_EXPORT AJ_Status AJ_Connect(AJ_BusAttachment* bus, const char* serviceName, uint32_t timeout); #ifdef AJ_ARDP /** * Establish an ARDP-based AllJoyn UDP connection. * * @param bus The bus attachment to connect. * @param context The context that will be used to send and receive data * @param service The connection information * @param netSock The netSock * * @return * - AJ_OK if the connection was succesfully established * - AJ_ERR_TIMEOUT if the connection attempt timed out */ AJ_EXPORT AJ_Status AJ_ARDP_UDP_Connect(AJ_BusAttachment* bus, void* context, const AJ_Service* service, AJ_NetSocket* netSock); #endif /** * Find a daemon, connect to it and then authenticate. * * @param bus The bus attachment to connect. * @param serviceName Name of a specific service to connect to, NULL for the default name. * @param timeout How long to spend attempting to connect * * @return * - AJ_OK if the connection was succesfully established * - AJ_ERR_TIMEOUT if the connection attempt timed out */ AJ_EXPORT AJ_Status AJ_FindBusAndConnect(AJ_BusAttachment* bus, const char* serviceName, uint32_t timeout); /** * Terminate an AllJoyn connection * * @param bus The bus attachment to disconnect. */ AJ_EXPORT void AJ_Disconnect(AJ_BusAttachment* bus); /** * Bus authentication password function prototype for requesting a * password (to authenticate with the daemon) from the application. * * @param buffer The buffer to receive the password * @param bufLen The size of the buffer * * @return Returns the length of the password. If the length is zero, * this will be treated as a rejected password request. */ typedef uint32_t (*BusAuthPwdFunc)(uint8_t* buffer, uint32_t bufLen); /** * Set the callback for the application to provide a password for authentication to the daemon bus * * @param callback The callback provided by the application */ AJ_EXPORT void SetBusAuthPwdCallback(BusAuthPwdFunc callback); /** * Check whether we have already attempted to connect to the routing node * specified by service. * * @param service The service info struct * * @return TRUE if blacklisted */ uint8_t AJ_IsRoutingNodeBlacklisted(AJ_Service* service); void AJ_AddRoutingNodeToResponseList(AJ_Service* service); AJ_Status AJ_SelectRoutingNodeFromResponseList(AJ_Service* service); uint8_t AJ_GetRoutingNodeResponseListSize(); /** * Clear the list of blacklisted routing nodes. */ void AJ_InitRoutingNodeBlacklist(); void AJ_InitRoutingNodeResponselist(); #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_crc16.h000066400000000000000000000036221256742562600153160ustar00rootroot00000000000000#ifndef _AJ_CRC16_H #define _AJ_CRC16_H /** * @file */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #ifdef __cplusplus extern "C" { #endif /** * Computes a 16-bit CRC on a buffer. The caller provides the context for the running CRC. * * @param buffer buffer over which to compute the CRC * @param bufLen length of the buffer in bytes * @param runningCrc On input the current CRC, on output the updated CRC. */ void AJ_CRC16_Compute(const uint8_t* buffer, uint16_t bufLen, uint16_t* runningCrc); /** * This function completes the CRC computation by rearranging the CRC bits and bytes * into the correct order. * * @param crc computed crc as calculated by AJ_CRC16_Compute() * @param crcBlock pointer to a 2-byte buffer where the resulting CRC will be stored */ void AJ_CRC16_Complete(uint16_t crc, uint8_t* crcBlock); #ifdef __cplusplus } #endif #endif /* _AJ_CRC16_H */ ajtcl-15.04b/inc/aj_creds.h000066400000000000000000000161321256742562600155000ustar00rootroot00000000000000#ifndef _AJ_CREDS_H #define _AJ_CREDS_H /** * @file aj_creds.h * @defgroup aj_creads Credentials Management * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_guid.h" #include "aj_status.h" #include "aj_config.h" #ifdef __cplusplus extern "C" { #endif #define AJ_CRED_TYPE_GENERIC 1 /** < generic type */ #define AJ_CRED_TYPE_AES 2 /** < AES type */ #define AJ_CRED_TYPE_PRIVATE 3 /** < private key type */ #define AJ_CRED_TYPE_PEM 4 /** < PEM encoded type */ #define AJ_CRED_TYPE_PUBLIC 5 /** < public key type */ #define AJ_CRED_TYPE_SPKI_CERT 6 /** < SPKI style certificate type */ #define AJ_CRED_TYPE_DSA_PRIVATE 7 /** < DSA private key type */ #define AJ_CRED_TYPE_DSA_PUBLIC 8 /** < DSA public key type */ /** * Credentials for a remote peer */ typedef struct _AJ_PeerCred { uint16_t type; /** < credential type */ uint8_t idLen; /** < the length of the id field */ uint8_t* id; /**< the id field, it can be GUID for the peer */ uint32_t expiration; /**< the expiry time expressed a number of seconds since Epoch */ uint8_t associationLen; /**< association length */ uint8_t* association; /**< association */ uint16_t dataLen; /**< data length */ uint8_t* data; /**< data */ } AJ_PeerCred; /** * Write a peer credential to NVRAM * * @param peerCred The credentials to write. * * @return * - AJ_OK if the credentials were written. * - AJ_ERR_RESOURCES if there is no space to write the credentials */ AJ_Status AJ_StoreCredential(AJ_PeerCred* peerCred); /** * Store the peer secret * * @param peerGuid The peer's GUID * @param secret The peer's secret * @param len The peer's secret's length * @param expiration The expiration of the secret * * @return * - AJ_OK if the credentials were written. * - AJ_ERR_RESOURCES if there is no space to write the credentials */ AJ_Status AJ_StorePeerSecret(const AJ_GUID* peerGuid, const uint8_t* secret, const uint8_t len, uint32_t expiration); /** * Delete a peer credential from NVRAM * * @param peerGuid The guid for the peer that has credentials to delete. * * @return * - AJ_OK if the credentials were deleted. */ AJ_Status AJ_DeletePeerCredential(const AJ_GUID* peerGuid); /** * Clears all peer credentials. * * @return * - AJ_OK if all credentials have been deleted */ AJ_Status AJ_ClearCredentials(void); /** * Get the credentials for a specific remote peer from NVRAM * * @param peerGuid The GUID for the remote peer. * @param peerCredHolder Pointer to a credential object pointer. This address will hold the new allocated credential object for the specific remote peer identified by a GUID * * @return * - AJ_OK if the credentials for the specific remote peer exist and are copied into the buffer * - AJ_ERR_FAILURE otherwise. */ AJ_Status AJ_GetPeerCredential(const AJ_GUID* peerGuid, AJ_PeerCred** peerCredHolder); /** * Get the GUID for this peer. If this is the first time the GUID has been requested this function * will generate the GUID and store it in NVRAM * * @param[out] localGuid Pointer to a bufffer that has enough space to store the local GUID * * @return AJ_OK if the local GUID is copied into the buffer. */ AJ_Status AJ_GetLocalGUID(AJ_GUID* localGuid); /** * Free the memory allocation for this credential object. The object itself * will also be freed. * * @param cred Pointer to a credential object * * @return * - AJ_OK if the deallocation process succeeds * - AJ_ERR_FAILURE otherwise. */ AJ_Status AJ_FreeCredential(AJ_PeerCred* cred); /** * Delete a credential from NVRAM * * @param credType the credential type * @param id the credential id * @param idLen the credential id length * * @return * - AJ_OK if the credentials were deleted. */ AJ_Status AJ_DeleteCredential(const uint16_t credType, const uint8_t* id, uint8_t idLen); /** * Get the credentials for a specific id from NVRAM * * @param credType the credential type to search * @param id the credential id to search * @param idLen the credential id length to search * @param credHolder Pointer to a credential object pointer. This address will hold the new allocated credential object for the specific custom credential * * @return * - AJ_OK if the credential is found * - AJ_ERR_FAILURE otherwise. */ AJ_Status AJ_GetCredential(const uint16_t credType, const uint8_t* id, uint8_t idLen, AJ_PeerCred** credHolder); /** * Get the local credentials for a specific id from NVRAM * * @param credType the credential type to search * @param id the credential id to search * @param[out] credHolder Pointer to a credential object pointer. This address will hold the new allocated credential object for the specific custom credential * * @return * - AJ_OK if the credential is found * - AJ_ERR_FAILURE otherwise. */ AJ_Status AJ_GetLocalCredential(const uint16_t credType, const uint16_t id, AJ_PeerCred** credHolder); /** * Store a local credential * * @param credType the credential type * @param id The local id * @param data The data * @param len The data length * @param expiration The expiration of the data * * @return * - AJ_OK if the credentials were written. * - AJ_ERR_RESOURCES if there is no space to write the credentials */ AJ_Status AJ_StoreLocalCredential(const uint16_t credType, const uint16_t id, const uint8_t* data, const uint8_t len, uint32_t expiration); /** * Delete the local credentials for a specific id from NVRAM * * @param credType the credential type to delete * @param id the credential id to delete * * @return * - AJ_OK if the credential is deleted * - AJ_ERR_FAILURE otherwise. */ AJ_Status AJ_DeleteLocalCredential(const uint16_t credType, const uint16_t id); /** * Checks a credential's expiry * @return * - AJ_OK if the credential has not expired * - AJ_ERR_KEY_EXPIRED if the credential has expired * - AJ_ERR_INVALID if not clock is available */ AJ_Status AJ_CredentialExpired(AJ_PeerCred* cred); #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_crypto.h000066400000000000000000000170441256742562600157230ustar00rootroot00000000000000#ifndef _AJ_CRYPTO_H #define _AJ_CRYPTO_H /** * @file aj_crypto.h * @defgroup aj_crypto Cryptographic Support * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_status.h" #ifdef __cplusplus extern "C" { #endif /** * Implements AES-CCM (Counter with CBC-MAC) encryption as described in RFC 3610. The message in * encrypted in place. * * @param key The AES-128 encryption key * @param msg The buffer containing the entire message that is to be encrypted, The buffer must * have room at the end to append an authentication tag of length tagLen. * @param msgLen The length of the entire message * @param hdrLen The length of the header portion that will be authenticated but not encrypted * @param tagLen The length of the authentication tag to be appended to the message * @param nonce The nonce * @param nLen The length of the nonce * * @return * - AJ_OK if the CCM context is initialized * - AJ_ERR_RESOURCES if the resources required are not available. */ AJ_Status AJ_Encrypt_CCM(const uint8_t* key, uint8_t* msg, uint32_t msgLen, uint32_t hdrLen, uint8_t tagLen, const uint8_t* nonce, uint32_t nLen); /** * Implements AES-CCM (Counter with CBC-MAC) decryption as described in RFC 3610. The message in * decrypted in place. * * @param key The AES-128 encryption key * @param msg The buffer containing the entire message to be decrypted. * @param msgLen The length of the entire message, excluding the tag. * @param hdrLen The length of the header portion that will be authenticated but not encrypted * @param tagLen The length of the authentication tag to be appended to the message * @param nonce The nonce * @param nLen The length of the nonce * * @return * - AJ_OK if the CCM context is initialized * - AJ_ERR_RESOURCES if the resources required are not available. */ AJ_Status AJ_Decrypt_CCM(const uint8_t* key, uint8_t* msg, uint32_t msgLen, uint32_t hdrLen, uint8_t tagLen, const uint8_t* nonce, uint32_t nLen); /** * A pseudo-random function for generation of keying material. This function uses AES-CCM to * as the MAC function. * * @param inputs Array of input data blocks * @param lengths The lengths of input data blocks * @param count The number of input data blocks * @param out The buffer to receive the keying material * @param outLen The amount of keying materail to be generated. * * @return * - AJ_OK if the PRF ran succesfully * - AJ_ERR_RESOURCES if the resources required are not available. */ AJ_Status AJ_Crypto_PRF(const uint8_t** inputs, const uint8_t* lengths, uint32_t count, uint8_t* out, uint32_t outLen); /** * Return a string of randomly generated bytes. * * @param rand Pointer to a buffer to return the random data * @param size The number of random bytes to return. */ void AJ_RandBytes(uint8_t* rand, uint32_t size); /** * Return a random hexadecimal string of the requested length * * @param rand Pointer to a buffer to return the random data * @param bufLen The length of the buffer. The buffer must be at * least (len * 2) + 1 bytes. * @param len The length of the hexadecimal string * * @return Return AJ_Status * - AJ_OK if the string was converted * - AJ_ERR_RESOURCES if the hexLen is too small to fit the converted string. */ AJ_Status AJ_RandHex(char* rand, uint32_t bufLen, uint32_t len); /** * Enable AES allocating any resources required * * @param key The key in case this is required */ void AJ_AES_Enable(const uint8_t* key); /** * Disable AES freeing any resources that were allocated */ void AJ_AES_Disable(void); /** * AES counter mode encryption/decryption. Note that in CTR mode encrytion is its own inverse. * * @param key The AES encryption key * @param in The data to encrypt * @param out The encrypted data * @param len The length of the input data, must be multiple of 16 * @param ctr Pointer to a 16 byte counter block */ void AJ_AES_CTR_128(const uint8_t* key, const uint8_t* in, uint8_t* out, uint32_t len, uint8_t* ctr); /** * AES CCM mode encryption * * @param key The AES encryption key * @param in The data to encrypt * @param out The encrypted data * @param len The length of the input data, must be multiple of 16 * @param iv Pointer to a 16 byte initialization vector */ void AJ_AES_CBC_128_ENCRYPT(const uint8_t* key, const uint8_t* in, uint8_t* out, uint32_t len, uint8_t* iv); /** * Encrypt a single 16 byte block using AES in ECB mode * * @param key The AES encryption key * @param in The data to encrypt * @param out The encrypted data */ void AJ_AES_ECB_128_ENCRYPT(const uint8_t* key, const uint8_t* in, uint8_t* out); /** * AES-128 CTR DRBG constants */ #define OUTLEN 16 #define KEYLEN 16 #define SEEDLEN OUTLEN + KEYLEN /** * Context for AES-128 CTR DRBG */ typedef struct _CTR_DRBG_CTX { uint8_t df; /**< Use DF or not */ uint8_t v[OUTLEN]; /**< Internal working state */ uint8_t k[KEYLEN]; /**< Key working state */ uint32_t c; /**< Reseed counter */ } CTR_DRBG_CTX; /** * AES-128 CTR DRBG instantiate function * This takes a seed value: entropy || nonce || personalization * * @param ctx The context * @param seed Input seed material * @param size Input seed material size * @param df Use DF or not */ void AES_CTR_DRBG_Instantiate(CTR_DRBG_CTX* ctx, uint8_t* seed, size_t size, uint8_t df); /** * AES-128 CTR DRBG reseed function * This takes a seed value: entropy || additional * * @param ctx The context * @param seed Input seed material * @param size Input seed material size */ void AES_CTR_DRBG_Reseed(CTR_DRBG_CTX* ctx, uint8_t* seed, size_t size); /** * AES-128 CTR DRBG generate function * This implementation does not take additional input * * @param ctx The context * @param rand Output rand material * @param size Required output rand material size * * @return Return AJ_Status * - AJ_OK on success * - AJ_ERR_SECURITY if reseed required */ AJ_Status AES_CTR_DRBG_Generate(CTR_DRBG_CTX* ctx, uint8_t* rand, size_t size); #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_crypto_ecc.h000066400000000000000000000121061256742562600165270ustar00rootroot00000000000000#ifndef _AJ_CRYPTO_ECC_H #define _AJ_CRYPTO_ECC_H /** * @file aj_crypto_ecc.h * @defgroup aj_crypto Cryptographic Support * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_status.h" #ifdef __cplusplus extern "C" { #endif typedef enum {B_FALSE, B_TRUE} boolean_t; #define BIGLEN 9 /* * For P256 bigval_t types hold 288-bit 2's complement numbers (9 * 32-bit words). For P192 they hold 224-bit 2's complement numbers * (7 32-bit words). * * The representation is little endian by word and native endian * within each word. */ typedef struct { uint32_t data[BIGLEN]; } bigval_t; typedef struct { bigval_t x; bigval_t y; uint32_t infinity; } affine_point_t; typedef struct { bigval_t r; bigval_t s; } ECDSA_sig_t; typedef bigval_t ecc_privatekey; typedef affine_point_t ecc_publickey; typedef affine_point_t ecc_secret; typedef ECDSA_sig_t ecc_signature; /** * ECC type sizes */ #define KEY_ECC_SZ (8 * sizeof (uint32_t)) #define KEY_ECC_PRV_SZ KEY_ECC_SZ #define KEY_ECC_PUB_SZ (2 * KEY_ECC_SZ) #define KEY_ECC_SEC_SZ (2 * KEY_ECC_SZ) #define KEY_ECC_SIG_SZ (2 * KEY_ECC_SZ) /** * Generates the Ephemeral Diffie-Hellman key pair. * * @param publicKey The output public key * @param privateKey The output private key * * @return - AJ_OK if the key pair is successfully generated. * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_GenerateDHKeyPair(ecc_publickey* publicKey, ecc_privatekey* privateKey); /** * Generates the Diffie-Hellman share secret. * * @param peerPublicKey The peer's public key * @param privateKey The private key * @param secret The output share secret * * @return - AJ_OK if the share secret is successfully generated. * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_GenerateShareSecret(ecc_publickey* peerPublicKey, ecc_privatekey* privateKey, ecc_secret* secret); /** * Generates the DSA key pair. * * @param publicKey The output public key * @param privateKey The output private key * @return - AJ_OK if the key pair is successfully generated * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_GenerateDSAKeyPair(ecc_publickey* publicKey, ecc_privatekey* privateKey); /** * Sign a digest using the DSA key * @param digest The digest to sign * @param signingPrivateKey The signing private key * @param sig The output signature * @return - AJ_OK if the signing process succeeds * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_DSASignDigest(const uint8_t* digest, const ecc_privatekey* signingPrivateKey, ecc_signature* sig); /** * Sign a buffer using the DSA key * @param buf The buffer to sign * @param len The buffer len * @param signingPrivateKey The signing private key * @param sig The output signature * @return - AJ_OK if the signing process succeeds * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_DSASign(const uint8_t* buf, uint16_t len, const ecc_privatekey* signingPrivateKey, ecc_signature* sig); /** * Verify DSA signature of a digest * @param digest The digest to sign * @param sig The signature * @param pubKey The signing public key * @return - AJ_OK if the signature verification succeeds * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_DSAVerifyDigest(const uint8_t* digest, const ecc_signature* sig, const ecc_publickey* pubKey); /** * Verify DSA signature of a buffer * @param buf The buffer to sign * @param len The buffer len * @param sig The signature * @param pubKey The signing public key * @return - AJ_OK if the signature verification succeeds * - AJ_ERR_SECURITY otherwise */ AJ_Status AJ_DSAVerify(const uint8_t* buf, uint16_t len, const ecc_signature* sig, const ecc_publickey* pubKey); /** * Encode Bigval to big-endian byte array * @param src The input bigval * @param tgt The output buffer * @param tgtlen The output buffer length */ void AJ_BigvalEncode(const bigval_t* src, uint8_t* tgt, size_t tgtlen); /** * Decode Bigval from big-endian byte array * @param src The input buffer * @param tgt The output bigval * @param srclen The input buffer length */ void AJ_BigvalDecode(const uint8_t* src, bigval_t* tgt, size_t srclen); #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_crypto_sha2.h000066400000000000000000000107611256742562600166370ustar00rootroot00000000000000#ifndef _AJ_CRYPTO_SHA2_H #define _AJ_CRYPTO_SHA2_H /** * @file aj_crypto_sha2.h * @defgroup aj_crypto SHA-256 Cryptographic Support * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_status.h" #include "sha2.h" #ifdef __cplusplus extern "C" { #endif typedef SHA256_CTX AJ_SHA256_Context; #define HMAC_SHA256_DIGEST_LENGTH SHA256_DIGEST_LENGTH #define HMAC_SHA256_BLOCK_LENGTH 64 typedef struct _AJ_HMAC_SHA256_CTX { uint8_t ipad[HMAC_SHA256_BLOCK_LENGTH]; uint8_t opad[HMAC_SHA256_BLOCK_LENGTH]; AJ_SHA256_Context hashCtx; } AJ_HMAC_SHA256_CTX; /*** SHA-256/384/512 Function Prototypes ******************************/ #ifndef NOPROTO /** * Initialize the hash context * @param context the hash context */ void AJ_SHA256_Init(AJ_SHA256_Context* context); /** * Update the digest using the specific bytes * @param context the hash context * @param buf the bytes to digest * @param bufSize the number of bytes to digest */ void AJ_SHA256_Update(AJ_SHA256_Context* context, const uint8_t* buf, size_t bufSize); /** * Retrieve the digest * @param context the hash context * @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH * @param keepAlive keep the digest process alive for continuing digest */ void AJ_SHA256_GetDigest(AJ_SHA256_Context* context, uint8_t* digest, const uint8_t keepAlive); /** * Retrieve the final digest * @param context the hash context * @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH */ void AJ_SHA256_Final(AJ_SHA256_Context* context, uint8_t* digest); /** * Initialize the HMAC context * @param ctx the HMAC context * @param key the key * @param keyLen the length of the key * @return * - AJ_OK if successful * - AJ_ERR_INVALID if the length is negative */ AJ_Status AJ_HMAC_SHA256_Init(AJ_HMAC_SHA256_CTX* ctx, const uint8_t* key, size_t keyLen); /** * Update the hash with data * @param ctx the HMAC context * @param data the data * @param dataLen the length of the data * @return * - AJ_OK if successful * - AJ_ERR_INVALID if the length is negative */ AJ_Status AJ_HMAC_SHA256_Update(AJ_HMAC_SHA256_CTX* ctx, const uint8_t* data, size_t dataLen); /** * Retrieve the final digest for the HMAC * @param ctx the HMAC context * @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH */ AJ_Status AJ_HMAC_SHA256_Final(AJ_HMAC_SHA256_CTX* ctx, uint8_t* digest); /** * Random function * @param inputs array holding secret, label, seed * @param lengths array holding the lengths of the inputs * @param count the size of the input array * @param out the buffer holding the random value * @param outLen the buffer size * @return AJ_OK if succeeds; otherwise error */ AJ_Status AJ_Crypto_PRF_SHA256(const uint8_t** inputs, const uint8_t* lengths, uint32_t count, uint8_t* out, uint32_t outLen); #else /* NOPROTO */ /** * Initialize the hash context * @param context the hash context * @return AJ_OK if successful */ void AJ_SHA256_Init(); /** * Update the digest using the specific bytes * @param context the hash context * @param buf the bytes to digest * @param bufSize the number of bytes to digest * @return AJ_OK if successful */ void AJ_SHA256_Update(); /** * Update the digest using the specific bytes * @param context the hash context * @param digest the buffer to hold the digest. Must be of size SHA256_DIGEST_LENGTH * @return AJ_OK if successful */ void AJ_SHA256_GetDigest(); #endif /* NOPROTO */ #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_debug.h000066400000000000000000000315771256742562600155000ustar00rootroot00000000000000#ifndef _AJ_DEBUG_H #define _AJ_DEBUG_H /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ /** * @file aj_debug.h * This file contains the debug logging support for the Thin Client. * * @defgroup aj_debug Debug Logging * * @brief The debug logging module provides structured support for what is * sometimes called "printf debugging" or "debug tracing." As in most such * facilities, support for different levels of verbosity is provided. Since a * Thin Client program can be run on different devices with very different * capabilities, the debug logging module allows for convenient and verbose * debug logging on off-target (desktop-like) platforms; and it provides the * ability to constrain debug logging in on-target (embedded system) platforms. * Because debug logging needs to work in both desktop and embedded environments * there are a few more "knobs" than one might expect. The next sections * describe how to quickly enable debug output and then continues to explain how * to configure debug logging in more detail on platforms of different * capabilities. * * @section aj_debug_qs Quick Start * * To enable all debug logging from all modules, open inc/aj_debug.h in your * favorite editor and change the definition of @c AJ_DEBUG_RESTRICT to: * * @code * #define AJ_DEBUG_RESTRICT AJ_DEBUG_ALL * @endcode * * Open src/aj_debug.c in your favorite editor and set the initial value of the * verbosity setting @c AJ_DbgLevel to: * * @code * AJ_DebugLevel AJ_DbgLevel = AJ_DEBUG_ALL; * @endcode * * If you want to enable logging from all modules, change the initial value of * @c dbgALL in src/aj_debug.c to: * * @code * uint8_t dbgALL = 1; * @endcode * * After the changes are made, do a debug build (NDEBUG must be set to false to * allow any logging above the warning level). Debug logging will now be * enabled for all modules. When a Thin Client program is run, the system will * begin logging debug messages to the device console formatted as: * * @code * seconds.milliseconds filename:line-number message * @endcode * * If you find the logging from all modules to be too verbose, you can enable * logging from specific modules. In this case, leave @c dbgALL set to zero and * enable logging for each module individually. For a module named @c MODULE * change the initial value of the variable @c dbgMODULE in src/aj_MODULE.c to * nonzero. For example, to enable logging in the CONNECT module, change the * variable @c dbgCONNECT in src/aj_connect.c to: * * @code * uint8_t dbgCONNECT = 1; * @endcode * * @note Setting @c dbgALL or @c dbgCONNECT may be done by changing the variable * in memory using a debugger at runtime instead of by hardcoding as shown here. * * @section aj_debug_env Enabling Debug Logging Using Environment Variables * * On targets that support it (for example Linux or Windows), debug logging may * also enabled using environment variables. Instead of setting a memory variable * named as @c dbgMODULE one can set a corresponding environment variable named as * @c ER_DEBUG_MODULE. If one wanted to enable debug logging in the CONNECT module * as done in the @ref aj_debug_qs section, one would set the environment variable * for the CONNECT module: * * @code * export ER_DEBUG_CONNECT=1 * @endcode * * @note There is an environment variable corresponding to the @c dbgALL memory * variable. to enable logging on @c ALL modules, simply set the @c * ER_DEBUG_ALL environment variable. * * @section aj_debug_ver Changing Verbosity of Debug Logging * * Often, the amount of debug logging printed can be quite large. To minimize * the amount of "debug spew" it is possible to control the verbosity of the * debug output. This is done by changing the value of the memory variable @c * AJ_DbgLevel. * * There are several different levels of verbosity: @par * @ref AJ_DEBUG_OFF @par * @ref AJ_DEBUG_ERROR @par * @ref AJ_DEBUG_WARN @par * @ref AJ_DEBUG_INFO @par * @ref AJ_DEBUG_DUMP @par * @ref AJ_DEBUG_ALL @par * * To use this feature, set the variable @c AJ_DbgLevel either by hardcoding in * src/aj_debug.c or by setting the memory variable using a debugger. Think of * this value as enabling messages of the specified verbosity and lesser. For * example, in order to enable error, warning and informational messages, go to * src/aj_debug.c and set the initial value of @c AJ_DbgLevel to: * * @code * AJ_DebugLevel AJ_DbgLevel = AJ_DEBUG_INFO; * @endcode * * @note Again, one can set AJ_DbgLevel in the debugger to dynamically control the * verbosity of logging at runtime. * * @section aj_debug_com Restricting Compilation of Debug Logging * * It is possible that some target environments are restricted to such a degree that * it is not possible to store all of the strings required for the various log * statements in memory. To accommodate such environments a @c RESTRICT mechanism * is provided. This restriction mechanism is controlled by the definition of * @c AJ_DEBUG_RESTRICT in the inc/aj_debug.h header file. * * The same verbosity levels are used in the @c RESTRICT mechanism as were shown * in the @ref aj_debug_ver section, but the meaning is different. Think of the * definition of AJ_DEBUG_RESTRICT as meaning, restrict messages of levels * greater than the specified level from even being compiled into the code. The * default value of AJ_DEBUG_RESTRICT is given as AJ_DEBUG_WARN so by default * only error and warning messages will be logged. Messages of AJ_DEBUG_INFO * level and greater are not compiled into the code by default. In the @ref * aj_debug_qs section, AJ_DEBUG_RESTRICT was set to AJ_DEBUG_ALL to allow all * messages to be compiled into the code so they could be logged. * * Typically, if one is running on a platform that has enough memory to * accommodate all of the log messages one would change AJ_DEBUG_RESTRICT to * AJ_DEBUG_ALL and simply leave it along. The usefulness of this definition is * when the target cannot accommodate all of the strings. In that case, it may * be useful to relax the restriction on a per-module basis to enable subsets of * logging when required. To accomplish this, one would leave AJ_DEBUG_RESTRICT * set to AJ_DEBUG_INFO in inc/aj_debug.h and add the following code to the * source file of the module where logging was to be enabled before inclusion of * aj_debug.h: * * @code * #define AJ_DEBUG_RESTRICT AJ_DEBUG_ALL * @endcode * * @{ */ #include "aj_target.h" #include "aj_msg.h" #ifdef __cplusplus extern "C" { #endif /** * Always print a message in a fashion similar to other conditional log outputs. * Do not include time stamp, file and line number. * * @param msg A format string and arguments */ #define AJ_AlwaysPrintf(msg) \ do { \ AJ_Printf msg; \ } while (0) #ifndef NDEBUG /** * Dump message name and content. if body is true, dump raw data * * @param tag tag name of message * @param msg message header * @param body if true, dump raw data */ void _AJ_DumpMsg(const char* tag, AJ_Message* msg, uint8_t body); /** * Dump raw (byte) data in a convenient format. * * @param tag tag name of message * @param data start address to dump * @param len length to dump */ void _AJ_DumpBytes(const char* tag, const uint8_t* data, uint32_t len); /* * Threshold level for debug output. When used with AJ_DbgLevel the setting * controls which debug messages are actually printed. These values are also * used in the AJ_DEBUG_RESTRICT mechanism to control which log messages are * actually compiled into the code. */ #define AJ_DEBUG_OFF 0 /**< Suppresses all debug output */ #define AJ_DEBUG_ERROR 1 /**< Indicates a log message conveying an error condition */ #define AJ_DEBUG_WARN 2 /**< Indicates a log message corresponding to a warning */ #define AJ_DEBUG_INFO 3 /**< Indicates a log message with general information */ #define AJ_DEBUG_DUMP 4 /**< Indicates a message with a detailed, possibly byte-by-byte dump */ #define AJ_DEBUG_ALL 5 /**< A placeholder level above other levels */ /** * Type definition for a value used to control the debug level (verbosity) * threshold. */ typedef uint32_t AJ_DebugLevel; /** * We allow the verbosity of debug output to be controlled programmatically using * predefined AJ_DEBUG_* threshold levels. The macro AJ_DEBUG_RESTRICT is used * in the sense of restricting (not compiling in) messages with verbosity levels * greater than the given level. * * By default, all messages of all verbosity at info level and above are not * compiled into the code (by defining AJ_DEBUG_RESTRICT to be AJ_DEBUG_WARN). */ #ifndef AJ_DEBUG_RESTRICT #define AJ_DEBUG_RESTRICT AJ_DEBUG_WARN #endif /** * Set this value to control the debug output threshold level. The default is AJ_DEBUG_ERROR */ AJ_EXPORT extern AJ_DebugLevel AJ_DbgLevel; AJ_EXPORT extern uint8_t dbgALL; extern int _AJ_DbgEnabled(const char* module); /** * Internal debug printf function. Don't call this directly, use the AJ_*Printf() macros. * * @param level The level associated with this debug print * @param file File name for file calling this function * @param line Line number for line this function was called from */ AJ_EXPORT int _AJ_DbgHeader(AJ_DebugLevel level, const char* file, int line); #define QUOTE(x) # x #define STR(x) QUOTE(x) #define CONCAT(x, y) x ## y #define MKVAR(x, y) CONCAT(x, y) #if AJ_DEBUG_RESTRICT >= AJ_DEBUG_ERROR /** * Print an error message. Error messages may be suppressed by AJ_DEBUG_RESTRICT * * @param msg A format string and arguments */ #define AJ_ErrPrintf(msg) \ do { \ if (_AJ_DbgHeader(AJ_DEBUG_ERROR, __FILE__, __LINE__)) { AJ_Printf msg; } \ } while (0) #else #define AJ_ErrPrintf(_msg) #endif #if AJ_DEBUG_RESTRICT >= AJ_DEBUG_WARN /** * Print a warning message. Warnings may be suppressed by AJ_DEBUG_RESTRICT * * @param msg A format string and arguments */ #define AJ_WarnPrintf(msg) \ do { \ if (_AJ_DbgHeader(AJ_DEBUG_WARN, __FILE__, __LINE__)) { AJ_Printf msg; } \ } while (0) #else #define AJ_WarnPrintf(_msg) #endif #if AJ_DEBUG_RESTRICT >= AJ_DEBUG_INFO /** * Print an informational message. Informational messages may be suppressed by * AJ_DEBUG_RESTRICT or by the module selection (global memory value or shell * environment variable) mechanism. * * @param msg A format string and arguments */ #define AJ_InfoPrintf(msg) \ do { \ if (dbgALL || MKVAR(dbg, AJ_MODULE) || _AJ_DbgEnabled(STR(AJ_MODULE))) { \ if (_AJ_DbgHeader(AJ_DEBUG_INFO, __FILE__, __LINE__)) { AJ_Printf msg; } \ } \ } while (0) #else #define AJ_InfoPrintf(_msg) #endif #if AJ_DEBUG_RESTRICT >= AJ_DEBUG_DUMP /** * Dump the bytes in a buffer in a human readable way. Byte dumps messages may * be suppressed by AJ_DEBUG_RESTRICT or by the module selection (global memory * value or shell environment variable) mechanism. * * @param msg A format string * and arguments */ #define AJ_DumpBytes(tag, data, len) \ do { \ if (MKVAR(dbg, AJ_MODULE) || _AJ_DbgEnabled(STR(AJ_MODULE))) { _AJ_DumpBytes(tag, data, len); } \ } while (0) #else #define AJ_DumpBytes(tag, data, len) #endif #if AJ_DEBUG_RESTRICT >= AJ_DEBUG_DUMP /** * Print a human readable summary of a message. Message dumps messages may be * suppressed by AJ_DEBUG_RESTRICT or by the module selection (global memory * value or shell environment variable) mechanism. * * @param msg A format string and arguments */ #define AJ_DumpMsg(tag, msg, body) \ do { \ if (MKVAR(dbg, AJ_MODULE) || _AJ_DbgEnabled(STR(AJ_MODULE))) { _AJ_DumpMsg(tag, msg, body); } \ } while (0) #else #define AJ_DumpMsg(tag, msg, body) #endif #else #define AJ_DumpMsg(tag, msg, body) #define AJ_DumpBytes(tag, data, len) #define AJ_ErrPrintf(_msg) #define AJ_WarnPrintf(_msg) #define AJ_InfoPrintf(_msg) #endif /** * Utility function that converts numerical status to a readable string * * @param status A status code */ AJ_EXPORT const char* AJ_StatusText(AJ_Status status); #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_disco.h000066400000000000000000000045341256742562600155040ustar00rootroot00000000000000#ifndef _AJ_DISCO_H #define _AJ_DISCO_H /** * @file */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_bufio.h" #ifdef __cplusplus extern "C" { #endif /** * Information about the remote service */ typedef struct _AJ_Service { uint8_t addrTypes; /**< address type */ uint16_t transportMask; /**< restricts the transports the advertisement */ uint16_t ipv4port; /**< port number of ipv4 */ uint16_t ipv6port; /**< port number of ipv6 */ uint32_t ipv4; /**< ipv4 address */ uint16_t priority; /**< priority */ uint32_t pv; /**< protocol version */ uint32_t ipv6[4]; /**< ipv6 address */ uint16_t ipv4portUdp; /**< port number of ipv4 */ uint16_t ipv6portUdp; /**< port number of ipv6 */ uint32_t ipv4Udp; /**< ipv4 address */ uint32_t ipv6Udp[4]; /**< ipv6 address */ } AJ_Service; /** * Discover a remote service * * @param prefix The service name prefix * @param service Information about the service that was found * @param timeout How long to wait to discover the service * @param selectionTimeout How long to wait to receive router responses * * @return Return AJ_Status */ AJ_Status AJ_Discover(const char* prefix, AJ_Service* service, uint32_t timeout, uint32_t selectionTimeout); #ifdef __cplusplus } #endif #endif ajtcl-15.04b/inc/aj_guid.h000066400000000000000000000177621256742562600153420ustar00rootroot00000000000000#ifndef _AJ_GUID_H #define _AJ_GUID_H /** * @file aj_guid.h * @defgroup aj_guid Globally Unique Identifier Support * @{ * @file */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_status.h" #include "aj_bus.h" #ifdef __cplusplus extern "C" { #endif /** * Type for a GUID */ typedef struct _AJ_GUID { uint8_t val[16]; /**< string for a GUID */ } AJ_GUID; /** * Type for tracking serial numbers */ typedef struct _AJ_SerialNum { uint32_t serial; /**< base serial number */ uint64_t offset; /**< offset (from base) of allowed message */ } AJ_SerialNum; /** * Return a pointer to an ASCII string representation of a GUID * * @param guid The guid to convert * @param buffer The buffer to store the string * @param bufLen The size of the buffer. * * * @return Return AJ_Status * - AJ_OK if the GUID was converted * - AJ_ERR_RESOURCES if the buffer was not big enough */ AJ_Status AJ_GUID_ToString(const AJ_GUID* guid, char* buffer, uint32_t bufLen); /** * Unpacks a string into a GUID * * @param guid Pointer to a GUID structure * @param str A hex string representation of the GUID * * @return Return AJ_Status * - AJ_OK if the conversion was succsessful * - An error status otherwise */ AJ_Status AJ_GUID_FromString(AJ_GUID* guid, const char* str); /** * Clears names from the GUID map */ void AJ_GUID_ClearNameMap(void); /** * Adds a unique name to the GUID map. * * This also adds a match rule for the name owner changed signal to * detect when the name mapping can be deleted. * * @param bus The bus attachment * @param guid The GUID to add * @param uniqueName A unique name that maps to the GUID * @param serviceName A service name that maps to the GUID * * @return Return AJ_Status * - AJ_OK if the mapping was added * - AJ_ERR_RESOURCES if there is no room to the mapping */ AJ_Status AJ_GUID_AddNameMapping(AJ_BusAttachment* bus, const AJ_GUID* guid, const char* uniqueName, const char* serviceName); #define AJ_ROLE_KEY_UNDEFINED 0 /**< Indicates the session key role is undefined (only applies for group keys) */ #define AJ_ROLE_KEY_INITIATOR 1 /**< Indicates the session key was initiated by this peer */ #define AJ_ROLE_KEY_RESPONDER 2 /**< Indicates the session key was initiated by the remote peer */ /** * Delete a name mapping from the GUID map. * * This is called when a name owner changed signal is received * indicating that the unique name has gone away. * * @param bus The bus attachment * @param uniqueName The unique name that went away */ void AJ_GUID_DeleteNameMapping(AJ_BusAttachment* bus, const char* uniqueName); /** * Looks up the GUID for a name * * @param name The unique or well-known name to lookup * * @return Return A pointer to a GUID or NULL, if there is no mapping. */ const AJ_GUID* AJ_GUID_Find(const char* name); /** * Sets a session key for an entry in the GUID map * * @param uniqueName The unique name for a remote peer * @param key The 16 byte session key to add * @param role Indicates which peer initiated the session key * @param authVersion Indicates the authentication version associated with this key * * @return Return AJ_Status * - AJ_OK if the key was added * - AJ_ERR_NO_MATCH if there is no entry to the peer */ AJ_Status AJ_SetSessionKey(const char* uniqueName, const uint8_t* key, uint8_t role, uint32_t authVersion); /** * Sets a group key for an entry in the GUID map * * @param uniqueName The unique name for a remote peer * @param key The 16 byte session key to add * * @return Return AJ_Status * - AJ_OK if the key was added * - AJ_ERR_NO_MATCH if there is no entry to the peer */ AJ_Status AJ_SetGroupKey(const char* uniqueName, const uint8_t* key); /** * Gets a session key for an entry from the GUID map * * @param name The unique or well-known name for a remote peer * @param key Buffer to receive the 16 byte session key * @param role Indicates which peer initiated the session key * @param authVersion Indicates the authentication version associated with this key * * @return Return AJ_Status * - AJ_OK if the key was obtained * - AJ_ERR_NO_MATCH if there is no entry to the peer */ AJ_Status AJ_GetSessionKey(const char* name, uint8_t* key, uint8_t* role, uint32_t* authVersion); /** * Gets serial numbers for an entry from the GUID map * * @param name The unique or well-known name for a remote peer * @param incoming The incoming serial numbers * * @return Return AJ_Status * - AJ_OK if the information was obtained * - AJ_ERR_NO_MATCH if there is no entry to the peer */ AJ_Status AJ_GetSerialNumbers(const char* name, AJ_SerialNum** incoming); /** * Gets unique name for an entry from the GUID map * * @param name The well-known name for a remote peer. Unique names are ok too. * @param unique Unique name corresponding to the requested name * * @return Return AJ_Status * - AJ_OK if the information was obtained * - AJ_ERR_NO_MATCH if there is no entry to the peer */ AJ_Status AJ_GetRemoteUniqueName(const char* name, const char** unique); /** * Gets a group key for an entry from the GUID map * * @param name The unique or well-known name for a remote peer or NULL to get the local group key. * @param key Buffer to receive the 16 byte group key * * @return Return AJ_Status * - AJ_OK if the key was obtained * - AJ_ERR_NO_MATCH if there is no entry to the peer */ AJ_Status AJ_GetGroupKey(const char* name, uint8_t* key); /** * Handle an add match reply message * * @param msg The add match reply message * * @return Return AJ_Status * - AJ_OK if successful * - AJ_ERR_RESOURCES if resource error or authentication in progress * - AJ_ERR_SECURITY if generic security violation */ AJ_Status AJ_GUID_HandleAddMatchReply(AJ_Message* msg); /** * Handle a remove match reply message * * @param msg The remove match reply message * * @return Return AJ_Status * - AJ_OK if successful * - AJ_ERR_RESOURCES if resource error or authentication in progress * - AJ_ERR_SECURITY if generic security violation */ AJ_Status AJ_GUID_HandleRemoveMatchReply(AJ_Message* msg); /** * Handle a name has owner reply message * * @param msg The name has owner reply message * * @return Return AJ_Status * - AJ_OK if successful * - AJ_ERR_RESOURCES if resource error or authentication in progress * - AJ_ERR_SECURITY if generic security violation */ AJ_Status AJ_GUID_HandleNameHasOwnerReply(AJ_Message* msg); /** * Handle a name owner changed message * * @param msg The name owner changed message * * @return Return AJ_Status * - AJ_OK if successful * - AJ_ERR_RESOURCES if resource error or authentication in progress * - AJ_ERR_SECURITY if generic security violation */ AJ_Status AJ_GUID_HandleNameOwnerChanged(AJ_Message* msg); #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_helper.h000066400000000000000000000311421256742562600156550ustar00rootroot00000000000000#ifndef _AJ_HELPER_H #define _AJ_HELPER_H /** * @file aj_helper.h * @defgroup aj_helper Helper Functions * @{ * @file */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_status.h" #include "aj_bus.h" #include "aj_about.h" #ifdef __cplusplus extern "C" { #endif #define AJ_JOINSESSION_REPLY_SUCCESS 1 /**< JoinSession reply: Success */ #define AJ_JOINSESSION_REPLY_NO_SESSION 2 /**< JoinSession reply: Session with given name does not exist */ #define AJ_JOINSESSION_REPLY_UNREACHABLE 3 /**< JoinSession reply: Failed to find suitable transport */ #define AJ_JOINSESSION_REPLY_CONNECT_FAILED 4 /**< JoinSession reply: Connect to advertised address */ #define AJ_JOINSESSION_REPLY_REJECTED 5 /**< JoinSession reply: The session creator rejected the join req */ #define AJ_JOINSESSION_REPLY_BAD_SESSION_OPTS 6 /**< JoinSession reply: Failed due to session option incompatibilities */ #define AJ_JOINSESSION_REPLY_ALREADY_JOINED 7 /**< JoinSession reply: Caller has already joined this session */ #define AJ_JOINSESSION_REPLY_FAILED 10 /**< JoinSession reply: Failed for unknown reason */ /** * Callback function prototype for a callback function to handle a method or signal * * @param msg The message received * @param reply The method reply (NULL if msg is a signal or method reply) * * @return Return AJ_Status * - AJ_OK if the message was correctly decoded (and a reply sent in the case of a method call) * - An error status if something went wrong decoding the message */ typedef AJ_Status (*MessageHandler)(AJ_Message* msg, AJ_Message* reply); /** * Callback function prototype for a callback function to handle new sessions * * @param msg The message received * * @return Return uint8_t * - TRUE if the service should allow the session * - FALSE if the service should *NOT* allow the session */ typedef uint8_t (*AcceptSessionHandler)(AJ_Message* msg); /** * Callback function prototype to indicate when the Daemon connection status changes * * @param connected TRUE if connected, FALSE if disconnected */ typedef void (*ConnectionHandler)(uint8_t connected); /** * Type to describe a mapping of message id to message handler. */ typedef struct { uint32_t msgid; MessageHandler handler; } MessageHandlerEntry; /** * Type to describe a mapping of property get/set message id * to get/set handler with context pointer */ typedef struct { uint32_t msgid; AJ_BusPropGetCallback callback; void* context; } PropHandlerEntry; /** * Type to describe the AllJoyn service configuration */ typedef struct { const char* daemonName; /**< Name of a specific daemon service to connect to, NULL for the default name. */ uint32_t connect_timeout; /**< How long to spend attempting to connect to the bus */ uint8_t connected; /**< Whether the bus attachment is already connected to the daemon bus */ uint16_t session_port; /**< The port to bind */ const char* service_name; /**< The name being requested */ uint32_t flags; /**< An OR of the name request flags */ const AJ_SessionOpts* opts; /**< The session option setting. */ AJ_AuthPwdFunc password_callback; /**< The auth password callback */ uint32_t link_timeout; /**< The daemon connection's link timeout */ AcceptSessionHandler acceptor; /**< The AcceptSession callback */ ConnectionHandler connection_handler; /**< A callback for when the daemon connection status changes */ const MessageHandlerEntry* message_handlers; /**< An array of message handlers */ const PropHandlerEntry* prop_handlers; /**< An array of property get/set handlers */ } AllJoynConfiguration; /** * Helper function that connects to a bus initializes an AllJoyn service. * * @param bus The bus attachment * @param config The AllJoyn configuration object * * @return AJ_OK if service was successfully run to completion. */ AJ_Status AJ_RunAllJoynService(AJ_BusAttachment* bus, AllJoynConfiguration* config); /** * Callback function prototype for a timer function callback * * @param context The context pointer passed in to AJ_SetTimer */ typedef void (*TimeoutHandler)(void* context); /** * Start a timer * * @param relative_time The time (relative to now) when the timer should first go off * @param handler The callback to execute after milliseconds * @param context The context pointer that will be passed into the handler * @param repeat If nonzero, repeat this timer every msec * * @return The id of the new timer, which can be used to cancel it later * 0 if timer was not set. */ uint32_t AJ_SetTimer(uint32_t relative_time, TimeoutHandler handler, void* context, uint32_t repeat); /** * Cancel the timer specified * * @param id The id of the timer to cancel (returned by AJ_SetTimer) */ void AJ_CancelTimer(uint32_t id); /** * Helper function that connects to a bus initializes an AllJoyn service. * * @param bus The bus attachment * @param daemonName Name of a specific daemon service to connect to, NULL for the default name. * @param timeout How long to spend attempting to connect to the bus * @param connected Whether the bus attachment is already connected to the daemon bus * @param port The port to bind * @param name The name being requested * @param flags An OR of the name request flags * @param opts The session option setting. * * @return AJ_OK if service was successfully started. */ AJ_EXPORT AJ_Status AJ_StartService(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, uint16_t port, const char* name, uint32_t flags, const AJ_SessionOpts* opts); /** * @deprecated * Initializes an AllJoyn client and connect to a service. Note that this function is deprecated * and AJ_StartClientByName() should be used instead. * * @param bus The bus attachment * @param daemonName Name of a specific daemon service to connect to, NULL for the default name. * @param timeout How long to spend attempting to find a remote service to connect to. * @param connected Whether the bus attachment is already connected to the daemon bus. * @param name The name of the service to connect to. * @param port The service port to connect to. * @param[out] sessionId The session id returned if the connection was successful * @param opts The session option setting. * * @return AJ_OK if connection was successfully established */ AJ_EXPORT AJ_Status AJ_StartClient(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, const char* name, uint16_t port, uint32_t* sessionId, const AJ_SessionOpts* opts); /** * Initializes an AllJoyn client and connect to a service * * @param bus The bus attachment * @param daemonName Name of a specific daemon service to connect to, NULL for the default name. * @param timeout How long to spend attempting to find a remote service to connect to. * @param connected Whether the bus attachment is already connected to the daemon bus. * @param name The name of the service to connect to. * @param port The service port to connect to. * @param[out] sessionId The session id returned if the connection was successful * @param opts The session option setting. * @param[out] fullName This buffer passed in will be filled with the full service name if the connection * was successful. The buffer should be of size AJ_MAX_SERVICE_NAME_SIZE or buffer overflow may occur. * * @return AJ_OK if connection was successfully established */ AJ_EXPORT AJ_Status AJ_StartClientByName(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, const char* name, uint16_t port, uint32_t* sessionId, const AJ_SessionOpts* opts, char* fullName); /** * Initialize an AllJoyn client, discover service by interface name, and connect. * * @param bus The bus attachment * @param daemonName Name of a specific daemon service to connect to, NULL for the default name. * @param timeout How long to spend attempting to find a remote service to connect to. * @param connected Whether the bus attachment is already connected to the daemon bus. * @param interfaces Find a service that implements these interface(s) (NULL-terminated list of names) * @param[out] sessionId The session id if the connection was successful * @param[out] uniqueName The unique name of the service if the connection was successful (supply array of size AJ_MAX_NAME_SIZE+1) * @param opts The session option setting. * * @return AJ_OK if connection was successfully established */ AJ_EXPORT AJ_Status AJ_StartClientByInterface(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, const char** interfaces, uint32_t* sessionId, char* uniqueName, const AJ_SessionOpts* opts); #ifdef ANNOUNCE_BASED_DISCOVERY /** * Initialize an AllJoyn client, discover service by peer description, and connect. * * @param bus The bus attachment * @param daemonName Name of a specific daemon service to connect to, NULL for the default name. * @param timeout How long to spend attempting to find a remote service to connect to. * @param connected Whether the bus attachment is already connected to the daemon bus. * @param peerDesc Find a peer that matched the description i.e. that implements thes interface(s) and register match callbacks * @param port The service port to connect to. If value is 0 use the About port in the Announcement. * @param[out] sessionId The session id if the connection was successful * @param[out] uniqueName The unique name of the service if the connection was successful (supply array of size AJ_MAX_NAME_SIZE+1) * @param opts The session option setting. * * @return AJ_OK if connection was successfully established * * This function is experimental, and as such has not been fully tested. * Please help make it more solid by contributing fixes if you find issues. */ AJ_EXPORT AJ_Status AJ_StartClientByPeerDescription(AJ_BusAttachment* bus, const char* daemonName, uint32_t timeout, uint8_t connected, const AJ_AboutPeerDescription* peerDesc, uint16_t port, uint32_t* sessionId, char* uniqueName, const AJ_SessionOpts* opts); #endif #ifdef __cplusplus } #endif /** * @} */ #endif /* _AJ_HELPER_H */ ajtcl-15.04b/inc/aj_init.h000066400000000000000000000025131256742562600153410ustar00rootroot00000000000000#ifndef _AJ_INIT_H #define _AJ_INIT_H /** * @file aj_init.h * @defgroup aj_init Initialization * @{ * @file */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #ifdef __cplusplus extern "C" { #endif /** * Initialization for AllJoyn. This function should be called before calling any * other AllJoyn APIs. */ AJ_EXPORT void AJ_Initialize(void); #ifdef __cplusplus } #endif /** * @} */ #endif ajtcl-15.04b/inc/aj_introspect.h000066400000000000000000000576061256742562600166050ustar00rootroot00000000000000#ifndef _AJ_INTROSPECT_H #define _AJ_INTROSPECT_H /** * @file aj_introspect.h * @defgroup aj_introspect Introspection Support * @{ */ /****************************************************************************** * Copyright AllSeen Alliance. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ******************************************************************************/ #include "aj_target.h" #include "aj_status.h" #include "aj_bus.h" #include "aj_msg.h" #ifdef __cplusplus extern "C" { #endif /** * Support for introspection */ /** * An interface description is a NULL terminated array of strings. The first string is the interface * name. The subsequent strings are a compact representation of the members of the interface. In * this representation special characters encode information about the members, whitespace is * significant. * * If the first character of the interface name is a '$' character this indicates that the interface * is secure and only authenticated peers can make method calls and received signals defined in the * interface. If the first character of the interface name is a '#' character this indicates that * security is not applicable to this interface even if the interface is implemented by an otherwise * secure object. The '$' and '#' characters are merely signifiers and are not part of the interface * name. * * The first character of a member string identifies the type of member: * * A '?' character indicates the member is a METHOD * A '!' character indicates the member is a SIGNAL * A '@' character indicates the member is a PROPERTY * * The type character is a signifier, it is not part of the member name. Characters following the * member type character up to the end of the string or to the first space character comprise the * member names. If the member is a METHOD or SIGNAL the remaining characters encode the argument * names, direction (IN or OUT) and the argument type as a standard AllJoyn signature string. For * SIGNALS for correctness the direction should be specified as OUT but it really doesn't matter as * the direction is ignored. * * Arguments are separated by a single space character. Argument names are optional and if present are * all characters between the space character and the directions character. All characters after the * direction character up to the next space or the end of the string are the argument type. The * argument direction is specified as follows: * * A '>' character indicates the argument is an OUT parameter. * A '<' character indicates the argument is an IN parameter. * * If the member is a PROPERTY the member name is terminated by an access rights character which is * immediately followed by the property type signature. The access rights for a property are * READ_ONLY, WRITE_ONLY and READ_WRITE. The access rights are specified as follows: * * A '>' character indicates the argument is READ_ONLY (i.e. an OUT parameter) * A '<' character indicates the argument is WRITE_ONLY (i.e. an IN parameter) * A '=' character indicates the argument is READ/WRITE * @code static const char* const ExampleInterface[] = { "org.alljoyn.example", // The interface name "?StringPing inStr", // A method called StringPing with an IN arg and OUT arg of type string "?Hello", // A method call with no arguments "?Add i", // A method call that takes two integers and returns an integer. The args are not named "!ListChanged >a{ys}", // A signal that returns a dictionary "@TimeNow>(yyy)", // A READ_ONLY property that returns a struct with three 8 bit integers "@Counter=u", // A READ/WRITE property "@SecretKey