[Olsr-dev] =? ?q?=5BPATCH=20v1=203/5=5D=20PUD=3A=20include=20nmealib=20v0=2E6=2E6-1-gbfff65b?=
Ferry Huberts
(spam-protected)
Thu May 10 16:09:59 CEST 2012
From: Ferry Huberts <(spam-protected)>
Signed-off-by: Ferry Huberts <(spam-protected)>
---
lib/pud/{wireformat => nmealib}/.gitignore | 0
lib/pud/nmealib/LICENSE.TXT | 502 +++++++++++++++++++
lib/pud/nmealib/Makefile | 81 +++
lib/pud/nmealib/Makefile.inc | 39 ++
lib/pud/nmealib/README.TXT | 33 ++
lib/pud/nmealib/doc/.gitignore | 5 +
lib/pud/nmealib/doc/Makefile | 18 +
.../{doc/doxygen.conf => nmealib/doc/nmea.doxygen} | 10 +-
lib/pud/nmealib/include/nmea/config.h | 34 ++
lib/pud/nmealib/include/nmea/context.h | 51 ++
lib/pud/nmealib/include/nmea/generate.h | 52 ++
lib/pud/nmealib/include/nmea/generator.h | 89 ++++
lib/pud/nmealib/include/nmea/gmath.h | 102 ++++
lib/pud/nmealib/include/nmea/info.h | 132 +++++
lib/pud/nmealib/include/nmea/nmea.h | 37 ++
lib/pud/nmealib/include/nmea/parse.h | 50 ++
lib/pud/nmealib/include/nmea/parser.h | 69 +++
lib/pud/nmealib/include/nmea/sentence.h | 139 ++++++
lib/pud/nmealib/include/nmea/time.h | 54 ++
lib/pud/nmealib/include/nmea/tok.h | 38 ++
lib/pud/nmealib/include/nmea/units.h | 38 ++
lib/pud/nmealib/include/nmea/util.h | 37 ++
lib/pud/nmealib/samples/Makefile | 44 ++
lib/pud/nmealib/samples/generate/main.c | 69 +++
lib/pud/nmealib/samples/generator/main.c | 55 +++
lib/pud/nmealib/samples/math/main.c | 97 ++++
lib/pud/nmealib/samples/parse/main.c | 58 +++
lib/pud/nmealib/samples/parse_file/gpslog.txt | 311 ++++++++++++
lib/pud/nmealib/samples/parse_file/main.c | 93 ++++
lib/pud/nmealib/src/context.c | 78 +++
lib/pud/nmealib/src/generate.c | 237 +++++++++
lib/pud/nmealib/src/generator.c | 412 ++++++++++++++++
lib/pud/nmealib/src/gmath.c | 379 +++++++++++++++
lib/pud/nmealib/src/info.c | 347 +++++++++++++
lib/pud/nmealib/src/parse.c | 513 ++++++++++++++++++++
lib/pud/nmealib/src/parser.c | 419 ++++++++++++++++
lib/pud/nmealib/src/sentence.c | 64 +++
lib/pud/nmealib/src/time.c | 41 ++
lib/pud/nmealib/src/tok.c | 270 ++++++++++
lib/pud/nmealib/src/util.c | 85 ++++
40 files changed, 5177 insertions(+), 5 deletions(-)
copy lib/pud/{wireformat => nmealib}/.gitignore (100%)
create mode 100644 lib/pud/nmealib/LICENSE.TXT
create mode 100644 lib/pud/nmealib/Makefile
create mode 100644 lib/pud/nmealib/Makefile.inc
create mode 100644 lib/pud/nmealib/README.TXT
create mode 100644 lib/pud/nmealib/doc/.gitignore
create mode 100644 lib/pud/nmealib/doc/Makefile
copy lib/pud/{doc/doxygen.conf => nmealib/doc/nmea.doxygen} (99%)
create mode 100644 lib/pud/nmealib/include/nmea/config.h
create mode 100644 lib/pud/nmealib/include/nmea/context.h
create mode 100644 lib/pud/nmealib/include/nmea/generate.h
create mode 100644 lib/pud/nmealib/include/nmea/generator.h
create mode 100644 lib/pud/nmealib/include/nmea/gmath.h
create mode 100644 lib/pud/nmealib/include/nmea/info.h
create mode 100644 lib/pud/nmealib/include/nmea/nmea.h
create mode 100644 lib/pud/nmealib/include/nmea/parse.h
create mode 100644 lib/pud/nmealib/include/nmea/parser.h
create mode 100644 lib/pud/nmealib/include/nmea/sentence.h
create mode 100644 lib/pud/nmealib/include/nmea/time.h
create mode 100644 lib/pud/nmealib/include/nmea/tok.h
create mode 100644 lib/pud/nmealib/include/nmea/units.h
create mode 100644 lib/pud/nmealib/include/nmea/util.h
create mode 100644 lib/pud/nmealib/samples/Makefile
create mode 100644 lib/pud/nmealib/samples/generate/main.c
create mode 100644 lib/pud/nmealib/samples/generator/main.c
create mode 100644 lib/pud/nmealib/samples/math/main.c
create mode 100644 lib/pud/nmealib/samples/parse/main.c
create mode 100644 lib/pud/nmealib/samples/parse_file/gpslog.txt
create mode 100644 lib/pud/nmealib/samples/parse_file/main.c
create mode 100644 lib/pud/nmealib/src/context.c
create mode 100644 lib/pud/nmealib/src/generate.c
create mode 100644 lib/pud/nmealib/src/generator.c
create mode 100644 lib/pud/nmealib/src/gmath.c
create mode 100644 lib/pud/nmealib/src/info.c
create mode 100644 lib/pud/nmealib/src/parse.c
create mode 100644 lib/pud/nmealib/src/parser.c
create mode 100644 lib/pud/nmealib/src/sentence.c
create mode 100644 lib/pud/nmealib/src/time.c
create mode 100644 lib/pud/nmealib/src/tok.c
create mode 100644 lib/pud/nmealib/src/util.c
diff --git a/lib/pud/wireformat/.gitignore b/lib/pud/nmealib/.gitignore
similarity index 100%
copy from lib/pud/wireformat/.gitignore
copy to lib/pud/nmealib/.gitignore
diff --git a/lib/pud/nmealib/LICENSE.TXT b/lib/pud/nmealib/LICENSE.TXT
new file mode 100644
index 0000000..4362b49
--- /dev/null
+++ b/lib/pud/nmealib/LICENSE.TXT
@@ -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.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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
+
+ 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
index 0000000..6ba877a
--- /dev/null
+++ b/lib/pud/nmealib/Makefile
@@ -0,0 +1,81 @@
+include Makefile.inc
+
+#
+# Settings
+#
+
+LIBNAME = libnmea.so
+
+DESTDIR ?=
+
+MACHINE=$(shell uname -m)
+ifeq ($(strip $(MACHINE)),x86_64)
+LIBDIR = usr/lib64
+else
+LIBDIR = usr/lib
+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)"
+ cp "lib/$(LIBNAME)" "$(DESTDIR)/$(LIBDIR)/$(LIBNAME).$(VERSION)"
+ $(STRIP) "$(DESTDIR)/$(LIBDIR)/$(LIBNAME).$(VERSION)"
+ ldconfig -n "$(DESTDIR)/$(LIBDIR)"
+
+install-headers: all
+ @mkdir -v -p "$(DESTDIR)/$(INCLUDEDIR)"
+ @rm -fr "$(DESTDIR)/$(INCLUDEDIR)/nmea"
+ cp -r include/nmea "$(DESTDIR)/$(INCLUDEDIR)"
+
+uninstall:
+ rm -f "$(DESTDIR)/$(LIBDIR)/$(LIBNAME)" "$(DESTDIR)/$(LIBDIR)/$(LIBNAME).$(VERSION)"
+ ldconfig -n "$(DESTDIR)/$(LIBDIR)"
+ @rmdir -v -p --ignore-fail-on-non-empty "$(DESTDIR)/$(LIBDIR)"
+
+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
index 0000000..98ee50d
--- /dev/null
+++ b/lib/pud/nmealib/Makefile.inc
@@ -0,0 +1,39 @@
+######################
+#
+# 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=$(shell git describe | \
+ sed -r -e 's/^([^[:digit:]]+)(.*)/\2/' \
+ -e 's/^([^-]+)(.*)/\1/' | \
+ grep -E '[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+')
+
+# 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
index 0000000..f24bc87
--- /dev/null
+++ b/lib/pud/nmealib/README.TXT
@@ -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
index 0000000..447bc4d
--- /dev/null
+++ b/lib/pud/nmealib/doc/.gitignore
@@ -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
index 0000000..81a5118
--- /dev/null
+++ b/lib/pud/nmealib/doc/Makefile
@@ -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/doc/doxygen.conf b/lib/pud/nmealib/doc/nmea.doxygen
similarity index 99%
copy from lib/pud/doc/doxygen.conf
copy to lib/pud/nmealib/doc/nmea.doxygen
index f3ecc07..5ae8c60 100644
--- a/lib/pud/doc/doxygen.conf
+++ b/lib/pud/nmealib/doc/nmea.doxygen
@@ -25,13 +25,13 @@ 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 = "__LIBNAME__"
+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 = "__PLUGIN_VER__"
+PROJECT_NUMBER =
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.
@@ -581,7 +581,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
-INPUT = ../src
+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
@@ -908,7 +908,7 @@ GENERATE_HTMLHELP = NO
# can add a path in front of the file if the result should not be
# written to the html output directory.
-CHM_FILE = __LIBNAME__.chm
+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
@@ -1122,7 +1122,7 @@ COMPACT_LATEX = NO
# by the printer. Possible values are: a4, a4wide, letter, legal and
# executive. If left blank a4wide will be used.
-PAPER_TYPE = a4
+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.
diff --git a/lib/pud/nmealib/include/nmea/config.h b/lib/pud/nmealib/include/nmea/config.h
new file mode 100644
index 0000000..915c4fb
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/config.h
@@ -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
index 0000000..c692a86
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/context.h
@@ -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
index 0000000..34eab4e
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/generate.h
@@ -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
index 0000000..6d7c049
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/generator.h
@@ -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
index 0000000..5bd37d9
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/gmath.h
@@ -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
index 0000000..ce74e80
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/info.h
@@ -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
index 0000000..c761579
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/nmea.h
@@ -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
index 0000000..adfe406
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/parse.h
@@ -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
index 0000000..94d71c8
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/parser.h
@@ -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
index 0000000..8f36272
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/sentence.h
@@ -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
index 0000000..9e6666d
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/time.h
@@ -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
index 0000000..e132d68
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/tok.h
@@ -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
index 0000000..ebc717a
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/units.h
@@ -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
index 0000000..f3b0f6d
--- /dev/null
+++ b/lib/pud/nmealib/include/nmea/util.h
@@ -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
index 0000000..a583a20
--- /dev/null
+++ b/lib/pud/nmealib/samples/Makefile
@@ -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
index 0000000..73e584d
--- /dev/null
+++ b/lib/pud/nmealib/samples/generate/main.c
@@ -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
index 0000000..f95cf1e
--- /dev/null
+++ b/lib/pud/nmealib/samples/generator/main.c
@@ -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
index 0000000..d1bcfa8
--- /dev/null
+++ b/lib/pud/nmealib/samples/math/main.c
@@ -0,0 +1,97 @@
+/*
+ * 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>
+
+#define NUM_POINTS 4
+
+int main()
+{
+ const char *buff[] = {
+ "$GPRMC,213916.199,A,4221.0377,N,07102.9778,W,0.00,,010207,,,A*6A\r\n",
+ "$GPRMC,213917.199,A,4221.0510,N,07102.9549,W,0.23,175.43,010207,,,A*77\r\n",
+ "$GPRMC,213925.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*68\r\n",
+ "$GPRMC,111609.14,A,5001.27,N,3613.06,E,11.2,0.0,261206,0.0,E*50\r\n"
+ };
+
+ nmeaPOS pos[NUM_POINTS], pos_moved[NUM_POINTS][2];
+ double dist[NUM_POINTS][2];
+ double azimuth[NUM_POINTS][2], azimuth_moved[NUM_POINTS];
+ int result[2];
+ int it = 0;
+
+ nmeaPARSER parser;
+ nmea_parser_init(&parser);
+
+ for(it = 0; it < NUM_POINTS; ++it)
+ {
+ nmeaINFO info;
+ nmea_zero_INFO(&info);
+ (void)nmea_parse(&parser, buff[it], (int)strlen(buff[it]), &info);
+ nmea_info2pos(&info, &pos[it]);
+ }
+
+ nmea_parser_destroy(&parser);
+
+ for(it = 0; it < NUM_POINTS; ++it)
+ {
+ dist[it][0] = nmea_distance(&pos[0], &pos[it]);
+ dist[it][1] = nmea_distance_ellipsoid(
+ &pos[0], &pos[it], &azimuth[it][0], &azimuth[it][1]
+ );
+ }
+
+ for(it = 0; it < NUM_POINTS; ++it)
+ {
+ result[0] = nmea_move_horz(&pos[0], &pos_moved[it][0], azimuth[it][0], dist[it][0]);
+ result[1] = nmea_move_horz_ellipsoid(
+ &pos[0], &pos_moved[it][1], azimuth[it][0], dist[it][0], &azimuth_moved[it]
+ );
+
+ }
+
+ /* Output of results */
+ printf("Coordinate points:\n");
+ for(it = 0; it < NUM_POINTS; ++it)
+ {
+ printf(
+ "P%d in radians: lat:%9.6lf lon:%9.6lf \tin degree: lat:%+010.6lf° lon:%+011.6lf°\n",
+ it, pos[it].lat, pos[it].lon, nmea_radian2degree(pos[it].lat), nmea_radian2degree(pos[it].lon)
+ );
+ }
+
+ printf("\nCalculation results:\n");
+ for(it = 0; it < NUM_POINTS; ++it)
+ {
+ printf("\n");
+ printf("Distance P0 to P%d\ton spheroid: %14.3lf m\n", it, dist[it][0]);
+ printf("Distance P0 to P%d\ton ellipsoid: %14.3lf m\n", it, dist[it][1]);
+ 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]));
+ printf("Move P0 to P%d\t \tAzimuth at end: %8.3lf°\n", it, nmea_radian2degree(azimuth_moved[it]));
+ 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));
+ 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));
+ 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));
+ }
+
+ return 0;
+}
diff --git a/lib/pud/nmealib/samples/parse/main.c b/lib/pud/nmealib/samples/parse/main.c
new file mode 100644
index 0000000..3f03da8
--- /dev/null
+++ b/lib/pud/nmealib/samples/parse/main.c
@@ -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
index 0000000..f6086da
--- /dev/null
+++ b/lib/pud/nmealib/samples/parse_file/gpslog.txt
@@ -0,0 +1,311 @@
+$PSRFTXTVersion GSW3.2.1PAT_3.1.00.12-SDK001P1.00c *3F
+$PSRFTXTHTC GPS_ART_321000_GEN*20
+$PSRFTXTTOW: 258712*32
+$PSRFTXTWK: 1412*4F
+$PSRFTXTPOS: 1518885 -4470072 4274168*24
+$PSRFTXTCLK: 94817*02
+$PSRFTXTCHNL: 12*5F
+$PSRFTXTBaud rate: 57600 *51
+$GPGGA,213638.949,,,,,0,00,,,M,0.0,M,,0000*5F
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213638.949,V,,,,,,,010207,,,N*40
+$GPGGA,213639.897,,,,,0,00,,,M,0.0,M,,0000*5C
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213639.897,V,,,,,,,010207,,,N*43
+$GPGGA,213640.886,,,,,0,00,,,M,0.0,M,,0000*52
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213640.886,V,,,,,,,010207,,,N*4D
+$GPGGA,213641.886,,,,,0,00,,,M,0.0,M,,0000*53
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213641.886,V,,,,,,,010207,,,N*4C
+$GPGGA,213642.897,,,,,0,00,,,M,0.0,M,,0000*50
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,12,20,00,000,,10,00,000,,25,00,000,,27,00,000,*79
+$GPGSV,3,2,12,22,00,000,,07,00,000,,21,00,000,,24,00,000,*79
+$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78
+$GPRMC,213642.897,V,,,,,,,010207,,,N*4F
+$GPGGA,213643.886,,,,,0,00,,,M,0.0,M,,0000*51
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213643.886,V,,,,,,,010207,,,N*4E
+$GPGGA,213644.886,,,,,0,00,,,M,0.0,M,,0000*56
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213644.886,V,,,,,,,010207,,,N*49
+$GPGGA,213645.897,,,,,0,00,,,M,0.0,M,,0000*57
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213645.897,V,,,,,,,010207,,,N*48
+$GPGGA,213646.886,,,,,0,00,,,M,0.0,M,,0000*54
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213646.886,V,,,,,,,010207,,,N*4B
+$GPGGA,213647.886,,,,,0,00,,,M,0.0,M,,0000*55
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,12,20,00,000,,10,00,000,,25,00,000,,27,00,000,*79
+$GPGSV,3,2,12,22,00,000,,07,00,000,,21,00,000,,24,00,000,*79
+$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78
+$GPRMC,213647.886,V,,,,,,,010207,,,N*4A
+$GPGGA,213648.897,,,,,0,00,,,M,0.0,M,,0000*5A
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213648.897,V,,,,,,,010207,,,N*45
+$GPGGA,213649.886,,,,,0,00,,,M,0.0,M,,0000*5B
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213649.886,V,,,,,,,010207,,,N*44
+$GPGGA,213650.886,,,,,0,00,,,M,0.0,M,,0000*53
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213650.886,V,,,,,,,010207,,,N*4C
+$GPGGA,213651.897,,,,,0,00,,,M,0.0,M,,0000*52
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213651.897,V,,,,,,,010207,,,N*4D
+$GPGGA,213652.886,,,,,0,00,,,M,0.0,M,,0000*51
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,12,20,00,000,,10,00,000,,25,00,000,,27,00,000,*79
+$GPGSV,3,2,12,22,00,000,,07,00,000,,21,00,000,,24,00,000,*79
+$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78
+$GPRMC,213652.886,V,,,,,,,010207,,,N*4E
+$GPGGA,213653.886,,,,,0,00,,,M,0.0,M,,0000*50
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213653.886,V,,,,,,,010207,,,N*4F
+$GPGGA,213654.898,,,,,0,00,,,M,0.0,M,,0000*58
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213654.898,V,,,,,,,010207,,,N*47
+$GPGGA,213655.886,,,,,0,00,,,M,0.0,M,,0000*56
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213655.886,V,,,,,,,010207,,,N*49
+$GPGGA,213656.886,,,,,0,00,,,M,0.0,M,,0000*55
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213656.886,V,,,,,,,010207,,,N*4A
+$GPGGA,213657.897,,,,,0,00,,,M,0.0,M,,0000*54
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,12,20,00,000,,10,00,000,,25,00,000,,27,00,000,*79
+$GPGSV,3,2,12,22,00,000,,07,00,000,,21,00,000,,24,00,000,*79
+$GPGSV,3,3,12,16,00,000,,28,00,000,,26,00,000,,29,00,000,*78
+$GPRMC,213657.897,V,,,,,,,010207,,,N*4B
+$GPGGA,213658.886,,,,,0,00,,,M,0.0,M,,0000*5B
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213658.886,V,,,,,,,010207,,,N*44
+$GPGGA,213659.886,,,,,0,00,,,M,0.0,M,,0000*5A
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213659.886,V,,,,,,,010207,,,N*45
+$GPGGA,213700.880,,,,,0,00,,,M,0.0,M,,0000*51
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213700.880,V,,,,,,,010207,,,N*4E
+$GPGGA,213701.880,,,,,0,00,,,M,0.0,M,,0000*50
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213701.880,V,,,,,,,010207,,,N*4F
+$GPGGA,213702.880,,,,,0,00,,,M,0.0,M,,0000*53
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,,10,46,055,*70
+$GPGSV,3,2,10,06,41,282,,02,23,120,,21,21,303,,08,16,068,*73
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B
+$GPRMC,213702.880,V,,,,,,,010207,,,N*4C
+$GPGGA,213703.880,,,,,0,00,,,M,0.0,M,,0000*52
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213703.880,V,,,,,,,010207,,,N*4D
+$GPGGA,213704.880,,,,,0,00,,,M,0.0,M,,0000*55
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213704.880,V,,,,,,,010207,,,N*4A
+$GPGGA,213705.879,,,,,0,00,,,M,0.0,M,,0000*52
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213705.879,V,,,,,,,010207,,,N*4D
+$GPGGA,213706.879,,,,,0,00,,,M,0.0,M,,0000*51
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213706.879,V,,,,,,,010207,,,N*4E
+$GPGGA,213707.879,,,,,0,00,,,M,0.0,M,,0000*50
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,,10,46,055,*70
+$GPGSV,3,2,10,06,41,282,,02,23,120,,21,21,303,,08,16,068,*73
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B
+$GPRMC,213707.879,V,,,,,,,010207,,,N*4F
+$GPGGA,213708.879,,,,,0,00,,,M,0.0,M,,0000*5F
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213708.879,V,,,,,,,010207,,,N*40
+$GPGGA,213709.879,,,,,0,00,,,M,0.0,M,,0000*5E
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213709.879,V,,,,,,,010207,,,N*41
+$GPGGA,213710.879,,,,,0,00,,,M,0.0,M,,0000*56
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213710.879,V,,,,,,,010207,,,N*49
+$GPGGA,213711.879,,,,,0,00,,,M,0.0,M,,0000*57
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213711.879,V,,,,,,,010207,,,N*48
+$GPGGA,213712.879,,,,,0,00,,,M,0.0,M,,0000*54
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,,10,46,055,*70
+$GPGSV,3,2,10,06,41,282,,02,23,120,,21,21,303,,08,16,068,*73
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B
+$GPRMC,213712.879,V,,,,,,,010207,,,N*4B
+$GPGGA,213713.879,,,,,0,00,,,M,0.0,M,,0000*55
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213713.879,V,,,,,,,010207,,,N*4A
+$GPGGA,213714.879,,,,,0,00,,,M,0.0,M,,0000*52
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213714.879,V,,,,,,,010207,,,N*4D
+$GPGGA,213715.879,,,,,0,00,,,M,0.0,M,,0000*53
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213715.879,V,,,,,,,010207,,,N*4C
+$GPGGA,213716.879,,,,,0,00,,,M,0.0,M,,0000*50
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213716.879,V,,,,,,,010207,,,N*4F
+$GPGGA,213717.879,,,,,0,00,,,M,0.0,M,,0000*51
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,25,10,46,055,*77
+$GPGSV,3,2,10,06,41,282,35,02,23,120,,21,21,303,,08,16,068,*75
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B
+$GPRMC,213717.879,V,,,,,,,010207,,,N*4E
+$GPGGA,213718.879,,,,,0,00,,,M,0.0,M,,0000*5E
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213718.879,V,,,,,,,010207,,,N*41
+$GPGGA,213719.879,,,,,0,00,,,M,0.0,M,,0000*5F
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213719.879,V,,,,,,,010207,,,N*40
+$GPGGA,213720.879,,,,,0,00,,,M,0.0,M,,0000*55
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213720.879,V,,,,,,,010207,,,N*4A
+$GPGGA,213721.879,,,,,0,00,,,M,0.0,M,,0000*54
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213721.879,V,,,,,,,010207,,,N*4B
+$GPGGA,213722.879,,,,,0,00,,,M,0.0,M,,0000*57
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,31,10,46,055,*72
+$GPGSV,3,2,10,06,41,282,34,02,23,120,,21,21,303,,08,16,068,*74
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B
+$GPRMC,213722.879,V,,,,,,,010207,,,N*48
+$GPGGA,213723.990,,,,,0,00,,,M,0.0,M,,0000*50
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213723.990,V,,,,,,,010207,,,N*4F
+$GPGGA,213724.990,,,,,0,00,,,M,0.0,M,,0000*57
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213724.990,V,,,,,,,010207,,,N*48
+$GPGGA,213725.990,,,,,0,00,,,M,0.0,M,,0000*56
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213725.990,V,,,,,,,010207,,,N*49
+$GPGGA,213726.990,,,,,0,00,,,M,0.0,M,,0000*55
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213726.990,V,,,,,,,010207,,,N*4A
+$GPGGA,213727.990,,,,,0,00,,,M,0.0,M,,0000*54
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,30,10,46,055,*73
+$GPGSV,3,2,10,06,41,282,34,02,23,120,,21,21,303,,08,16,068,*74
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B
+$GPRMC,213727.990,V,,,,,,,010207,,,N*4B
+$GPGGA,213728.990,,,,,0,00,,,M,0.0,M,,0000*5B
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213728.990,V,,,,,,,010207,,,N*44
+$GPGGA,213729.990,,,,,0,00,,,M,0.0,M,,0000*5A
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213729.990,V,,,,,,,010207,,,N*45
+$GPGGA,213730.990,,,,,0,00,,,M,0.0,M,,0000*52
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213730.990,V,,,,,,,010207,,,N*4D
+$GPGGA,213731.990,,,,,0,00,,,M,0.0,M,,0000*53
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213731.990,V,,,,,,,010207,,,N*4C
+$GPGGA,213732.990,,,,,0,00,,,M,0.0,M,,0000*50
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,27,10,46,055,*75
+$GPGSV,3,2,10,06,41,282,35,02,23,120,,21,21,303,,08,16,068,*75
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B
+$GPRMC,213732.990,V,,,,,,,010207,,,N*4F
+$GPGGA,213733.990,,,,,0,00,,,M,0.0,M,,0000*51
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213733.990,V,,,,,,,010207,,,N*4E
+$GPGGA,213734.990,,,,,0,00,,,M,0.0,M,,0000*56
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213734.990,V,,,,,,,010207,,,N*49
+$GPGGA,213735.990,,,,,0,00,,,M,0.0,M,,0000*57
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213735.990,V,,,,,,,010207,,,N*48
+$GPGGA,213736.990,,,,,0,00,,,M,0.0,M,,0000*54
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213736.990,V,,,,,,,010207,,,N*4B
+$GPGGA,213737.990,,,,,0,00,,,M,0.0,M,,0000*55
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,28,10,46,055,*7A
+$GPGSV,3,2,10,06,41,282,34,02,23,120,,21,21,303,,08,16,068,*74
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B
+$GPRMC,213737.990,V,,,,,,,010207,,,N*4A
+$GPGGA,213738.990,,,,,0,00,,,M,0.0,M,,0000*5A
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213738.990,V,,,,,,,010207,,,N*45
+$GPGGA,213739.990,,,,,0,00,,,M,0.0,M,,0000*5B
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213739.990,V,,,,,,,010207,,,N*44
+$GPGGA,213740.990,,,,,0,00,,,M,0.0,M,,0000*55
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213740.990,V,,,,,,,010207,,,N*4A
+$GPGGA,213741.990,,,,,0,00,,,M,0.0,M,,0000*54
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213741.990,V,,,,,,,010207,,,N*4B
+$GPGGA,213742.990,,,,,0,00,,,M,0.0,M,,0000*57
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPGSV,3,1,10,24,83,052,,29,63,170,,26,55,179,28,10,46,055,*7A
+$GPGSV,3,2,10,06,41,282,34,02,23,120,,21,21,303,,08,16,068,*74
+$GPGSV,3,3,10,27,10,042,,18,08,257,*7B
+$GPRMC,213742.990,V,,,,,,,010207,,,N*48
+$GPGGA,213743.990,,,,,0,00,,,M,0.0,M,,0000*56
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213743.990,V,,,,,,,010207,,,N*49
+$GPGGA,213744.990,,,,,0,00,,,M,0.0,M,,0000*51
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213744.990,V,,,,,,,010207,,,N*4E
+$GPGGA,213745.990,,,,,0,00,,,M,0.0,M,,0000*50
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213745.990,V,,,,,,,010207,,,N*4F
+$GPGGA,213746.990,,,,,0,00,,,M,0.0,M,,0000*53
+$PSRFTXTVersion GSW3.2.1PAT_3.1.00.12-SDK001P1.00c *3F
+$PSRFTXTHTC GPS_ART_321000_GEN*20
+$PSRFTXTTOW: 423546*3B
+$PSRFTXTWK: 1412*4F
+$PSRFTXTPOS: 1533096 -4464909 4274442*2A
+$PSRFTXTCLK: 94810*05
+$PSRFTXTCHNL: 12*5F
+$PSRFTXTBaud rate: 57600 *51
+$GPGGA,213912.270,,,,,0,00,,,M,0.0,M,,0000*59
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213912.270,V,,,,,,,010207,,,N*46
+$GPGGA,213913.211,,,,,0,00,,,M,0.0,M,,0000*5F
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213913.211,V,,,,,,,010207,,,N*40
+$GPGGA,213914.200,,,,,0,00,,,M,0.0,M,,0000*58
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213914.200,V,,,,,,,010207,,,N*47
+$GPGGA,213915.196,,,,,0,00,,,M,0.0,M,,0000*55
+$GPGSA,A,1,,,,,,,,,,,,,,,*1E
+$GPRMC,213915.196,V,,,,,,,010207,,,N*4A
+$GPGGA,213916.199,4221.0377,N,07102.9778,W,1,03,13.4,-32.4,M,-33.7,M,,0000*45
+$GPGSA,A,2,26,07,06,,,,,,,,,,13.4,13.4,1.0*37
+$GPGSV,3,1,11,26,55,180,28,06,46,258,33,07,43,272,30,21,22,304,*77
+$GPGSV,3,2,11,24,83,061,,29,64,170,,10,45,056,,02,23,121,*7F
+$GPGSV,3,3,11,08,17,067,,27,10,041,,18,05,257,*4B
+$GPRMC,213916.199,A,4221.0377,N,07102.9778,W,0.00,,010207,,,A*6A
+$GPGGA,213917.199,4221.0510,N,07102.9549,W,1,04,3.9,-65.2,M,-33.7,M,,0000*7C
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A
+$GPRMC,213917.199,A,4221.0510,N,07102.9549,W,0.23,175.43,010207,,,A*77
+$GPGGA,213918.199,4221.0853,N,07102.9382,W,1,04,3.9,50.0,M,-33.7,M,,0000*51
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A
+$GPRMC,213918.199,A,4221.0853,N,07102.9382,W,0.95,326.55,010207,,,A*7D
+$GPGGA,213919.000,4221.0975,N,07102.9300,W,1,04,3.9,86.2,M,-33.7,M,,0000*57
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A
+$GPRMC,213919.000,A,4221.0975,N,07102.9300,W,0.55,332.53,010207,,,A*7D
+$GPGGA,213920.000,4221.1129,N,07102.9146,W,1,04,3.9,129.7,M,-33.7,M,,0000*6C
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A
+$GPRMC,213920.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*6D
+$GPGGA,213921.000,4221.1129,N,07102.9146,W,1,04,3.9,129.7,M,-33.7,M,,0000*6D
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A
+$GPGSV,3,1,11,26,55,180,29,06,46,258,26,07,43,272,33,21,22,304,26*75
+$GPGSV,3,2,11,24,83,061,,29,64,170,,10,45,056,,02,23,121,*7F
+$GPGSV,3,3,11,08,17,067,28,27,10,041,,18,05,257,*41
+$GPRMC,213921.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*6C
+$GPGGA,213922.000,4221.1129,N,07102.9146,W,1,04,3.9,129.7,M,-33.7,M,,0000*6E
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A
+$GPRMC,213922.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*6F
+$GPGGA,213923.000,4221.1129,N,07102.9146,W,1,04,3.9,129.7,M,-33.7,M,,0000*6F
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.1,3.9,1.0*3A
+$GPRMC,213923.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*6E
+$GPGGA,213924.000,4221.1129,N,07102.9146,W,1,04,3.9,129.7,M,-33.7,M,,0000*68
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.0,3.9,1.0*3B
+$GPRMC,213924.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*69
+$GPGGA,213925.000,4221.1129,N,07102.9146,W,1,04,3.9,129.7,M,-33.7,M,,0000*69
+$GPGSA,A,3,26,07,06,21,,,,,,,,,4.0,3.9,1.0*3B
+$GPRMC,213925.000,A,4221.1129,N,07102.9146,W,0.00,,010207,,,A*68
+$GPGGA,213926.000,4221.1112,N,07102.9177,W,1,04,3.9,136.5,M,-33.7,M,,0000*6C
+
+
diff --git a/lib/pud/nmealib/samples/parse_file/main.c b/lib/pud/nmealib/samples/parse_file/main.c
new file mode 100644
index 0000000..a6f3617
--- /dev/null
+++ b/lib/pud/nmealib/samples/parse_file/main.c
@@ -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
index 0000000..c49d66f
--- /dev/null
+++ b/lib/pud/nmealib/src/context.c
@@ -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 ∝
+}
+
+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
index 0000000..abbb98f
--- /dev/null
+++ b/lib/pud/nmealib/src/generate.c
@@ -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
index 0000000..5cc2158
--- /dev/null
+++ b/lib/pud/nmealib/src/generator.c
@@ -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
index 0000000..d0fda8c
--- /dev/null
+++ b/lib/pud/nmealib/src/gmath.c
@@ -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, °);
+ 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, °);
+ 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
index 0000000..7cd20d4
--- /dev/null
+++ b/lib/pud/nmealib/src/info.c
@@ -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
index 0000000..1d54840
--- /dev/null
+++ b/lib/pud/nmealib/src/parse.c
@@ -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
index 0000000..4884321
--- /dev/null
+++ b/lib/pud/nmealib/src/parser.c
@@ -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
index 0000000..cf98c72
--- /dev/null
+++ b/lib/pud/nmealib/src/sentence.c
@@ -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
index 0000000..18d6be8
--- /dev/null
+++ b/lib/pud/nmealib/src/time.c
@@ -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
index 0000000..c9126a0
--- /dev/null
+++ b/lib/pud/nmealib/src/tok.c
@@ -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
index 0000000..45e57e0
--- /dev/null
+++ b/lib/pud/nmealib/src/util.c
@@ -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;
+}
--
1.7.7.6
More information about the Olsr-dev
mailing list