PUD: include nmealib v0.6.7
authorFerry Huberts <ferry.huberts@pelagic.nl>
Thu, 10 May 2012 09:47:45 +0000 (11:47 +0200)
committerFerry Huberts <ferry.huberts@pelagic.nl>
Fri, 11 May 2012 07:39:19 +0000 (09:39 +0200)
Signed-off-by: Ferry Huberts <ferry.huberts@pelagic.nl>
40 files changed:
lib/pud/nmealib/.gitignore [new file with mode: 0644]
lib/pud/nmealib/LICENSE.TXT [new file with mode: 0644]
lib/pud/nmealib/Makefile [new file with mode: 0644]
lib/pud/nmealib/Makefile.inc [new file with mode: 0644]
lib/pud/nmealib/README.TXT [new file with mode: 0644]
lib/pud/nmealib/doc/.gitignore [new file with mode: 0644]
lib/pud/nmealib/doc/Makefile [new file with mode: 0644]
lib/pud/nmealib/doc/nmea.doxygen [new file with mode: 0644]
lib/pud/nmealib/include/nmea/config.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/context.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/generate.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/generator.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/gmath.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/info.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/nmea.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/parse.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/parser.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/sentence.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/time.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/tok.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/units.h [new file with mode: 0644]
lib/pud/nmealib/include/nmea/util.h [new file with mode: 0644]
lib/pud/nmealib/samples/Makefile [new file with mode: 0644]
lib/pud/nmealib/samples/generate/main.c [new file with mode: 0644]
lib/pud/nmealib/samples/generator/main.c [new file with mode: 0644]
lib/pud/nmealib/samples/math/main.c [new file with mode: 0644]
lib/pud/nmealib/samples/parse/main.c [new file with mode: 0644]
lib/pud/nmealib/samples/parse_file/gpslog.txt [new file with mode: 0644]
lib/pud/nmealib/samples/parse_file/main.c [new file with mode: 0644]
lib/pud/nmealib/src/context.c [new file with mode: 0644]
lib/pud/nmealib/src/generate.c [new file with mode: 0644]
lib/pud/nmealib/src/generator.c [new file with mode: 0644]
lib/pud/nmealib/src/gmath.c [new file with mode: 0644]
lib/pud/nmealib/src/info.c [new file with mode: 0644]
lib/pud/nmealib/src/parse.c [new file with mode: 0644]
lib/pud/nmealib/src/parser.c [new file with mode: 0644]
lib/pud/nmealib/src/sentence.c [new file with mode: 0644]
lib/pud/nmealib/src/time.c [new file with mode: 0644]
lib/pud/nmealib/src/tok.c [new file with mode: 0644]
lib/pud/nmealib/src/util.c [new file with mode: 0644]

diff --git a/lib/pud/nmealib/.gitignore b/lib/pud/nmealib/.gitignore
new file mode 100644 (file)
index 0000000..8e0bc29
--- /dev/null
@@ -0,0 +1,2 @@
+/build/
+/lib/
diff --git a/lib/pud/nmealib/LICENSE.TXT b/lib/pud/nmealib/LICENSE.TXT
new file mode 100644 (file)
index 0000000..4362b49
--- /dev/null
@@ -0,0 +1,502 @@
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+\f
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+\f
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+\f
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+\f
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+\f
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+\f
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+\f
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+\f
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+\f
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
diff --git a/lib/pud/nmealib/Makefile b/lib/pud/nmealib/Makefile
new file mode 100644 (file)
index 0000000..28e1640
--- /dev/null
@@ -0,0 +1,83 @@
+include Makefile.inc
+
+#
+# Settings
+#
+
+LIBNAME = libnmea.so
+
+DESTDIR ?=
+
+MACHINE=$(shell uname -m)
+LIBDIR_INSTALL = usr/lib
+ifeq ($(strip $(MACHINE)),x86_64)
+  LIB64DIR := $(shell test -d "/usr/lib64" && echo "YES")
+  ifeq ($(strip $(LIB64DIR)),YES)
+    LIBDIR_INSTALL = usr/lib64
+  endif
+endif
+INCLUDEDIR = usr/include
+
+MODULES = context generate generator gmath info parse parser sentence time tok util
+OBJ = $(MODULES:%=build/%.o)
+
+LIBS = -lm
+INCS = -I ./include
+
+
+#
+# Targets
+#
+
+all: all-before lib/$(LIBNAME)
+
+remake: clean all
+
+lib/$(LIBNAME): $(OBJ)
+       @echo "[LD] $@"
+       @$(CC) -shared -Wl,-soname=$(LIBNAME) -o lib/$(LIBNAME) $(OBJ) -lc
+
+build/%.o: src/%.c Makefile Makefile.inc
+       @echo "[CC] $<"
+       @$(CC) $(CCFLAGS) $(INCS) -c $< -o $@
+
+samples: all
+       $(MAKE) -C samples all
+
+
+#
+# Phony Targets
+#
+
+.PHONY: all-before clean doc install install-headers uninstall uninstall-headers
+
+all-before:
+       @mkdir -p build lib
+
+clean:
+       $(MAKE) -C doc clean
+       $(MAKE) -C samples clean
+       rm -fr build lib
+
+doc:
+       $(MAKE) -C doc all
+
+install: all
+       @mkdir -v -p "$(DESTDIR)/$(LIBDIR_INSTALL)"
+       cp "lib/$(LIBNAME)" "$(DESTDIR)/$(LIBDIR_INSTALL)/$(LIBNAME).$(VERSION)"
+       $(STRIP) "$(DESTDIR)/$(LIBDIR_INSTALL)/$(LIBNAME).$(VERSION)"
+       ldconfig -n "$(DESTDIR)/$(LIBDIR_INSTALL)"
+
+install-headers: all
+       @mkdir -v -p "$(DESTDIR)/$(INCLUDEDIR)"
+       @rm -fr "$(DESTDIR)/$(INCLUDEDIR)/nmea"
+       cp -r include/nmea "$(DESTDIR)/$(INCLUDEDIR)"
+
+uninstall:
+       rm -f "$(DESTDIR)/$(LIBDIR_INSTALL)/$(LIBNAME)" "$(DESTDIR)/$(LIBDIR_INSTALL)/$(LIBNAME).$(VERSION)"
+       ldconfig -n "$(DESTDIR)/$(LIBDIR_INSTALL)"
+       @rmdir -v -p --ignore-fail-on-non-empty "$(DESTDIR)/$(LIBDIR_INSTALL)"
+
+uninstall-headers:
+       rm -fr "$(DESTDIR)/$(INCLUDEDIR)/nmea"
+       @rmdir -v -p --ignore-fail-on-non-empty "$(DESTDIR)/$(INCLUDEDIR)"
diff --git a/lib/pud/nmealib/Makefile.inc b/lib/pud/nmealib/Makefile.inc
new file mode 100644 (file)
index 0000000..1c94397
--- /dev/null
@@ -0,0 +1,36 @@
+######################
+#
+# Highlevel configuration options for all
+#
+#
+
+# activate debugging with 1 or deactivate with 0
+DEBUG ?= 1
+
+
+######################
+#
+# Lowlevel options and rules
+#
+
+ifeq ($(DEBUG),0)
+STRIP ?=       strip
+else
+STRIP ?=       :
+endif
+
+
+GITVERSION = $(shell git describe --dirty='-dirty')
+
+# we expect the version to be like 'v0.5.3-27-g0c2727a' and then strip the 'v',
+# and the '-27-g0c2727a' parts
+VERSION=0.6.7
+
+# protect against no version number
+ifeq ($(strip $(VERSION)),)
+VERSION=0.0.0
+endif
+
+CC ?= gcc
+CCFLAGS += -fPIC -O2 -Wall -Wextra -Wformat=2 -Winit-self \
+           -Wmissing-include-dirs -Wswitch-default -Wswitch-enum -Werror
diff --git a/lib/pud/nmealib/README.TXT b/lib/pud/nmealib/README.TXT
new file mode 100644 (file)
index 0000000..f24bc87
--- /dev/null
@@ -0,0 +1,33 @@
+NMEA library
+
+Disclaimer
+
+The National Marine Electronics Association (NMEA) has developed a specification
+that defines the interface between various pieces of marine electronic
+equipment. The standard permits marine electronics to send information to
+computers and to other marine equipment.
+
+Most computer programs that provide real time position information understand
+and expect data to be in NMEA format. This data includes the complete PVT
+(position, velocity, time) solution computed by the GPS receiver. The idea of
+NMEA is to send a line of data called a sentence that is totally self contained
+and independent from other sentences. All NMEA sentences are sequences of ACSII
+symbols that begin with a '$' and end with a carriage return/line feed sequence
+and can be no longer than 80 characters of visible text (plus the line
+terminators).
+
+Introduction
+
+Features
+
+- Analysis NMEA sentences and granting GPS data in C structures
+- Generate NMEA sentences
+- Supported sentences: GPGGA, GPGSA, GPGSV, GPRMC, GPVTG
+- Multilevel architecture of algorithms
+- Additional functions of geographical mathematics and work with navigation data
+
+Supported (tested) platforms
+
+- Linux (GCC)
+
+Licence: LGPL
diff --git a/lib/pud/nmealib/doc/.gitignore b/lib/pud/nmealib/doc/.gitignore
new file mode 100644 (file)
index 0000000..447bc4d
--- /dev/null
@@ -0,0 +1,5 @@
+/html/
+/latex/
+/man/
+/nmealib.pdf
+/nmea.doxygen.temp
diff --git a/lib/pud/nmealib/doc/Makefile b/lib/pud/nmealib/doc/Makefile
new file mode 100644 (file)
index 0000000..81a5118
--- /dev/null
@@ -0,0 +1,18 @@
+include ../Makefile.inc
+
+.PHONY: all clean
+
+clean:
+       rm -fr html latex man nmealib.pdf
+
+all: clean nmea.doxygen
+       @echo "Updating version..."
+       @sed -r "s/^([[:space:]]*PROJECT_NUMBER[[:space:]]*=).*/\1 $(GITVERSION)/" nmea.doxygen > nmea.doxygen.temp
+       @echo "Generating HTML and man pages..."
+       @doxygen nmea.doxygen.temp
+       @rm nmea.doxygen.temp
+       @echo "Generating PDF..."
+       @make -C latex -s > /dev/null 2>&1
+       @mv latex/refman.pdf nmealib.pdf
+       @rm -fr latex
+       @echo "Done"
diff --git a/lib/pud/nmealib/doc/nmea.doxygen b/lib/pud/nmealib/doc/nmea.doxygen
new file mode 100644 (file)
index 0000000..5ae8c60
--- /dev/null
@@ -0,0 +1,1636 @@
+# Doxyfile 1.7.1
+
+# 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           = "NMEAlib"
+
+# 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         =
+
+# 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-Cyrilic, 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        = NO
+
+# 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 is your file systems
+# 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      = YES
+
+# 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               = 2
+
+# 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 make 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 to 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 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   = NO
+
+# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to
+# determine which symbols to keep in memory and which to flush to disk.
+# When the cache is full, less often used symbols will be written to disk.
+# For small to medium size projects (<1000 input files) the default value is
+# probably good enough. For larger projects a too small cache size can cause
+# doxygen to be busy swapping symbols to and from disk most of the time
+# causing a significant performance penality.
+# If the system has enough physical memory increasing the cache will improve the
+# performance by keeping more symbols in memory. Note that the value works on
+# a logarithmic scale so increasing the size by one will rougly double the
+# memory usage. The cache size is given by this formula:
+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,
+# corresponding to a cache size of 2^16 = 65536 symbols
+
+SYMBOL_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# 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            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# 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  = YES
+
+# 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 namespace are hidden.
+
+EXTRACT_ANON_NSPACES   = YES
+
+# 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       = YES
+
+# 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
+
+# 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 define 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 defines 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
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# 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 <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> 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                  = YES
+
+# 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
+
+# This WARN_NO_PARAMDOC option can be abled 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       = YES
+
+# 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                  = ../src ../include/nmea
+
+# 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++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS          = *.c *.h
+
+# 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              = YES
+
+# 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 filesystem 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 <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> 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, INPUT_FILTER
+# is applied to all files.
+
+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
+
+#---------------------------------------------------------------------------
+# 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         = YES
+
+# 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    = NO
+
+# 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 = YES
+
+# 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    = YES
+
+# 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    = 2
+
+# 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.
+
+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            =
+
+# If the HTML_TIMESTAMP tag is set to YES then the generated HTML
+# documentation will contain the timesstamp.
+
+HTML_TIMESTAMP         = NO
+
+# 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_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_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = 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               = nmealib.chm
+
+# 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             = YES
+
+# 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
+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">
+# Qt Help Project / Custom Filters</a>.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's
+# filter section matches.
+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">
+# Qt Help Project / Filter Attributes</a>.
+
+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
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+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      = YES
+
+# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories,
+# and Class Hierarchy pages using a tree view instead of an ordered list.
+
+USE_INLINE_TREES       = 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
+
+# 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 disadvances is 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         = YES
+
+# 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, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# 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           =
+
+# 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        = YES
+
+# 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         = YES
+
+# 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           = YES
+
+# 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              = YES
+
+#---------------------------------------------------------------------------
+# 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        = YES
+
+# 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     = YES
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if 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             =
+PREDEFINED            += "__attribute__(x)="
+
+# 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.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and 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 is superseded by the HAVE_DOT option below. This is only a
+# fallback. 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               = YES
+
+# 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 FreeSans.ttf to the output
+# directory and reference it in all dot files that doxygen generates. This
+# font does not include all possible unicode characters however, so when you need
+# these (or just want a differently looking font) you can specify the font name
+# using DOT_FONTNAME. You need 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           = FreeSans.ttf
+
+# 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               = YES
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = YES
+
+# 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             = YES
+
+# 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           = YES
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will 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 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 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        = YES
+
+# 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      = YES
+
+# 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
diff --git a/lib/pud/nmealib/include/nmea/config.h b/lib/pud/nmealib/include/nmea/config.h
new file mode 100644 (file)
index 0000000..915c4fb
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __NMEA_CONFIG_H__
+#define __NMEA_CONFIG_H__
+
+#define NMEA_POSIX(x)  (x)
+#define NMEA_INLINE    inline
+
+#if !defined(NDEBUG)
+#include <assert.h>
+#define NMEA_ASSERT(x)   assert(x)
+#else
+#define NMEA_ASSERT(x)
+#endif
+
+#endif /* __NMEA_CONFIG_H__ */
diff --git a/lib/pud/nmealib/include/nmea/context.h b/lib/pud/nmealib/include/nmea/context.h
new file mode 100644 (file)
index 0000000..c692a86
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __NMEA_CONTEXT_H__
+#define __NMEA_CONTEXT_H__
+
+#define NMEA_DEF_PARSEBUFF  (1024)
+#define NMEA_MIN_PARSEBUFF  (256)
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+typedef void (*nmeaTraceFunc)(const char *str, int str_size);
+typedef void (*nmeaErrorFunc)(const char *str, int str_size);
+
+typedef struct _nmeaPROPERTY {
+       nmeaTraceFunc trace_func;
+       nmeaErrorFunc error_func;
+       int parse_buff_size;
+
+} nmeaPROPERTY;
+
+nmeaPROPERTY * nmea_property(void);
+
+void nmea_trace(const char *str, ...);
+void nmea_trace_buff(const char *buff, int buff_size);
+void nmea_error(const char *str, ...);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __NMEA_CONTEXT_H__ */
diff --git a/lib/pud/nmealib/include/nmea/generate.h b/lib/pud/nmealib/include/nmea/generate.h
new file mode 100644 (file)
index 0000000..34eab4e
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __NMEA_GENERATE_H__
+#define __NMEA_GENERATE_H__
+
+#include <nmea/info.h>
+#include <nmea/sentence.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+int nmea_generate(char *buff, int buff_sz, const nmeaINFO *info,
+               int generate_mask);
+
+int nmea_gen_GPGGA(char *buff, int buff_sz, nmeaGPGGA *pack);
+int nmea_gen_GPGSA(char *buff, int buff_sz, nmeaGPGSA *pack);
+int nmea_gen_GPGSV(char *buff, int buff_sz, nmeaGPGSV *pack);
+int nmea_gen_GPRMC(char *buff, int buff_sz, nmeaGPRMC *pack);
+int nmea_gen_GPVTG(char *buff, int buff_sz, nmeaGPVTG *pack);
+
+void nmea_info2GPGGA(const nmeaINFO *info, nmeaGPGGA *pack);
+void nmea_info2GPGSA(const nmeaINFO *info, nmeaGPGSA *pack);
+void nmea_info2GPRMC(const nmeaINFO *info, nmeaGPRMC *pack);
+void nmea_info2GPVTG(const nmeaINFO *info, nmeaGPVTG *pack);
+
+int nmea_gsv_npack(int sat_count);
+void nmea_info2GPGSV(const nmeaINFO *info, nmeaGPGSV *pack, int pack_idx);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __NMEA_GENERATE_H__ */
diff --git a/lib/pud/nmealib/include/nmea/generator.h b/lib/pud/nmealib/include/nmea/generator.h
new file mode 100644 (file)
index 0000000..6d7c049
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __NMEA_GENERATOR_H__
+#define __NMEA_GENERATOR_H__
+
+#include <nmea/info.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * high level
+ */
+
+struct _nmeaGENERATOR;
+
+enum nmeaGENTYPE
+{
+    NMEA_GEN_NOISE = 0,
+    NMEA_GEN_STATIC,
+    NMEA_GEN_ROTATE,
+
+    NMEA_GEN_SAT_STATIC,
+    NMEA_GEN_SAT_ROTATE,
+    NMEA_GEN_POS_RANDMOVE,
+
+    NMEA_GEN_LAST
+};
+
+struct _nmeaGENERATOR * nmea_create_generator(int type, nmeaINFO *info);
+void    nmea_destroy_generator(struct _nmeaGENERATOR *gen);
+
+int     nmea_generate_from(
+        char *buff, int buff_sz,    /* buffer */
+        nmeaINFO *info,             /* source info */
+        struct _nmeaGENERATOR *gen, /* generator */
+        int generate_mask           /* mask of sentence`s (e.g. GPGGA | GPGSA) */
+        );
+
+/*
+ * low level
+ */
+
+typedef int (*nmeaNMEA_GEN_INIT)(struct _nmeaGENERATOR *gen, nmeaINFO *info);
+typedef int (*nmeaNMEA_GEN_LOOP)(struct _nmeaGENERATOR *gen, nmeaINFO *info);
+typedef int (*nmeaNMEA_GEN_RESET)(struct _nmeaGENERATOR *gen, nmeaINFO *info);
+typedef int (*nmeaNMEA_GEN_DESTROY)(struct _nmeaGENERATOR *gen);
+
+typedef struct _nmeaGENERATOR
+{
+    void                *gen_data;
+    nmeaNMEA_GEN_INIT    init_call;
+    nmeaNMEA_GEN_LOOP    loop_call;
+    nmeaNMEA_GEN_RESET   reset_call;
+    nmeaNMEA_GEN_DESTROY destroy_call;
+    struct _nmeaGENERATOR *next;
+
+} nmeaGENERATOR;
+
+int     nmea_gen_init(nmeaGENERATOR *gen, nmeaINFO *info);
+int     nmea_gen_loop(nmeaGENERATOR *gen, nmeaINFO *info);
+int     nmea_gen_reset(nmeaGENERATOR *gen, nmeaINFO *info);
+void    nmea_gen_destroy(nmeaGENERATOR *gen);
+void    nmea_gen_add(nmeaGENERATOR *to, nmeaGENERATOR *gen);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __NMEA_GENERATOR_H__ */
diff --git a/lib/pud/nmealib/include/nmea/gmath.h b/lib/pud/nmealib/include/nmea/gmath.h
new file mode 100644 (file)
index 0000000..5bd37d9
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __NMEA_GMATH_H__
+#define __NMEA_GMATH_H__
+
+#include <nmea/info.h>
+
+#define NMEA_PI                     (3.141592653589793)             /**< PI value */
+#define NMEA_PI180                  (NMEA_PI / 180)                 /**< PI division by 180 */
+#define NMEA_EARTHRADIUS_KM         (6378)                          /**< Earth's mean radius in km */
+#define NMEA_EARTHRADIUS_M          (NMEA_EARTHRADIUS_KM * 1000)    /**< Earth's mean radius in m */
+#define NMEA_EARTH_SEMIMAJORAXIS_M  (6378137.0)                     /**< Earth's semi-major axis in m according WGS84 */
+#define NMEA_EARTH_SEMIMAJORAXIS_KM (NMEA_EARTHMAJORAXIS_KM / 1000) /**< Earth's semi-major axis in km according WGS 84 */
+#define NMEA_EARTH_FLATTENING       (1 / 298.257223563)             /**< Earth's flattening according WGS 84 */
+#define NMEA_DOP_FACTOR             (5)                             /**< Factor for translating DOP to meters */
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * degree VS radian
+ */
+
+double nmea_degree2radian(double val);
+double nmea_radian2degree(double val);
+
+/*
+ * NDEG (NMEA degree)
+ */
+
+double nmea_ndeg2degree(double val);
+double nmea_degree2ndeg(double val);
+
+double nmea_ndeg2radian(double val);
+double nmea_radian2ndeg(double val);
+
+/*
+ * DOP
+ */
+
+double nmea_calc_pdop(double hdop, double vdop);
+double nmea_dop2meters(double dop);
+double nmea_meters2dop(double meters);
+
+/*
+ * positions work
+ */
+
+void nmea_info2pos(const nmeaINFO *info, nmeaPOS *pos);
+void nmea_pos2info(const nmeaPOS *pos, nmeaINFO *info);
+
+double  nmea_distance(
+        const nmeaPOS *from_pos,
+        const nmeaPOS *to_pos
+        );
+
+double  nmea_distance_ellipsoid(
+        const nmeaPOS *from_pos,
+        const nmeaPOS *to_pos,
+        double *from_azimuth,
+        double *to_azimuth
+        );
+
+int     nmea_move_horz(
+        const nmeaPOS *start_pos,
+        nmeaPOS *end_pos,
+        double azimuth,
+        double distance
+        );
+
+int     nmea_move_horz_ellipsoid(
+        const nmeaPOS *start_pos,
+        nmeaPOS *end_pos,
+        double azimuth,
+        double distance,
+        double *end_azimuth
+        );
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __NMEA_GMATH_H__ */
diff --git a/lib/pud/nmealib/include/nmea/info.h b/lib/pud/nmealib/include/nmea/info.h
new file mode 100644 (file)
index 0000000..ce74e80
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*! \file */
+
+#ifndef __NMEA_INFO_H__
+#define __NMEA_INFO_H__
+
+#include <nmea/time.h>
+#include <stdbool.h>
+
+#define NMEA_SIG_BAD   (0)
+#define NMEA_SIG_LOW   (1)
+#define NMEA_SIG_MID   (2)
+#define NMEA_SIG_HIGH  (3)
+
+#define NMEA_FIX_BAD   (1)
+#define NMEA_FIX_2D    (2)
+#define NMEA_FIX_3D    (3)
+
+#define NMEA_MAXSAT    (12)
+#define NMEA_SATINPACK (4)
+#define NMEA_NSATPACKS (NMEA_MAXSAT / NMEA_SATINPACK)
+
+#define NMEA_DEF_LAT   (5001.2621)
+#define NMEA_DEF_LON   (3613.0595)
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Position data in fractional degrees or radians
+ */
+typedef struct _nmeaPOS {
+       double lat; /**< Latitude */
+       double lon; /**< Longitude */
+
+} nmeaPOS;
+
+/**
+ * Information about satellite
+ * @see nmeaSATINFO
+ * @see nmeaGPGSV
+ */
+typedef struct _nmeaSATELLITE {
+       int id;      /**< Satellite PRN number */
+       int in_use;  /**< Used in position fix */
+       int elv;     /**< Elevation in degrees, 90 maximum */
+       int azimuth; /**< Azimuth, degrees from true north, 000 to 359 */
+       int sig;     /**< Signal, 00-99 dB */
+
+} nmeaSATELLITE;
+
+/**
+ * Information about all satellites in view
+ * @see nmeaINFO
+ * @see nmeaGPGSV
+ */
+typedef struct _nmeaSATINFO {
+       int inuse;  /**< Number of satellites in use (not those in view) */
+       int inview; /**< Total number of satellites in view */
+       nmeaSATELLITE sat[NMEA_MAXSAT]; /**< Satellites information */
+
+} nmeaSATINFO;
+
+/**
+ * Summary GPS information from all parsed packets,
+ * used also for generating NMEA stream
+ * @see nmea_parse
+ * @see nmea_GPGGA2info,  nmea_...2info
+ */
+typedef struct _nmeaINFO {
+       int smask;    /**< Mask specifying from which sentences data has been obtained */
+
+       nmeaTIME utc; /**< UTC of position */
+
+       int sig; /**< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive) */
+       int fix; /**< Operating mode, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D) */
+
+       double PDOP;        /**< Position Dilution Of Precision */
+       double HDOP;        /**< Horizontal Dilution Of Precision */
+       double VDOP;        /**< Vertical Dilution Of Precision */
+
+       double lat;         /**< Latitude in NDEG - +/-[degree][min].[sec/60] */
+       double lon;         /**< Longitude in NDEG - +/-[degree][min].[sec/60] */
+       double elv;         /**< Antenna altitude above/below mean sea level (geoid) in meters */
+       double speed;       /**< Speed over the ground in kilometers/hour */
+       double direction;   /**< Track angle in degrees True */
+       double declination; /**< Magnetic variation degrees (Easterly var. subtracts from true course) */
+
+       nmeaSATINFO satinfo; /**< Satellites information */
+} nmeaINFO;
+
+/**
+ * Enumeration for the fields names of a nmeaINFO structure
+ */
+typedef enum _nmeaINFO_FIELD {
+       SMASK, UTC, SIG, FIX, PDOP, HDOP, VDOP, LAT, LON, ELV, SPEED, DIRECTION,
+       DECLINATION, SATINFO
+} nmeaINFO_FIELD;
+
+void nmea_zero_INFO(nmeaINFO *info);
+
+bool nmea_INFO_has_field(int smask, nmeaINFO_FIELD fieldName);
+
+void nmea_INFO_sanitise(nmeaINFO *nmeaInfo);
+
+void nmea_INFO_unit_conversion(nmeaINFO * nmeaInfo);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __NMEA_INFO_H__ */
diff --git a/lib/pud/nmealib/include/nmea/nmea.h b/lib/pud/nmealib/include/nmea/nmea.h
new file mode 100644 (file)
index 0000000..c761579
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __NMEA_H__
+#define __NMEA_H__
+
+#include <nmea/config.h>
+#include <nmea/context.h>
+#include <nmea/generate.h>
+#include <nmea/generator.h>
+#include <nmea/gmath.h>
+#include <nmea/info.h>
+#include <nmea/parse.h>
+#include <nmea/parser.h>
+#include <nmea/sentence.h>
+#include <nmea/time.h>
+#include <nmea/tok.h>
+#include <nmea/units.h>
+
+#endif /* __NMEA_H__ */
diff --git a/lib/pud/nmealib/include/nmea/parse.h b/lib/pud/nmealib/include/nmea/parse.h
new file mode 100644 (file)
index 0000000..adfe406
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __NMEA_PARSE_H__
+#define __NMEA_PARSE_H__
+
+#include <nmea/info.h>
+#include <nmea/sentence.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+int nmea_pack_type(const char *buff, int buff_sz);
+int nmea_find_tail(const char *buff, int buff_sz, int *res_crc);
+
+int nmea_parse_GPGGA(const char *buff, int buff_sz, nmeaGPGGA *pack);
+int nmea_parse_GPGSA(const char *buff, int buff_sz, nmeaGPGSA *pack);
+int nmea_parse_GPGSV(const char *buff, int buff_sz, nmeaGPGSV *pack);
+int nmea_parse_GPRMC(const char *buff, int buff_sz, nmeaGPRMC *pack);
+int nmea_parse_GPVTG(const char *buff, int buff_sz, nmeaGPVTG *pack);
+
+void nmea_GPGGA2info(nmeaGPGGA *pack, nmeaINFO *info);
+void nmea_GPGSA2info(nmeaGPGSA *pack, nmeaINFO *info);
+void nmea_GPGSV2info(nmeaGPGSV *pack, nmeaINFO *info);
+void nmea_GPRMC2info(nmeaGPRMC *pack, nmeaINFO *info);
+void nmea_GPVTG2info(nmeaGPVTG *pack, nmeaINFO *info);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __NMEA_PARSE_H__ */
diff --git a/lib/pud/nmealib/include/nmea/parser.h b/lib/pud/nmealib/include/nmea/parser.h
new file mode 100644 (file)
index 0000000..94d71c8
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __NMEA_PARSER_H__
+#define __NMEA_PARSER_H__
+
+#include <nmea/info.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/*
+ * high level
+ */
+
+typedef struct _nmeaPARSER
+{
+    void *top_node;
+    void *end_node;
+    unsigned char *buffer;
+    int buff_size;
+    int buff_use;
+
+} nmeaPARSER;
+
+int     nmea_parser_init(nmeaPARSER *parser);
+void    nmea_parser_destroy(nmeaPARSER *parser);
+
+int     nmea_parse(
+        nmeaPARSER *parser,
+        const char *buff, int buff_sz,
+        nmeaINFO *info
+        );
+
+/*
+ * low level
+ */
+
+int     nmea_parser_push(nmeaPARSER *parser, const char *buff, int buff_sz);
+int     nmea_parser_top(nmeaPARSER *parser);
+int     nmea_parser_pop(nmeaPARSER *parser, void **pack_ptr);
+int     nmea_parser_peek(nmeaPARSER *parser, void **pack_ptr);
+int     nmea_parser_drop(nmeaPARSER *parser);
+int     nmea_parser_buff_clear(nmeaPARSER *parser);
+int     nmea_parser_queue_clear(nmeaPARSER *parser);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __NMEA_PARSER_H__ */
diff --git a/lib/pud/nmealib/include/nmea/sentence.h b/lib/pud/nmealib/include/nmea/sentence.h
new file mode 100644 (file)
index 0000000..8f36272
--- /dev/null
@@ -0,0 +1,139 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*! \file */
+
+#ifndef __NMEA_SENTENCE_H__
+#define __NMEA_SENTENCE_H__
+
+#include <nmea/info.h>
+#include <nmea/time.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/**
+ * NMEA packets type which parsed and generated by library
+ */
+enum nmeaPACKTYPE
+{
+    GPNON   = 0x0000,   /**< Unknown packet type. */
+    GPGGA   = 0x0001,   /**< GGA - Essential fix data which provide 3D location and accuracy data. */
+    GPGSA   = 0x0002,   /**< GSA - GPS receiver operating mode, SVs used for navigation, and DOP values. */
+    GPGSV   = 0x0004,   /**< GSV - Number of SVs in view, PRN numbers, elevation, azimuth & SNR values. */
+    GPRMC   = 0x0008,   /**< RMC - Recommended Minimum Specific GPS/TRANSIT Data. */
+    GPVTG   = 0x0010    /**< VTG - Actual track made good and speed over ground. */
+};
+
+/**
+ * GGA packet information structure (Global Positioning System Fix Data)
+ */
+typedef struct _nmeaGPGGA
+{
+    nmeaTIME utc;       /**< UTC of position (just time) */
+       double  lat;        /**< Latitude in NDEG - [degree][min].[sec/60] */
+    char    ns;         /**< [N]orth or [S]outh */
+       double  lon;        /**< Longitude in NDEG - [degree][min].[sec/60] */
+    char    ew;         /**< [E]ast or [W]est */
+    int     sig;        /**< GPS quality indicator (0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive) */
+       int     satinuse;   /**< Number of satellites in use (not those in view) */
+    double  HDOP;       /**< Horizontal dilution of precision */
+    double  elv;        /**< Antenna altitude above/below mean sea level (geoid) */
+    char    elv_units;  /**< [M]eters (Antenna height unit) */
+    double  diff;       /**< Geoidal separation (Diff. between WGS-84 earth ellipsoid and mean sea level. '-' = geoid is below WGS-84 ellipsoid) */
+    char    diff_units; /**< [M]eters (Units of geoidal separation) */
+    double  dgps_age;   /**< Time in seconds since last DGPS update */
+    int     dgps_sid;   /**< DGPS station ID number */
+
+} nmeaGPGGA;
+
+/**
+ * GSA packet information structure (Satellite status)
+ */
+typedef struct _nmeaGPGSA
+{
+    char    fix_mode;   /**< Mode (M = Manual, forced to operate in 2D or 3D; A = Automatic, 3D/2D) */
+    int     fix_type;   /**< Type, used for navigation (1 = Fix not available; 2 = 2D; 3 = 3D) */
+    int     sat_prn[NMEA_MAXSAT]; /**< PRNs of satellites used in position fix (null for unused fields) */
+    double  PDOP;       /**< Dilution of precision */
+    double  HDOP;       /**< Horizontal dilution of precision */
+    double  VDOP;       /**< Vertical dilution of precision */
+
+} nmeaGPGSA;
+
+/**
+ * GSV packet information structure (Satellites in view)
+ */
+typedef struct _nmeaGPGSV
+{
+    int     pack_count; /**< Total number of messages of this type in this cycle */
+    int     pack_index; /**< Message number */
+    int     sat_count;  /**< Total number of satellites in view */
+    nmeaSATELLITE sat_data[NMEA_SATINPACK];
+
+} nmeaGPGSV;
+
+/**
+ * RMC packet information structure (Recommended Minimum sentence C)
+ */
+typedef struct _nmeaGPRMC
+{
+    nmeaTIME utc;       /**< UTC of position */
+    char    status;     /**< Status (A = active or V = void) */
+       double  lat;        /**< Latitude in NDEG - [degree][min].[sec/60] */
+    char    ns;         /**< [N]orth or [S]outh */
+       double  lon;        /**< Longitude in NDEG - [degree][min].[sec/60] */
+    char    ew;         /**< [E]ast or [W]est */
+    double  speed;      /**< Speed over the ground in knots */
+    double  direction;  /**< Track angle in degrees True */
+    double  declination; /**< Magnetic variation degrees (Easterly var. subtracts from true course) */
+    char    declin_ew;  /**< [E]ast or [W]est */
+    char    mode;       /**< Mode indicator of fix type (A = autonomous, D = differential, E = estimated, N = not valid, S = simulator) */
+
+} nmeaGPRMC;
+
+/**
+ * VTG packet information structure (Track made good and ground speed)
+ */
+typedef struct _nmeaGPVTG
+{
+    double  dir;        /**< True track made good (degrees) */
+    char    dir_t;      /**< Fixed text 'T' indicates that track made good is relative to true north */
+    double  dec;        /**< Magnetic track made good */
+    char    dec_m;      /**< Fixed text 'M' */
+    double  spn;        /**< Ground speed, knots */
+    char    spn_n;      /**< Fixed text 'N' indicates that speed over ground is in knots */
+    double  spk;        /**< Ground speed, kilometers per hour */
+    char    spk_k;      /**< Fixed text 'K' indicates that speed over ground is in kilometers/hour */
+
+} nmeaGPVTG;
+
+void nmea_zero_GPGGA(nmeaGPGGA *pack);
+void nmea_zero_GPGSA(nmeaGPGSA *pack);
+void nmea_zero_GPGSV(nmeaGPGSV *pack);
+void nmea_zero_GPRMC(nmeaGPRMC *pack);
+void nmea_zero_GPVTG(nmeaGPVTG *pack);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __NMEA_SENTENCE_H__ */
diff --git a/lib/pud/nmealib/include/nmea/time.h b/lib/pud/nmealib/include/nmea/time.h
new file mode 100644 (file)
index 0000000..9e6666d
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*! \file */
+
+#ifndef __NMEA_TIME_H__
+#define __NMEA_TIME_H__
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Date and time data
+ * @see nmea_time_now
+ */
+typedef struct _nmeaTIME {
+       int year; /**< Years since 1900 */
+       int mon;  /**< Months since January - [0,11] */
+       int day;  /**< Day of the month - [1,31] */
+       int hour; /**< Hours since midnight - [0,23] */
+       int min;  /**< Minutes after the hour - [0,59] */
+       int sec;  /**< Seconds after the minute - [0,59] */
+       int hsec; /**< Hundredth part of second - [0,99] */
+
+} nmeaTIME;
+
+/**
+ * \brief Get time now to nmeaTIME structure
+ */
+void nmea_time_now(nmeaTIME *t);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __NMEA_TIME_H__ */
diff --git a/lib/pud/nmealib/include/nmea/tok.h b/lib/pud/nmealib/include/nmea/tok.h
new file mode 100644 (file)
index 0000000..e132d68
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __NMEA_TOK_H__
+#define __NMEA_TOK_H__
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+int nmea_calc_crc(const char *buff, int buff_sz);
+int nmea_atoi(const char *str, int str_sz, int radix);
+double nmea_atof(const char *str, int str_sz);
+int nmea_printf(char *buff, int buff_sz, const char *format, ...);
+int nmea_scanf(const char *buff, int buff_sz, const char *format, ...);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __NMEA_TOK_H__ */
diff --git a/lib/pud/nmealib/include/nmea/units.h b/lib/pud/nmealib/include/nmea/units.h
new file mode 100644 (file)
index 0000000..ebc717a
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __NMEA_UNITS_H__
+#define __NMEA_UNITS_H__
+
+/*
+ * Distance units
+ */
+
+#define NMEA_TUD_YARDS (1.0936) /**< Yards, meter * NMEA_TUD_YARDS = yard */
+#define NMEA_TUD_KNOTS (1.852)  /**< Knots, kilometer / NMEA_TUD_KNOTS = knot */
+#define NMEA_TUD_MILES (1.609)  /**< Miles, kilometer / NMEA_TUD_MILES = mile */
+
+/*
+ * Speed units
+ */
+
+#define NMEA_TUS_MS    (3.6)    /**< Meters per seconds, (k/h) / NMEA_TUS_MS= (m/s) */
+
+#endif /* __NMEA_UNITS_H__ */
diff --git a/lib/pud/nmealib/include/nmea/util.h b/lib/pud/nmealib/include/nmea/util.h
new file mode 100644 (file)
index 0000000..f3b0f6d
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __NMEA_UTIL_H__
+#define __NMEA_UTIL_H__
+
+#include <stdbool.h>
+#include <stddef.h>
+
+#ifdef  __cplusplus
+extern "C" {
+#endif
+
+bool nmea_string_has_invalid_chars(const char * str, const char * strName,
+               char * report, size_t reportSize);
+
+#ifdef  __cplusplus
+}
+#endif
+
+#endif /* __NMEA_UTIL_H__ */
diff --git a/lib/pud/nmealib/samples/Makefile b/lib/pud/nmealib/samples/Makefile
new file mode 100644 (file)
index 0000000..a583a20
--- /dev/null
@@ -0,0 +1,44 @@
+include ../Makefile.inc
+
+#
+# Settings
+#
+
+SAMPLES = generate generator math parse parse_file
+SMPLS = $(SAMPLES:%=../build/samples/%)
+SMPLOBJ = $(SAMPLES:%=%/main.o)
+
+LIBS = -lm -L../lib -lnmea
+INCS = -I ../include
+
+
+#
+# Targets
+#
+
+all: all-before samples
+
+remake: clean all
+
+samples: $(SMPLS)
+
+../build/samples/%: %/main.o
+       @echo "[LD] $@"
+       @$(CC) $(CCFLAGS) $< $(LIBS) -o $@
+
+%/main.o: %/main.c Makefile ../Makefile.inc
+       @echo "[CC] $<"
+       @$(CC) $(CCFLAGS) $(INCS) -c $< -o $@
+
+
+#
+# Phony Targets
+#
+
+.PHONY: all-before clean
+
+all-before:
+       @mkdir -p ../build/samples
+
+clean:
+       rm -f $(SMPLOBJ) $(SMPLS)
diff --git a/lib/pud/nmealib/samples/generate/main.c b/lib/pud/nmealib/samples/generate/main.c
new file mode 100644 (file)
index 0000000..73e584d
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <nmea/nmea.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+int main()
+{
+    nmeaINFO info;
+    char buff[2048];
+    int gen_sz;
+    int it;
+
+    nmea_zero_INFO(&info);
+
+    info.sig = 3;
+    info.fix = 3;
+    info.lat = 5000.0;
+    info.lon = 3600.0;
+    info.speed = 2.14 * NMEA_TUS_MS;
+    info.elv = 10.86;
+
+    info.satinfo.inuse = 1;
+    info.satinfo.inview = 1;
+
+    /*
+    info.satinfo.sat[0].id = 1;
+    info.satinfo.sat[0].in_use = 1;
+    info.satinfo.sat[0].elv = 50;
+    info.satinfo.sat[0].azimuth = 0;
+    info.satinfo.sat[0].sig = 99;
+    */
+
+    for(it = 0; it < 10; ++it)
+    {
+        gen_sz = nmea_generate(
+            &buff[0], 2048, &info,
+            GPGGA | GPGSA | GPGSV | GPRMC | GPVTG
+            );
+
+        buff[gen_sz] = 0;
+        printf("%s\n", &buff[0]);
+
+        usleep(500000);
+
+        info.speed += .1;
+    }
+
+    return 0;
+}
diff --git a/lib/pud/nmealib/samples/generator/main.c b/lib/pud/nmealib/samples/generator/main.c
new file mode 100644 (file)
index 0000000..f95cf1e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <nmea/nmea.h>
+
+#include <stdio.h>
+#include <unistd.h>
+
+int main()
+{
+    nmeaGENERATOR *gen;
+    nmeaINFO info;
+    char buff[2048];
+    int gen_sz;
+    int it;
+
+    nmea_zero_INFO(&info);
+
+    if(0 == (gen = nmea_create_generator(NMEA_GEN_ROTATE, &info)))
+        return -1;
+
+    for(it = 0; it < 10000; ++it)
+    {
+        gen_sz = nmea_generate_from(
+            &buff[0], 2048, &info, gen,
+            GPGGA | GPGSA | GPGSV | GPRMC | GPVTG
+            );
+
+        buff[gen_sz] = 0;
+        printf("%s\n", &buff[0]);
+
+        usleep(500000);        
+    }
+
+    nmea_gen_destroy(gen);
+
+    return 0;
+}
diff --git a/lib/pud/nmealib/samples/math/main.c b/lib/pud/nmealib/samples/math/main.c
new file mode 100644 (file)
index 0000000..d1bcfa8
--- /dev/null
@@ -0,0 +1,97 @@
+/*\r
+ * This file is part of nmealib.\r
+ *\r
+ * Copyright (c) 2008 Timur Sinitsyn\r
+ * Copyright (c) 2011 Ferry Huberts\r
+ *\r
+ * This library is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU Lesser General Public\r
+ * License as published by the Free Software Foundation; either\r
+ * version 2.1 of the License, or (at your option) any later version.\r
+ *\r
+ * This library is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
+ * Lesser General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#include <nmea/nmea.h>\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#define NUM_POINTS 4\r
+\r
+int main()\r
+{\r
+    const char *buff[] = {\r
+        "$GPRMC,213916.199,A,4221.0377,N,07102.9778,W,0.00,,010207,,,A*6A\r\n",\r
+        "$GPRMC,213917.199,A,4221.0510,N,07102.9549,W,0.23,175.43,010207,,,A*77\r\n",\r
+        "$GPRMC,213925.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*68\r\n",\r
+        "$GPRMC,111609.14,A,5001.27,N,3613.06,E,11.2,0.0,261206,0.0,E*50\r\n"\r
+    };\r
+\r
+    nmeaPOS pos[NUM_POINTS], pos_moved[NUM_POINTS][2];\r
+    double dist[NUM_POINTS][2]; \r
+    double azimuth[NUM_POINTS][2], azimuth_moved[NUM_POINTS];\r
+    int result[2];\r
+    int it = 0;\r
+\r
+    nmeaPARSER parser;\r
+    nmea_parser_init(&parser);\r
+\r
+    for(it = 0; it < NUM_POINTS; ++it)\r
+    {\r
+        nmeaINFO info;\r
+        nmea_zero_INFO(&info);\r
+        (void)nmea_parse(&parser, buff[it], (int)strlen(buff[it]), &info);\r
+        nmea_info2pos(&info, &pos[it]);\r
+    }\r
+\r
+    nmea_parser_destroy(&parser);\r
+\r
+    for(it = 0; it < NUM_POINTS; ++it)\r
+    {\r
+        dist[it][0] = nmea_distance(&pos[0], &pos[it]);\r
+        dist[it][1] = nmea_distance_ellipsoid(\r
+            &pos[0], &pos[it], &azimuth[it][0], &azimuth[it][1]\r
+            );\r
+    }\r
+\r
+    for(it = 0; it < NUM_POINTS; ++it)\r
+    {\r
+        result[0] = nmea_move_horz(&pos[0], &pos_moved[it][0], azimuth[it][0], dist[it][0]);\r
+        result[1] = nmea_move_horz_ellipsoid(\r
+            &pos[0], &pos_moved[it][1], azimuth[it][0], dist[it][0], &azimuth_moved[it]\r
+            );\r
+\r
+    }\r
+\r
+    /* Output of results */\r
+    printf("Coordinate points:\n");\r
+    for(it = 0; it < NUM_POINTS; ++it)\r
+    {\r
+        printf(\r
+            "P%d in radians: lat:%9.6lf lon:%9.6lf  \tin degree: lat:%+010.6lf° lon:%+011.6lf°\n",\r
+            it, pos[it].lat, pos[it].lon, nmea_radian2degree(pos[it].lat), nmea_radian2degree(pos[it].lon)\r
+            );\r
+    }\r
+\r
+    printf("\nCalculation results:\n");\r
+    for(it = 0; it < NUM_POINTS; ++it)\r
+    {\r
+        printf("\n");\r
+        printf("Distance P0 to P%d\ton spheroid:  %14.3lf m\n", it, dist[it][0]);\r
+        printf("Distance P0 to P%d\ton ellipsoid: %14.3lf m\n", it, dist[it][1]);\r
+        printf("Azimuth  P0 to P%d\tat start: %8.3lf°\tat end: %8.3lf°\n", it, nmea_radian2degree(azimuth[it][0]), nmea_radian2degree(azimuth[it][1]));\r
+        printf("Move     P0 to P%d\t         \tAzimuth at end: %8.3lf°\n", it, nmea_radian2degree(azimuth_moved[it]));\r
+        printf("Move     P0 to P%d\ton spheroid:  %3s lat:%+010.6lf° lon:%+011.6lf°\n", it, result[0] == 1 ? "OK" : "nOK", nmea_radian2degree(pos_moved[it][0].lat), nmea_radian2degree(pos_moved[it][0].lon));\r
+        printf("Move     P0 to P%d\ton ellipsoid: %3s lat:%+010.6lf° lon:%+011.6lf°\n", it, result[0] == 1 ? "OK" : "nOK", nmea_radian2degree(pos_moved[it][1].lat), nmea_radian2degree(pos_moved[it][1].lon));\r
+        printf("Move     P0 to P%d\toriginal:         lat:%+010.6lf° lon:%+011.6lf°\n", it, nmea_radian2degree(pos[it].lat), nmea_radian2degree(pos[it].lon));\r
+    }\r
+\r
+    return 0;\r
+}\r
diff --git a/lib/pud/nmealib/samples/parse/main.c b/lib/pud/nmealib/samples/parse/main.c
new file mode 100644 (file)
index 0000000..3f03da8
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <nmea/nmea.h>
+
+#include <stdio.h>
+#include <string.h>
+
+int main()
+{
+    const char *buff[] = {
+        "$GPRMC,173843,A,3349.896,N,11808.521,W,000.0,360.0,230108,013.4,E*69\r\n",
+        "$GPGGA,111609.14,5001.27,N,3613.06,E,3,08,0.0,10.2,M,0.0,M,0.0,0000*70\r\n",
+        "$GPGSV,2,1,08,01,05,005,80,02,05,050,80,03,05,095,80,04,05,140,80*7f\r\n",
+        "$GPGSV,2,2,08,05,05,185,80,06,05,230,80,07,05,275,80,08,05,320,80*71\r\n",
+        "$GPGSA,A,3,01,02,03,04,05,06,07,08,00,00,00,00,0.0,0.0,0.0*3a\r\n",
+        "$GPRMC,111609.14,A,5001.27,N,3613.06,E,11.2,0.0,261206,0.0,E*50\r\n",
+        "$GPVTG,217.5,T,208.8,M,000.00,N,000.01,K*4C\r\n"
+    };
+
+    int it;
+    nmeaINFO info;
+    nmeaPARSER parser;
+    nmeaPOS dpos;
+
+    nmea_zero_INFO(&info);
+    nmea_parser_init(&parser);
+
+    for(it = 0; it < 6; ++it)
+    {
+        nmea_parse(&parser, buff[it], (int)strlen(buff[it]), &info);
+
+        nmea_info2pos(&info, &dpos);
+        printf("%03d, Lat: %f, Lon: %f, Sig: %d, Fix: %d\n", it, dpos.lat,
+               dpos.lon, info.sig, info.fix);
+    }
+
+    nmea_parser_destroy(&parser);
+
+    return 0;
+}
diff --git a/lib/pud/nmealib/samples/parse_file/gpslog.txt b/lib/pud/nmealib/samples/parse_file/gpslog.txt
new file mode 100644 (file)
index 0000000..f6086da
--- /dev/null
@@ -0,0 +1,311 @@
+$PSRFTXTVersion GSW3.2.1PAT_3.1.00.12-SDK001P1.00c *3F\r
+$PSRFTXTHTC GPS_ART_321000_GEN*20\r
+$PSRFTXTTOW:  258712*32\r
+$PSRFTXTWK:   1412*4F\r
+$PSRFTXTPOS:  1518885 -4470072 4274168*24\r
+$PSRFTXTCLK:  94817*02\r
+$PSRFTXTCHNL: 12*5F\r
+$PSRFTXTBaud rate: 57600 *51\r
+$GPGGA,213638.949,,,,,0,00,,,M,0.0,M,,0000*5F\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213638.949,V,,,,,,,010207,,,N*40\r
+$GPGGA,213639.897,,,,,0,00,,,M,0.0,M,,0000*5C\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213639.897,V,,,,,,,010207,,,N*43\r
+$GPGGA,213640.886,,,,,0,00,,,M,0.0,M,,0000*52\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213640.886,V,,,,,,,010207,,,N*4D\r
+$GPGGA,213641.886,,,,,0,00,,,M,0.0,M,,0000*53\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213641.886,V,,,,,,,010207,,,N*4C\r
+$GPGGA,213642.897,,,,,0,00,,,M,0.0,M,,0000*50\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,12,20,00,000,,10,00,000,,25,00,000,,27,00,000,*79\r
+$GPGSV,3,2,12,22,00,000,,07,00,000,,21,00,000,,24,00,000,*79\r
+$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78\r
+$GPRMC,213642.897,V,,,,,,,010207,,,N*4F\r
+$GPGGA,213643.886,,,,,0,00,,,M,0.0,M,,0000*51\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213643.886,V,,,,,,,010207,,,N*4E\r
+$GPGGA,213644.886,,,,,0,00,,,M,0.0,M,,0000*56\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213644.886,V,,,,,,,010207,,,N*49\r
+$GPGGA,213645.897,,,,,0,00,,,M,0.0,M,,0000*57\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213645.897,V,,,,,,,010207,,,N*48\r
+$GPGGA,213646.886,,,,,0,00,,,M,0.0,M,,0000*54\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213646.886,V,,,,,,,010207,,,N*4B\r
+$GPGGA,213647.886,,,,,0,00,,,M,0.0,M,,0000*55\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,12,20,00,000,,10,00,000,,25,00,000,,27,00,000,*79\r
+$GPGSV,3,2,12,22,00,000,,07,00,000,,21,00,000,,24,00,000,*79\r
+$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78\r
+$GPRMC,213647.886,V,,,,,,,010207,,,N*4A\r
+$GPGGA,213648.897,,,,,0,00,,,M,0.0,M,,0000*5A\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213648.897,V,,,,,,,010207,,,N*45\r
+$GPGGA,213649.886,,,,,0,00,,,M,0.0,M,,0000*5B\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213649.886,V,,,,,,,010207,,,N*44\r
+$GPGGA,213650.886,,,,,0,00,,,M,0.0,M,,0000*53\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213650.886,V,,,,,,,010207,,,N*4C\r
+$GPGGA,213651.897,,,,,0,00,,,M,0.0,M,,0000*52\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213651.897,V,,,,,,,010207,,,N*4D\r
+$GPGGA,213652.886,,,,,0,00,,,M,0.0,M,,0000*51\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,12,20,00,000,,10,00,000,,25,00,000,,27,00,000,*79\r
+$GPGSV,3,2,12,22,00,000,,07,00,000,,21,00,000,,24,00,000,*79\r
+$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78\r
+$GPRMC,213652.886,V,,,,,,,010207,,,N*4E\r
+$GPGGA,213653.886,,,,,0,00,,,M,0.0,M,,0000*50\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213653.886,V,,,,,,,010207,,,N*4F\r
+$GPGGA,213654.898,,,,,0,00,,,M,0.0,M,,0000*58\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213654.898,V,,,,,,,010207,,,N*47\r
+$GPGGA,213655.886,,,,,0,00,,,M,0.0,M,,0000*56\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213655.886,V,,,,,,,010207,,,N*49\r
+$GPGGA,213656.886,,,,,0,00,,,M,0.0,M,,0000*55\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213656.886,V,,,,,,,010207,,,N*4A\r
+$GPGGA,213657.897,,,,,0,00,,,M,0.0,M,,0000*54\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,12,20,00,000,,10,00,000,,25,00,000,,27,00,000,*79\r
+$GPGSV,3,2,12,22,00,000,,07,00,000,,21,00,000,,24,00,000,*79\r
+$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78\r
+$GPRMC,213657.897,V,,,,,,,010207,,,N*4B\r
+$GPGGA,213658.886,,,,,0,00,,,M,0.0,M,,0000*5B\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213658.886,V,,,,,,,010207,,,N*44\r
+$GPGGA,213659.886,,,,,0,00,,,M,0.0,M,,0000*5A\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213659.886,V,,,,,,,010207,,,N*45\r
+$GPGGA,213700.880,,,,,0,00,,,M,0.0,M,,0000*51\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213700.880,V,,,,,,,010207,,,N*4E\r
+$GPGGA,213701.880,,,,,0,00,,,M,0.0,M,,0000*50\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213701.880,V,,,,,,,010207,,,N*4F\r
+$GPGGA,213702.880,,,,,0,00,,,M,0.0,M,,0000*53\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,,10,46,055,*70\r
+$GPGSV,3,2,10,06,41,282,,02,23,120,,21,21,303,,08,16,068,*73\r
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B\r
+$GPRMC,213702.880,V,,,,,,,010207,,,N*4C\r
+$GPGGA,213703.880,,,,,0,00,,,M,0.0,M,,0000*52\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213703.880,V,,,,,,,010207,,,N*4D\r
+$GPGGA,213704.880,,,,,0,00,,,M,0.0,M,,0000*55\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213704.880,V,,,,,,,010207,,,N*4A\r
+$GPGGA,213705.879,,,,,0,00,,,M,0.0,M,,0000*52\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213705.879,V,,,,,,,010207,,,N*4D\r
+$GPGGA,213706.879,,,,,0,00,,,M,0.0,M,,0000*51\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213706.879,V,,,,,,,010207,,,N*4E\r
+$GPGGA,213707.879,,,,,0,00,,,M,0.0,M,,0000*50\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,,10,46,055,*70\r
+$GPGSV,3,2,10,06,41,282,,02,23,120,,21,21,303,,08,16,068,*73\r
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B\r
+$GPRMC,213707.879,V,,,,,,,010207,,,N*4F\r
+$GPGGA,213708.879,,,,,0,00,,,M,0.0,M,,0000*5F\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213708.879,V,,,,,,,010207,,,N*40\r
+$GPGGA,213709.879,,,,,0,00,,,M,0.0,M,,0000*5E\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213709.879,V,,,,,,,010207,,,N*41\r
+$GPGGA,213710.879,,,,,0,00,,,M,0.0,M,,0000*56\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213710.879,V,,,,,,,010207,,,N*49\r
+$GPGGA,213711.879,,,,,0,00,,,M,0.0,M,,0000*57\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213711.879,V,,,,,,,010207,,,N*48\r
+$GPGGA,213712.879,,,,,0,00,,,M,0.0,M,,0000*54\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,,10,46,055,*70\r
+$GPGSV,3,2,10,06,41,282,,02,23,120,,21,21,303,,08,16,068,*73\r
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B\r
+$GPRMC,213712.879,V,,,,,,,010207,,,N*4B\r
+$GPGGA,213713.879,,,,,0,00,,,M,0.0,M,,0000*55\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213713.879,V,,,,,,,010207,,,N*4A\r
+$GPGGA,213714.879,,,,,0,00,,,M,0.0,M,,0000*52\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213714.879,V,,,,,,,010207,,,N*4D\r
+$GPGGA,213715.879,,,,,0,00,,,M,0.0,M,,0000*53\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213715.879,V,,,,,,,010207,,,N*4C\r
+$GPGGA,213716.879,,,,,0,00,,,M,0.0,M,,0000*50\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213716.879,V,,,,,,,010207,,,N*4F\r
+$GPGGA,213717.879,,,,,0,00,,,M,0.0,M,,0000*51\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,25,10,46,055,*77\r
+$GPGSV,3,2,10,06,41,282,35,02,23,120,,21,21,303,,08,16,068,*75\r
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B\r
+$GPRMC,213717.879,V,,,,,,,010207,,,N*4E\r
+$GPGGA,213718.879,,,,,0,00,,,M,0.0,M,,0000*5E\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213718.879,V,,,,,,,010207,,,N*41\r
+$GPGGA,213719.879,,,,,0,00,,,M,0.0,M,,0000*5F\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213719.879,V,,,,,,,010207,,,N*40\r
+$GPGGA,213720.879,,,,,0,00,,,M,0.0,M,,0000*55\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213720.879,V,,,,,,,010207,,,N*4A\r
+$GPGGA,213721.879,,,,,0,00,,,M,0.0,M,,0000*54\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213721.879,V,,,,,,,010207,,,N*4B\r
+$GPGGA,213722.879,,,,,0,00,,,M,0.0,M,,0000*57\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,31,10,46,055,*72\r
+$GPGSV,3,2,10,06,41,282,34,02,23,120,,21,21,303,,08,16,068,*74\r
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B\r
+$GPRMC,213722.879,V,,,,,,,010207,,,N*48\r
+$GPGGA,213723.990,,,,,0,00,,,M,0.0,M,,0000*50\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213723.990,V,,,,,,,010207,,,N*4F\r
+$GPGGA,213724.990,,,,,0,00,,,M,0.0,M,,0000*57\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213724.990,V,,,,,,,010207,,,N*48\r
+$GPGGA,213725.990,,,,,0,00,,,M,0.0,M,,0000*56\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213725.990,V,,,,,,,010207,,,N*49\r
+$GPGGA,213726.990,,,,,0,00,,,M,0.0,M,,0000*55\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213726.990,V,,,,,,,010207,,,N*4A\r
+$GPGGA,213727.990,,,,,0,00,,,M,0.0,M,,0000*54\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,30,10,46,055,*73\r
+$GPGSV,3,2,10,06,41,282,34,02,23,120,,21,21,303,,08,16,068,*74\r
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B\r
+$GPRMC,213727.990,V,,,,,,,010207,,,N*4B\r
+$GPGGA,213728.990,,,,,0,00,,,M,0.0,M,,0000*5B\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213728.990,V,,,,,,,010207,,,N*44\r
+$GPGGA,213729.990,,,,,0,00,,,M,0.0,M,,0000*5A\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213729.990,V,,,,,,,010207,,,N*45\r
+$GPGGA,213730.990,,,,,0,00,,,M,0.0,M,,0000*52\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213730.990,V,,,,,,,010207,,,N*4D\r
+$GPGGA,213731.990,,,,,0,00,,,M,0.0,M,,0000*53\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213731.990,V,,,,,,,010207,,,N*4C\r
+$GPGGA,213732.990,,,,,0,00,,,M,0.0,M,,0000*50\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,27,10,46,055,*75\r
+$GPGSV,3,2,10,06,41,282,35,02,23,120,,21,21,303,,08,16,068,*75\r
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B\r
+$GPRMC,213732.990,V,,,,,,,010207,,,N*4F\r
+$GPGGA,213733.990,,,,,0,00,,,M,0.0,M,,0000*51\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213733.990,V,,,,,,,010207,,,N*4E\r
+$GPGGA,213734.990,,,,,0,00,,,M,0.0,M,,0000*56\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213734.990,V,,,,,,,010207,,,N*49\r
+$GPGGA,213735.990,,,,,0,00,,,M,0.0,M,,0000*57\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213735.990,V,,,,,,,010207,,,N*48\r
+$GPGGA,213736.990,,,,,0,00,,,M,0.0,M,,0000*54\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213736.990,V,,,,,,,010207,,,N*4B\r
+$GPGGA,213737.990,,,,,0,00,,,M,0.0,M,,0000*55\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,28,10,46,055,*7A\r
+$GPGSV,3,2,10,06,41,282,34,02,23,120,,21,21,303,,08,16,068,*74\r
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B\r
+$GPRMC,213737.990,V,,,,,,,010207,,,N*4A\r
+$GPGGA,213738.990,,,,,0,00,,,M,0.0,M,,0000*5A\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213738.990,V,,,,,,,010207,,,N*45\r
+$GPGGA,213739.990,,,,,0,00,,,M,0.0,M,,0000*5B\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213739.990,V,,,,,,,010207,,,N*44\r
+$GPGGA,213740.990,,,,,0,00,,,M,0.0,M,,0000*55\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213740.990,V,,,,,,,010207,,,N*4A\r
+$GPGGA,213741.990,,,,,0,00,,,M,0.0,M,,0000*54\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213741.990,V,,,,,,,010207,,,N*4B\r
+$GPGGA,213742.990,,,,,0,00,,,M,0.0,M,,0000*57\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,28,10,46,055,*7A\r
+$GPGSV,3,2,10,06,41,282,34,02,23,120,,21,21,303,,08,16,068,*74\r
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B\r
+$GPRMC,213742.990,V,,,,,,,010207,,,N*48\r
+$GPGGA,213743.990,,,,,0,00,,,M,0.0,M,,0000*56\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213743.990,V,,,,,,,010207,,,N*49\r
+$GPGGA,213744.990,,,,,0,00,,,M,0.0,M,,0000*51\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213744.990,V,,,,,,,010207,,,N*4E\r
+$GPGGA,213745.990,,,,,0,00,,,M,0.0,M,,0000*50\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213745.990,V,,,,,,,010207,,,N*4F\r
+$GPGGA,213746.990,,,,,0,00,,,M,0.0,M,,0000*53\r
+$PSRFTXTVersion GSW3.2.1PAT_3.1.00.12-SDK001P1.00c *3F\r
+$PSRFTXTHTC GPS_ART_321000_GEN*20\r
+$PSRFTXTTOW:  423546*3B\r
+$PSRFTXTWK:   1412*4F\r
+$PSRFTXTPOS:  1533096 -4464909 4274442*2A\r
+$PSRFTXTCLK:  94810*05\r
+$PSRFTXTCHNL: 12*5F\r
+$PSRFTXTBaud rate: 57600 *51\r
+$GPGGA,213912.270,,,,,0,00,,,M,0.0,M,,0000*59\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213912.270,V,,,,,,,010207,,,N*46\r
+$GPGGA,213913.211,,,,,0,00,,,M,0.0,M,,0000*5F\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213913.211,V,,,,,,,010207,,,N*40\r
+$GPGGA,213914.200,,,,,0,00,,,M,0.0,M,,0000*58\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213914.200,V,,,,,,,010207,,,N*47\r
+$GPGGA,213915.196,,,,,0,00,,,M,0.0,M,,0000*55\r
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E\r
+$GPRMC,213915.196,V,,,,,,,010207,,,N*4A\r
+$GPGGA,213916.199,4221.0377,N,07102.9778,W,1,03,13.4,-32.4,M,-33.7,M,,0000*45\r
+$GPGSA,A,2,26,07,06,,,,,,,,,,13.4,13.4,1.0*37\r
+$GPGSV,3,1,11,26,55,180,28,06,46,258,33,07,43,272,30,21,22,304,*77\r
+$GPGSV,3,2,11,24,83,061,,29,64,170,,10,45,056,,02,23,121,*7F\r
+$GPGSV,3,3,11,08,17,067,,27,10,041,,18,05,257,*4B\r
+$GPRMC,213916.199,A,4221.0377,N,07102.9778,W,0.00,,010207,,,A*6A\r
+$GPGGA,213917.199,4221.0510,N,07102.9549,W,1,04,3.9,-65.2,M,-33.7,M,,0000*7C\r
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A\r
+$GPRMC,213917.199,A,4221.0510,N,07102.9549,W,0.23,175.43,010207,,,A*77\r
+$GPGGA,213918.199,4221.0853,N,07102.9382,W,1,04,3.9,50.0,M,-33.7,M,,0000*51\r
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A\r
+$GPRMC,213918.199,A,4221.0853,N,07102.9382,W,0.95,326.55,010207,,,A*7D\r
+$GPGGA,213919.000,4221.0975,N,07102.9300,W,1,04,3.9,86.2,M,-33.7,M,,0000*57\r
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A\r
+$GPRMC,213919.000,A,4221.0975,N,07102.9300,W,0.55,332.53,010207,,,A*7D\r
+$GPGGA,213920.000,4221.1129,N,07102.9146,W,1,04,3.9,129.7,M,-33.7,M,,0000*6C\r
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A\r
+$GPRMC,213920.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*6D\r
+$GPGGA,213921.000,4221.1129,N,07102.9146,W,1,04,3.9,129.7,M,-33.7,M,,0000*6D\r
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A\r
+$GPGSV,3,1,11,26,55,180,29,06,46,258,26,07,43,272,33,21,22,304,26*75\r
+$GPGSV,3,2,11,24,83,061,,29,64,170,,10,45,056,,02,23,121,*7F\r
+$GPGSV,3,3,11,08,17,067,28,27,10,041,,18,05,257,*41\r
+$GPRMC,213921.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*6C\r
+$GPGGA,213922.000,4221.1129,N,07102.9146,W,1,04,3.9,129.7,M,-33.7,M,,0000*6E\r
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A\r
+$GPRMC,213922.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*6F\r
+$GPGGA,213923.000,4221.1129,N,07102.9146,W,1,04,3.9,129.7,M,-33.7,M,,0000*6F\r
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A\r
+$GPRMC,213923.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*6E\r
+$GPGGA,213924.000,4221.1129,N,07102.9146,W,1,04,3.9,129.7,M,-33.7,M,,0000*68\r
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.0,3.9,1.0*3B\r
+$GPRMC,213924.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*69\r
+$GPGGA,213925.000,4221.1129,N,07102.9146,W,1,04,3.9,129.7,M,-33.7,M,,0000*69\r
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.0,3.9,1.0*3B\r
+$GPRMC,213925.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*68\r
+$GPGGA,213926.000,4221.1112,N,07102.9177,W,1,04,3.9,136.5,M,-33.7,M,,0000*6C\r
+\r
+\r
diff --git a/lib/pud/nmealib/samples/parse_file/main.c b/lib/pud/nmealib/samples/parse_file/main.c
new file mode 100644 (file)
index 0000000..a6f3617
--- /dev/null
@@ -0,0 +1,93 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <nmea/nmea.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+void trace(const char *str, int str_size)
+{
+    printf("Trace: ");
+    write(1, str, str_size);
+    printf("\n");
+}
+void error(const char *str, int str_size)
+{
+    printf("Error: ");
+    write(1, str, str_size);
+    printf("\n");
+}
+
+int main()
+{
+    static const char * filename = "../../samples/parse_file/gpslog.txt";
+    nmeaINFO info;
+    nmeaPARSER parser;
+    FILE *file;
+    char buff[2048];
+    int size, it = 0;
+    nmeaPOS dpos;
+
+    file = fopen(filename, "rb");
+
+    if(!file) {
+        printf("Could not open file %s\n", filename);
+        return -1;
+    }
+
+    nmea_property()->trace_func = &trace;
+    nmea_property()->error_func = &error;
+
+    nmea_zero_INFO(&info);
+    nmea_parser_init(&parser);
+
+    /*
+    while(1)
+    {
+    */
+
+    while(!feof(file))
+    {
+        size = (int)fread(&buff[0], 1, 100, file);
+
+        nmea_parse(&parser, &buff[0], size, &info);
+
+        nmea_info2pos(&info, &dpos);
+
+        printf(
+            "%03d, Lat: %f, Lon: %f, Sig: %d, Fix: %d\n",
+            it++, dpos.lat, dpos.lon, info.sig, info.fix
+            );
+    }
+
+    fseek(file, 0, SEEK_SET);
+
+    /*
+    }
+    */
+
+    nmea_parser_destroy(&parser);
+    fclose(file);
+
+    return 0;
+}
diff --git a/lib/pud/nmealib/src/context.c b/lib/pud/nmealib/src/context.c
new file mode 100644 (file)
index 0000000..c49d66f
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <nmea/context.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <nmea/config.h>
+
+nmeaPROPERTY * nmea_property()
+{
+    static nmeaPROPERTY prop = {
+        0, 0, NMEA_DEF_PARSEBUFF
+        };
+
+    return &prop;
+}
+
+void nmea_trace(const char *str, ...)
+{
+    int size;
+    va_list arg_list;
+    char buff[NMEA_DEF_PARSEBUFF];
+    nmeaTraceFunc func = nmea_property()->trace_func;
+
+    if(func)
+    {
+        va_start(arg_list, str);
+        size = NMEA_POSIX(vsnprintf)(&buff[0], NMEA_DEF_PARSEBUFF - 1, str, arg_list);
+        va_end(arg_list);
+
+        if(size > 0)
+            (*func)(&buff[0], size);
+    }
+}
+
+void nmea_trace_buff(const char *buff, int buff_size)
+{
+    nmeaTraceFunc func = nmea_property()->trace_func;
+    if(func && buff_size)
+        (*func)(buff, buff_size);
+}
+
+void nmea_error(const char *str, ...)
+{
+    int size;
+    va_list arg_list;
+    char buff[NMEA_DEF_PARSEBUFF];
+    nmeaErrorFunc func = nmea_property()->error_func;
+
+    if(func)
+    {
+        va_start(arg_list, str);
+        size = NMEA_POSIX(vsnprintf)(&buff[0], NMEA_DEF_PARSEBUFF - 1, str, arg_list);
+        va_end(arg_list);
+
+        if(size > 0)
+            (*func)(&buff[0], size);
+    }
+}
diff --git a/lib/pud/nmealib/src/generate.c b/lib/pud/nmealib/src/generate.c
new file mode 100644 (file)
index 0000000..abbb98f
--- /dev/null
@@ -0,0 +1,237 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <nmea/generate.h>
+
+#include <math.h>
+
+#include <nmea/tok.h>
+#include <nmea/units.h>
+
+int nmea_gen_GPGGA(char *buff, int buff_sz, nmeaGPGGA *pack)
+{
+    return nmea_printf(buff, buff_sz,
+        "$GPGGA,%02d%02d%02d.%02d,%09.4f,%C,%010.4f,%C,%1d,%02d,%03.1f,%03.1f,%C,%03.1f,%C,%03.1f,%04d",
+        pack->utc.hour, pack->utc.min, pack->utc.sec, pack->utc.hsec,
+        pack->lat, pack->ns, pack->lon, pack->ew,
+        pack->sig, pack->satinuse, pack->HDOP, pack->elv, pack->elv_units,
+        pack->diff, pack->diff_units, pack->dgps_age, pack->dgps_sid);
+}
+
+int nmea_gen_GPGSA(char *buff, int buff_sz, nmeaGPGSA *pack)
+{
+    return nmea_printf(buff, buff_sz,
+        "$GPGSA,%C,%1d,%02d,%02d,%02d,%02d,%02d,%02d,%02d,%02d,%02d,%02d,%02d,%02d,%03.1f,%03.1f,%03.1f",
+        pack->fix_mode, pack->fix_type,
+        pack->sat_prn[0], pack->sat_prn[1], pack->sat_prn[2], pack->sat_prn[3], pack->sat_prn[4], pack->sat_prn[5],
+        pack->sat_prn[6], pack->sat_prn[7], pack->sat_prn[8], pack->sat_prn[9], pack->sat_prn[10], pack->sat_prn[11],
+        pack->PDOP, pack->HDOP, pack->VDOP);
+}
+
+int nmea_gen_GPGSV(char *buff, int buff_sz, nmeaGPGSV *pack)
+{
+    return nmea_printf(buff, buff_sz,
+        "$GPGSV,%1d,%1d,%02d,"
+        "%02d,%02d,%03d,%02d,"
+        "%02d,%02d,%03d,%02d,"
+        "%02d,%02d,%03d,%02d,"
+        "%02d,%02d,%03d,%02d",
+        pack->pack_count, pack->pack_index + 1, pack->sat_count,
+        pack->sat_data[0].id, pack->sat_data[0].elv, pack->sat_data[0].azimuth, pack->sat_data[0].sig,
+        pack->sat_data[1].id, pack->sat_data[1].elv, pack->sat_data[1].azimuth, pack->sat_data[1].sig,
+        pack->sat_data[2].id, pack->sat_data[2].elv, pack->sat_data[2].azimuth, pack->sat_data[2].sig,
+        pack->sat_data[3].id, pack->sat_data[3].elv, pack->sat_data[3].azimuth, pack->sat_data[3].sig);
+}
+
+int nmea_gen_GPRMC(char *buff, int buff_sz, nmeaGPRMC *pack)
+{
+    return nmea_printf(buff, buff_sz,
+        "$GPRMC,%02d%02d%02d.%02d,%C,%09.4f,%C,%010.4f,%C,%03.1f,%03.1f,%02d%02d%02d,%03.1f,%C,%C",
+        pack->utc.hour, pack->utc.min, pack->utc.sec, pack->utc.hsec,
+        pack->status, pack->lat, pack->ns, pack->lon, pack->ew,
+        pack->speed, pack->direction,
+        pack->utc.day, pack->utc.mon + 1, pack->utc.year - 100,
+        pack->declination, pack->declin_ew, pack->mode);
+}
+
+int nmea_gen_GPVTG(char *buff, int buff_sz, nmeaGPVTG *pack)
+{
+    return nmea_printf(buff, buff_sz,
+        "$GPVTG,%.1f,%C,%.1f,%C,%.1f,%C,%.1f,%C",
+        pack->dir, pack->dir_t,
+        pack->dec, pack->dec_m,
+        pack->spn, pack->spn_n,
+        pack->spk, pack->spk_k);
+}
+
+void nmea_info2GPGGA(const nmeaINFO *info, nmeaGPGGA *pack)
+{
+    nmea_zero_GPGGA(pack);
+
+    pack->utc = info->utc;
+    pack->lat = fabs(info->lat);
+    pack->ns = ((info->lat > 0)?'N':'S');
+    pack->lon = fabs(info->lon);
+    pack->ew = ((info->lon > 0)?'E':'W');
+    pack->sig = info->sig;
+    pack->satinuse = info->satinfo.inuse;
+    pack->HDOP = info->HDOP;
+    pack->elv = info->elv;
+}
+
+void nmea_info2GPGSA(const nmeaINFO *info, nmeaGPGSA *pack)
+{
+    int it;
+
+    nmea_zero_GPGSA(pack);
+
+    pack->fix_type = info->fix;
+    pack->PDOP = info->PDOP;
+    pack->HDOP = info->HDOP;
+    pack->VDOP = info->VDOP;
+
+    for(it = 0; it < NMEA_MAXSAT; ++it)
+    {
+        pack->sat_prn[it] =
+            ((info->satinfo.sat[it].in_use)?info->satinfo.sat[it].id:0);
+    }
+}
+
+int nmea_gsv_npack(int sat_count)
+{
+    int pack_count = (int)ceil(((double)sat_count) / NMEA_SATINPACK);
+
+    if(0 == pack_count)
+        pack_count = 1;
+
+    return pack_count;
+}
+
+void nmea_info2GPGSV(const nmeaINFO *info, nmeaGPGSV *pack, int pack_idx)
+{
+    int sit, pit;
+
+    nmea_zero_GPGSV(pack);
+
+    pack->sat_count = (info->satinfo.inview <= NMEA_MAXSAT)?info->satinfo.inview:NMEA_MAXSAT;
+    pack->pack_count = nmea_gsv_npack(pack->sat_count);
+
+    if(pack->pack_count == 0)
+        pack->pack_count = 1;
+
+    if(pack_idx >= pack->pack_count)
+        pack->pack_index = pack_idx % pack->pack_count;
+    else
+        pack->pack_index = pack_idx;
+
+    for(pit = 0, sit = pack->pack_index * NMEA_SATINPACK; pit < NMEA_SATINPACK; ++pit, ++sit)
+        pack->sat_data[pit] = info->satinfo.sat[sit];
+}
+
+void nmea_info2GPRMC(const nmeaINFO *info, nmeaGPRMC *pack)
+{
+    nmea_zero_GPRMC(pack);
+
+    pack->utc = info->utc;
+    pack->status = ((info->sig > 0)?'A':'V');
+    pack->lat = fabs(info->lat);
+    pack->ns = ((info->lat > 0)?'N':'S');
+    pack->lon = fabs(info->lon);
+    pack->ew = ((info->lon > 0)?'E':'W');
+    pack->speed = info->speed / NMEA_TUD_KNOTS;
+    pack->direction = info->direction;
+    pack->declination = info->declination;
+    pack->declin_ew = 'E';
+    pack->mode = ((info->sig > 0)?'A':'N');
+}
+
+void nmea_info2GPVTG(const nmeaINFO *info, nmeaGPVTG *pack)
+{
+    nmea_zero_GPVTG(pack);
+
+    pack->dir = info->direction;
+    pack->dec = info->declination;
+    pack->spn = info->speed / NMEA_TUD_KNOTS;
+    pack->spk = info->speed;
+}
+
+int nmea_generate(
+    char *buff, int buff_sz,
+    const nmeaINFO *info,
+    int generate_mask
+    )
+{
+    int gen_count = 0, gsv_it, gsv_count;
+    int pack_mask = generate_mask;
+
+    nmeaGPGGA gga;
+    nmeaGPGSA gsa;
+    nmeaGPGSV gsv;
+    nmeaGPRMC rmc;
+    nmeaGPVTG vtg;
+
+    if(!buff)
+        return 0;
+
+    while(pack_mask)
+    {
+        if(pack_mask & GPGGA)
+        {
+            nmea_info2GPGGA(info, &gga);
+            gen_count += nmea_gen_GPGGA(buff + gen_count, buff_sz - gen_count, &gga);
+            pack_mask &= ~GPGGA;
+        }
+        else if(pack_mask & GPGSA)
+        {
+            nmea_info2GPGSA(info, &gsa);
+            gen_count += nmea_gen_GPGSA(buff + gen_count, buff_sz - gen_count, &gsa);
+            pack_mask &= ~GPGSA;
+        }
+        else if(pack_mask & GPGSV)
+        {
+            gsv_count = nmea_gsv_npack(info->satinfo.inview);
+            for(gsv_it = 0; gsv_it < gsv_count && buff_sz - gen_count > 0; ++gsv_it)
+            {
+                nmea_info2GPGSV(info, &gsv, gsv_it);
+                gen_count += nmea_gen_GPGSV(buff + gen_count, buff_sz - gen_count, &gsv);
+            }
+            pack_mask &= ~GPGSV;
+        }
+        else if(pack_mask & GPRMC)
+        {
+            nmea_info2GPRMC(info, &rmc);
+            gen_count += nmea_gen_GPRMC(buff + gen_count, buff_sz - gen_count, &rmc);
+            pack_mask &= ~GPRMC;
+        }
+        else if(pack_mask & GPVTG)
+        {
+            nmea_info2GPVTG(info, &vtg);
+            gen_count += nmea_gen_GPVTG(buff + gen_count, buff_sz - gen_count, &vtg);
+            pack_mask &= ~GPVTG;
+        }
+        else
+            break;
+
+        if(buff_sz - gen_count <= 0)
+            break;
+    }
+
+    return gen_count;
+}
diff --git a/lib/pud/nmealib/src/generator.c b/lib/pud/nmealib/src/generator.c
new file mode 100644 (file)
index 0000000..5cc2158
--- /dev/null
@@ -0,0 +1,412 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <nmea/generator.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <nmea/context.h>
+#include <nmea/generate.h>
+#include <nmea/gmath.h>
+
+double nmea_random(double min, double max)
+{
+    static double rand_max = RAND_MAX;
+    double rand_val = rand();
+    double bounds = max - min;
+    return min + (rand_val * bounds) / rand_max;
+}
+
+/*
+ * low level
+ */
+
+int nmea_gen_init(nmeaGENERATOR *gen, nmeaINFO *info)
+{
+    int RetVal = 1; int smask = info->smask;
+    nmeaGENERATOR *igen = gen;
+
+    nmea_zero_INFO(info);
+    info->smask = smask;
+
+    info->lat = NMEA_DEF_LAT;
+    info->lon = NMEA_DEF_LON;
+
+    while(RetVal && igen)
+    {
+        if(igen->init_call)
+            RetVal = (*igen->init_call)(igen, info);
+        igen = igen->next;
+    }
+
+    return RetVal;
+}
+
+int nmea_gen_loop(nmeaGENERATOR *gen, nmeaINFO *info)
+{
+    int RetVal = 1;
+
+    if(gen->loop_call)
+        RetVal = (*gen->loop_call)(gen, info);
+
+    if(RetVal && gen->next)
+        RetVal = nmea_gen_loop(gen->next, info);
+
+    return RetVal;
+}
+
+int nmea_gen_reset(nmeaGENERATOR *gen, nmeaINFO *info)
+{
+    int RetVal = 1;
+
+    if(gen->reset_call)
+        RetVal = (*gen->reset_call)(gen, info);
+
+    return RetVal;
+}
+
+void nmea_gen_destroy(nmeaGENERATOR *gen)
+{
+    if(gen->next)
+    {
+        nmea_gen_destroy(gen->next);
+        gen->next = 0;
+    }
+
+    if(gen->destroy_call)
+        (*gen->destroy_call)(gen);
+
+    free(gen);
+}
+
+void nmea_gen_add(nmeaGENERATOR *to, nmeaGENERATOR *gen)
+{
+    if(to->next)
+        nmea_gen_add(to->next, gen);
+    else
+        to->next = gen;
+}
+
+int nmea_generate_from(
+    char *buff, int buff_sz,
+    nmeaINFO *info,
+    nmeaGENERATOR *gen,
+    int generate_mask
+    )
+{
+    int retval;
+
+    if(0 != (retval = nmea_gen_loop(gen, info)))
+        retval = nmea_generate(buff, buff_sz, info, generate_mask);
+
+    return retval;
+}
+
+/*
+ * NOISE generator
+ */
+
+int nmea_igen_noise_init(nmeaGENERATOR *gen __attribute__ ((unused)),
+               nmeaINFO *info __attribute__ ((unused)))
+{
+    return 1;
+}
+
+int nmea_igen_noise_loop(nmeaGENERATOR *gen __attribute__ ((unused)),
+               nmeaINFO *info)
+{
+    int it;
+    int in_use;
+
+    info->sig = (int)nmea_random(1, 3);
+    info->PDOP = nmea_random(0, 9);
+    info->HDOP = nmea_random(0, 9);
+    info->VDOP = nmea_random(0, 9);
+    info->fix = (int)nmea_random(2, 3);
+    info->lat = nmea_random(0, 100);
+    info->lon = nmea_random(0, 100);
+    info->speed = nmea_random(0, 100);
+    info->direction = nmea_random(0, 360);
+    info->declination = nmea_random(0, 360);
+    info->elv = (int)nmea_random(-100, 100);
+
+    info->satinfo.inuse = 0;
+    info->satinfo.inview = 0;
+
+    for(it = 0; it < 12; ++it)
+    {
+        info->satinfo.sat[it].id = it;
+        info->satinfo.sat[it].in_use = in_use = (int)nmea_random(0, 3);
+        info->satinfo.sat[it].elv = (int)nmea_random(0, 90);
+        info->satinfo.sat[it].azimuth = (int)nmea_random(0, 359);
+        info->satinfo.sat[it].sig = (int)(in_use?nmea_random(40, 99):nmea_random(0, 40));
+
+        if(in_use)
+            info->satinfo.inuse++;
+        if(info->satinfo.sat[it].sig > 0)
+            info->satinfo.inview++;
+    }
+
+    return 1;
+}
+
+int nmea_igen_noise_reset(nmeaGENERATOR *gen __attribute__ ((unused)),
+               nmeaINFO *info __attribute__ ((unused)))
+{
+    return 1;
+}
+
+/*
+ * STATIC generator
+ */
+
+int nmea_igen_static_loop(nmeaGENERATOR *gen __attribute__ ((unused)),
+               nmeaINFO *info)
+{
+    nmea_time_now(&info->utc);
+    return 1;
+};
+
+int nmea_igen_static_reset(nmeaGENERATOR *gen __attribute__ ((unused)),
+               nmeaINFO *info)
+{
+    info->satinfo.inuse = 4;
+    info->satinfo.inview = 4;
+
+    info->satinfo.sat[0].id = 1;
+    info->satinfo.sat[0].in_use = 1;
+    info->satinfo.sat[0].elv = 50;
+    info->satinfo.sat[0].azimuth = 0;
+    info->satinfo.sat[0].sig = 99;
+
+    info->satinfo.sat[1].id = 2;
+    info->satinfo.sat[1].in_use = 1;
+    info->satinfo.sat[1].elv = 50;
+    info->satinfo.sat[1].azimuth = 90;
+    info->satinfo.sat[1].sig = 99;
+
+    info->satinfo.sat[2].id = 3;
+    info->satinfo.sat[2].in_use = 1;
+    info->satinfo.sat[2].elv = 50;
+    info->satinfo.sat[2].azimuth = 180;
+    info->satinfo.sat[2].sig = 99;
+
+    info->satinfo.sat[3].id = 4;
+    info->satinfo.sat[3].in_use = 1;
+    info->satinfo.sat[3].elv = 50;
+    info->satinfo.sat[3].azimuth = 270;
+    info->satinfo.sat[3].sig = 99;
+
+    return 1;
+}
+
+int nmea_igen_static_init(nmeaGENERATOR *gen, nmeaINFO *info)
+{
+    info->sig = 3;
+    info->fix = 3;
+
+    nmea_igen_static_reset(gen, info);
+
+    return 1;
+}
+
+/*
+ * SAT_ROTATE generator
+ */
+
+int nmea_igen_rotate_loop(nmeaGENERATOR *gen __attribute__ ((unused)),
+               nmeaINFO *info)
+{
+    int it;
+    int count = info->satinfo.inview;
+    double deg = 360 / (count?count:1);
+    double srt = (count?(info->satinfo.sat[0].azimuth):0) + 5;
+
+    nmea_time_now(&info->utc);
+
+    for(it = 0; it < count; ++it)
+    {
+        info->satinfo.sat[it].azimuth =
+            (int)((srt >= 360)?srt - 360:srt);
+        srt += deg;
+    }
+
+    return 1;
+};
+
+int nmea_igen_rotate_reset(nmeaGENERATOR *gen __attribute__ ((unused)),
+               nmeaINFO *info)
+{
+    int it;
+    double deg = 360 / 8;
+    double srt = 0;
+
+    info->satinfo.inuse = 8;
+    info->satinfo.inview = 8;
+
+    for(it = 0; it < info->satinfo.inview; ++it)
+    {
+        info->satinfo.sat[it].id = it + 1;
+        info->satinfo.sat[it].in_use = 1;
+        info->satinfo.sat[it].elv = 5;
+        info->satinfo.sat[it].azimuth = (int)srt;
+        info->satinfo.sat[it].sig = 80;
+        srt += deg;
+    }
+
+    return 1;
+}
+
+int nmea_igen_rotate_init(nmeaGENERATOR *gen, nmeaINFO *info)
+{
+    info->sig = 3;
+    info->fix = 3;
+
+    nmea_igen_rotate_reset(gen, info);
+
+    return 1;
+}
+
+/*
+ * POS_RANDMOVE generator
+ */
+
+int nmea_igen_pos_rmove_init(nmeaGENERATOR *gen __attribute__ ((unused)),
+               nmeaINFO *info)
+{    
+    info->sig = 3;
+    info->fix = 3;
+    info->direction = info->declination = 0;
+    info->speed = 20;
+    return 1;
+}
+
+int nmea_igen_pos_rmove_loop(nmeaGENERATOR *gen __attribute__ ((unused)),
+               nmeaINFO *info)
+{
+    nmeaPOS crd;
+
+    info->direction += nmea_random(-10, 10);
+    info->speed += nmea_random(-2, 3);
+
+    if(info->direction < 0)
+        info->direction = 359 + info->direction;
+    if(info->direction > 359)
+        info->direction -= 359;
+
+    if(info->speed > 40)
+        info->speed = 40;
+    if(info->speed < 1)
+        info->speed = 1;
+
+    nmea_info2pos(info, &crd);
+    nmea_move_horz(&crd, &crd, info->direction, info->speed / 3600);
+    nmea_pos2info(&crd, info);
+
+    info->declination = info->direction;
+
+    return 1;
+};
+
+int nmea_igen_pos_rmove_destroy(nmeaGENERATOR *gen __attribute__ ((unused)))
+{
+    return 1;
+};
+
+/*
+ * generator create
+ */
+
+nmeaGENERATOR * __nmea_create_generator(int type, nmeaINFO *info)
+{
+    nmeaGENERATOR *gen = 0;
+
+    switch(type)
+    {
+    case NMEA_GEN_NOISE:
+        if(0 == (gen = malloc(sizeof(nmeaGENERATOR))))
+            nmea_error("Insufficient memory!");
+        else
+        {
+            memset(gen, 0, sizeof(nmeaGENERATOR));
+            gen->init_call = &nmea_igen_noise_init;
+            gen->loop_call = &nmea_igen_noise_loop;
+            gen->reset_call = &nmea_igen_noise_reset;
+        }
+        break;
+    case NMEA_GEN_STATIC:
+    case NMEA_GEN_SAT_STATIC:
+        if(0 == (gen = malloc(sizeof(nmeaGENERATOR))))
+            nmea_error("Insufficient memory!");
+        else
+        {
+            memset(gen, 0, sizeof(nmeaGENERATOR));
+            gen->init_call = &nmea_igen_static_init;
+            gen->loop_call = &nmea_igen_static_loop;
+            gen->reset_call = &nmea_igen_static_reset;
+        }
+        break;
+    case NMEA_GEN_SAT_ROTATE:
+        if(0 == (gen = malloc(sizeof(nmeaGENERATOR))))
+            nmea_error("Insufficient memory!");
+        else
+        {
+            memset(gen, 0, sizeof(nmeaGENERATOR));
+            gen->init_call = &nmea_igen_rotate_init;
+            gen->loop_call = &nmea_igen_rotate_loop;
+            gen->reset_call = &nmea_igen_rotate_reset;
+        }
+        break;
+    case NMEA_GEN_POS_RANDMOVE:
+        if(0 == (gen = malloc(sizeof(nmeaGENERATOR))))
+            nmea_error("Insufficient memory!");
+        else
+        {
+            memset(gen, 0, sizeof(nmeaGENERATOR));
+            gen->init_call = &nmea_igen_pos_rmove_init;
+            gen->loop_call = &nmea_igen_pos_rmove_loop;
+            gen->destroy_call = &nmea_igen_pos_rmove_destroy;
+        }
+        break;
+    default:
+    /* case NMEA_GEN_ROTATE: */
+        gen = __nmea_create_generator(NMEA_GEN_SAT_ROTATE, info);
+        nmea_gen_add(gen, __nmea_create_generator(NMEA_GEN_POS_RANDMOVE, info));
+        break;
+    };
+
+    return gen;
+}
+
+nmeaGENERATOR * nmea_create_generator(int type, nmeaINFO *info)
+{
+    nmeaGENERATOR *gen = __nmea_create_generator(type, info);
+
+    if(gen)
+        nmea_gen_init(gen, info);
+
+    return gen;
+}
+
+void nmea_destroy_generator(nmeaGENERATOR *gen)
+{
+    nmea_gen_destroy(gen);
+}
diff --git a/lib/pud/nmealib/src/gmath.c b/lib/pud/nmealib/src/gmath.c
new file mode 100644 (file)
index 0000000..d0fda8c
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*! \file gmath.h */
+
+#include <nmea/gmath.h>
+
+#include <math.h>
+
+#include <nmea/config.h>
+
+/**
+ * \brief Convert degree to radian
+ */
+double nmea_degree2radian(double val)
+{ return (val * NMEA_PI180); }
+
+/**
+ * \brief Convert radian to degree
+ */
+double nmea_radian2degree(double val)
+{ return (val / NMEA_PI180); }
+
+/**
+ * \brief Convert NDEG (NMEA degree) to fractional degree
+ */
+double nmea_ndeg2degree(double val)
+{
+    double deg;
+    double fra_part = modf(val / 100.0, &deg);
+    return (deg + ((fra_part * 100.0) / 60.0));
+}
+
+/**
+ * \brief Convert fractional degree to NDEG (NMEA degree)
+ */
+double nmea_degree2ndeg(double val)
+{
+    double deg;
+    double fra_part = modf(val, &deg);
+    return ((deg * 100.0) + (fra_part * 60.0));
+}
+
+/**
+ * \brief Convert NDEG (NMEA degree) to radian
+ */
+double nmea_ndeg2radian(double val)
+{ return nmea_degree2radian(nmea_ndeg2degree(val)); }
+
+/**
+ * \brief Convert radian to NDEG (NMEA degree)
+ */
+double nmea_radian2ndeg(double val)
+{ return nmea_degree2ndeg(nmea_radian2degree(val)); }
+
+/**
+ * \brief Calculate PDOP (Position Dilution Of Precision) factor
+ */
+double nmea_calc_pdop(double hdop, double vdop)
+{
+    return sqrt(pow(hdop, 2) + pow(vdop, 2));
+}
+
+double nmea_dop2meters(double dop)
+{ return (dop * NMEA_DOP_FACTOR); }
+
+double nmea_meters2dop(double meters)
+{ return (meters / NMEA_DOP_FACTOR); }
+
+/**
+ * \brief Calculate distance between two points
+ * \return Distance in meters
+ */
+double nmea_distance(
+        const nmeaPOS *from_pos,    /**< From position in radians */
+        const nmeaPOS *to_pos       /**< To position in radians */
+        )
+{
+    double dist = ((double)NMEA_EARTHRADIUS_M) * acos(
+        sin(to_pos->lat) * sin(from_pos->lat) +
+        cos(to_pos->lat) * cos(from_pos->lat) * cos(to_pos->lon - from_pos->lon)
+        );
+    return dist;
+}
+
+/**
+ * \brief Calculate distance between two points
+ * This function uses an algorithm for an oblate spheroid earth model.
+ * The algorithm is described here: 
+ * http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
+ * \return Distance in meters
+ */
+double nmea_distance_ellipsoid(
+        const nmeaPOS *from_pos,    /**< From position in radians */
+        const nmeaPOS *to_pos,      /**< To position in radians */
+        double *from_azimuth,       /**< (O) azimuth at "from" position in radians */
+        double *to_azimuth          /**< (O) azimuth at "to" position in radians */
+        )
+{
+    /* All variables */
+    double f, a, b, sqr_a, sqr_b;
+    double L, phi1, phi2, U1, U2, sin_U1, sin_U2, cos_U1, cos_U2;
+    double sigma, sin_sigma, cos_sigma, cos_2_sigmam, sqr_cos_2_sigmam, sqr_cos_alpha, lambda, sin_lambda, cos_lambda, delta_lambda;
+    int remaining_steps; 
+    double sqr_u, A, B, delta_sigma;
+
+    /* Check input */
+    NMEA_ASSERT(from_pos != 0);
+    NMEA_ASSERT(to_pos != 0);
+
+    if ((from_pos->lat == to_pos->lat) && (from_pos->lon == to_pos->lon))
+    { /* Identical points */
+        if ( from_azimuth != 0 )
+            *from_azimuth = 0;
+        if ( to_azimuth != 0 )
+            *to_azimuth = 0;
+        return 0;    
+    } /* Identical points */
+
+    /* Earth geometry */
+    f = NMEA_EARTH_FLATTENING;
+    a = NMEA_EARTH_SEMIMAJORAXIS_M;
+    b = (1 - f) * a;
+    sqr_a = a * a;
+    sqr_b = b * b;
+
+    /* Calculation */
+    L = to_pos->lon - from_pos->lon;
+    phi1 = from_pos->lat;
+    phi2 = to_pos->lat;
+    U1 = atan((1 - f) * tan(phi1));
+    U2 = atan((1 - f) * tan(phi2));
+    sin_U1 = sin(U1);
+    sin_U2 = sin(U2);
+    cos_U1 = cos(U1);
+    cos_U2 = cos(U2);
+
+    /* Initialize iteration */
+    sigma = 0;
+    sin_sigma = sin(sigma);
+    cos_sigma = cos(sigma);
+    cos_2_sigmam = 0;
+    sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam;
+    sqr_cos_alpha = 0;
+    lambda = L;
+    sin_lambda = sin(lambda);                            
+    cos_lambda = cos(lambda);                       
+    delta_lambda = lambda;
+    remaining_steps = 20; 
+
+    while ((delta_lambda > 1e-12) && (remaining_steps > 0)) 
+    { /* Iterate */
+        /* Variables */
+        double tmp1, tmp2, sin_alpha, cos_alpha, C, lambda_prev;
+
+        /* Calculation */
+        tmp1 = cos_U2 * sin_lambda;
+        tmp2 = cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda;  
+        sin_sigma = sqrt(tmp1 * tmp1 + tmp2 * tmp2);                
+        cos_sigma = sin_U1 * sin_U2 + cos_U1 * cos_U2 * cos_lambda;   
+        sin_alpha = cos_U1 * cos_U2 * sin_lambda / sin_sigma;  
+        cos_alpha = cos(asin(sin_alpha));                 
+        sqr_cos_alpha = cos_alpha * cos_alpha;                     
+        cos_2_sigmam = cos_sigma - 2 * sin_U1 * sin_U2 / sqr_cos_alpha;
+        sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam; 
+        C = f / 16 * sqr_cos_alpha * (4 + f * (4 - 3 * sqr_cos_alpha));
+        lambda_prev = lambda; 
+        sigma = asin(sin_sigma); 
+        lambda = L + 
+            (1 - C) * f * sin_alpha
+            * (sigma + C * sin_sigma * (cos_2_sigmam + C * cos_sigma * (-1 + 2 * sqr_cos_2_sigmam)));                                                
+        delta_lambda = lambda_prev - lambda; 
+        if ( delta_lambda < 0 ) delta_lambda = -delta_lambda; 
+        sin_lambda = sin(lambda);
+        cos_lambda = cos(lambda);
+        remaining_steps--; 
+    }  /* Iterate */
+
+    /* More calculation  */
+    sqr_u = sqr_cos_alpha * (sqr_a - sqr_b) / sqr_b; 
+    A = 1 + sqr_u / 16384 * (4096 + sqr_u * (-768 + sqr_u * (320 - 175 * sqr_u)));
+    B = sqr_u / 1024 * (256 + sqr_u * (-128 + sqr_u * (74 - 47 * sqr_u)));
+    delta_sigma = B * sin_sigma * ( 
+        cos_2_sigmam + B / 4 * ( 
+        cos_sigma * (-1 + 2 * sqr_cos_2_sigmam) -
+        B / 6 * cos_2_sigmam * (-3 + 4 * sin_sigma * sin_sigma) * (-3 + 4 * sqr_cos_2_sigmam)
+        ));
+
+    /* Calculate result */
+    if ( from_azimuth != 0 )
+    {
+        double tan_alpha_1 = cos_U2 * sin_lambda / (cos_U1 * sin_U2 - sin_U1 * cos_U2 * cos_lambda);
+        *from_azimuth = atan(tan_alpha_1);
+    }
+    if ( to_azimuth != 0 )
+    {
+        double tan_alpha_2 = cos_U1 * sin_lambda / (-sin_U1 * cos_U2 + cos_U1 * sin_U2 * cos_lambda);
+        *to_azimuth = atan(tan_alpha_2);
+    }
+
+    return b * A * (sigma - delta_sigma);
+}
+
+/**
+ * \brief Horizontal move of point position
+ */
+int nmea_move_horz(
+    const nmeaPOS *start_pos,   /**< Start position in radians */
+    nmeaPOS *end_pos,           /**< Result position in radians */
+    double azimuth,             /**< Azimuth (degree) [0, 359] */
+    double distance             /**< Distance (km) */
+    )
+{
+    nmeaPOS p1 = *start_pos;
+    int RetVal = 1;
+
+    distance /= NMEA_EARTHRADIUS_KM; /* Angular distance covered on earth's surface */
+    azimuth = nmea_degree2radian(azimuth);
+
+    end_pos->lat = asin(
+        sin(p1.lat) * cos(distance) + cos(p1.lat) * sin(distance) * cos(azimuth));
+    end_pos->lon = p1.lon + atan2(
+        sin(azimuth) * sin(distance) * cos(p1.lat), cos(distance) - sin(p1.lat) * sin(end_pos->lat));
+
+    if(NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon))
+    {
+        end_pos->lat = 0; end_pos->lon = 0;
+        RetVal = 0;
+    }
+
+    return RetVal;
+}
+
+/**
+ * \brief Horizontal move of point position
+ * This function uses an algorithm for an oblate spheroid earth model.
+ * The algorithm is described here: 
+ * http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf
+ */
+int nmea_move_horz_ellipsoid(
+    const nmeaPOS *start_pos,   /**< Start position in radians */
+    nmeaPOS *end_pos,           /**< (O) Result position in radians */
+    double azimuth,             /**< Azimuth in radians */
+    double distance,            /**< Distance (km) */
+    double *end_azimuth         /**< (O) Azimuth at end position in radians */
+    )
+{
+    /* Variables */
+    double f, a, b, sqr_a, sqr_b;
+    double phi1, tan_U1, sin_U1, cos_U1, s, alpha1, sin_alpha1, cos_alpha1;
+    double sigma1, sin_alpha, sqr_cos_alpha, sqr_u, A, B;
+    double sigma_initial, sigma, sigma_prev, sin_sigma, cos_sigma, cos_2_sigmam, sqr_cos_2_sigmam, delta_sigma;
+    int remaining_steps;
+    double tmp1, phi2, lambda, C, L;
+    
+    /* Check input */
+    NMEA_ASSERT(start_pos != 0);
+    NMEA_ASSERT(end_pos != 0);
+    
+    if (fabs(distance) < 1e-12)
+    { /* No move */
+        *end_pos = *start_pos;
+        if ( end_azimuth != 0 ) *end_azimuth = azimuth;
+        return ! (NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon));
+    } /* No move */
+
+    /* Earth geometry */
+    f = NMEA_EARTH_FLATTENING;
+    a = NMEA_EARTH_SEMIMAJORAXIS_M;
+    b = (1 - f) * a;
+    sqr_a = a * a;
+    sqr_b = b * b;
+    
+    /* Calculation */
+    phi1 = start_pos->lat;
+    tan_U1 = (1 - f) * tan(phi1);
+    cos_U1 = 1 / sqrt(1 + tan_U1 * tan_U1);
+    sin_U1 = tan_U1 * cos_U1;
+    s = distance;
+    alpha1 = azimuth;
+    sin_alpha1 = sin(alpha1);
+    cos_alpha1 = cos(alpha1);
+    sigma1 = atan2(tan_U1, cos_alpha1);
+    sin_alpha = cos_U1 * sin_alpha1;
+    sqr_cos_alpha = 1 - sin_alpha * sin_alpha;
+    sqr_u = sqr_cos_alpha * (sqr_a - sqr_b) / sqr_b; 
+    A = 1 + sqr_u / 16384 * (4096 + sqr_u * (-768 + sqr_u * (320 - 175 * sqr_u)));
+    B = sqr_u / 1024 * (256 + sqr_u * (-128 + sqr_u * (74 - 47 * sqr_u)));
+    
+    /* Initialize iteration */
+    sigma_initial = s / (b * A);
+    sigma = sigma_initial;
+    sin_sigma = sin(sigma);
+    cos_sigma = cos(sigma);
+    cos_2_sigmam = cos(2 * sigma1 + sigma);
+    sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam;
+    delta_sigma = 0;
+    sigma_prev = 2 * NMEA_PI;
+    remaining_steps = 20;
+
+    while ((fabs(sigma - sigma_prev) > 1e-12) && (remaining_steps > 0))
+    { /* Iterate */
+        cos_2_sigmam = cos(2 * sigma1 + sigma);
+        sqr_cos_2_sigmam = cos_2_sigmam * cos_2_sigmam;
+        sin_sigma = sin(sigma);
+        cos_sigma = cos(sigma);
+        delta_sigma = B * sin_sigma * ( 
+             cos_2_sigmam + B / 4 * ( 
+             cos_sigma * (-1 + 2 * sqr_cos_2_sigmam) - 
+             B / 6 * cos_2_sigmam * (-3 + 4 * sin_sigma * sin_sigma) * (-3 + 4 * sqr_cos_2_sigmam)
+             ));
+        sigma_prev = sigma;
+        sigma = sigma_initial + delta_sigma;
+        remaining_steps --;
+    } /* Iterate */
+    
+    /* Calculate result */
+    tmp1 = (sin_U1 * sin_sigma - cos_U1 * cos_sigma * cos_alpha1);
+    phi2 = atan2(
+            sin_U1 * cos_sigma + cos_U1 * sin_sigma * cos_alpha1,
+            (1 - f) * sqrt(sin_alpha * sin_alpha + tmp1 * tmp1)
+            );
+    lambda = atan2(
+            sin_sigma * sin_alpha1,
+            cos_U1 * cos_sigma - sin_U1 * sin_sigma * cos_alpha1
+            );
+    C = f / 16 * sqr_cos_alpha * (4 + f * (4 - 3 * sqr_cos_alpha));
+    L = lambda -
+        (1 - C) * f * sin_alpha * (
+        sigma + C * sin_sigma *
+        (cos_2_sigmam + C * cos_sigma * (-1 + 2 * sqr_cos_2_sigmam))
+        );
+    
+    /* Result */
+    end_pos->lon = start_pos->lon + L;
+    end_pos->lat = phi2;
+    if ( end_azimuth != 0 )
+    {
+        *end_azimuth = atan2(
+            sin_alpha, -sin_U1 * sin_sigma + cos_U1 * cos_sigma * cos_alpha1
+            );
+    }
+    return ! (NMEA_POSIX(isnan)(end_pos->lat) || NMEA_POSIX(isnan)(end_pos->lon));
+}
+
+/**
+ * \brief Convert position from INFO to radians position
+ */
+void nmea_info2pos(const nmeaINFO *info, nmeaPOS *pos)
+{
+    pos->lat = nmea_ndeg2radian(info->lat);
+    pos->lon = nmea_ndeg2radian(info->lon);
+}
+
+/**
+ * \brief Convert radians position to INFOs position
+ */
+void nmea_pos2info(const nmeaPOS *pos, nmeaINFO *info)
+{
+    info->lat = nmea_radian2ndeg(pos->lat);
+    info->lon = nmea_radian2ndeg(pos->lon);
+}
diff --git a/lib/pud/nmealib/src/info.c b/lib/pud/nmealib/src/info.c
new file mode 100644 (file)
index 0000000..7cd20d4
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <nmea/info.h>
+
+#include <nmea/sentence.h>
+#include <nmea/gmath.h>
+#include <nmea/time.h>
+
+#include <string.h>
+#include <math.h>
+
+void nmea_zero_INFO(nmeaINFO *info)
+{
+       if (!info) {
+               return;
+       }
+
+    memset(info, 0, sizeof(nmeaINFO));
+    nmea_time_now(&info->utc);
+    info->sig = NMEA_SIG_BAD;
+    info->fix = NMEA_FIX_BAD;
+}
+
+/**
+ * Determine whether a given nmeaINFO structure has a certain field.
+ *
+ * nmeaINFO dependencies:
+ <pre>
+ field/sentence GPGGA   GPGSA   GPGSV   GPRMC   GPVTG
+ smask:         x       x       x       x       x
+ utc:           x                       x
+ sig:           x                       x
+ fix:                   x               x
+ PDOP:                  x
+ HDOP:          x       x
+ VDOP:                  x
+ lat:           x                       x
+ lon:           x                       x
+ elv:           x
+ speed:                                 x       x
+ direction:                             x       x
+ declination:                                   x
+ satinfo:               x       x
+ </pre>
+ *
+ * @param smask
+ * the smask of a nmeaINFO structure
+ * @param fieldName
+ * the field name
+ *
+ * @return
+ * - true when the nmeaINFO structure has the field
+ * - false otherwise
+ */
+bool nmea_INFO_has_field(int smask, nmeaINFO_FIELD fieldName) {
+       switch (fieldName) {
+               case SMASK:
+                       return true;
+
+               case UTC:
+               case SIG:
+               case LAT:
+               case LON:
+                       return ((smask & (GPGGA | GPRMC)) != 0);
+
+               case FIX:
+                       return ((smask & (GPGSA | GPRMC)) != 0);
+
+               case PDOP:
+               case VDOP:
+                       return ((smask & GPGSA) != 0);
+
+               case HDOP:
+                       return ((smask & (GPGGA | GPGSA)) != 0);
+
+               case ELV:
+                       return ((smask & GPGGA) != 0);
+
+               case SPEED:
+               case DIRECTION:
+                       return ((smask & (GPRMC | GPVTG)) != 0);
+
+               case DECLINATION:
+                       return ((smask & GPVTG) != 0);
+
+               case SATINFO:
+                       return ((smask & (GPGSA | GPGSV)) != 0);
+
+               default:
+                       return false;
+       }
+}
+
+/**
+ * Sanitise the NMEA info, make sure that:
+ * - latitude is in the range [-9000, 9000],
+ * - longitude is in the range [-18000, 18000],
+ * - DOPs are positive,
+ * - speed is positive,
+ * - direction is in the range [0, 360>.
+ *
+ * Time is set to the current time when not present.
+ *
+ * When a field is not present then it is reset to its default (NMEA_SIG_BAD,
+ * NMEA_FIX_BAD, 0).
+ *
+ * Satinfo is not touched.
+ *
+ * @param nmeaInfo
+ * the NMEA info structure to sanitise
+ */
+void nmea_INFO_sanitise(nmeaINFO *nmeaInfo) {
+       double lat = 0;
+       double lon = 0;
+       double speed = 0;
+       double direction = 0;
+       bool latAdjusted = false;
+       bool lonAdjusted = false;
+       bool speedAdjusted = false;
+       bool directionAdjusted = false;
+
+       if (!nmeaInfo) {
+               return;
+       }
+
+       if (!nmea_INFO_has_field(nmeaInfo->smask, UTC)) {
+               nmea_time_now(&nmeaInfo->utc);
+       }
+
+       if (!nmea_INFO_has_field(nmeaInfo->smask, SIG)) {
+               nmeaInfo->sig = NMEA_SIG_BAD;
+       }
+
+       if (!nmea_INFO_has_field(nmeaInfo->smask, FIX)) {
+               nmeaInfo->fix = NMEA_FIX_BAD;
+       }
+
+       if (!nmea_INFO_has_field(nmeaInfo->smask, PDOP)) {
+               nmeaInfo->PDOP = 0;
+       } else {
+               nmeaInfo->PDOP = fabs(nmeaInfo->PDOP);
+       }
+
+       if (!nmea_INFO_has_field(nmeaInfo->smask, HDOP)) {
+               nmeaInfo->HDOP = 0;
+       } else {
+               nmeaInfo->HDOP = fabs(nmeaInfo->HDOP);
+       }
+
+       if (!nmea_INFO_has_field(nmeaInfo->smask, VDOP)) {
+               nmeaInfo->VDOP = 0;
+       } else {
+               nmeaInfo->VDOP = fabs(nmeaInfo->VDOP);
+       }
+
+       if (!nmea_INFO_has_field(nmeaInfo->smask, LAT)) {
+               nmeaInfo->lat = 0;
+       }
+
+       if (!nmea_INFO_has_field(nmeaInfo->smask, LON)) {
+               nmeaInfo->lon = 0;
+       }
+
+       if (!nmea_INFO_has_field(nmeaInfo->smask, ELV)) {
+               nmeaInfo->elv = 0;
+       }
+
+       if (!nmea_INFO_has_field(nmeaInfo->smask, SPEED)) {
+               nmeaInfo->speed = 0;
+       }
+
+       if (!nmea_INFO_has_field(nmeaInfo->smask, DIRECTION)) {
+               nmeaInfo->direction = 0;
+       }
+
+       if (!nmea_INFO_has_field(nmeaInfo->smask, DECLINATION)) {
+               nmeaInfo->declination = 0;
+       }
+
+       /* satinfo is not used */
+
+       /*
+        * lat
+        */
+
+       lat = nmeaInfo->lat;
+       lon = nmeaInfo->lon;
+
+       /* force lat in [-18000, 18000] */
+       while (lat < -18000.0) {
+               lat += 36000.0;
+               latAdjusted = true;
+       }
+       while (lat > 18000.0) {
+               lat -= 36000.0;
+               latAdjusted = true;
+       }
+
+       /* lat is now in [-18000, 18000] */
+
+       /* force lat from <9000, 18000] in [9000, 0] */
+       if (lat > 9000.0) {
+               lat = 18000.0 - lat;
+               lon += 18000.0;
+               latAdjusted = true;
+               lonAdjusted = true;
+       }
+
+       /* force lat from [-18000, -9000> in [0, -9000] */
+       if (lat < -9000.0) {
+               lat = -18000.0 - lat;
+               lon += 18000.0;
+               latAdjusted = true;
+               lonAdjusted = true;
+       }
+
+       /* lat is now in [-9000, 9000] */
+
+       if (latAdjusted) {
+               nmeaInfo->lat = lat;
+       }
+
+       /*
+        * lon
+        */
+
+       /* force lon in [-18000, 18000] */
+       while (lon < -18000.0) {
+               lon += 36000.0;
+               lonAdjusted = true;
+       }
+       while (lon > 18000.0) {
+               lon -= 36000.0;
+               lonAdjusted = true;
+       }
+
+       /* lon is now in [-18000, 18000] */
+
+       if (lonAdjusted) {
+               nmeaInfo->lon = lon;
+       }
+
+       /*
+        * speed
+        */
+
+       speed = nmeaInfo->speed;
+       direction = nmeaInfo->direction;
+
+       if (speed < 0.0) {
+               speed = -speed;
+               direction += 180.0;
+               speedAdjusted = true;
+               directionAdjusted = true;
+       }
+
+       /* speed is now in [0, max> */
+
+       if (speedAdjusted) {
+               nmeaInfo->speed = speed;
+       }
+
+       /*
+        * direction
+        */
+
+       /* force direction in [0, 360> */
+       while (direction < 0.0) {
+               direction += 360.0;
+               directionAdjusted = true;
+       }
+       while (direction >= 360.0) {
+               direction -= 360.0;
+               directionAdjusted = true;
+       }
+
+       /* direction is now in [0, 360> */
+
+       if (directionAdjusted) {
+               nmeaInfo->direction = direction;
+       }
+}
+
+/**
+ * Converts the position fields to degrees and DOP fields to meters so that
+ * all fields use normal metric units.
+ *
+ * @param nmeaInfo
+ * the nmeaINFO
+ */
+void nmea_INFO_unit_conversion(nmeaINFO * nmeaInfo) {
+       if (!nmeaInfo) {
+               return;
+       }
+
+       /* smask (already in correct format) */
+
+       /* utc (already in correct format) */
+
+       /* sig (already in correct format) */
+       /* fix (already in correct format) */
+
+       if (nmea_INFO_has_field(nmeaInfo->smask, PDOP)) {
+               nmeaInfo->PDOP = nmea_dop2meters(nmeaInfo->PDOP);
+       }
+
+       if (nmea_INFO_has_field(nmeaInfo->smask, HDOP)) {
+               nmeaInfo->HDOP = nmea_dop2meters(nmeaInfo->HDOP);
+       }
+
+       if (nmea_INFO_has_field(nmeaInfo->smask, VDOP)) {
+               nmeaInfo->VDOP = nmea_dop2meters(nmeaInfo->VDOP);
+       }
+
+       if (nmea_INFO_has_field(nmeaInfo->smask, LAT)) {
+               nmeaInfo->lat = nmea_ndeg2degree(nmeaInfo->lat);
+       }
+
+       if (nmea_INFO_has_field(nmeaInfo->smask, LON)) {
+               nmeaInfo->lon = nmea_ndeg2degree(nmeaInfo->lon);
+       }
+
+       /* elv (already in correct format) */
+       /* speed (already in correct format) */
+       /* direction (already in correct format) */
+       /* declination (already in correct format) */
+
+       /* satinfo (not used) */
+}
diff --git a/lib/pud/nmealib/src/parse.c b/lib/pud/nmealib/src/parse.c
new file mode 100644 (file)
index 0000000..1d54840
--- /dev/null
@@ -0,0 +1,513 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file parse.h
+ * \brief Functions of a low level for analysis of
+ * packages of NMEA stream.
+ *
+ * \code
+ * ...
+ * ptype = nmea_pack_type(
+ *     (const char *)parser->buffer + nparsed + 1,
+ *     parser->buff_use - nparsed - 1);
+ * 
+ * if(0 == (node = malloc(sizeof(nmeaParserNODE))))
+ *     goto mem_fail;
+ * 
+ * node->pack = 0;
+ * 
+ * switch(ptype)
+ * {
+ * case GPGGA:
+ *     if(0 == (node->pack = malloc(sizeof(nmeaGPGGA))))
+ *         goto mem_fail;
+ *     node->packType = GPGGA;
+ *     if(!nmea_parse_GPGGA(
+ *         (const char *)parser->buffer + nparsed,
+ *         sen_sz, (nmeaGPGGA *)node->pack))
+ *     {
+ *         free(node);
+ *         node = 0;
+ *     }
+ *     break;
+ * case GPGSA:
+ *     if(0 == (node->pack = malloc(sizeof(nmeaGPGSA))))
+ *         goto mem_fail;
+ *     node->packType = GPGSA;
+ *     if(!nmea_parse_GPGSA(
+ *         (const char *)parser->buffer + nparsed,
+ *         sen_sz, (nmeaGPGSA *)node->pack))
+ *     {
+ *         free(node);
+ *         node = 0;
+ *     }
+ *     break;
+ * ...
+ * \endcode
+ */
+
+#include <nmea/parse.h>
+
+#include <string.h>
+
+#include <nmea/config.h>
+#include <nmea/context.h>
+#include <nmea/tok.h>
+#include <nmea/units.h>
+
+#define NMEA_TIMEPARSE_BUF  (256)
+
+int _nmea_parse_time(const char *buff, int buff_sz, nmeaTIME *res)
+{
+    int success = 0;
+
+    switch(buff_sz)
+    {
+    case sizeof("hhmmss") - 1:
+        success = (3 == nmea_scanf(buff, buff_sz,
+            "%2d%2d%2d", &(res->hour), &(res->min), &(res->sec)
+            ));
+        break;
+    case sizeof("hhmmss.s") - 1:
+    case sizeof("hhmmss.ss") - 1:
+    case sizeof("hhmmss.sss") - 1:
+        success = (4 == nmea_scanf(buff, buff_sz,
+            "%2d%2d%2d.%d", &(res->hour), &(res->min), &(res->sec), &(res->hsec)
+            ));
+        break;
+    default:
+        nmea_error("Parse of time error (format error)!");
+        success = 0;
+        break;
+    }
+
+    return (success?0:-1);        
+}
+
+/**
+ * \brief Define packet type by header (nmeaPACKTYPE).
+ * @param buff a constant character pointer of packet buffer.
+ * @param buff_sz buffer size.
+ * @return The defined packet type
+ * @see nmeaPACKTYPE
+ */
+int nmea_pack_type(const char *buff, int buff_sz)
+{
+    static const char *pheads[] = {
+        "GPGGA",
+        "GPGSA",
+        "GPGSV",
+        "GPRMC",
+        "GPVTG",
+    };
+
+    NMEA_ASSERT(buff);
+
+    if(buff_sz < 5)
+        return GPNON;
+    else if(0 == memcmp(buff, pheads[0], 5))
+        return GPGGA;
+    else if(0 == memcmp(buff, pheads[1], 5))
+        return GPGSA;
+    else if(0 == memcmp(buff, pheads[2], 5))
+        return GPGSV;
+    else if(0 == memcmp(buff, pheads[3], 5))
+        return GPRMC;
+    else if(0 == memcmp(buff, pheads[4], 5))
+        return GPVTG;
+
+    return GPNON;
+}
+
+/**
+ * \brief Find tail of packet ("\r\n") in buffer and check control sum (CRC).
+ * @param buff a constant character pointer of packets buffer.
+ * @param buff_sz buffer size.
+ * @param res_crc a integer pointer for return CRC of packet (must be defined).
+ * @return Number of bytes to packet tail.
+ */
+int nmea_find_tail(const char *buff, int buff_sz, int *res_crc)
+{
+    static const int tail_sz = 3 /* *[CRC] */ + 2 /* \r\n */;
+
+    const char *end_buff = buff + buff_sz;
+    int nread = 0;
+    int crc = 0;
+
+    NMEA_ASSERT(buff && res_crc);
+
+    *res_crc = -1;
+
+    for(;buff < end_buff; ++buff, ++nread)
+    {
+        if(('$' == *buff) && nread)
+        {
+            buff = 0;
+            break;
+        }
+        else if('*' == *buff)
+        {
+            if(buff + tail_sz <= end_buff && '\r' == buff[3] && '\n' == buff[4])
+            {
+                *res_crc = nmea_atoi(buff + 1, 2, 16);
+                nread = buff_sz - (int)(end_buff - (buff + tail_sz));
+                if(*res_crc != crc)
+                {
+                    *res_crc = -1;
+                    buff = 0;
+                }
+            }
+
+            break;
+        }
+        else if(nread)
+            crc ^= (int)*buff;
+    }
+
+    if(*res_crc < 0 && buff)
+        nread = 0;
+
+    return nread;
+}
+
+/**
+ * \brief Parse GGA packet from buffer.
+ * @param buff a constant character pointer of packet buffer.
+ * @param buff_sz buffer size.
+ * @param pack a pointer of packet which will filled by function.
+ * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
+ */
+int nmea_parse_GPGGA(const char *buff, int buff_sz, nmeaGPGGA *pack)
+{
+    char time_buff[NMEA_TIMEPARSE_BUF];
+
+    NMEA_ASSERT(buff && pack);
+
+    memset(pack, 0, sizeof(nmeaGPGGA));
+
+    nmea_trace_buff(buff, buff_sz);
+
+    if(14 != nmea_scanf(buff, buff_sz,
+        "$GPGGA,%s,%f,%C,%f,%C,%d,%d,%f,%f,%C,%f,%C,%f,%d*",
+        &(time_buff[0]),
+        &(pack->lat), &(pack->ns), &(pack->lon), &(pack->ew),
+        &(pack->sig), &(pack->satinuse), &(pack->HDOP), &(pack->elv), &(pack->elv_units),
+        &(pack->diff), &(pack->diff_units), &(pack->dgps_age), &(pack->dgps_sid)))
+    {
+        nmea_error("GPGGA parse error!");
+        return 0;
+    }
+
+    if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc)))
+    {
+        nmea_error("GPGGA time parse error!");
+        return 0;
+    }
+
+    return 1;
+}
+
+/**
+ * \brief Parse GSA packet from buffer.
+ * @param buff a constant character pointer of packet buffer.
+ * @param buff_sz buffer size.
+ * @param pack a pointer of packet which will filled by function.
+ * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
+ */
+int nmea_parse_GPGSA(const char *buff, int buff_sz, nmeaGPGSA *pack)
+{
+    NMEA_ASSERT(buff && pack);
+
+    memset(pack, 0, sizeof(nmeaGPGSA));
+
+    nmea_trace_buff(buff, buff_sz);
+
+    if(17 != nmea_scanf(buff, buff_sz,
+        "$GPGSA,%C,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%f,%f,%f*",
+        &(pack->fix_mode), &(pack->fix_type),
+        &(pack->sat_prn[0]), &(pack->sat_prn[1]), &(pack->sat_prn[2]), &(pack->sat_prn[3]), &(pack->sat_prn[4]), &(pack->sat_prn[5]),
+        &(pack->sat_prn[6]), &(pack->sat_prn[7]), &(pack->sat_prn[8]), &(pack->sat_prn[9]), &(pack->sat_prn[10]), &(pack->sat_prn[11]),
+        &(pack->PDOP), &(pack->HDOP), &(pack->VDOP)))
+    {
+        nmea_error("GPGSA parse error!");
+        return 0;
+    }
+
+    return 1;
+}
+
+/**
+ * \brief Parse GSV packet from buffer.
+ * @param buff a constant character pointer of packet buffer.
+ * @param buff_sz buffer size.
+ * @param pack a pointer of packet which will filled by function.
+ * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
+ */
+int nmea_parse_GPGSV(const char *buff, int buff_sz, nmeaGPGSV *pack)
+{
+    int nsen, nsat;
+
+    NMEA_ASSERT(buff && pack);
+
+    memset(pack, 0, sizeof(nmeaGPGSV));
+
+    nmea_trace_buff(buff, buff_sz);
+
+    nsen = nmea_scanf(buff, buff_sz,
+        "$GPGSV,%d,%d,%d,"
+        "%d,%d,%d,%d,"
+        "%d,%d,%d,%d,"
+        "%d,%d,%d,%d,"
+        "%d,%d,%d,%d*",
+        &(pack->pack_count), &(pack->pack_index), &(pack->sat_count),
+        &(pack->sat_data[0].id), &(pack->sat_data[0].elv), &(pack->sat_data[0].azimuth), &(pack->sat_data[0].sig),
+        &(pack->sat_data[1].id), &(pack->sat_data[1].elv), &(pack->sat_data[1].azimuth), &(pack->sat_data[1].sig),
+        &(pack->sat_data[2].id), &(pack->sat_data[2].elv), &(pack->sat_data[2].azimuth), &(pack->sat_data[2].sig),
+        &(pack->sat_data[3].id), &(pack->sat_data[3].elv), &(pack->sat_data[3].azimuth), &(pack->sat_data[3].sig));
+
+    nsat = (pack->pack_index - 1) * NMEA_SATINPACK;
+    nsat = (nsat + NMEA_SATINPACK > pack->sat_count)?pack->sat_count - nsat:NMEA_SATINPACK;
+    nsat = nsat * 4 + 3 /* first three sentence`s */;
+
+    if(nsen < nsat || nsen > (NMEA_SATINPACK * 4 + 3))
+    {
+        nmea_error("GPGSV parse error!");
+        return 0;
+    }
+
+    return 1;
+}
+
+/**
+ * \brief Parse RMC packet from buffer.
+ * @param buff a constant character pointer of packet buffer.
+ * @param buff_sz buffer size.
+ * @param pack a pointer of packet which will filled by function.
+ * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
+ */
+int nmea_parse_GPRMC(const char *buff, int buff_sz, nmeaGPRMC *pack)
+{
+    int nsen;
+    char time_buff[NMEA_TIMEPARSE_BUF];
+
+    NMEA_ASSERT(buff && pack);
+
+    memset(pack, 0, sizeof(nmeaGPRMC));
+
+    nmea_trace_buff(buff, buff_sz);
+
+    nsen = nmea_scanf(buff, buff_sz,
+        "$GPRMC,%s,%C,%f,%C,%f,%C,%f,%f,%2d%2d%2d,%f,%C,%C*",
+        &(time_buff[0]),
+        &(pack->status), &(pack->lat), &(pack->ns), &(pack->lon), &(pack->ew),
+        &(pack->speed), &(pack->direction),
+        &(pack->utc.day), &(pack->utc.mon), &(pack->utc.year),
+        &(pack->declination), &(pack->declin_ew), &(pack->mode));
+
+    if(nsen != 13 && nsen != 14)
+    {
+        nmea_error("GPRMC parse error!");
+        return 0;
+    }
+
+    if(0 != _nmea_parse_time(&time_buff[0], (int)strlen(&time_buff[0]), &(pack->utc)))
+    {
+        nmea_error("GPRMC time parse error!");
+        return 0;
+    }
+
+    if(pack->utc.year < 90)
+        pack->utc.year += 100;
+    pack->utc.mon -= 1;
+
+    return 1;
+}
+
+/**
+ * \brief Parse VTG packet from buffer.
+ * @param buff a constant character pointer of packet buffer.
+ * @param buff_sz buffer size.
+ * @param pack a pointer of packet which will filled by function.
+ * @return 1 (true) - if parsed successfully or 0 (false) - if fail.
+ */
+int nmea_parse_GPVTG(const char *buff, int buff_sz, nmeaGPVTG *pack)
+{
+    NMEA_ASSERT(buff && pack);
+
+    memset(pack, 0, sizeof(nmeaGPVTG));
+
+    nmea_trace_buff(buff, buff_sz);
+
+    if(8 != nmea_scanf(buff, buff_sz,
+        "$GPVTG,%f,%C,%f,%C,%f,%C,%f,%C*",
+        &(pack->dir), &(pack->dir_t),
+        &(pack->dec), &(pack->dec_m),
+        &(pack->spn), &(pack->spn_n),
+        &(pack->spk), &(pack->spk_k)))
+    {
+        nmea_error("GPVTG parse error!");
+        return 0;
+    }
+
+    if( pack->dir_t != 'T' ||
+        pack->dec_m != 'M' ||
+        pack->spn_n != 'N' ||
+        pack->spk_k != 'K')
+    {
+        nmea_error("GPVTG parse error (format error)!");
+        return 0;
+    }
+
+    return 1;
+}
+
+/**
+ * \brief Fill nmeaINFO structure by GGA packet data.
+ * @param pack a pointer of packet structure.
+ * @param info a pointer of summary information structure.
+ */
+void nmea_GPGGA2info(nmeaGPGGA *pack, nmeaINFO *info)
+{
+    NMEA_ASSERT(pack && info);
+
+    info->utc.hour = pack->utc.hour;
+    info->utc.min = pack->utc.min;
+    info->utc.sec = pack->utc.sec;
+    info->utc.hsec = pack->utc.hsec;
+    info->sig = pack->sig;
+    info->HDOP = pack->HDOP;
+    info->elv = pack->elv;
+    info->lat = ((pack->ns == 'N')?pack->lat:-(pack->lat));
+    info->lon = ((pack->ew == 'E')?pack->lon:-(pack->lon));
+    info->smask |= GPGGA;
+}
+
+/**
+ * \brief Fill nmeaINFO structure by GSA packet data.
+ * @param pack a pointer of packet structure.
+ * @param info a pointer of summary information structure.
+ */
+void nmea_GPGSA2info(nmeaGPGSA *pack, nmeaINFO *info)
+{
+    int i, j, nuse = 0;
+
+    NMEA_ASSERT(pack && info);
+
+    info->fix = pack->fix_type;
+    info->PDOP = pack->PDOP;
+    info->HDOP = pack->HDOP;
+    info->VDOP = pack->VDOP;
+
+    for(i = 0; i < NMEA_MAXSAT; ++i)
+    {
+        for(j = 0; j < info->satinfo.inview; ++j)
+        {
+            if(pack->sat_prn[i] && pack->sat_prn[i] == info->satinfo.sat[j].id)
+            {
+                info->satinfo.sat[j].in_use = 1;
+                nuse++;
+            }
+        }
+    }
+
+    info->satinfo.inuse = nuse;
+    info->smask |= GPGSA;
+}
+
+/**
+ * \brief Fill nmeaINFO structure by GSV packet data.
+ * @param pack a pointer of packet structure.
+ * @param info a pointer of summary information structure.
+ */
+void nmea_GPGSV2info(nmeaGPGSV *pack, nmeaINFO *info)
+{
+    int isat, isi, nsat;
+
+    NMEA_ASSERT(pack && info);
+
+    if(pack->pack_index > pack->pack_count ||
+        pack->pack_index * NMEA_SATINPACK > NMEA_MAXSAT)
+        return;
+
+    if(pack->pack_index < 1)
+        pack->pack_index = 1;
+
+    info->satinfo.inview = pack->sat_count;
+
+    nsat = (pack->pack_index - 1) * NMEA_SATINPACK;
+    nsat = (nsat + NMEA_SATINPACK > pack->sat_count)?pack->sat_count - nsat:NMEA_SATINPACK;
+
+    for(isat = 0; isat < nsat; ++isat)
+    {
+        isi = (pack->pack_index - 1) * NMEA_SATINPACK + isat;
+        info->satinfo.sat[isi].id = pack->sat_data[isat].id;
+        info->satinfo.sat[isi].elv = pack->sat_data[isat].elv;
+        info->satinfo.sat[isi].azimuth = pack->sat_data[isat].azimuth;
+        info->satinfo.sat[isi].sig = pack->sat_data[isat].sig;
+    }
+
+    info->smask |= GPGSV;
+}
+
+/**
+ * \brief Fill nmeaINFO structure by RMC packet data.
+ * @param pack a pointer of packet structure.
+ * @param info a pointer of summary information structure.
+ */
+void nmea_GPRMC2info(nmeaGPRMC *pack, nmeaINFO *info)
+{
+    NMEA_ASSERT(pack && info);
+
+    if('A' == pack->status)
+    {
+        if(NMEA_SIG_BAD == info->sig)
+            info->sig = NMEA_SIG_MID;
+        if(NMEA_FIX_BAD == info->fix)
+            info->fix = NMEA_FIX_2D;
+    }
+    else if('V' == pack->status)
+    {
+        info->sig = NMEA_SIG_BAD;
+        info->fix = NMEA_FIX_BAD;
+    }
+
+    info->utc = pack->utc;
+    info->lat = ((pack->ns == 'N')?pack->lat:-(pack->lat));
+    info->lon = ((pack->ew == 'E')?pack->lon:-(pack->lon));
+    info->speed = pack->speed * NMEA_TUD_KNOTS;
+    info->direction = pack->direction;
+    info->smask |= GPRMC;
+}
+
+/**
+ * \brief Fill nmeaINFO structure by VTG packet data.
+ * @param pack a pointer of packet structure.
+ * @param info a pointer of summary information structure.
+ */
+void nmea_GPVTG2info(nmeaGPVTG *pack, nmeaINFO *info)
+{
+    NMEA_ASSERT(pack && info);
+
+    info->direction = pack->dir;
+    info->declination = pack->dec;
+    info->speed = pack->spk;
+    info->smask |= GPVTG;
+}
diff --git a/lib/pud/nmealib/src/parser.c b/lib/pud/nmealib/src/parser.c
new file mode 100644 (file)
index 0000000..4884321
--- /dev/null
@@ -0,0 +1,419 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file parser.h
+ */
+
+#include <nmea/parser.h>
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+
+#include <nmea/config.h>
+#include <nmea/context.h>
+#include <nmea/parse.h>
+#include <nmea/sentence.h>
+
+typedef struct _nmeaParserNODE
+{
+    int packType;
+    void *pack;
+    struct _nmeaParserNODE *next_node;
+
+} nmeaParserNODE;
+
+/*
+ * high level
+ */
+
+/**
+ * \brief Initialization of parser object
+ * @return true (1) - success or false (0) - fail
+ */
+int nmea_parser_init(nmeaPARSER *parser)
+{
+    int resv = 0;
+    int buff_size = nmea_property()->parse_buff_size;
+
+    NMEA_ASSERT(parser);
+
+    if(buff_size < NMEA_MIN_PARSEBUFF)
+        buff_size = NMEA_MIN_PARSEBUFF;
+
+    memset(parser, 0, sizeof(nmeaPARSER));
+
+    if(0 == (parser->buffer = malloc(buff_size)))
+        nmea_error("Insufficient memory!");
+    else
+    {
+        parser->buff_size = buff_size;
+        resv = 1;
+    }    
+
+    return resv;
+}
+
+/**
+ * \brief Destroy parser object
+ */
+void nmea_parser_destroy(nmeaPARSER *parser)
+{
+    NMEA_ASSERT(parser);
+    if (parser->buffer) {
+       free(parser->buffer);
+       parser->buffer = NULL;
+    }
+    nmea_parser_queue_clear(parser);
+    memset(parser, 0, sizeof(nmeaPARSER));
+}
+
+/**
+ * \brief Analysis of buffer and put results to information structure
+ * @return Number of packets wos parsed
+ */
+int nmea_parse(    
+    nmeaPARSER *parser,
+    const char *buff, int buff_sz,
+    nmeaINFO *info
+    )
+{
+    int ptype, nread = 0;
+    void *pack = 0;
+
+    NMEA_ASSERT(parser && parser->buffer);
+
+    nmea_parser_push(parser, buff, buff_sz);
+
+    while(GPNON != (ptype = nmea_parser_pop(parser, &pack)))
+    {
+        nread++;
+
+        switch(ptype)
+        {
+        case GPGGA:
+            nmea_GPGGA2info((nmeaGPGGA *)pack, info);
+            break;
+        case GPGSA:
+            nmea_GPGSA2info((nmeaGPGSA *)pack, info);
+            break;
+        case GPGSV:
+            nmea_GPGSV2info((nmeaGPGSV *)pack, info);
+            break;
+        case GPRMC:
+            nmea_GPRMC2info((nmeaGPRMC *)pack, info);
+            break;
+        case GPVTG:
+            nmea_GPVTG2info((nmeaGPVTG *)pack, info);
+            break;
+        default:
+            break;
+        };
+
+        free(pack);
+    }
+
+    return nread;
+}
+
+/*
+ * low level
+ */
+
+int nmea_parser_real_push(nmeaPARSER *parser, const char *buff, int buff_sz)
+{
+    int nparsed = 0, crc, sen_sz, ptype;
+    nmeaParserNODE *node = 0;
+
+    NMEA_ASSERT(parser && parser->buffer);
+
+    /* clear unuse buffer (for debug) */
+    /*
+    memset(
+        parser->buffer + parser->buff_use, 0,
+        parser->buff_size - parser->buff_use
+        );
+        */
+
+    /* add */
+    if(parser->buff_use + buff_sz >= parser->buff_size)
+        nmea_parser_buff_clear(parser);
+
+    memcpy(parser->buffer + parser->buff_use, buff, buff_sz);
+    parser->buff_use += buff_sz;
+
+    /* parse */
+    for(;;node = 0)
+    {
+        sen_sz = nmea_find_tail(
+            (const char *)parser->buffer + nparsed,
+            (int)parser->buff_use - nparsed, &crc);
+
+        if(!sen_sz)
+        {
+            if(nparsed)
+                memcpy(
+                parser->buffer,
+                parser->buffer + nparsed,
+                parser->buff_use -= nparsed);
+            break;
+        }
+        else if(crc >= 0)
+        {
+            ptype = nmea_pack_type(
+                (const char *)parser->buffer + nparsed + 1,
+                parser->buff_use - nparsed - 1);
+
+            if(0 == (node = malloc(sizeof(nmeaParserNODE))))
+                goto mem_fail;
+
+            node->pack = 0;
+
+            switch(ptype)
+            {
+            case GPGGA:
+                if(0 == (node->pack = malloc(sizeof(nmeaGPGGA))))
+                    goto mem_fail;
+                node->packType = GPGGA;
+                if(!nmea_parse_GPGGA(
+                    (const char *)parser->buffer + nparsed,
+                    sen_sz, (nmeaGPGGA *)node->pack))
+                {
+                    free(node);
+                    node = 0;
+                }
+                break;
+            case GPGSA:
+                if(0 == (node->pack = malloc(sizeof(nmeaGPGSA))))
+                    goto mem_fail;
+                node->packType = GPGSA;
+                if(!nmea_parse_GPGSA(
+                    (const char *)parser->buffer + nparsed,
+                    sen_sz, (nmeaGPGSA *)node->pack))
+                {
+                    free(node);
+                    node = 0;
+                }
+                break;
+            case GPGSV:
+                if(0 == (node->pack = malloc(sizeof(nmeaGPGSV))))
+                    goto mem_fail;
+                node->packType = GPGSV;
+                if(!nmea_parse_GPGSV(
+                    (const char *)parser->buffer + nparsed,
+                    sen_sz, (nmeaGPGSV *)node->pack))
+                {
+                    free(node);
+                    node = 0;
+                }
+                break;
+            case GPRMC:
+                if(0 == (node->pack = malloc(sizeof(nmeaGPRMC))))
+                    goto mem_fail;
+                node->packType = GPRMC;
+                if(!nmea_parse_GPRMC(
+                    (const char *)parser->buffer + nparsed,
+                    sen_sz, (nmeaGPRMC *)node->pack))
+                {
+                    free(node);
+                    node = 0;
+                }
+                break;
+            case GPVTG:
+                if(0 == (node->pack = malloc(sizeof(nmeaGPVTG))))
+                    goto mem_fail;
+                node->packType = GPVTG;
+                if(!nmea_parse_GPVTG(
+                    (const char *)parser->buffer + nparsed,
+                    sen_sz, (nmeaGPVTG *)node->pack))
+                {
+                    free(node);
+                    node = 0;
+                }
+                break;
+            default:
+                free(node);
+                node = 0;
+                break;
+            };
+
+            if(node)
+            {
+                if(parser->end_node)
+                    ((nmeaParserNODE *)parser->end_node)->next_node = node;
+                parser->end_node = node;
+                if(!parser->top_node)
+                    parser->top_node = node;
+                node->next_node = 0;
+            }
+        }
+
+        nparsed += sen_sz;
+    }
+
+    return nparsed;
+
+mem_fail:
+    if(node)
+        free(node);
+
+    nmea_error("Insufficient memory!");
+
+    return -1;
+}
+
+/**
+ * \brief Analysis of buffer and keep results into parser
+ * @return Number of bytes wos parsed from buffer
+ */
+int nmea_parser_push(nmeaPARSER *parser, const char *buff, int buff_sz)
+{
+    int nparse, nparsed = 0;
+
+    do
+    {
+        if(buff_sz > parser->buff_size)
+            nparse = parser->buff_size;
+        else
+            nparse = buff_sz;
+
+        nparsed += nmea_parser_real_push(
+            parser, buff, nparse);
+
+        buff_sz -= nparse;
+
+    } while(buff_sz);
+
+    return nparsed;
+}
+
+/**
+ * \brief Get type of top packet keeped into parser
+ * @return Type of packet
+ * @see nmeaPACKTYPE
+ */
+int nmea_parser_top(nmeaPARSER *parser)
+{
+    int retval = GPNON;
+    nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
+
+    NMEA_ASSERT(parser && parser->buffer);
+
+    if(node)
+        retval = node->packType;
+
+    return retval;
+}
+
+/**
+ * \brief Withdraw top packet from parser
+ * @return Received packet type
+ * @see nmeaPACKTYPE
+ */
+int nmea_parser_pop(nmeaPARSER *parser, void **pack_ptr)
+{
+    int retval = GPNON;
+    nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
+
+    NMEA_ASSERT(parser && parser->buffer);
+
+    if(node)
+    {
+        *pack_ptr = node->pack;
+        retval = node->packType;
+        parser->top_node = node->next_node;
+        if(!parser->top_node)
+            parser->end_node = 0;
+        free(node);
+    }
+
+    return retval;
+}
+
+/**
+ * \brief Get top packet from parser without withdraw
+ * @return Received packet type
+ * @see nmeaPACKTYPE
+ */
+int nmea_parser_peek(nmeaPARSER *parser, void **pack_ptr)
+{
+    int retval = GPNON;
+    nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
+
+    NMEA_ASSERT(parser && parser->buffer);
+
+    if(node)
+    {
+        *pack_ptr = node->pack;
+        retval = node->packType;
+    }
+
+    return retval;
+}
+
+/**
+ * \brief Delete top packet from parser
+ * @return Deleted packet type
+ * @see nmeaPACKTYPE
+ */
+int nmea_parser_drop(nmeaPARSER *parser)
+{
+    int retval = GPNON;
+    nmeaParserNODE *node = (nmeaParserNODE *)parser->top_node;
+
+    NMEA_ASSERT(parser && parser->buffer);
+
+    if(node)
+    {
+        if(node->pack)
+            free(node->pack);
+        retval = node->packType;
+        parser->top_node = node->next_node;
+        if(!parser->top_node)
+            parser->end_node = 0;
+        free(node);
+    }
+
+    return retval;
+}
+
+/**
+ * \brief Clear cache of parser
+ * @return true (1) - success
+ */
+int nmea_parser_buff_clear(nmeaPARSER *parser)
+{
+    NMEA_ASSERT(parser && parser->buffer);
+    parser->buff_use = 0;
+    return 1;
+}
+
+/**
+ * \brief Clear packets queue into parser
+ * @return true (1) - success
+ */
+int nmea_parser_queue_clear(nmeaPARSER *parser)
+{
+    NMEA_ASSERT(parser);
+    while(parser->top_node)
+        nmea_parser_drop(parser);
+    return 1;
+}
diff --git a/lib/pud/nmealib/src/sentence.c b/lib/pud/nmealib/src/sentence.c
new file mode 100644 (file)
index 0000000..cf98c72
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <nmea/sentence.h>
+
+#include <string.h>
+
+void nmea_zero_GPGGA(nmeaGPGGA *pack)
+{
+    memset(pack, 0, sizeof(nmeaGPGGA));
+    nmea_time_now(&pack->utc);
+    pack->ns = 'N';
+    pack->ew = 'E';
+    pack->elv_units = 'M';
+    pack->diff_units = 'M';
+}
+
+void nmea_zero_GPGSA(nmeaGPGSA *pack)
+{
+    memset(pack, 0, sizeof(nmeaGPGSA));
+    pack->fix_mode = 'A';
+    pack->fix_type = NMEA_FIX_BAD;
+}
+
+void nmea_zero_GPGSV(nmeaGPGSV *pack)
+{
+    memset(pack, 0, sizeof(nmeaGPGSV));
+}
+
+void nmea_zero_GPRMC(nmeaGPRMC *pack)
+{
+    memset(pack, 0, sizeof(nmeaGPRMC));
+    nmea_time_now(&pack->utc);
+    pack->status = 'V';
+    pack->ns = 'N';
+    pack->ew = 'E';
+    pack->declin_ew = 'E';
+}
+
+void nmea_zero_GPVTG(nmeaGPVTG *pack)
+{
+    memset(pack, 0, sizeof(nmeaGPVTG));
+    pack->dir_t = 'T';
+    pack->dec_m = 'M';
+    pack->spn_n = 'N';
+    pack->spk_k = 'K';
+}
diff --git a/lib/pud/nmealib/src/time.c b/lib/pud/nmealib/src/time.c
new file mode 100644 (file)
index 0000000..18d6be8
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <nmea/time.h>
+
+#include <stddef.h>
+#include <time.h>
+#include <sys/time.h>
+
+void nmea_time_now(nmeaTIME *stm) {
+       struct timeval tp;
+       struct tm tt;
+
+       gettimeofday(&tp, NULL);
+       gmtime_r(&tp.tv_sec, &tt);
+
+       stm->year = tt.tm_year;
+       stm->mon = tt.tm_mon;
+       stm->day = tt.tm_mday;
+       stm->hour = tt.tm_hour;
+       stm->min = tt.tm_min;
+       stm->sec = tt.tm_sec;
+       stm->hsec = (tp.tv_usec / 10000);
+}
diff --git a/lib/pud/nmealib/src/tok.c b/lib/pud/nmealib/src/tok.c
new file mode 100644 (file)
index 0000000..c9126a0
--- /dev/null
@@ -0,0 +1,270 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2008 Timur Sinitsyn
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/*! \file tok.h */
+
+#include <nmea/tok.h>
+
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <nmea/config.h>
+
+#define NMEA_TOKS_COMPARE   (1)
+#define NMEA_TOKS_PERCENT   (2)
+#define NMEA_TOKS_WIDTH     (3)
+#define NMEA_TOKS_TYPE      (4)
+
+#define NMEA_CONVSTR_BUF    (256)
+
+/**
+ * \brief Calculate control sum of binary buffer
+ */
+int nmea_calc_crc(const char *buff, int buff_sz)
+{
+    int chsum = 0,
+        it;
+
+    for(it = 0; it < buff_sz; ++it)
+        chsum ^= (int)buff[it];
+
+    return chsum;
+}
+
+/**
+ * \brief Convert string to number
+ */
+int nmea_atoi(const char *str, int str_sz, int radix)
+{
+    char *tmp_ptr;
+    char buff[NMEA_CONVSTR_BUF];
+    int res = 0;
+
+    if(str_sz < NMEA_CONVSTR_BUF)
+    {
+        memcpy(&buff[0], str, str_sz);
+        buff[str_sz] = '\0';
+        res = strtol(&buff[0], &tmp_ptr, radix);
+    }
+
+    return res;
+}
+
+/**
+ * \brief Convert string to fraction number
+ */
+double nmea_atof(const char *str, int str_sz)
+{
+    char *tmp_ptr;
+    char buff[NMEA_CONVSTR_BUF];
+    double res = 0;
+
+    if(str_sz < NMEA_CONVSTR_BUF)
+    {
+        memcpy(&buff[0], str, str_sz);
+        buff[str_sz] = '\0';
+        res = strtod(&buff[0], &tmp_ptr);
+    }
+
+    return res;
+}
+
+/**
+ * \brief Formating string (like standart printf) with CRC tail (*CRC)
+ */
+int nmea_printf(char *buff, int buff_sz, const char *format, ...)
+{
+    int retval, add = 0;
+    va_list arg_ptr;
+
+    if(buff_sz <= 0)
+        return 0;
+
+    va_start(arg_ptr, format);
+
+    retval = NMEA_POSIX(vsnprintf)(buff, buff_sz, format, arg_ptr);
+
+    if(retval > 0)
+    {
+        add = NMEA_POSIX(snprintf)(
+            buff + retval, buff_sz - retval, "*%02x\r\n",
+            nmea_calc_crc(buff + 1, retval - 1));
+    }
+
+    retval += add;
+
+    if(retval < 0 || retval > buff_sz)
+    {
+        memset(buff, ' ', buff_sz);
+        retval = buff_sz;
+    }
+
+    va_end(arg_ptr);
+
+    return retval;
+}
+
+/**
+ * \brief Analyse string (specificate for NMEA sentences)
+ */
+int nmea_scanf(const char *buff, int buff_sz, const char *format, ...)
+{
+    const char *beg_tok;
+    const char *end_buf = buff + buff_sz;
+
+    va_list arg_ptr;
+    int tok_type = NMEA_TOKS_COMPARE;
+    int width = 0;
+    const char *beg_fmt = 0;
+    int snum = 0, unum = 0;
+
+    int tok_count = 0;
+    void *parg_target;
+
+    va_start(arg_ptr, format);
+    
+    for(; *format && buff < end_buf; ++format)
+    {
+        switch(tok_type)
+        {
+        case NMEA_TOKS_COMPARE:
+            if('%' == *format)
+                tok_type = NMEA_TOKS_PERCENT;
+            else if(*buff++ != *format)
+                goto fail;
+            break;
+        case NMEA_TOKS_PERCENT:
+            width = 0;
+            beg_fmt = format;
+            tok_type = NMEA_TOKS_WIDTH;
+            /* no break */
+        case NMEA_TOKS_WIDTH:
+            if(isdigit(*format))
+                break;
+            {
+                tok_type = NMEA_TOKS_TYPE;
+                if(format > beg_fmt)
+                    width = nmea_atoi(beg_fmt, (int)(format - beg_fmt), 10);
+            }
+            /* no break */
+        case NMEA_TOKS_TYPE:
+            beg_tok = buff;
+
+            if(!width && ('c' == *format || 'C' == *format) && *buff != format[1])
+                width = 1;
+
+            if(width)
+            {
+                if(buff + width <= end_buf)
+                    buff += width;
+                else
+                    goto fail;
+            }
+            else
+            {
+                if(!format[1] || (0 == (buff = (char *)memchr(buff, format[1], end_buf - buff))))
+                    buff = end_buf;
+            }
+
+            if(buff > end_buf)
+                goto fail;
+
+            tok_type = NMEA_TOKS_COMPARE;
+            tok_count++;
+
+            parg_target = 0; width = (int)(buff - beg_tok);
+
+            switch(*format)
+            {
+            case 'c':
+            case 'C':
+                parg_target = (void *)va_arg(arg_ptr, char *);
+                if(width && 0 != (parg_target))
+                    *((char *)parg_target) = *beg_tok;
+                break;
+            case 's':
+            case 'S':
+                parg_target = (void *)va_arg(arg_ptr, char *);
+                if(width && 0 != (parg_target))
+                {
+                    memcpy(parg_target, beg_tok, width);
+                    ((char *)parg_target)[width] = '\0';
+                }
+                break;
+            case 'f':
+            case 'g':
+            case 'G':
+            case 'e':
+            case 'E':
+                parg_target = (void *)va_arg(arg_ptr, double *);
+                if(width && 0 != (parg_target))
+                    *((double *)parg_target) = nmea_atof(beg_tok, width);
+                break;
+            default:
+                break;
+            };
+
+            if(parg_target)
+                break;
+            if(0 == (parg_target = (void *)va_arg(arg_ptr, int *)))
+                break;
+            if(!width)
+                break;
+
+            switch(*format)
+            {
+            case 'd':
+            case 'i':
+                snum = nmea_atoi(beg_tok, width, 10);
+                memcpy(parg_target, &snum, sizeof(int));
+                break;
+            case 'u':
+                unum = nmea_atoi(beg_tok, width, 10);
+                memcpy(parg_target, &unum, sizeof(unsigned int));
+                break;
+            case 'x':
+            case 'X':
+                unum = nmea_atoi(beg_tok, width, 16);
+                memcpy(parg_target, &unum, sizeof(unsigned int));
+                break;
+            case 'o':
+                unum = nmea_atoi(beg_tok, width, 8);
+                memcpy(parg_target, &unum, sizeof(unsigned int));
+                break;
+            default:
+                goto fail;
+            };
+
+            break;
+
+        default:
+            break;
+        };
+    }
+
+fail:
+
+    va_end(arg_ptr);
+
+    return tok_count;
+}
diff --git a/lib/pud/nmealib/src/util.c b/lib/pud/nmealib/src/util.c
new file mode 100644 (file)
index 0000000..45e57e0
--- /dev/null
@@ -0,0 +1,85 @@
+/*
+ * This file is part of nmealib.
+ *
+ * Copyright (c) 2011 Ferry Huberts
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <nmea/util.h>
+
+#include <string.h>
+#include <stdio.h>
+
+/**
+ * Determine whether the given string contains characters that are not allowed
+ * for fields in an NMEA string.
+ *
+ * @param str
+ * The string to check
+ * @param strName
+ * The name of the string to report when invalid characters are encountered
+ * @param report
+ * A pointer to a buffer in which to place the report string when an invalid
+ * nmea character is detected
+ * @param reportSize
+ * The size of the report buffer
+ *
+ * @return
+ * - true when the string has invalid characters
+ * - false otherwise
+ */
+bool nmea_string_has_invalid_chars(const char * str, const char * strName,
+               char * report, size_t reportSize) {
+       static const char invalidChars[] = { '$', '*', ',', '!', '\\', '^', '~' };
+       static const char * invalidCharsNames[] = { "sentence delimiter ($)",
+                       "checksum field delimiter (*)", "comma (,)", "exclamation mark (!)",
+                       "backslash (\\)", "^ (^)", "tilde (~)" };
+
+       size_t i;
+       size_t j;
+
+       if (!str) {
+               return false;
+       }
+
+       for (i = 0; i < strlen(str); i++) {
+               char c = str[i];
+
+               if ((c < 32) || (c > 126)) {
+                       if (report) {
+                               snprintf((char*) report, reportSize, "Configured %s (%s),"
+                                               " character %lu, can not contain non-printable"
+                                               " characters (codes outside the range [32, 126])",
+                                               strName, str, (unsigned long)i + 1);
+                               report[reportSize - 1] = '\0';
+                       }
+                       return true;
+               }
+
+               for (j = 0; j < sizeof(invalidChars); j++) {
+                       if (c == invalidChars[j]) {
+                               if (report) {
+                                       snprintf((char *) report, reportSize, "Configured %s (%s),"
+                                                       " character %lu, can not contain %s characters",
+                                                       strName, str, (unsigned long)i + 1, invalidCharsNames[j]);
+                                       report[reportSize - 1] = '\0';
+                               }
+                               return true;
+                       }
+               }
+       }
+
+       return false;
+}