pax_global_header00006660000000000000000000000064124254431270014516gustar00rootroot0000000000000052 comment=f3ef7f3b2823a6367a29994fe42fb0fe3fca55e8 gnuais-0.3.3/000077500000000000000000000000001242544312700130075ustar00rootroot00000000000000gnuais-0.3.3/.gitignore000066400000000000000000000000121242544312700147700ustar00rootroot00000000000000createdeb gnuais-0.3.3/AUTHORS000066400000000000000000000003121242544312700140530ustar00rootroot00000000000000 Ruben Undheim Heikki Hannikainen Sakari Nylund Tomi Manninen Thanks to Ariel Mastracchio for sending patch for fixing negative latitudes! gnuais-0.3.3/CMakeLists.txt000066400000000000000000000013451242544312700155520ustar00rootroot00000000000000cmake_minimum_required (VERSION 2.6) SET(CMAKE_BUILD_TYPE Release CACHE STRING "If build type is not specified on command line, build Release") project (gnuais) INCLUDE(CheckIncludeFiles) CHECK_INCLUDE_FILES(alsa/asoundlib.h HAVE_ALSA) CHECK_INCLUDE_FILES(mysql/mysql.h HAVE_MYSQL) CHECK_INCLUDE_FILES(curl/curl.h HAVE_CURL) CHECK_INCLUDE_FILES(pulse/pulseaudio.h HAVE_PULSEAUDIO) if(NOT HAVE_ALSA) MESSAGE(FATAL_ERROR "The development files for ALSA are required - libasound-dev") endif(NOT HAVE_ALSA) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) install(FILES gnuais.conf-example DESTINATION share/doc/gnuais) add_subdirectory(src) gnuais-0.3.3/COPYING000066400000000000000000000431221242544312700140440ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 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. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, 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 or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's 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 give any other recipients of the Program a copy of this License along with the Program. 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 Program or any portion of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, 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 Program, 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 Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) 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; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, 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 executable. However, as a special exception, the source code 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. If distribution of executable or 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 counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program 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. 5. 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 Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program 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 to this License. 7. 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 Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program 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 Program. 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. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program 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. 9. The Free Software Foundation may publish revised and/or new versions of the 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 Program 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 Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, 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 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 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 Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. 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. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, 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. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. gnuais-0.3.3/ChangeLog000066400000000000000000000070511242544312700145640ustar00rootroot000000000000000.3.3: Able to print receiver statistics (range) Cleaned up some code Better console output messages 0.3.2: Building with osm-gps-map > 1.0 and GTK 3 0.3.1: Updated copyright information for files Workaround for tiles not working in gnuaisgui 0.3.0: GUI is working (using OpenStreetMap). Various other fixes 0.2.7: Added pulseaudio support 0.2.6: Fixed some compile issues 0.2.5: Looks for configuration file also in /etc/gnuais.conf, and installs a configuration file there automatically at "make install" Using cmake instead of autotools New filter taps Prepared for deb-package generation Other small fixes 0.2.2: Changed code a bit. Class B transponders do not have any "destination"-field. Code now adds fake destination field when it receives class B transponders message (type 19, 24). Fake field sets destination: "CLASS B TX". Just for "nice to know it came from class B vessel"- purposes. (Saku) 0.2.1: Added support of class B frames (types 18, 19, 24) Type 19 may have bug(s). Very little class B transponders around and type 19 frame is seen only if another station polls class B transponder (actualLy never here) so debugging is not easy on any class B frames. (Sakari Nylund) 0.2.0: Fixed 6-bit ASCII decoding to also handle numbers and special characters. (Hessu) Latitude and longitude were mixed in the ais_basestation MySQL table, fixed. (Ruben) The separate gnuaissavetofile program was removed. (Ruben) Fixed MySQL handling in the configure script. (David Herring) 0.1.1: Fixed a little bug in ALSA sound device handling: use exactly whatever buffer size is suggested by ALSA, so that some sound devices won't fail with an overrun after running for a while. (Tomi, Hessu) 0.1.0: Improved AIS decoding DSP code. Added JSON AIS HTTP POST data exporting. Implemented decoding from a stereo sound card, either left, right, or both channels at the same time. Supports two receivers on the two AIS channels. Implemented sound peak level logging at configurable interval, or every 30 seconds when the level is higher than 98%. Added configurable logging to stderr/syslog/log file. Added a nice configuration file and command line parser. Implemented forking to background (-f). Removed separate gnuaisfromfile.c file, since it was almost completely duplicate with ais.c - the "read from file" functionality is now done using the -l option to gnuais. Reduces maintenance work. Fixed buffer overflow (security) bugs in the SQL query generation. The SQL code crashed on SEGV when run with file input (lots of data coming in and overwriting the query buffers). Implemented automatic reconnection to MySQL if the connection goes away (server crash, network outage, inactivity timeout). Fixed memory corruption bugs, now works when compiled with -O3. 0.0.7: gnuais can decode positions south of equator + minor other fixes 0.0.6: Added GUI which is in development. A lot of work to do yet.. There have also been made some minor fixes. For example the configure script now checks for alsa and gtk. 0.0.5: Some fixes 0.0.4: Added NMEA-sentences for outputting to third-party map software (Thanks to Sakari Nylund). There have also been made some bug-fixes, and different details here and there, have been changed. 0.0.3: Translated all code from C++ to C. Using Alsa instead of OSS. Using only one thread now. It seemed to be unnecessary to have one extra thread for sound input. 0.0.2: MySQL-functionality and config file (/etc/gnuais.conf) gnuais-0.3.3/INSTALL000066400000000000000000000005631242544312700140440ustar00rootroot00000000000000Installation Instructions ************************* To install, run these commands: cmake . make make install (as root) The development files for ALSA (libasound) are required. It is also nice to have the development files for mysql and curl since these will enable some extra features. For the GUI to be built, gtk-3 and osmgpsmap are also required. gnuais-0.3.3/NEWS000066400000000000000000000004071242544312700135070ustar00rootroot00000000000000Sat Dec 20 17:59:17 EET 2008 gnuais 0.1.0 has been released. It has a number of new features and significant improvements. Check the ChangeLog for details! The GUI is broken in this release - the focus has been stability and features of the decoder core. gnuais-0.3.3/README.md000066400000000000000000000016031242544312700142660ustar00rootroot00000000000000 The first time GNU AIS is started, a configuration file is created in ~/.config/gnuais/config. An alternative configuration file can be specified with the command line argument -c . If an alternative configuration file is specified the first time you run gnuais, the file ~/.config/gnuais/config will not be generated. It is explained in ~/.config/gnuais/config how you will have to edit it in order to fullfill your wishes. You will also have to create a table in the database if the mysql option is desired: Make new database (if needed) with command: mysqladmin create You can also use any existing database adding table 'ais': mysql < create\_table.sql Or if you have specified username and password for your database: mysql -u -p < create\_table.sql The file create\_table.sql can be found in this folder. gnuais-0.3.3/config.h.in000066400000000000000000000003501242544312700150300ustar00rootroot00000000000000#cmakedefine HAVE_ALSA 1 #cmakedefine HAVE_CURL #cmakedefine HAVE_GTK #cmakedefine HAVE_MYSQL #cmakedefine HAVE_PULSEAUDIO /* Name of package */ #define PACKAGE "gnuais" /* Version number of package */ #define VERSION "0.3.3" gnuais-0.3.3/create_table.sql000077500000000000000000000014031242544312700161430ustar00rootroot00000000000000 drop table if exists `ais_nmea`; drop table if exists `ais_position`; drop table if exists `ais_vesseldata`; drop table if exists `ais_basestation`; create table ais_nmea ( id int not null primary key auto_increment, time bigint, message varchar(200) ); create table ais_position ( id int not null primary key auto_increment, time bigint, mmsi int, latitude float, longitude float, heading float, course float, speed float ); create table ais_vesseldata ( id int not null primary key auto_increment, time bigint, mmsi int, name varchar(21), destination varchar(21), draught float, A int, B int, C int, D int ); create table ais_basestation ( id int not null primary key auto_increment, time bigint, mmsi int, latitude float, longitude float ); gnuais-0.3.3/create_table.txt000066400000000000000000000005661242544312700161710ustar00rootroot00000000000000If you have mysql installed and mysqld running you can: Make new database (if needed) with command: mysqladmin create You can also use any existing database adding table 'ais': mysql < create_table.sql Or if you have specified username and password for your database: mysql -u -p < create_table.sql gnuais-0.3.3/gnuais.conf-example000066400000000000000000000052401242544312700165760ustar00rootroot00000000000000 # Configuration for gnuais # My callsign or nickname, used when exporting AIS data MyCall GNUAIS # My email address MyEmail gnuais@example.com # Directory, where logs will be written. Defaults to current directory. #LogDir logs # ALSA sound device name or "pulse" for pulseaudio, # If alsa is used: either the name of the card (default for the # first / default card), or a device name, for example: hw:2,0 for the first # input of the third card. SoundDevice default # Which sound channels to decode: # both # - ask the sound card for a stereo signal and decode both channels # - a good default, if you're not sure which channel your receiver is in # mono # - ask the sound card for a single mono channel # - needed for a true mono card, like some USB audio sticks, which only # have a single audio input channel # left # - ask the sound card for a stereo signal and only decode the # left channel # right # - ask the sound card for a stereo signal and decode the right channel # SoundChannels both # Print sound peak level information in the log every N seconds. # The input level should be around 70-90% - if it's 100% the signal is too loud # and distorted. Tune your mixer settings. Comment the line out, or set to 0, # to disable level logging below distortion levels. SoundLevelLog 1 # Print receiver range statistics in the log every N seconds. # StatsInterval defines the logging interval. Latitude and Longitude of the # receiver are given in decimal degrees (not degrees and minutes, or seconds). # Positive values for northern latitude and eastern longitude, negative # values for southern latitude and western longitude. #StatsInterval 10 #Latitude 35.2512 #Longitude 110.8175 # AIS data uplink configuration - received APRS data will be posted here # periodically. Can be used for exporting data to aprs.fi. You need to get a # key for your receiving site to submit data, please read the instructions # at http://aprs.fi/page/ais_receiver ! # # Uplink #Uplink aprs.fi json http://aprs.fi/jsonais/post/ask-for-your-key # MySQL database configuration - received AIS data will be stored in the # specified database. See create_table.txt for instructions. #mysql_host localhost #mysql_db yourmysqldatabase #mysql_user yourmysqlusername #mysql_password xxxx #mysql_keepsmall yes #mysql_oldlimit 800 # Serial port for AIS export - NMEA sentences will be written here after # decoding. Currently it is not possible to read AIS data from an # AIS receiver connected to a serial port. #serial_port /dev/ttyS0 # Use test file as input instead of the audio device input #SoundInFile ../testmessages/gnuais-stereo-2rx.raw gnuais-0.3.3/src/000077500000000000000000000000001242544312700135765ustar00rootroot00000000000000gnuais-0.3.3/src/CMakeLists.txt000066400000000000000000000022601242544312700163360ustar00rootroot00000000000000if(HAVE_PULSEAUDIO) add_executable(gnuais ais.c ais.c cfg.c crc32.c hlog.c input.c out_mysql.c receiver.c splay.c cache.c range.c cfgfile.c filter.c hmalloc.c out_json.c protodec.c rwlock.c serial.c spsymbol.c ipc.c pulseaudio.c) else() add_executable(gnuais ais.c ais.c cfg.c crc32.c hlog.c input.c out_mysql.c receiver.c splay.c cache.c range.c cfgfile.c filter.c hmalloc.c out_json.c protodec.c rwlock.c serial.c spsymbol.c ipc.c) endif() target_link_libraries(gnuais pthread asound m) if(HAVE_MYSQL) target_link_libraries(gnuais mysqlclient) else() message(WARNING "You do not have development files for mysql. Mysql functionality will therefore be disabled") endif() if(HAVE_CURL) target_link_libraries(gnuais curl) else() message(WARNING "You do not have the development files for curl. Functionaly using curl will therefore be disabled") endif() if(HAVE_PULSEAUDIO) target_link_libraries(gnuais pulse-simple) else() message(WARNING "You do not have the development files for pulseaudio. Support for pulseaudio will therefore not be included") endif() install(TARGETS gnuais DESTINATION bin) #if(HAVE_GTK) add_subdirectory(gui) #endif(HAVE_GTK) gnuais-0.3.3/src/ais.c000066400000000000000000000171021242544312700145170ustar00rootroot00000000000000 /* * ais.c * * (c) Ruben Undheim 2008 * (c) Heikki Hannikainen 2008 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #if HAVE_CONFIG_H #include "config.h" #endif #include #include #include "ais.h" #include "input.h" #include "receiver.h" #include "protodec.h" #include "hmalloc.h" #include "hlog.h" #include "cfg.h" #include "out_mysql.h" #include "out_json.h" #include "cache.h" #include "range.h" #include "ipc.h" #ifdef HAVE_PULSEAUDIO #include "pulseaudio.h" #endif #ifdef DMALLOC #include #endif int done; void closedown(int sig) { done = 1; } void brokenconnection(int sig) { hlog(LOG_DEBUG,"There is a broken connection\n"); } int main(int argc, char *argv[]) { int err; done = 0; snd_pcm_t *handle; FILE *sound_in_fd = NULL; FILE *sound_out_fd = NULL; int channels; short *buffer = NULL; int buffer_l; int buffer_read; struct serial_state_t *serial = NULL; struct ipc_state_t *ipc = NULL; struct receiver *rx_a = NULL; struct receiver *rx_b = NULL; #ifdef HAVE_PULSEAUDIO pa_simple *pa_dev = NULL; #endif time_t last_stats = time(NULL); /* command line */ parse_cmdline(argc, argv); /* open syslog, write an initial log message and read configuration */ open_log(logname, 0); hlog(LOG_NOTICE, "Starting up..."); if (read_config()) { hlog(LOG_CRIT, "Initial configuration failed."); exit(1); } /* fork a daemon */ if (fork_a_daemon) { int i = fork(); if (i < 0) { hlog(LOG_CRIT, "Fork to background failed: %s", strerror(errno)); fprintf(stderr, "Fork to background failed: %s\n", strerror(errno)); exit(1); } else if (i == 0) { /* child */ /* write pid file, now that we have our final pid... might fail, which is critical */ hlog(LOG_DEBUG, "Writing pid..."); if (!writepid(pidfile)) exit(1); } else { /* parent, quitting */ hlog(LOG_DEBUG, "Forked daemon process %d, parent quitting", i); exit(0); } } signal(SIGINT, closedown); signal(SIGPIPE, brokenconnection); /* initialize position cache for timed JSON AIS transmission */ if (uplink_config) { hlog(LOG_DEBUG, "Initializing cache..."); if (cache_init()) exit(1); hlog(LOG_DEBUG, "Initializing jsonout..."); if (jsonout_init()) exit(1); } /* initialize serial port for NMEA output */ if (serial_port) serial = serial_init(); /* initialize Unix domain socket for communication with gnuaisgui */ ipc = gnuais_ipc_init(); if(ipc == 0){ hlog(LOG_ERR, "Could not open Unix Domain Socket"); } /* initialize the AIS decoders */ if (sound_channels != SOUND_CHANNELS_MONO) { hlog(LOG_DEBUG, "Initializing demodulator A"); rx_a = init_receiver('A', 2, 0,serial,ipc); hlog(LOG_DEBUG, "Initializing demodulator B"); rx_b = init_receiver('B', 2, 1,serial,ipc); channels = 2; } else { hlog(LOG_DEBUG, "Initializing demodulator A"); rx_a = init_receiver('A', 1, 0,serial,ipc); channels = 1; } #ifdef HAVE_PULSEAUDIO if(sound_device != NULL && ((strcmp("pulse",sound_device) == 0) || (strcmp("pulseaudio",sound_device) == 0))){ if((pa_dev = pulseaudio_initialize()) == NULL){ hlog(LOG_CRIT, "Error opening pulseaudio device"); return -1; } buffer_l = 1024; int extra = buffer_l % 5; buffer_l -= extra; buffer = (short *) hmalloc(buffer_l * sizeof(short) * channels); } else if (sound_device){ #else if (sound_device){ #endif if ((err = snd_pcm_open(&handle, sound_device, SND_PCM_STREAM_CAPTURE, 0)) < 0) { hlog(LOG_CRIT, "Error opening sound device (%s)", sound_device); return -1; } if (input_initialize(handle, &buffer, &buffer_l) < 0) return -1; } else if (sound_in_file) { if ((sound_in_fd = fopen(sound_in_file, "r")) == NULL) { hlog(LOG_CRIT, "Could not open sound file %s: %s", sound_in_file, strerror(errno)); return -1; } hlog(LOG_NOTICE, "Reading audio from file: %s", sound_in_file); buffer_l = 1024; int extra = buffer_l % 5; buffer_l -= extra; buffer = (short *) hmalloc(buffer_l * sizeof(short) * channels); } else { hlog(LOG_CRIT, "Neither sound device or sound file configured."); return -1; } if (sound_out_file) { if ((sound_out_fd = fopen(sound_out_file, "w")) == NULL) { hlog(LOG_CRIT, "Could not open sound output file %s: %s", sound_out_file, strerror(errno)); return -1; } hlog(LOG_NOTICE, "Recording audio to file: %s", sound_out_file); } #ifdef HAVE_MYSQL if (mysql_db) { hlog(LOG_DEBUG, "Saving to MySQL database \"%s\"", mysql_db); if (!(my = myout_init())) return -1; if (mysql_keepsmall) hlog(LOG_DEBUG, "Updating database rows only."); else hlog(LOG_DEBUG, "Inserting data to database."); if (mysql_oldlimit) hlog(LOG_DEBUG, "Deleting data older than %d seconds", mysql_oldlimit); } #endif hlog(LOG_NOTICE, "Started"); while (!done) { if (sound_in_fd) { buffer_read = fread(buffer, channels * sizeof(short), buffer_l, sound_in_fd); if (buffer_read <= 0) done = 1; } #ifdef HAVE_PULSEAUDIO else if (pa_dev){ buffer_read = pulseaudio_read(pa_dev, buffer, buffer_l); } #endif else { buffer_read = input_read(handle, buffer, buffer_l); //printf("read %d\n", buffer_read); } if (buffer_read <= 0) continue; if (sound_out_fd) { fwrite(buffer, channels * sizeof(short), buffer_read, sound_out_fd); } if (sound_channels == SOUND_CHANNELS_MONO) { receiver_run(rx_a, buffer, buffer_read); } if (sound_channels == SOUND_CHANNELS_BOTH || sound_channels == SOUND_CHANNELS_RIGHT) { /* ch a/0/right */ receiver_run(rx_a, buffer, buffer_read); } if (sound_channels == SOUND_CHANNELS_BOTH || sound_channels == SOUND_CHANNELS_LEFT) { /* ch b/1/left */ receiver_run(rx_b, buffer, buffer_read); } if (stats_interval) { time_t now = time(NULL); if (last_stats > now) { // clock jumped backwards last_stats = now; } else if (now - last_stats >= stats_interval) { last_stats = now; if (rx_a) log_range(rx_a->decoder); if (rx_b) log_range(rx_b->decoder); } } } hlog(LOG_NOTICE, "Closing down..."); if (sound_in_fd) { fclose(sound_in_fd); } #ifdef HAVE_PULSEAUDIO else if (pa_dev) { pulseaudio_cleanup(pa_dev); } #endif else { input_cleanup(handle); handle = NULL; } if (sound_out_fd) fclose(sound_out_fd); hfree(buffer); gnuais_ipc_deinit(ipc); if (serial) serial_close(serial); if (uplink_config) jsonout_deinit(); if (cache_positions) cache_deinit(); if (rx_a) { struct demod_state_t *d = rx_a->decoder; hlog(LOG_INFO, "A: Received correctly: %d packets, wrong CRC: %d packets, wrong size: %d packets", d->receivedframes, d->lostframes, d->lostframes2); } if (rx_b) { struct demod_state_t *d = rx_b->decoder; hlog(LOG_INFO, "B: Received correctly: %d packets, wrong CRC: %d packets, wrong size: %d packets", d->receivedframes, d->lostframes, d->lostframes2); } free_receiver(rx_a); free_receiver(rx_b); free_config(); close_log(0); return 0; } gnuais-0.3.3/src/ais.h000066400000000000000000000016231242544312700145250ustar00rootroot00000000000000 /* * ais.h * * (c) Ruben Undheim 2008 * (c) Heikki Hannikainen 2008 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef INC_AIS_H #define INC_AIS_H #include extern long int cntr; #endif gnuais-0.3.3/src/cache.c000066400000000000000000000170721242544312700150140ustar00rootroot00000000000000 /* * cache.c * * (c) Heikki Hannikainen 2008 * * Cache received AIS position reports, storing the most current * up-to-date information for each MMSI, so that it can be sent out * at regular intervals. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "config.h" #include #include #include #include "cache.h" #include "crc32.h" #include "hlog.h" #include "hmalloc.h" #ifdef DMALLOC #include #endif //#define DEBUG_CACHE #ifdef DEBUG_CACHE #define CACHE_DBG(x) x #else #define CACHE_DBG(x) #endif /* are we caching positions? */ int cache_positions = 0; /* the splay tree root for the cache */ struct sptree *cache_spt; pthread_mutex_t cache_spt_mut = PTHREAD_MUTEX_INITIALIZER; /* * initialize the cache */ int cache_init(void) { CACHE_DBG(hlog(LOG_DEBUG, "cache_init")); /* initialize crc32 */ crcinit(); /* initialize the cache splay tree */ pthread_mutex_lock(&cache_spt_mut); cache_spt = sp_init(); cache_spt->symbols = NULL; pthread_mutex_unlock(&cache_spt_mut); /* ok, we're clear to go */ cache_positions = 1; return 0; } /* * free a cache entry */ void cache_free_entry(struct cache_ent *e) { if (e->name) hfree(e->name); if (e->destination) hfree(e->destination); if (e->callsign) hfree(e->callsign); hfree(e); } /* * uninitialize a copy of the cache */ int cache_free(struct sptree *sp) { struct spblk *x, *nextx; struct cache_ent *e; int freed = 0; CACHE_DBG(hlog(LOG_DEBUG, "cache_free")); for (x = sp_fhead(sp); x != NULL; x = nextx) { nextx = sp_fnext(x); e = (struct cache_ent *)x->data; cache_free_entry(e); sp_delete(x, sp); freed++; } hlog(LOG_DEBUG, "cache_free: %d ship entries freed", freed); return 0; } /* * uninitialize the main cache */ int cache_deinit(void) { int ret; pthread_mutex_lock(&cache_spt_mut); ret = cache_free(cache_spt); hfree(cache_spt); sp_free_freelist(); pthread_mutex_unlock(&cache_spt_mut); return ret; } /* * get the existing cache (for export) and create a new one */ struct sptree *cache_rotate(void) { struct sptree *got_spt; pthread_mutex_lock(&cache_spt_mut); got_spt = cache_spt; cache_spt = sp_init(); cache_spt->symbols = NULL; pthread_mutex_unlock(&cache_spt_mut); return got_spt; } /* * look up an existing entry - if it doesn't exist, create one */ static struct cache_ent *cache_get(int mmsi) { struct spblk *spl; struct cache_ent *e; /* check if we already have this key */ spl = sp_lookup((spkey_t)mmsi, cache_spt); if (spl) { e = (struct cache_ent *)spl->data; CACHE_DBG(hlog(LOG_DEBUG, "cache_get hit: %d", mmsi)); } else { CACHE_DBG(hlog(LOG_DEBUG, "cache_get miss: %d", mmsi)); /* oh, new ship... install in cache */ spl = sp_install((spkey_t)mmsi, cache_spt); e = hmalloc(sizeof(*e)); spl->data = (void *)e; /* reset data in the allocated entry */ memset((void *)e, 0, sizeof(*e)); /* floats need to be set separately */ e->lat = 0; e->lon = 0; e->hdg = -1; e->course = -1; e->sog = -1; e->shiptype = -1; e->imo = -1; e->navstat = -1; e->A = e->B = e->C = e->D = -1; e->persons_on_board = -1; } return e; } /* * cache a ship's position */ int cache_position( int received_t, int mmsi, int navstat, float lat, float lon, int hdg, float course, int rateofturn, float sog) { struct cache_ent *e; CACHE_DBG(hlog(LOG_DEBUG, "cache_position %d t %d", mmsi, received_t)); pthread_mutex_lock(&cache_spt_mut); e = cache_get(mmsi); e->mmsi = mmsi; e->received_pos = received_t; e->mmsi = mmsi; e->lat = lat; e->lon = lon; e->hdg = hdg; e->course = course; e->sog = sog; e->navstat = navstat; pthread_mutex_unlock(&cache_spt_mut); return 0; } /* * cache static vessel data */ int cache_vesseldata(int received_t, int mmsi, int imo, char *callsign, char *name, char *destination, int shiptype, int A, int B, int C, int D, float draught) { struct cache_ent *e; CACHE_DBG(hlog(LOG_DEBUG, "cache_vesseldata %d: name '%s' dest '%s' t %d", mmsi, name, destination, received_t)); pthread_mutex_lock(&cache_spt_mut); e = cache_get(mmsi); e->mmsi = mmsi; e->imo = imo; e->received_data = received_t; if (!e->callsign || strcmp(e->callsign, callsign) != 0) { if (e->callsign) hfree(e->callsign); e->callsign = hstrdup(callsign); } if (!e->name || strcmp(e->name, name) != 0) { if (e->name) hfree(e->name); e->name = hstrdup(name); } if (!e->destination || strcmp(e->destination, destination)) { if (e->destination) hfree(e->destination); e->destination = hstrdup(destination); } e->shiptype = shiptype; e->A = A; e->B = B; e->C = C; e->D = D; e->draught = draught; pthread_mutex_unlock(&cache_spt_mut); return 0; } int cache_vesseldatab(int received_t, int mmsi, char *callsign, int shiptype, int A, int B, int C, int D) { struct cache_ent *e; CACHE_DBG(hlog(LOG_DEBUG, "cache_vesseldatab %d: t %d", mmsi, received_t)); pthread_mutex_lock(&cache_spt_mut); e = cache_get(mmsi); e->mmsi = mmsi; e->imo = 0; //NO imo; e->received_data = received_t; if (!e->callsign || strcmp(e->callsign, callsign) != 0) { if (e->callsign) hfree(e->callsign); e->callsign = hstrdup(callsign); } e->shiptype = shiptype; e->A = A; e->B = B; e->C = C; e->D = D; e->draught = 0;//NO draught; pthread_mutex_unlock(&cache_spt_mut); return 0; } int cache_vesseldatabb(int received_t, int mmsi, int shiptype, int A, int B, int C, int D) { struct cache_ent *e; CACHE_DBG(hlog(LOG_DEBUG, "cache_vesseldatab %d: t %d", mmsi, received_t)); pthread_mutex_lock(&cache_spt_mut); e = cache_get(mmsi); e->mmsi = mmsi; e->imo = 0; //NO imo; e->received_data = received_t; e->shiptype = shiptype; e->A = A; e->B = B; e->C = C; e->D = D; e->draught = 0;//NO draught; pthread_mutex_unlock(&cache_spt_mut); return 0; } int cache_vesselname(int received_t, int mmsi, char *name, const char *destination) { struct cache_ent *e; CACHE_DBG(hlog(LOG_DEBUG, "cache_vesselname %d: name '%s' destination '%s' t %d", mmsi, name, destination, received_t)); pthread_mutex_lock(&cache_spt_mut); e = cache_get(mmsi); e->mmsi = mmsi; e->received_data = received_t; if (!e->name || strcmp(e->name, name) != 0) { if (e->name) hfree(e->name); e->name = hstrdup(name); } if (!e->destination || strcmp(e->destination, destination)) { if (e->destination) hfree(e->destination); e->destination = hstrdup(destination); } pthread_mutex_unlock(&cache_spt_mut); return 0; } int cache_vessel_persons(int received_t, int mmsi, int persons_on_board) { struct cache_ent *e; CACHE_DBG(hlog(LOG_DEBUG, "cache_vessel_persons %d: %d t %d", mmsi, persons_on_board, received_t)); pthread_mutex_lock(&cache_spt_mut); e = cache_get(mmsi); e->mmsi = mmsi; e->received_persons_on_board = received_t; e->persons_on_board = persons_on_board; pthread_mutex_unlock(&cache_spt_mut); return 0; } gnuais-0.3.3/src/cache.h000066400000000000000000000045011242544312700150120ustar00rootroot00000000000000 /* * cache.h * * (c) Heikki Hannikainen 2008 * * Cache received AIS position reports, storing the most current * up-to-date information for each MMSI, so that it can be sent out * at regular intervals. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "splay.h" /* an entry in the cache */ struct cache_ent { int mmsi; /* position message */ time_t received_pos; float lat; float lon; int hdg; float course; float sog; int navstat; /* vessel data message */ time_t received_data; int imo; char *callsign; char *name; char *destination; int shiptype; int A; int B; int C; int D; float draught; /* persons on board */ time_t received_persons_on_board; int persons_on_board; }; extern int cache_positions; extern int cache_init(void); extern int cache_deinit(void); extern void cache_free_entry(struct cache_ent *e); extern int cache_free(struct sptree *sp); extern struct sptree *cache_rotate(void); extern int cache_position( int received_t, int mmsi, int navstat, float lat, float lon, int hdg, float course, int rateofturn, float sog); extern int cache_vesseldata( int received_t, int mmsi, int imo, char *callsign, char *name, char *destination, int shiptype, int A, int B, int C, int D, float draught); extern int cache_vessel_persons(int received_t, int mmsi, int persons_on_board); extern int cache_vesselname(int received_t, int mmsi, char *name, const char *destination); extern int cache_vesseldatab(int received_t, int mmsi, char *callsign, int shiptype, int A, int B, int C, int D); extern int cache_vesseldatabb(int received_t, int mmsi, int shiptype, int A, int B, int C, int D); gnuais-0.3.3/src/cfg.c000066400000000000000000000240231242544312700145020ustar00rootroot00000000000000/* * (c) Heikki Hannikainen, OH7LZB * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ /* * cfg.c: configuration parsing, based on Tomi's code */ #include #include #include #include #include #include #include #include #include #include "cfg.h" #include "hmalloc.h" #include "hlog.h" #include "cfgfile.h" #include "range.h" #ifdef DMALLOC #include #endif #define HELPS "Usage: " PACKAGE " [-c cfgfile] [-f (fork)] [-n ] [-e ] [-o ] [-r ] [-l ] [-s ] [-h (help)]\n" char def_cfgfile[] = PROGNAME ".conf"; char def_logname[] = PROGNAME; char def_sound_device[] = "default"; char *cfgfile = def_cfgfile; char *pidfile; char *logdir; /* access logs go here */ char *logname = def_logname; /* syslog entries use this program name */ char *mycall; char *myemail; float mylat = -200.0; float mylng = -200.0; int have_my_loc; char *sound_device; char *sound_in_file; char *sound_out_file; int sound_channels = SOUND_CHANNELS_MONO; int sound_levellog = 0; char *mysql_host; char *mysql_db; char *mysql_user; char *mysql_password; int mysql_keepsmall; int mysql_oldlimit; char *serial_port; struct uplink_config_t *uplink_config; struct uplink_config_t *new_uplink_config; int fork_a_daemon; /* fork a daemon */ int stats_interval; int expiry_interval; int skip_type[MAX_AIS_PACKET_TYPE+1]; int verbose; int do_interval(int *dest, int argc, char **argv); int do_uplink(struct uplink_config_t **lq, int argc, char **argv); int do_skip_type(int *dest, int argc, char **argv); int do_sound_ch(int *dest, int argc, char **argv); /* * Configuration file commands */ #define _CFUNC_ (int (*)(void *dest, int argc, char **argv)) static struct cfgcmd cfg_cmds[] = { { "logdir", _CFUNC_ do_string, &logdir }, { "mycall", _CFUNC_ do_string, &mycall }, { "myemail", _CFUNC_ do_string, &myemail }, { "latitude", _CFUNC_ do_float, &mylat }, { "longitude", _CFUNC_ do_float, &mylng }, { "statsinterval", _CFUNC_ do_interval, &stats_interval }, { "expiryinterval", _CFUNC_ do_interval, &expiry_interval }, { "uplink", _CFUNC_ do_uplink, &new_uplink_config }, { "mysql_host", _CFUNC_ do_string, &mysql_host }, { "mysql_db", _CFUNC_ do_string, &mysql_db }, { "mysql_user", _CFUNC_ do_string, &mysql_user }, { "mysql_password", _CFUNC_ do_string, &mysql_password }, { "mysql_keepsmall", _CFUNC_ do_toggle, &mysql_keepsmall }, { "mysql_oldlimit", _CFUNC_ do_int, &mysql_oldlimit }, { "sounddevice", _CFUNC_ do_string, &sound_device }, { "soundinfile", _CFUNC_ do_string, &sound_in_file }, { "soundoutfile", _CFUNC_ do_string, &sound_out_file }, { "soundchannels", _CFUNC_ do_sound_ch, &sound_channels }, { "soundlevellog", _CFUNC_ do_int, &sound_levellog }, { "serialport", _CFUNC_ do_string, &serial_port }, { "serial_port", _CFUNC_ do_string, &serial_port }, { "skip_type", _CFUNC_ do_skip_type, &skip_type }, { NULL, NULL, NULL } }; /* * Free a uplink config tree */ void free_uplink_config(struct uplink_config_t **lc) { struct uplink_config_t *this; while (*lc) { this = *lc; *lc = this->next; hfree((void*)this->name); hfree((void*)this->url); hfree(this); } } /* * parse an interval specification */ time_t parse_interval(char *origs) { time_t t = 0; int i; char *s, *np, *p, c; np = p = s = hstrdup(origs); while (*p) { if (!isdigit((int)*p)) { c = tolower(*p); *p = '\0'; i = atoi(np); if (c == 's') t += i; else if (c == 'm') t += 60 * i; else if (c == 'h') t += 60 * 60 * i; else if (c == 'd') t += 24 * 60 * 60 * i; np = p + 1; } p++; } if (*np) t += atoi(np); hfree(s); return t; } /* * Parse an interval configuration entry */ int do_interval(int *dest, int argc, char **argv) { if (argc < 2) return -1; *dest = parse_interval(argv[1]); return 0; } /* * Parse the skip_type configuration entry */ int do_skip_type(int *dest, int argc, char **argv) { int i; if (argc < 2) return -1; i = atoi(argv[1]); if (i > 0 && i <= MAX_AIS_PACKET_TYPE) { skip_type[i] = 1; } else { hlog(LOG_CRIT, "skip_type value out of range: %d", i); return -1; } return 0; } /* * Parse the soundchannels configuration entry */ int do_sound_ch(int *dest, int argc, char **argv) { if (argc < 2) return -1; if (strcasecmp(argv[1], "mono") == 0) { *dest = SOUND_CHANNELS_MONO; } else if (strcasecmp(argv[1], "both") == 0) { *dest = SOUND_CHANNELS_BOTH; } else if (strcasecmp(argv[1], "left") == 0) { *dest = SOUND_CHANNELS_LEFT; } else if (strcasecmp(argv[1], "right") == 0) { *dest = SOUND_CHANNELS_RIGHT; } else { hlog(LOG_CRIT, "SoundChannels value unknown: %s", argv[1]); return -1; } return 0; } /* * Parse a uplink definition directive * * uplink