diff options
46 files changed, 10609 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1369c23 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +Debug/ +CppUnitTest/ +doc/html +doc/latex +doc/doxygen.log +.settings +*.xml +*.o +*.d +libmts_io.a +libmts_io.so* @@ -0,0 +1,2 @@ +Sean Godinez <sgodinez@multitech.com> +Jason Reiss <jreiss@multitech.com> @@ -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/Makefile b/Makefile new file mode 100644 index 0000000..a52c60b --- /dev/null +++ b/Makefile @@ -0,0 +1,78 @@ +include version + +includedir ?= /usr/include +libdir ?= /usr/lib + +OBJS += \ +MTS_IO_CdmaRadio.o \ +MTS_IO_CE910Radio.o \ +MTS_IO_CellularRadio.o \ +MTS_IO_CellularRadioFactory.o \ +MTS_IO_Connection.o \ +MTS_IO_DE910Radio.o \ +MTS_IO_GE910Radio.o \ +MTS_IO_HE910Radio.o \ +MTS_IO_HE910DRadio.o \ +MTS_IO_HE910EUDRadio.o \ +MTS_IO_LE910Radio.o \ +MTS_IO_LE910NAGRadio.o \ +MTS_IO_LE910SVGRadio.o \ +MTS_IO_LE910EUGRadio.o \ +MTS_IO_LockFile.o \ +MTS_IO_MccMncTable.o \ +MTS_IO_SerialConnection.o + +CPP_DEPS += \ +MTS_IO_CdmaRadio.d \ +MTS_IO_CE910Radio.d \ +MTS_IO_CellularRadio.d \ +MTS_IO_CellularRadioFactory.d \ +MTS_IO_Connection.d \ +MTS_IO_DE910Radio.d \ +MTS_IO_GE910Radio.d \ +MTS_IO_HE910Radio.d \ +MTS_IO_HE910DRadio.d \ +MTS_IO_HE910EUDRadio.d \ +MTS_IO_LE910Radio.d \ +MTS_IO_LE910NAGRadio.d \ +MTS_IO_LE910SVGRadio.d \ +MTS_IO_LE910EUGRadio.d \ +MTS_IO_LockFile.d \ +MTS_IO_MccMncTable.d \ +MTS_IO_SerialConnection.d + +all: libmts_io.a libmts_io.so.0 + +libmts_io.a: $(OBJS) + @echo 'Building target: $@' + $(AR) -r libmts_io.a $(OBJS) + @echo 'Finished building target: $@' + @echo ' ' + +libmts_io.so.0: $(OBJS) + @echo 'Building target: $@' + $(CXX) -shared -Wl,-soname,$@ -o libmts_io.so.$(VERSION) $(OBJS) + @echo 'Finished building target: $@' + @echo ' ' + +%.o: src/%.cpp + @echo 'Building file: $<' + $(CXX) $(CFLAGS) -I=$(includedir)/jsoncpp -Iinclude -Wall -Werror -c -fPIC -fmessage-length=0 -std=c++0x -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" -o "$@" "$<" + @echo 'Finished building: $<' + @echo ' ' + +install: + mkdir -p $(DESTDIR)$(libdir) + mkdir -p $(DESTDIR)$(includedir)/mts + install -m 0644 libmts_io.a libmts_io.so.$(VERSION) $(DESTDIR)$(libdir)/ + ln -sf libmts_io.so.$(VERSION) $(DESTDIR)$(libdir)/libmts_io.so.0 + ln -sf libmts_io.so.0 $(DESTDIR)$(libdir)/libmts_io.so + install -m 0644 include/mts/* $(DESTDIR)$(includedir)/mts/ + +clean: + -$(RM) $(OBJS) $(CPP_DEPS) libmts_io.a libmts_io.so* + -@echo ' ' + +.PHONY: all clean dependents install +.SECONDARY: + diff --git a/doc/MTS_IO_Documentation.doxyfile b/doc/MTS_IO_Documentation.doxyfile new file mode 100644 index 0000000..59aca39 --- /dev/null +++ b/doc/MTS_IO_Documentation.doxyfile @@ -0,0 +1,1679 @@ +# Doxyfile 1.7.3 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project. +# +# All text after a hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" "). + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "MTS IO C++ Library Documentation " + +# 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 = 0.1 + +# Using the PROJECT_BRIEF tag one can provide an optional one line description for a project that appears at the top of each page and should give viewer a quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = "An IO Library" + +# With the PROJECT_LOGO tag one can specify an logo or icon that is +# included in the documentation. The maximum height of the logo should not +# exceed 55 pixels and the maximum width should not exceed 200 pixels. +# Doxygen will copy the logo to the output directory. + +PROJECT_LOGO = mts_logo.jpeg + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful if your file system +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also makes the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penalty. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespaces are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper type resolution of all parameters of a function it will reject a +# match between the prototype and the implementation of a member function even if there is only one candidate or it is obvious which candidate to choose by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen +# will still accept a match between prototype and implementation in such cases. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST = YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or macro consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and macros in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command <command> <input-file>, where <command> is the value of +# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_NO_PARAMDOC option can be enabled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = doxygen.log + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = resource ../include ../../mts/include + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh +# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py +# *.f90 *.f *.for *.vhd *.vhdl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command <filter> <input-file>, where <filter> +# is the value of the INPUT_FILTER tag, and <input-file> is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty or if +# non of the patterns match the file name, INPUT_FILTER is applied. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) +# and it is also possible to disable source filtering for a specific pattern +# using *.ext= (so without naming a filter). This option only has effect when +# FILTER_SOURCE_FILES is enabled. + +FILTER_SOURCE_PATTERNS = + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = NO + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters"> +# Qt Help Project / Custom Filters</a>. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes"> +# Qt Help Project / Filter Attributes</a>. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [0,1..20]) +# that doxygen will group on one line in the generated HTML documentation. +# Note that a value of 0 will completely suppress the enum values from appearing in the overview section. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = YES + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax +# (see http://www.mathjax.org) which uses client side Javascript for the +# rendering instead of using prerendered bitmaps. Use this if you do not +# have LaTeX installed or if you want to formulas look prettier in the HTML +# output. When enabled you also need to install MathJax separately and +# configure the path to it using the MATHJAX_RELPATH option. + +USE_MATHJAX = NO + +# When MathJax is enabled you need to specify the location relative to the +# HTML output directory using the MATHJAX_RELPATH option. The destination +# directory should contain the MathJax.js script. For instance, if the mathjax +# directory is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the mathjax.org site, so you can quickly see the result without installing +# MathJax, but it is strongly recommended to install a local copy of MathJax +# before deployment. + +MATHJAX_RELPATH = http://www.mathjax.org/mathjax + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvantages are that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = YES + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4 + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition that overrules the definition found in the source code. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all references to function-like macros +# that are alone on a line, have an all uppercase name, and do not end with a +# semicolon, because these will confuse the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option also works with HAVE_DOT disabled, but it is recommended to +# install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called Helvetica to the output +# directory and reference it in all dot files that doxygen generates. +# When you want a differently looking font you can specify the font name +# using DOT_FONTNAME. You need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = Helvetica + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will generate a graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, svg, gif or svg. +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MSCFILE_DIRS tag can be used to specify one or more directories that +# contain msc files that are included in the documentation (see the +# \mscfile command). + +MSCFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/doc/resource/MTS_IO_DoxygenMain.h b/doc/resource/MTS_IO_DoxygenMain.h new file mode 100755 index 0000000..83f9c7f --- /dev/null +++ b/doc/resource/MTS_IO_DoxygenMain.h @@ -0,0 +1,28 @@ +/*! + \file MTS_IO_DoxygenMain.h + \brief Header for MTS IO Library Code Documentation. + \date 2012-12-13 + \author Sean Godinez + + Details. + */ + +#ifndef MTS_IO_DOXYGENMAIN_H_ +#define MTS_IO_DOXYGENMAIN_H_ + + +/** @mainpage Welcome to the Multi-Tech Systems MTS IO Library Documentation Site +* +* @authors MTS Software Developers +* +* @section intro Introduction +* @todo Provide an introduction describing the MTS IO library, +* build configuration, and unit testing. +* +* @todo Document MTS IO Libraries +* +* <hr> +* Website: <A HREF="http://www.multitech.com"> Multi-Tech Systems </A> +*/ + +#endif /* MTR_DOXYGENMAIN_H_ */ diff --git a/doc/resource/mts_logo.jpeg b/doc/resource/mts_logo.jpeg Binary files differnew file mode 100644 index 0000000..3bae16d --- /dev/null +++ b/doc/resource/mts_logo.jpeg diff --git a/include/mts/MTS_IO_CE910Radio.h b/include/mts/MTS_IO_CE910Radio.h new file mode 100644 index 0000000..9719c7a --- /dev/null +++ b/include/mts/MTS_IO_CE910Radio.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_CE910Radio.h + \brief A brief description + \date Nov 5, 2014 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_CE910RADIO_H_ +#define MTS_IO_CE910RADIO_H_ + +#include <mts/MTS_IO_CdmaRadio.h> + +namespace MTS { + namespace IO { + + class CE910Radio : public CdmaRadio { + + public: + static const std::string MODEL_NAME; + + CE910Radio(const std::string& sPort); + virtual ~CE910Radio(){}; + + protected: + + private: + + }; + } +} + + + + +#endif /* MTS_IO_CE910RADIO_H_ */ diff --git a/include/mts/MTS_IO_CdmaRadio.h b/include/mts/MTS_IO_CdmaRadio.h new file mode 100644 index 0000000..146034b --- /dev/null +++ b/include/mts/MTS_IO_CdmaRadio.h @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_CdmaRadio.h + \brief A brief description + \date Nov 19, 2014 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_CDMARADIO_H_ +#define MTS_IO_CDMARADIO_H_ + +#include <mts/MTS_IO_CellularRadio.h> + +namespace MTS { + namespace IO { + + class CdmaRadio : public CellularRadio { + + public: + virtual ~CdmaRadio(); + + virtual CODE getHardware(std::string& sHardware); + virtual CODE getMdn(std::string& sMdn); + virtual CODE getImei(std::string& sImei); + virtual CODE getMeid(std::string& sMeid); + virtual CODE getMsid(std::string& sMsid); + virtual CODE getCarrier(std::string& sCarrier); + virtual CODE getNetwork(std::string& sNetwork); + virtual CODE getSimStatus(std::string& sSimStatus); + virtual CODE getIccid(std::string& sIccid); + virtual CODE getLac(std::string& sLac); + virtual CODE getService(std::string& sService); + + virtual CODE validateMsl(const Json::Value& jArgs); + virtual CODE setMdn(const Json::Value& jArgs); + virtual CODE setMsid(const Json::Value& jArgs); + + virtual CODE getMipProfile(Json::Value& jMipProfile); + virtual CODE setMipActiveProfile(const Json::Value& jArgs); + virtual CODE setMipNai(const Json::Value& jArgs); + virtual CODE setMipHomeIp(const Json::Value& jArgs); + virtual CODE setMipPrimaryHa(const Json::Value& jArgs); + virtual CODE setMipSecondaryHa(const Json::Value& jArgs); + virtual CODE setMipMnAaaSpi(const Json::Value& jArgs); + virtual CODE setMipMnHaSpi(const Json::Value& jArgs); + virtual CODE setMipRevTun(const Json::Value& jArgs); + virtual CODE setMipMnAaaSs(const Json::Value& jArgs); + virtual CODE setMipMnHaSs(const Json::Value& jArgs); + + virtual CODE updateDc(const Json::Value& jArgs, UpdateCb& stepCb); + virtual CODE updatePrl(const Json::Value& jArgs, UpdateCb& stepCb); + virtual CODE updateFumo(const Json::Value& jArgs, UpdateCb& stepCb); + virtual CODE resetHfa(const Json::Value& jArgs, UpdateCb& stepCb); + virtual CODE activate(const Json::Value& jArgs, UpdateCb& stepCb); + + virtual CODE getNetworkStatus(Json::Value& jData); + + protected: + CdmaRadio(const std::string& sName, const std::string& sRadioPort); + + std::string getMeidLastSix(); + + private: + std::string m_sCarrier; + }; + } +} + + + + +#endif /* MTS_IO_CDMARADIO_H_ */ diff --git a/include/mts/MTS_IO_CellularRadio.h b/include/mts/MTS_IO_CellularRadio.h new file mode 100644 index 0000000..b253c80 --- /dev/null +++ b/include/mts/MTS_IO_CellularRadio.h @@ -0,0 +1,433 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_CellularRadio.h + \brief A brief description + \date Nov 5, 2014 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_CELLULARRADIO_H_ +#define MTS_IO_CELLULARRADIO_H_ + +#include <mts/MTS_IO_SerialConnection.h> +#include <mts/MTS_NonCopyable.h> +#include <mts/MTS_AutoPtr.h> +#include <mts/MTS_Lock.h> +#include <mts/MTS_Stdint.h> +#include <json/json.h> +#include <string> +#include <vector> +#include <functional> + +namespace MTS { + namespace IO { + + class CellularRadio : NonCopyable { + + public: + static const std::string DEFAULT_RADIO_PORT; + static const std::string DEFAULT_RADIO_DIR; + + static const std::string VALUE_UNKNOWN; + static const std::string VALUE_UNAVAILABLE; + static const std::string VALUE_NOT_SUPPORTED; + + //Special Payload Characters + static const char ETX; //Ends socket connection + static const char DLE; //Escapes ETX and DLE within Payload + static const char CR; + static const char NL; + static const char CTRL_Z; + + static const std::string RSP_OK; + static const std::string RSP_ERROR; + + //Registration Values + enum REGISTRATION : uint8_t { + NOT_REGISTERED = 0, + REGISTERED = 1, + SEARCHING=2, + DENIED=3, + UNKNOWN=4, + ROAMING=5 + }; + + enum SERVICEDOMAIN : uint8_t { + NO_SERVICE = 0, + CS_ONLY = 1, + PS_ONLY = 2, + CSPS = 3 + }; + + enum ACTIVEBAND : uint8_t { + GSM_850 = 0, + GSM_900 = 1, + DCS_1800 = 2, + PCS_1900 = 3 + }; + + enum CODE : uint8_t { + SUCCESS = 0, + ERROR, + FAILURE, + NO_RESPONSE, + NOT_APPLICABLE, + INVALID_ARGS + }; + + enum SIMSTATUS : uint8_t { + READY = 0, + LOCKED, + BLOCKED, + NOT_INSERTED + }; + + static const std::string VALUE_NOT_REGISTERED; + static const std::string VALUE_REGISTERED; + static const std::string VALUE_SEARCHING; + static const std::string VALUE_DENIED; + static const std::string VALUE_ROAMING; + + //Static Data + static const std::string KEY_TYPE; //!< GSM or CDMA + static const std::string KEY_CODE; //!< Product Code : H5, H6, C2, EV3, G3 + static const std::string KEY_MODEL; //!< Model : HE910, CE910, DE910, GE910 + static const std::string KEY_MANUFACTURER; //!< Manufacturer: Telit + static const std::string KEY_HARDWARE; //!< Radio Hardware Version + static const std::string KEY_FIRMWARE; //!< Radio Firmware Version + static const std::string KEY_IMEI; //!< International Mobile Station Equipment Identity + static const std::string KEY_MEID; //!< Mobile Equipment Identifier + static const std::string KEY_IMSI; //!< International Mobile Subscriber Identity + static const std::string KEY_MSID; //!< Mobil Station ID (MSID) aka MIN aka MSIN aka Last few digits of IMSI + static const std::string KEY_MDN; //!< Mobile Directory Number : Actual phone number dialed to reach radio + static const std::string KEY_CARRIER; //!< Cellular Service Provider (Home Network) + static const std::string KEY_ICCID; //!< Integrated Circuit Card Identifier + static const std::string KEY_MSL; //!< Master Subsidy Lock + + + //Network Status Data + static const std::string KEY_ROAMING; //!< Indicates whether or not using Home Network + static const std::string KEY_DATETIME; //!< Date and Time from tower + static const std::string KEY_SERVICE; //!< Service Connection Type [GPRS, EGPRS, WCDMA, HSDPA, 1xRTT, EVDO] + static const std::string KEY_NETWORK; //!< Cellular Service Provider + static const std::string KEY_CID; //!< Cellular ID (Tower) in HEX + static const std::string KEY_LAC; //!< Location Area Code in HEX + static const std::string KEY_RAC; //!< Routing Area Code in HEX + static const std::string KEY_RSSI; //!< Received Signal Strength Indication + static const std::string KEY_RSSIDBM; //!< Received Signal Strength Indication in dBm + static const std::string KEY_MCC; //!< Mobile Country Code + static const std::string KEY_MNC; //!< Mobile Network (Operator) Code + static const std::string KEY_CHANNEL; //!< ARFCN or UARFCN Assigned Radio Channel + static const std::string KEY_TXPWR; //!< Transmit Power + static const std::string KEY_PSC; //!< Active Primary Synchronization Code (PSC) + static const std::string KEY_ECIO; //!< Active Ec/Io (chip energy per total wideband power in dBm) + static const std::string KEY_RSCP; //!< Active RSCP (Received Signal Code Power in dBm) + static const std::string KEY_DRX; //!< Discontinuous reception cycle length (ms) + static const std::string KEY_MM; //!< Mobility Management State + static const std::string KEY_RR; //!< Radio Resource State + static const std::string KEY_NOM; //!< Network Operator Mode + static const std::string KEY_ABND; //!< Active Band + static const std::string KEY_BLER; //!< Block Error Rate (percentage) + static const std::string KEY_SD; //!< Service Domain + static const std::string KEY_DEBUG; //!< Debug Information + + static const std::string KEY_MIP; //!< Mobile IP Information + static const std::string KEY_MIP_ID; //!< MIP Profile ID + static const std::string KEY_MIP_ENABLED; //!< MIP Profile Enabled/Disabled + static const std::string KEY_MIP_NAI; //!< Network Access Identifier + static const std::string KEY_MIP_HOMEADDRESS; //!< Home Address + static const std::string KEY_MIP_PRIMARYHA; //!< Primary Home Agent + static const std::string KEY_MIP_SECONDARYHA; //!< Secondary Home Agent + static const std::string KEY_MIP_MNAAASPI; //!< Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index + static const std::string KEY_MIP_MNHASPI; //!< Mobile Node Home Agent Security Server Parameter Index + static const std::string KEY_MIP_REVTUN; //!< Reverse Tunneling Enabled + static const std::string KEY_MIP_MNAAASS; //!< Mobile Node Authentication, Authorization, and Accounting Server Shared Secret + static const std::string KEY_MIP_MNHASS; //!< Mobile Node Home Agent Shared Secret + + + //Values - Type + static const std::string VALUE_TYPE_LTE; + static const std::string VALUE_TYPE_GSM; + static const std::string VALUE_TYPE_CDMA; + + //Values - Carrier + static const std::string VALUE_CARRIER_VERIZON; + static const std::string VALUE_CARRIER_AERIS; + static const std::string VALUE_CARRIER_SPRINT; + static const std::string VALUE_CARRIER_ATT; + static const std::string VALUE_CARRIER_TMOBILE; + + static const std::string VALUE_SD_NO_SERVICE; + static const std::string VALUE_SD_CS_ONLY; + static const std::string VALUE_SD_PS_ONLY; + static const std::string VALUE_SD_CSPS; + + static const std::string VALUE_ABND_GSM_850; + static const std::string VALUE_ABND_GSM_900; + static const std::string VALUE_ABND_DCS_1800; + static const std::string VALUE_ABND_PCS_1900; + + static const std::vector<std::string> DEFAULT_BAIL_STRINGS; + + typedef std::function<bool(const std::string&/*iterationData*/, const std::string&/*allData*/)> IsNeedMoreData; + typedef std::function<void(const Json::Value&)> UpdateCb; + + virtual ~CellularRadio(); + + virtual bool initialize(uint32_t iTimeoutMillis = 5000); + virtual bool resetRadio(uint32_t iTimeoutMillis = 5000); + virtual bool resetConnection(uint32_t iTimeoutMillis = 5000); + virtual void shutdown(); + + const std::string& getName() const; + + virtual CODE getModel(std::string& sModel); + static CODE convertModelToType(const std::string& sModel, std::string& sType); + static CODE convertModelToMtsShortCode(const std::string& sModel, std::string& sCode); + static CODE convertServiceDomainToString(SERVICEDOMAIN eSd, std::string& sSd); + static CODE convertActiveBandToString(ACTIVEBAND eBand, std::string& sBand); + + virtual CODE getFirmware(std::string& sFirmware); + virtual CODE getHardware(std::string& sHardware); + virtual CODE getManufacturer(std::string& sManufacturer); + virtual CODE getImei(std::string& sImei); + virtual CODE getMeid(std::string& sMeid); + virtual CODE getImsi(std::string& sImsi); + virtual CODE getSimStatus(std::string& sSimStatus); + virtual CODE getIccid(std::string& sIccid); + virtual CODE getService(std::string& sService); + virtual CODE getLac(std::string& sLac); + virtual CODE getMdn(std::string& sMdn); + virtual CODE getMsid(std::string& sMsid); + virtual CODE getType(std::string& sType); + virtual CODE getCarrier(std::string& sCarrier); + virtual CODE getNetwork(std::string& sNetwork); + virtual CODE getTower(std::string& sTower); + virtual CODE getTime(std::string& sDate, std::string& sTime, std::string& sTimeZone); + virtual CODE getRoaming(bool& bRoaming); + + virtual CODE getSignalStrength(int32_t& iRssi); + virtual CODE convertSignalStrengthTodBm(const int32_t& iRssi, int32_t& dBm); + virtual CODE convertdBmToSignalStrength(const int32_t& dBm, int32_t& iRssi); + + virtual CODE getRegistration(REGISTRATION& eRegistration); + virtual CODE convertRegistrationToString(REGISTRATION eRegistration, std::string& sRegistration); + + //! Gather details of the radio's Mobile IP Profile + /*! + \param Json::Value object that will be populated with MIP data + \return Returns result code of gathering MIP + */ + virtual CODE getMipProfile(Json::Value& jMipProfile); + + /* + * jArgs = { + * "msl" : "Master Subsidy Lock (Aeris, Sprint): STRING" + * } + */ + virtual CODE validateMsl(const Json::Value& jArgs); + + /* + * jArgs = { + * "mdn" : "Mobile Directory Number : STRING", + * "msl" : "[OPTIONAL] Master Subsidy Lock (Aeris, Sprint): STRING" + * } + */ + virtual CODE setMdn(const Json::Value& jArgs); + + /* + * jArgs = { + * "msid" : "Mobil Station ID (MSID) aka MIN aka MSIN : STRING", + * "msl" : "[OPTIONAL] Master Subsidy Lock (Aeris, Sprint): STRING" + * } + */ + virtual CODE setMsid(const Json::Value& jArgs); + + /* + * jArgs = { + * "activeProfile" : "Set active profile: STRING" + * } + */ + virtual CODE setMipActiveProfile(const Json::Value& jArgs); + + /* + * jArgs = { + * "nai" : "Network Access Identifier : STRING" + * } + */ + virtual CODE setMipNai(const Json::Value& jArgs); + + /* + * jArgs = { + * "homeIp" : "Home Address : STRING" + * } + */ + virtual CODE setMipHomeIp(const Json::Value& jArgs); + + /* + * jArgs = { + * "primaryHa" : "Primary Home Agent : STRING" + * } + */ + virtual CODE setMipPrimaryHa(const Json::Value& jArgs); + + /* + * jArgs = { + * "secondaryHa" : "Secondary Home Agent : STRING" + * } + */ + virtual CODE setMipSecondaryHa(const Json::Value& jArgs); + + /* + * jArgs = { + * "mnAaaSpi" : "Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index : STRING" + * } + */ + virtual CODE setMipMnAaaSpi(const Json::Value& jArgs); + + /* + * jArgs = { + * "mnHaSpi" : "Mobile Node Home Agent Security Server Parameter Index : STRING" + * } + */ + virtual CODE setMipMnHaSpi(const Json::Value& jArgs); + + /* + * jArgs = { + * "revTun" : "[DESCRIPTION] : STRING" + * } + */ + virtual CODE setMipRevTun(const Json::Value& jArgs); + + /* + * jArgs = { + * "mnAaaSs" : "Mobile Node Authentication, Authorization, and Accounting Server Shared Secret : STRING" + * } + */ + virtual CODE setMipMnAaaSs(const Json::Value& jArgs); + + /* + * jArgs = { + * "mnHaSs" : "Mobile Node Home Agent Shared Secret : STRING" + * } + */ + virtual CODE setMipMnHaSs(const Json::Value& jArgs); + + /* + * jArgs = null + */ + virtual CODE updateDc(const Json::Value& jArgs, UpdateCb& stepCb); + + /* + * jArgs = null + */ + virtual CODE updatePrl(const Json::Value& jArgs, UpdateCb& stepCb); + + /* + * jArgs = null + */ + virtual CODE updateFumo(const Json::Value& jArgs, UpdateCb& stepCb); + + /* + * jArgs = { + * "msl" : "Master Subsidy Lock (Sprint): STRING" + * } + */ + virtual CODE resetHfa(const Json::Value& jArgs, UpdateCb& stepCb); + + /* + * jArgs = { + * "mdn" : "Mobile Directory Number (Aeris): STRING" + * "msid" : "Mobile Station ID (Aeris): STRING" + * } + */ + virtual CODE activate(const Json::Value& jArgs, UpdateCb& stepCb); + + virtual CODE getEcho(bool& bEnabled); + virtual CODE setEcho(bool bEnabled = true); + + virtual CODE getStaticInformation(Json::Value& jData); + virtual CODE getNetworkStatus(Json::Value& jData); + + virtual CODE sendBasicCommand(const std::string& sCmd, int32_t timeoutMillis = 100, const char& ESC = CR); + + virtual std::string sendCommand(const std::string& sCmd, + const std::vector<std::string>& vBail = DEFAULT_BAIL_STRINGS, + int32_t timeoutMillis = 100, + const char& ESC = CR); + + + static std::string sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, + const std::string& sCmd, + const std::vector<std::string>& vBail = DEFAULT_BAIL_STRINGS, + int32_t timeoutMillis = 100, + const char& ESC = CR); + + virtual std::string sendCommand(const std::string& sCmd, + IsNeedMoreData& isNeedMoreData, + int32_t timeoutMillis = 100, + const char& ESC = CR); + + static std::string sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, + const std::string& sCmd, + IsNeedMoreData& isNeedMoreData, + int32_t timeoutMillis = 100, + const char& ESC = CR); + + static CODE test(MTS::AutoPtr<MTS::IO::Connection>& apIo, uint32_t timeoutSeconds = 30); + + static std::string extractModelFromResult(const std::string& sResult); + static std::string getCodeAsString(CODE code); + + protected: + + CellularRadio(const std::string& sName, const std::string& sRadioPort); + + virtual bool getCarrierFromFirmware(const std::string& sFirmware, std::string& sCarrier); + virtual bool getHardwareVersionFromFirmware(const std::string& sFirmware, std::string& sHardware); + + virtual void getCommonNetworkStats(Json::Value& jData); + + void initMipProfile(Json::Value& jData); + + bool splitAndAssign(const std::string& sLine, const std::string& sKey, Json::Value& jParent, const std::string& sJsonKey, Json::ValueType eType = Json::ValueType::stringValue); + + + + private: + std::string m_sName; + std::string m_sRadioPort; + std::string m_sFirmware; + std::string m_sCarrier; + MTS::AutoPtr<MTS::IO::Connection> m_apIo; + + bool m_bEchoEnabled; + bool m_bEnableEchoOnClose; + + }; + } +} + + + +#endif /* MTS_IO_CELLULARRADIO_H_ */ diff --git a/include/mts/MTS_IO_CellularRadioFactory.h b/include/mts/MTS_IO_CellularRadioFactory.h new file mode 100644 index 0000000..5fa44d7 --- /dev/null +++ b/include/mts/MTS_IO_CellularRadioFactory.h @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_CellularRadioFactory.h + \brief A brief description + \date Nov 5, 2014 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_CELLULARRADIOFACTORY_H_ +#define MTS_IO_CELLULARRADIOFACTORY_H_ + +#include <mts/MTS_IO_CellularRadio.h> +#include <string> +#include <map> + +namespace MTS { + namespace IO { + + class HE910Radio; + class GE910Radio; + class DE910Radio; + class CE910Radio; + class CellularRadioFactory { + + public: + + CellularRadioFactory(); + virtual ~CellularRadioFactory() {}; + + virtual CellularRadio* create(const std::string& sModel, const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); + + virtual CellularRadio* createHE910D(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createHE910EUD(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE910NAG(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE910SVG(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createLE910EUG(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createGE910(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createDE910(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); + virtual CellularRadio* createCE910(const std::string& sPort = CellularRadio::DEFAULT_RADIO_PORT); + + protected: + typedef MTS::IO::CellularRadio* (CellularRadioFactory::*CREATEFUNCPTR)(const std::string& sPort); + std::map< std::string, CREATEFUNCPTR > m_mCreationMap; + + virtual std::string identifyRadio(const std::string& sPort); + + private: + + + }; + } +} + + + +#endif /* MTS_IO_CELLULARRADIOFACTORY_H_ */ diff --git a/include/mts/MTS_IO_Connection.h b/include/mts/MTS_IO_Connection.h new file mode 100644 index 0000000..bd4b32f --- /dev/null +++ b/include/mts/MTS_IO_Connection.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_Connection.h + \brief A brief description + \date Jan 15, 2013 + \author sgodinez + + A more elaborate description +*/ + +#ifndef MTS_IO_CONNECTION_H_ +#define MTS_IO_CONNECTION_H_ + +#include <mts/MTS_AutoPtr.h> +#include <mts/MTS_Lock.h> +#include <mts/MTS_NonCopyable.h> +#include <string> + +namespace MTS { + + class Buffer; + + namespace IO { + class Connection : public MTS::NonCopyable { + + private: + static int32_t BLOCKING; + + public: + + virtual ~Connection(); + + const std::string& getName() const; + + bool open(const int32_t& timeoutMillis = 1000); + void close(); + bool isClosed() const; + + void setCloseable(bool bCloseable); + bool isCloseable() const; + + int read(char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis = BLOCKING); + int read(std::string& sBuffer, const uint32_t& iSize, int32_t& timeoutMillis = BLOCKING); + int read(Buffer& oBuffer, const uint32_t& iSize, int32_t& timeoutMillis = BLOCKING); + + int write(const char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis = BLOCKING); + int write(const std::string& sBuffer, const uint32_t& iSize, int32_t& timeoutMillis = BLOCKING); + int write(const Buffer& oBuffer, const uint32_t& iSize, int32_t& timeoutMillis = BLOCKING); + + + + protected: + explicit Connection(const std::string& sName); + + private: + const std::string m_sName; + bool m_bClosed; + bool m_bCloseable; + AutoPtr<Lock> m_apLock; + AutoPtr<Lock> m_apReadLock; + AutoPtr<Lock> m_apWriteLock; + + /*! Opens the connection + * \return true if the connection has been opened, false otherwise + */ + virtual bool doOpen(const int32_t& timeoutMillis) = 0; + + /*! Closes the connection + */ + virtual void doClose() = 0; + + /*! Perform read from connection + * \param pBuffer the buffer allocated for read bytes + * \param iSize the number of bytes to be read. the size allocated for pBuffer must be greater or equal to iSize + * \param timeoutMillis the amount of time to attempt to read iSize bytes. less than zero will block until iSize bytes has been read + * \return the number of bytes read. -1 for error + */ + virtual int doRead(char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis) = 0; + + /*! Perform write to connection + * \param pBuffer the buffer that contains the data to be written + * \param iSize the number of bytes to be written + * \param timeoutMillis the amount of time to attempt to write iSize bytes. less than zero will block until iSize bytes has been written + * \return the number of bytes written. -1 for error + */ + virtual int doWrite(const char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis) = 0; + + }; + } +} + + + +#endif /* MTS_IO_CONNECTION_H_ */ diff --git a/include/mts/MTS_IO_DE910Radio.h b/include/mts/MTS_IO_DE910Radio.h new file mode 100644 index 0000000..40dc132 --- /dev/null +++ b/include/mts/MTS_IO_DE910Radio.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_DE910Radio.h + \brief A brief description + \date Nov 5, 2014 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_DE910RADIO_H_ +#define MTS_IO_DE910RADIO_H_ + +#include <mts/MTS_IO_CdmaRadio.h> + +namespace MTS { + namespace IO { + + class DE910Radio : public CdmaRadio { + + public: + static const std::string MODEL_NAME; + + DE910Radio(const std::string& sPort); + virtual ~DE910Radio(){}; + + protected: + + private: + + }; + } +} + + + +#endif /* MTS_IO_DE910RADIO_H_ */ diff --git a/include/mts/MTS_IO_GE910Radio.h b/include/mts/MTS_IO_GE910Radio.h new file mode 100644 index 0000000..079765d --- /dev/null +++ b/include/mts/MTS_IO_GE910Radio.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_GE910Radio.h + \brief A brief description + \date Nov 5, 2014 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_GE910RADIO_H_ +#define MTS_IO_GE910RADIO_H_ + +#include <mts/MTS_IO_CellularRadio.h> + +namespace MTS { + namespace IO { + + class GE910Radio : public CellularRadio { + + public: + static const std::string MODEL_NAME; + + GE910Radio(const std::string& sPort); + virtual ~GE910Radio(){}; + + protected: + + private: + + + }; + } +} + + + + +#endif /* MTS_IO_GE910RADIO_H_ */ diff --git a/include/mts/MTS_IO_HE910DRadio.h b/include/mts/MTS_IO_HE910DRadio.h new file mode 100644 index 0000000..2fd648e --- /dev/null +++ b/include/mts/MTS_IO_HE910DRadio.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_HE910DRadio.h + \brief A brief description + \date Nov 6, 2014 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_HE910DRADIO_H_ +#define MTS_IO_HE910DRADIO_H_ + +#include <mts/MTS_IO_HE910Radio.h> + +namespace MTS { + namespace IO { + + class HE910DRadio : public HE910Radio { + + public: + static const std::string MODEL_NAME; + + HE910DRadio(const std::string& sPort); + virtual ~HE910DRadio(){}; + + protected: + + private: + + }; + } +} + + + + +#endif /* MTS_IO_HE910DRADIO_H_ */ diff --git a/include/mts/MTS_IO_HE910EUDRadio.h b/include/mts/MTS_IO_HE910EUDRadio.h new file mode 100644 index 0000000..96353f2 --- /dev/null +++ b/include/mts/MTS_IO_HE910EUDRadio.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_HE910EUDRadio.h + \brief A brief description + \date Nov 6, 2014 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_HE910EUDRADIO_H_ +#define MTS_IO_HE910EUDRADIO_H_ + + +#include <mts/MTS_IO_HE910Radio.h> + +namespace MTS { + namespace IO { + + class HE910EUDRadio : public HE910Radio { + + public: + static const std::string MODEL_NAME; + + HE910EUDRadio(const std::string& sPort); + virtual ~HE910EUDRadio(){}; + + protected: + + private: + + }; + } +} + + +#endif /* MTS_IO_HE910EUDRADIO_H_ */ diff --git a/include/mts/MTS_IO_HE910Radio.h b/include/mts/MTS_IO_HE910Radio.h new file mode 100644 index 0000000..ee8e1e7 --- /dev/null +++ b/include/mts/MTS_IO_HE910Radio.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_HE910Radio.h + \brief A brief description + \date Nov 5, 2014 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_HE910RADIO_H_ +#define MTS_IO_HE910RADIO_H_ + +#include <mts/MTS_IO_CellularRadio.h> + +namespace MTS { + namespace IO { + + class HE910Radio : public CellularRadio { + + public: + + virtual ~HE910Radio(){}; + + protected: + HE910Radio(const std::string& sHE910Model, const std::string& sPort); + private: + + }; + } +} + + +#endif /* MTS_IO_HE910RADIO_H_ */ diff --git a/include/mts/MTS_IO_LE910EUGRadio.h b/include/mts/MTS_IO_LE910EUGRadio.h new file mode 100644 index 0000000..d0607e2 --- /dev/null +++ b/include/mts/MTS_IO_LE910EUGRadio.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_LE910EUGRadio.h + \brief A brief description + \date Jan 19, 2015 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_LE910EUGRADIO_H_ +#define MTS_IO_LE910EUGRADIO_H_ + +#include <mts/MTS_IO_LE910Radio.h> + +namespace MTS { + namespace IO { + + class LE910EUGRadio : public LE910Radio { + + public: + static const std::string MODEL_NAME; + + LE910EUGRadio(const std::string& sPort); + virtual ~LE910EUGRadio(){}; + + protected: + + private: + + }; + } +} + +#endif /* MTS_IO_LE910EUGRADIO_H_ */ diff --git a/include/mts/MTS_IO_LE910NAGRadio.h b/include/mts/MTS_IO_LE910NAGRadio.h new file mode 100644 index 0000000..a05a311 --- /dev/null +++ b/include/mts/MTS_IO_LE910NAGRadio.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_LE910NAGRadio.h + \brief A brief description + \date Jan 19, 2015 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_LE910NAGRADIO_H_ +#define MTS_IO_LE910NAGRADIO_H_ + +#include <mts/MTS_IO_LE910Radio.h> + +namespace MTS { + namespace IO { + + class LE910NAGRadio : public LE910Radio { + + public: + static const std::string MODEL_NAME; + + LE910NAGRadio(const std::string& sPort); + virtual ~LE910NAGRadio(){}; + + virtual CODE getCarrier(std::string& sCarrier); + + protected: + + private: + + }; + } +} + +#endif /* MTS_IO_LE910NAGRADIO_H_ */ diff --git a/include/mts/MTS_IO_LE910Radio.h b/include/mts/MTS_IO_LE910Radio.h new file mode 100644 index 0000000..e2f4c12 --- /dev/null +++ b/include/mts/MTS_IO_LE910Radio.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_LE910Radio.h + \brief A brief description + \date Nov 5, 2014 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_LE910RADIO_H_ +#define MTS_IO_LE910RADIO_H_ + +#include <mts/MTS_IO_CellularRadio.h> + +namespace MTS { + namespace IO { + + class LE910Radio : public CellularRadio { + + public: + static const std::string MODEL_NAME; + + LE910Radio(const std::string& sLE910Model, const std::string& sPort); + virtual ~LE910Radio(){}; + + protected: + + private: + + + }; + } +} + + + + +#endif /* MTS_IO_LE910RADIO_H_ */ diff --git a/include/mts/MTS_IO_LE910SVGRadio.h b/include/mts/MTS_IO_LE910SVGRadio.h new file mode 100644 index 0000000..d92f877 --- /dev/null +++ b/include/mts/MTS_IO_LE910SVGRadio.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_LE910SVGRadio.h + \brief A brief description + \date Jan 19, 2015 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_LE910SVGRADIO_H_ +#define MTS_IO_LE910SVGRADIO_H_ + +#include <mts/MTS_IO_LE910Radio.h> + +namespace MTS { + namespace IO { + + class LE910SVGRadio : public LE910Radio { + + public: + static const std::string MODEL_NAME; + + LE910SVGRadio(const std::string& sPort); + virtual ~LE910SVGRadio(){}; + + virtual CODE getCarrier(std::string& sCarrier); + + protected: + + private: + + }; + } +} + +#endif /* MTS_IO_LE910SVGRADIO_H_ */ diff --git a/include/mts/MTS_IO_LockFile.h b/include/mts/MTS_IO_LockFile.h new file mode 100644 index 0000000..dcfb9ae --- /dev/null +++ b/include/mts/MTS_IO_LockFile.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_LockFile.h + \brief A brief description + \date Oct 8, 2014 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_LOCKFILE_H_ +#define MTS_IO_LOCKFILE_H_ + +#include <mts/MTS_NonCopyable.h> +#include <string> + +namespace MTS { + namespace IO { + + class LockFile : MTS::NonCopyable { + + public: + + LockFile(const std::string& sFilePath); + virtual ~LockFile(); + + bool lock(uint32_t tryMillis); + void unlock(); + bool isLocked(); + + protected: + + private: + std::string m_sFile; + int m_iLockFd; + }; + + } +} + +#endif /* MTS_IO_LOCKFILE_H_ */ diff --git a/include/mts/MTS_IO_MccMncTable.h b/include/mts/MTS_IO_MccMncTable.h new file mode 100644 index 0000000..7772258 --- /dev/null +++ b/include/mts/MTS_IO_MccMncTable.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_MccMncTable.h + \brief A brief description + \date Dec 11, 2014 + \author sgodinez + + A more elaborate description +*/ +#ifndef MTS_IO_MCCMNCTABLE_H_ +#define MTS_IO_MCCMNCTABLE_H_ + +#include <mts/MTS_AutoPtr.h> +#include <mts/MTS_Lock.h> +#include <json/json.h> +#include <map> +#include <string> + +namespace MTS { + namespace IO { + + class MccMncTable { + public: + static MccMncTable* getInstance(); + + Json::Value lookup(const std::string& sMcc, const std::string& sMnc); + + private: + static MccMncTable* m_pInstance; + static MTS::AutoPtr<MTS::Lock> m_apLock; + + std::map<uint32_t, std::map<uint32_t, std::string> > m_mTable; + + MccMncTable(); + void createTable(); + }; + + } +} + + + +#endif /* MTS_IO_MCCMNCTABLE_H_ */ diff --git a/include/mts/MTS_IO_SerialConnection.h b/include/mts/MTS_IO_SerialConnection.h new file mode 100644 index 0000000..b4bb61f --- /dev/null +++ b/include/mts/MTS_IO_SerialConnection.h @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_SerialConnection.h + \brief A brief description + \date Jan 15, 2013 + \author sgodinez + + A more elaborate description +*/ + +#ifndef MTS_IO_SERIALCONNECTION_H_ +#define MTS_IO_SERIALCONNECTION_H_ + +#include <mts/MTS_IO_Connection.h> +#include <mts/MTS_IO_LockFile.h> +#include <sys/ioctl.h> +#include <termios.h> + +namespace MTS { + namespace IO { + + class SerialConnection : public Connection { + + public: + + enum ETYPE { + RS232, + RS422, + RS485 + }; + + enum EPARITY { + OFF, + ODD, + EVEN + }; + + enum EDATABITS { + B5, + B6, + B7, + B8 + }; + + enum ESTOPBITS { + B1, + B2 + }; + + enum IOCTL { + LE = TIOCM_LE, + DTR = TIOCM_DTR, + RTS = TIOCM_RTS, + ST = TIOCM_ST, + SR = TIOCM_SR, + CTS = TIOCM_CTS, + CAR = TIOCM_CAR, + CD = TIOCM_CD, + RNG = TIOCM_RNG, + RI = TIOCM_RI, + DSR = TIOCM_DSR + }; + + enum FLOW_CONTROL { + NONE, + RTS_CTS + }; + + class Builder { + public: + Builder(const std::string& sPortName); + + Builder& type(const ETYPE& eType); + Builder& rs232(); + Builder& rs422(); + Builder& rs485(); + + Builder& parity(const EPARITY& eParity); + Builder& parityOff(); + Builder& parityOdd(); + Builder& parityEven(); + + Builder& dataBits(const EDATABITS& eDataLength); + Builder& fiveDataBits(); + Builder& sixDataBits(); + Builder& sevenDataBits(); + Builder& eightDataBits(); + + Builder& stopBits(const ESTOPBITS& eStopBits); + Builder& oneStopBit(); + Builder& twoStopBits(); + + Builder& useLockFile(bool enabled = true); + Builder& flowControl(const FLOW_CONTROL& eFlowControl); + Builder& baudRate(uint32_t iBaud); + + Builder& build(); + + const std::string& getPortName() const; + const uint32_t& getBaudRate() const; + ETYPE getType() const; + EPARITY getParity() const; + EDATABITS getDataBits() const; + ESTOPBITS getStopBits() const; + FLOW_CONTROL getFlowControl() const; + std::string getTypeAsString() const; + bool isUsingLockFile() const; + bool isBuilt() const; + + private: + std::string m_sPortName; + uint32_t m_iBaudRate; + ETYPE m_eType; + EPARITY m_eParity; + EDATABITS m_eDataBits; + ESTOPBITS m_eStopBits; + FLOW_CONTROL m_eFlowControl; + bool m_bLockFile; + bool m_bBuilt; + }; + + SerialConnection(const Builder& oBuilder); + virtual ~SerialConnection(); + + const std::string& getPortName() const; + uint32_t getBaudRate() const; + + void flush(); + void drain(); + protected: + virtual int getFileDescriptor(); + + private: + const std::string m_sPortName; + uint32_t m_iBaudRate; + ETYPE m_eType; + EPARITY m_eParity; + EDATABITS m_eDataBits; + ESTOPBITS m_eStopBits; + FLOW_CONTROL m_eFlowControl; + AutoPtr<LockFile> m_apLockFile; + + AutoPtr<Lock> m_apHandleLock; +#ifdef WIN32 + HANDLE m_iHandle; +#else + int m_iHandle; + termios m_stPrevOptions; +#endif + + virtual bool doOpen(const int32_t& timeoutMillis); + virtual void doClose(); + virtual int doRead(char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis); + virtual int doWrite(const char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis); + + void cleanup(); + }; + } +} + + +#endif /* MTS_IO_SERIALCONNECTION_H_ */ diff --git a/scripts/create-mcc-mnc-table.py b/scripts/create-mcc-mnc-table.py new file mode 100644 index 0000000..761454c --- /dev/null +++ b/scripts/create-mcc-mnc-table.py @@ -0,0 +1,106 @@ +#Generates MTS_IO_MccMncTable.cpp file by pulling latest MCC/MNC values +#from http://mcc-mnc.com + +#Original Source Idea: https://github.com/musalbas/mcc-mnc-table + + +import re +import urllib2 +import datetime + +print "/*!" +print " \\file MTS_IO_MccMncTable.cpp" +print " \\brief Auto-Generated MCC-MNC Lookup Table" +print " \\date " + str(datetime.date.today()) +print " \\author sgodinez" +print "" +print " An Auto-Generated MCC-MNC Lookup Table" +print "*/" +print "" +print "#include <mts/MTS_IO_MccMncTable.h>" +print "#include <mts/MTS_Logger.h>" +print "#include <mts/MTS_Text.h>" +print "" +print "using namespace MTS::IO;" +print "" +print "MTS::AutoPtr<MTS::Lock> MccMncTable::m_apLock(new MTS::Lock());" +print "MccMncTable* MccMncTable::m_pInstance = NULL;" +print "" +print "MccMncTable* MccMncTable::getInstance() {" +print " if(m_pInstance == NULL) {" +print " m_apLock->lock();" +print " if (m_pInstance == NULL) {" +print " m_pInstance = new MccMncTable();" +print " }" +print " m_apLock->unlock();" +print " }" +print " return m_pInstance;" +print "}" +print "" +print "MccMncTable::MccMncTable() {" +print " createTable();" +print "}" +print "" +print "Json::Value MccMncTable::lookup(const std::string& sMcc, const std::string& sMnc) {" +print " uint32_t iMcc, iMnc;" +print ' printTrace("[MCCMNC] MCCx[%s] MNCx[%s]", sMcc.c_str(), sMnc.c_str());' +print " if(!MTS::Text::parseHex(iMcc, sMcc)) { return Json::Value::null; }" +print " if(!MTS::Text::parseHex(iMnc, sMnc)) { return Json::Value::null; }" +print ' printTrace("[MCCMNC] MCC0X[%d] MNC0X[%d]", iMcc, iMnc);' +print " if (m_mTable.count(iMcc)) {" +print " if(m_mTable[iMcc].count(iMnc)) {" +print " std::vector<std::string> vJson = MTS::Text::split(m_mTable[iMcc][iMnc], ',');" +print " Json::Value j;" +print ' j["iso"] = vJson[0];' +print ' j["country"] = vJson[1];' +print ' j["code"] = vJson[2];' +print ' j["carrier"] = vJson[3];' +print " return j;" +print " }" +print " }" +print "" +print " return Json::Value::null;" +print "}" +print "" +print "void MccMncTable::createTable() {" +print " std::string sData;" + +td_re = re.compile('<td>([^<]*)</td>'*6) + +html = urllib2.urlopen('http://mcc-mnc.com/').read() + +tbody_start = False +for line in html.split('\n'): + if '<tbody>' in line: + tbody_start = True + elif '</tbody>' in line: + break + elif tbody_start: + td_search = td_re.search(line) + mcc = td_search.group(1).strip().replace(',','') + mnc = td_search.group(2).strip().replace(',','') + iso = td_search.group(3).strip().replace(',','') + countryCode = td_search.group(4).strip().replace(',','') + country = td_search.group(5).strip().replace(',','') + carrier = td_search.group(6).strip().replace(',','') + + if mnc != "n/a": + mcc_int = int(mcc, 16) + if len(mnc) == 2: + mnc_int = int(mnc + 'f', 16) + else: + mnc_int = int(mnc, 16) + print ' m_mTable[' + str(mcc_int) + '][' + str(mnc_int) + '] = "' + \ + iso + ',' + countryCode + ',' + country + ',' + carrier + '";' + else: + print " //MCC(" + mcc + ') MNC(N/A) ISO(' + iso + ') Country Code(' + countryCode + ') Country(' + country + ') Carrier(' + carrier + ')' + + + +print "}" +print "" + + + + + diff --git a/src/MTS_IO_CE910Radio.cpp b/src/MTS_IO_CE910Radio.cpp new file mode 100644 index 0000000..b60c648 --- /dev/null +++ b/src/MTS_IO_CE910Radio.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_CE910Radio.cpp + \brief A brief description + \date Nov 6, 2014 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_CE910Radio.h> + +using namespace MTS::IO; + +const std::string CE910Radio::MODEL_NAME("CE910"); + +CE910Radio::CE910Radio(const std::string& sPort) +: CdmaRadio(MODEL_NAME, sPort) +{ + +} + + diff --git a/src/MTS_IO_CdmaRadio.cpp b/src/MTS_IO_CdmaRadio.cpp new file mode 100644 index 0000000..66ce820 --- /dev/null +++ b/src/MTS_IO_CdmaRadio.cpp @@ -0,0 +1,1297 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_CdmaRadio.cpp + \brief A brief description + \date Nov 19, 2014 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_CdmaRadio.h> +#include <mts/MTS_Text.h> +#include <mts/MTS_Logger.h> +#include <mts/MTS_Thread.h> + +using namespace MTS::IO; + +CdmaRadio::CdmaRadio(const std::string& sName, const std::string& sPort) +: CellularRadio(sName, sPort) +{ + +} + +CdmaRadio::~CdmaRadio() { + +} + +CellularRadio::CODE CdmaRadio::getImei(std::string& sImei) { + printTrace("%s| Get IMEI", getName().c_str()); + return getMeid(sImei); +} + +CellularRadio::CODE CdmaRadio::getMeid(std::string& sMeid) { + printTrace("%s| Get MEID", getName().c_str()); + sMeid = VALUE_NOT_SUPPORTED; + std::string sCmd("AT#MEIDESN?"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t pos = sResult.find(RSP_OK); + if (pos == std::string::npos) { + printWarning("%s| Unable to get MEID from radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + size_t start = sResult.find("#MEIDESN:") + sizeof("#MEIDESN:"); + size_t stop = sResult.find(","); + + if(stop != std::string::npos && stop > start) { + sMeid = sResult.substr(start, stop - start); + } else { + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::getMsid(std::string& sMsid) { + printTrace("%s| Get MSID", getName().c_str()); + sMsid = VALUE_NOT_SUPPORTED; + std::string sCmd("AT$MSID?"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to get MSID from radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + size_t start = sResult.find("$MSID:") + sizeof("$MSID:"); + sMsid = MTS::Text::trim(sResult.substr(start, end-start)); + if(sMsid.size() == 0) { + printWarning("%s| MSID is empty", getName().c_str()); + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::getCarrier(std::string& sCarrier) { + if(m_sCarrier != "") { + sCarrier = m_sCarrier; + return SUCCESS; + } + + std::string sFirmware; + CODE code = getFirmware(sFirmware); + if(code != SUCCESS) { + return code; + } + + if(!getCarrierFromFirmware(sFirmware, sCarrier)) { + return FAILURE; + } + + m_sCarrier = sCarrier; + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::getNetwork(std::string& sNetwork) { + return getCarrier(sNetwork); +} + +CellularRadio::CODE CdmaRadio::getSimStatus(std::string& sSimStatus) { + printTrace("%s| Get SIM Status", getName().c_str()); + sSimStatus = VALUE_NOT_SUPPORTED; + return NOT_APPLICABLE; +} + +CellularRadio::CODE CdmaRadio::getIccid(std::string& sIccid) { + printTrace("%s| Get ICCID", getName().c_str()); + sIccid = VALUE_NOT_SUPPORTED; + return NOT_APPLICABLE; +} + +CellularRadio::CODE CdmaRadio::getLac(std::string& sLac) { + printTrace("%s| Get LAC", getName().c_str()); + sLac = VALUE_NOT_SUPPORTED; + return NOT_APPLICABLE; +} + +CellularRadio::CODE CdmaRadio::getService(std::string& sService) { + printTrace("%s| Get Service", getName().c_str()); + sService = VALUE_NOT_SUPPORTED; + std::string sCmd("AT+SERVICE?"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to get Service from radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + size_t start = sResult.find("+SERVICE:"); + if(start != std::string::npos) { + start += sizeof("+SERVICE:"); + std::string sPsnt = MTS::Text::trim(sResult.substr(start, end-start)); + int32_t iService; + sscanf(sPsnt.c_str(), "%d", &iService); + + switch(iService) { + case 0: sService = "No Service"; break; + case 1: sService = "1xRTT"; break; + case 2: sService = "EVDO"; break; //Release 0 + case 3: sService = "EVDO"; break; //Release A + case 4: sService = "GPRS"; break; + default: sService = VALUE_UNKNOWN; break; + } + + printDebug("%s| Service ID: [%d][%s]", getName().c_str(), iService, sService.c_str()); + } + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::getHardware(std::string& sHardware) { + printTrace("%s| Get Hardware", getName().c_str()); + sHardware = VALUE_NOT_SUPPORTED; + std::string sCmd("AT#HWREV"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t pos = sResult.find(RSP_OK); + if (pos == std::string::npos) { + printWarning("%s| Unable to get hardware from radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + sHardware = MTS::Text::trim(sResult.substr(0, pos)); + if(sHardware.size() == 0) { + printWarning("%s| Unable to get hardware from radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::getMdn(std::string& sMdn) { + printTrace("%s| Get MDN", getName().c_str()); + sMdn = VALUE_NOT_SUPPORTED; + std::string sCmd("AT+CNUM"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to get MDN from radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + size_t start = sResult.find("CNUM:"); + std::vector<std::string> vParts = MTS::Text::split(sResult.substr(start + sizeof("CNUM:"), end), ","); + if(vParts.size() == 3) { + sMdn = vParts[1]; + if(sMdn.size() == 0) { + printWarning("%s| MDN is empty. Device may need to be activated", getName().c_str(), sCmd.c_str()); + } + } else { + printWarning("%s| Unable to parse MDN from radio using command [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::validateMsl(const Json::Value& jArgs) { + printTrace("%s| Validate MSL", getName().c_str()); + + if(!jArgs["msl"].isString()) { + return INVALID_ARGS; + } + + std::string sCarrier; + getCarrier(sCarrier); + + if(sCarrier != "Aeris" && sCarrier != "Sprint") { + return NOT_APPLICABLE; + } + + std::string sMdn; + if(getMdn(sMdn) != SUCCESS) { + return FAILURE; + } + + Json::Value jMdn(Json::objectValue); + jMdn["mdn"] = sMdn; + jMdn["msl"] = jArgs["msl"]; + + return setMdn(jMdn); +} + +CellularRadio::CODE CdmaRadio::setMdn(const Json::Value& jArgs) { + printTrace("%s| Set MDN", getName().c_str()); + + if(!jArgs["mdn"].isString()) { + printError("%s| Arguments missing \"mdn\"", getName().c_str()); + return INVALID_ARGS; + } + + std::string sCarrier; + getCarrier(sCarrier); + + std::string sCmd("AT$MDN="); + if(sCarrier == "Sprint") { + + if(!jArgs["msl"].isString()) { + printError("%s| Arguments missing \"msl\"", getName().c_str()); + return INVALID_ARGS; + } + sCmd += jArgs["msl"].asString() + ","; + } else if(sCarrier == "Aeris") { + //AT$MDN=<Last Six Digits of HEX MEID>,<MDN> + sCmd += getMeidLastSix() + ","; + } + + //Strip spaces and hyphens + std::string sMdn = jArgs["mdn"].asString(); + sMdn = MTS::Text::strip(sMdn, '-'); + sMdn = MTS::Text::strip(sMdn, '('); + sMdn = MTS::Text::strip(sMdn, ')'); + sMdn = MTS::Text::strip(sMdn, ' '); + + + sCmd += sMdn; + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set MDN for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::setMsid(const Json::Value& jArgs) { + printTrace("%s| Set MSID", getName().c_str()); + if(!jArgs["msid"].isString()) { + printError("%s| Arguments missing \"msid\"", getName().c_str()); + return INVALID_ARGS; + } + + std::string sCarrier; + getCarrier(sCarrier); + + std::string sCmd("AT$MSID="); + if(sCarrier == "Sprint") { + if(!jArgs["msl"].isString()) { + printError("%s| Arguments missing \"msl\"", getName().c_str()); + return INVALID_ARGS; + } + sCmd += jArgs["msl"].asString() + ","; + } else if(sCarrier == "Aeris") { + //AT$MSID=<Last Six Digits of HEX MEID>,<MSID> + sCmd += getMeidLastSix() + ","; + } + + + sCmd += jArgs["msid"].asString(); + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set MSID for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::getMipProfile(Json::Value& jMipProfile) { + printTrace("%s| Get MIP Active Profile", getName().c_str()); + + initMipProfile(jMipProfile); + + std::string sCarrier; + getCarrier(sCarrier); + + if(sCarrier == "Aeris" || sCarrier == "Sprint") { + std::string sCmd("AT$QCMIPGETP"); + std::string sResult = MTS::Text::trim(sendCommand(sCmd)); + if (sResult.find(RSP_OK) == std::string::npos) { + printWarning("%s| Unable to get active MIP profile for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + std::vector<std::string> vLine = MTS::Text::split(sResult, "\r\n"); + + //ACTIVE MIP PROFILE + std::string sLine = vLine[0]; + std::vector<std::string> vParts = MTS::Text::split(sLine, ':', 2); + if(vParts.size() == 2 && vParts[0] == "Profile") { + if(vParts[1].find("Enabled") != std::string::npos) { + jMipProfile[KEY_MIP_ENABLED] = true; + } else { + jMipProfile[KEY_MIP_ENABLED] = false; + } + int32_t id; + sscanf(vParts[1].c_str(), "%d", &id); + jMipProfile[KEY_MIP_ID] = id; + + } else { + printWarning("%s| Unable to parse active MIP profile from line [%s]", getName().c_str(), sLine.c_str()); + } + + + splitAndAssign(vLine[1], "NAI", jMipProfile, KEY_MIP_NAI); + splitAndAssign(vLine[2], "Home Addr", jMipProfile, KEY_MIP_HOMEADDRESS); + splitAndAssign(vLine[3], "Primary HA", jMipProfile, KEY_MIP_PRIMARYHA); + splitAndAssign(vLine[4], "Secondary HA", jMipProfile, KEY_MIP_SECONDARYHA); + splitAndAssign(vLine[5], "MN-AAA SPI", jMipProfile, KEY_MIP_MNAAASPI); + splitAndAssign(vLine[6], "MN-HA SPI", jMipProfile, KEY_MIP_MNHASPI); + + //Reverse Tunneling + sLine = vLine[7]; + vParts = MTS::Text::split(sLine, ':', 2); + if(vParts.size() == 2 && vParts[0] == "Rev Tun") { + if(vParts[1] == "1") { + jMipProfile[KEY_MIP_REVTUN] = true; + } else { + jMipProfile[KEY_MIP_REVTUN] = false; + } + } else { + printWarning("%s| Unable to parse Reverse Tunneling from line [%s]", getName().c_str(), sLine.c_str()); + } + + //MN-AAA SS + sLine = vLine[8]; + vParts = MTS::Text::split(sLine, ':', 2); + if(vParts.size() == 2 && vParts[0] == "MN-AAA SS") { + if(vParts[1] == "Set") { + jMipProfile[KEY_MIP_MNAAASS] = true; + } else { + jMipProfile[KEY_MIP_MNAAASS] = false; + } + } else { + printWarning("%s| Unable to parse MN-AAA SS from line [%s]", getName().c_str(), sLine.c_str()); + } + + //MN-HA SS + sLine = vLine[9]; + vParts = MTS::Text::split(sLine, ':', 2); + if(vParts.size() == 2 && vParts[0] == "MN-HA SS") { + if(vParts[1] == "Set") { + jMipProfile[KEY_MIP_MNHASS] = true; + } else { + jMipProfile[KEY_MIP_MNHASS] = false; + } + } else { + printWarning("%s| Unable to parse MN-HA SS from line [%s]", getName().c_str(), sLine.c_str()); + } + } + + + return SUCCESS; +} + + +CellularRadio::CODE CdmaRadio::setMipActiveProfile(const Json::Value& jArgs) { + printTrace("%s| Set MIP Active Profile", getName().c_str()); + + if(!jArgs["activeProfile"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd("AT$QCMIPP="); + sCmd += jArgs["activeProfile"].asString(); + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set Active profile for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::setMipNai(const Json::Value& jArgs) { + printTrace("%s| Set MIP NAI", getName().c_str()); + + if(!jArgs["nai"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd("AT$QCMIPNAI="); + sCmd += jArgs["nai"].asString() + ",1"; + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set NAI for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::setMipHomeIp(const Json::Value& jArgs) { + printTrace("%s| Set MIP Home IP", getName().c_str()); + + if(!jArgs["homeIp"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd("AT$QCMIPHA="); + sCmd += jArgs["homeIp"].asString() + ",1"; + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set Home IP profile for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::setMipPrimaryHa(const Json::Value& jArgs) { + printTrace("%s| Set MIP Primary HA", getName().c_str()); + + if(!jArgs["primaryHa"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd("AT$QCMIPPHA="); + sCmd += jArgs["primaryHa"].asString() + ",1"; + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set Primary HA for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::setMipSecondaryHa(const Json::Value& jArgs) { + printTrace("%s| Set MIP Secondary HA", getName().c_str()); + + if(!jArgs["secondaryHa"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd("AT$QCMIPSHA="); + sCmd += jArgs["secondaryHa"].asString() + ",1"; + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set Secondary HA for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::setMipMnAaaSpi(const Json::Value& jArgs) { + printTrace("%s| Set MIP MN-AAA SPI", getName().c_str()); + + if(!jArgs["mnAaaSpi"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd("AT$QCMIPMASPI="); + sCmd += jArgs["mnAaaSpi"].asString() + ",1"; + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set MN-AAA SPI for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::setMipMnHaSpi(const Json::Value& jArgs) { + printTrace("%s| Set MIP MN-HA SPI", getName().c_str()); + + if(!jArgs["mnHaSpi"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd("AT$QCMIPMHSPI="); + sCmd += jArgs["mnHaSpi"].asString() + ",1"; + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set MN-HA SPI for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::setMipRevTun(const Json::Value& jArgs) { + printTrace("%s| Set MIP Rev Tun", getName().c_str()); + + if(!jArgs["revTun"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd("AT$QCMIPRT="); + sCmd += jArgs["revTun"].asString() + ",1"; + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set Rev Tun for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::setMipMnAaaSs(const Json::Value& jArgs) { + printTrace("%s| Set MIP MN-AAA SS", getName().c_str()); + + if(!jArgs["mnAaaSs"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd("AT$QCMIPMASS="); + sCmd += jArgs["mnAaaSs"].asString() + ",1"; + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set MN-AAA SS for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::setMipMnHaSs(const Json::Value& jArgs) { + printTrace("%s| Set MIP MN-HA SS", getName().c_str()); + + if(!jArgs["mnHaSs"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd("AT$QCMIPMHSS="); + sCmd += jArgs["mnHaSs"].asString() + ",1"; + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set MN-HA SS for radio using command [%s]", getName().c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CdmaRadio::updateDc(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| Update Device Configuration", getName().c_str()); + + std::string sCarrier; + getCarrier(sCarrier); + + if(sCarrier != "Sprint") { + return NOT_APPLICABLE; + } + + CellularRadio::CODE result = FAILURE; + std::size_t pos = 0; + std::size_t end = 0; + + IsNeedMoreData isNeedMoreData = [&stepCb, &result, &pos, &end, this](const std::string& iterationData, const std::string& allData)->bool { + + if(iterationData.empty()) { + //No new data + return true; + } + + end = allData.find(NL, pos); + printTrace("%s| Update DC Callback Started", this->getName().c_str()); + + while(end != std::string::npos) { + size_t next; + std::string sLine = MTS::Text::getLine(allData, pos, next); + + printTrace("%s| Line: [%s]", this->getName().c_str(), sLine.c_str()); + + if(sLine == "#906") { + // DC DM session started + if(stepCb) { + stepCb(Json::Value("DC Info: DM session started")); + } + } else if(sLine == "#918") { + // DC Done, success + result = SUCCESS; + if(stepCb) { + stepCb(Json::Value("DC Done: success")); + } + return false; + } else if(sLine == "#924") { + // DC Done, no profile + result = SUCCESS; + if(stepCb) { + stepCb(Json::Value("DC Done: no profile")); + } + return false; + } else if(sLine == "#911") { + // DC Error: credential error + result = ERROR; + if(stepCb) { + stepCb(Json::Value("DC Error: credential error")); + } + return false; + } else if(sLine == "#912") { + // DC Error: unreachable server + result = ERROR; + if(stepCb) { + stepCb(Json::Value("DC Error: unreachable server")); + } + return false; + } else if(sLine == "#913") { + // DC Error: network error + result = ERROR; + if(stepCb) { + stepCb(Json::Value("DC Error: network error")); + } + return false; + } else if(sLine == "#915") { + // DC Error: update fails with other reasons + result = ERROR; + if(stepCb) { + stepCb(Json::Value("DC Error: update fails with other reasons")); + } + return false; + }else if(sLine == RSP_ERROR) { + result = ERROR; + return false; + } + + //Set cursors for next iteration + if(next != std::string::npos) { + pos = next; + } + end = allData.find(NL, pos); + } + + printTrace("%s| Update DC Callback Finished", this->getName().c_str()); + return true; + }; + + sendCommand("AT+OMADM=2", isNeedMoreData, 5 * 60000); + return result; +} + +CellularRadio::CODE CdmaRadio::updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| Update Preferred Roaming List", getName().c_str()); + + std::string sCarrier; + getCarrier(sCarrier); + + if(sCarrier != "Sprint") { + return NOT_APPLICABLE; + } + + CellularRadio::CODE result = FAILURE; + std::size_t pos = 0; + std::size_t end = 0; + + IsNeedMoreData isNeedMoreData = [&stepCb, &result, &pos, &end, this](const std::string& iterationData, const std::string& allData)->bool { + + if(iterationData.empty()) { + //No new data + return true; + } + + end = allData.find(NL, pos); + printTrace("%s| Update PRL Callback Started", this->getName().c_str()); + + while(end != std::string::npos) { + size_t next; + std::string sLine = MTS::Text::getLine(allData, pos, next); + + printTrace("%s| Line: [%s]", this->getName().c_str(), sLine.c_str()); + + if(sLine == "#905") { + // PRL DM session started + if(stepCb) { + stepCb(Json::Value("PRL Info: DM session started")); + } + } else if(sLine == "#909") { + // PRL Done, success + result = SUCCESS; + if(stepCb) { + stepCb(Json::Value("PRL Done: success")); + } + return false; + } else if(sLine == "#910") { + // PRL Done, no PRL update + result = SUCCESS; + if(stepCb) { + stepCb(Json::Value("PRL Done: no PRL update")); + } + return false; + } else if(sLine == "#911") { + // PRL Error: credential error + result = ERROR; + if(stepCb) { + stepCb(Json::Value("PRL Error: credential error")); + } + return false; + } else if(sLine == "#912") { + // PRL Error: unreachable server + result = ERROR; + if(stepCb) { + stepCb(Json::Value("PRL Error: unreachable server")); + } + return false; + } else if(sLine == "#913") { + // PRL Error: network error + result = ERROR; + if(stepCb) { + stepCb(Json::Value("PRL Error: network error")); + } + return false; + } else if(sLine == "#915") { + // PRL Error: update fails with other reasons + result = ERROR; + if(stepCb) { + stepCb(Json::Value("PRL Error: update fails with other reasons")); + } + return false; + } else if(sLine == RSP_ERROR) { + result = ERROR; + return false; + } + + //Set cursors for next iteration + if(next != std::string::npos) { + pos = next; + } + end = allData.find(NL, pos); + } + + printTrace("%s| Update PRL Callback Finished", this->getName().c_str()); + return true; + }; + + sendCommand("AT+PRL=2", isNeedMoreData, 5 * 60000); + return result; +} + +CellularRadio::CODE CdmaRadio::updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| Update Firmware Update Management Object", getName().c_str()); + + std::string sCarrier; + getCarrier(sCarrier); + + if(sCarrier != "Sprint") { + return NOT_APPLICABLE; + } + + CellularRadio::CODE result = FAILURE; + std::size_t pos = 0; + std::size_t end = 0; + + IsNeedMoreData isNeedMoreData = [&stepCb, &result, &pos, &end, this](const std::string& iterationData, const std::string& allData)->bool { + + if(iterationData.empty()) { + //No new data + return true; + } + + end = allData.find(NL, pos); + printTrace("%s| Update FUMO Callback Started", this->getName().c_str()); + + while(end != std::string::npos) { + size_t next; + std::string sLine = MTS::Text::getLine(allData, pos, next); + + printTrace("%s| Line: [%s]", this->getName().c_str(), sLine.c_str()); + + if(sLine == "#907") { + // FUMO DM session started + if(stepCb) { + stepCb(Json::Value("FUMO Info: DM session started")); + } + } else if(sLine == "#916") { + // FUMO Done, no firmware update + result = SUCCESS; + if(stepCb) { + stepCb(Json::Value("FUMO Done: no firmware update")); + } + return false; + } else if(sLine == "#911") { + // FUMO Error: credential error + result = ERROR; + if(stepCb) { + stepCb(Json::Value("FUMO Error: credential error")); + } + return false; + } else if(sLine == "#912") { + // FUMO Error: unreachable server + result = ERROR; + if(stepCb) { + stepCb(Json::Value("FUMO Error: unreachable server")); + } + return false; + } else if(sLine == "#913") { + // FUMO Error: network error + result = ERROR; + if(stepCb) { + stepCb(Json::Value("FUMO Error: network error")); + } + return false; + } else if(sLine == "#915") { + // FUMO Error: update fails with other reasons + result = ERROR; + if(stepCb) { + stepCb(Json::Value("FUMO Error: update fails with other reasons")); + } + return false; + } else if(sLine == "#919") { + // FUMO Firmware downloaded successfully + if(stepCb) { + stepCb(Json::Value("FUMO Info: firmware downloaded successfully")); + } + } else if(sLine == "#920:") { + // FUMO Firmware download progress (percent) + if(stepCb) { + stepCb(Json::Value(std::string("FUMO Info: firmware download progress ") + allData.substr(pos + 5, end + 5 - pos))); + } + } else if(sLine == "#921:") { + // FUMO Firmware size get from the OMA-DM server (byte) + if(stepCb) { + stepCb(Json::Value(std::string("FUMO Info: firmware size get from the OMA-DM server ") + allData.substr(pos + 5, end + 5 - pos) + " byte")); + } + } else if(sLine == "#921") { /// Info: check after check "#921:" + // FUMO Firmware download start + if(stepCb) { + stepCb(Json::Value("FUMO Info: firmware downloaded successfully")); + } + } else if(sLine == "#929: 200") { + // FUMO Done, success + result = SUCCESS; + if(stepCb) { + stepCb(Json::Value("FUMO Done: update success")); + } + return false; + } else if(sLine == "#929: 402") { + // FUMO Error, firmware corrupted, CRC error + result = ERROR; + if(stepCb) { + stepCb(Json::Value("FUMO Error: firmware corrupted, CRC error")); + } + return false; + } else if(sLine == "#929: 403") { + // FUMO Error, firmware package mismatch + result = ERROR; + if(stepCb) { + stepCb(Json::Value("FUMO Error: firmware package mismatch")); + } + return false; + } else if(sLine == "#929: 404") { + // FUMO Error, firmware signature failed + result = ERROR; + if(stepCb) { + stepCb(Json::Value("FUMO Error: firmware signature failed")); + } + return false; + } else if(sLine == "#929: 406") { + // FUMO Error, firmware update authentication failed + result = ERROR; + if(stepCb) { + stepCb(Json::Value("FUMO Error: firmware update authentication failed")); + } + return false; + } else if(sLine == "#929: 410") { + // FUMO Error, firmware update general error + result = ERROR; + if(stepCb) { + stepCb(Json::Value("FUMO Error: firmware update general error")); + } + return false; + } else if(sLine == "#930") { + // FUMO Reporting of Firmware Update result to server + if(stepCb) { + stepCb(Json::Value("FUMO Info: reporting of firmware update result to server")); + } + } else if(sLine == RSP_ERROR) { + result = ERROR; + return false; + } + + //Set cursors for next iteration + if(next != std::string::npos) { + pos = next; + } + end = allData.find(NL, pos); + } + + printTrace("%s| Update FUMO Callback Finished", this->getName().c_str()); + return true; + }; + + sendCommand("AT+FUMO=2", isNeedMoreData, 30 * 60000); + return result; +} + +CellularRadio::CODE CdmaRadio::resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| HFA Reset (after device reboot HFA will occur)", getName().c_str()); + + std::string sCarrier; + getCarrier(sCarrier); + + if(sCarrier != "Sprint") { + return NOT_APPLICABLE; + } + + if(!jArgs["msl"].isString()) { + return INVALID_ARGS; + } + + CellularRadio::CODE result = FAILURE; + std::size_t pos = 0; + std::size_t end = 0; + + IsNeedMoreData isNeedMoreData = [&stepCb, &result, &pos, &end, this](const std::string& iterationData, const std::string& allData)->bool { + /* Expected Events: + * #900 - DM Client ready + * #904 - HFA Started + * #914 - HFA Done - HFA Success + * #905 - PRL - Session started + * #909 - PRL - Done - PRL success + * #907 - FUMO - Firmware DM session started or started again until no more updates are available + * #916 - FUMO - Firmware Done, No firmware update + */ + + + if(iterationData.empty()) { + //No new data + return true; + } + + end = allData.find(NL, pos); + printTrace("%s| HFA Reset Callback Started", this->getName().c_str()); + + while(end != std::string::npos) { + size_t next; + std::string sLine = MTS::Text::getLine(allData, pos, next); + + printTrace("%s| Line: [%s]", this->getName().c_str(), sLine.c_str()); + + if(sLine == "#900") { + if(stepCb) { + stepCb(Json::Value("RTN Info: DM Client Ready")); + } + } else if(sLine == "#904") { + if(stepCb) { + stepCb(Json::Value("RTN Info: HFA - Session Started")); + } + } else if(sLine == "#914") { + if(stepCb) { + stepCb(Json::Value("RTN Info: HFA - Session Completed Successfully")); + } + } else if(sLine == "#905") { + if(stepCb) { + stepCb(Json::Value("RTN Info: PRL - Session Started")); + } + } else if(sLine == "#909") { + if(stepCb) { + stepCb(Json::Value("RTN Info: PRL - Session Completed Successfully")); + } + } else if(sLine == "#907") { + if(stepCb) { + stepCb(Json::Value("RTN Info: Firmware DM - Session Started")); + } + } else if(sLine == "#916") { + // RTN Done, success + result = SUCCESS; + if(stepCb) { + stepCb(Json::Value("RTN Done: Firmware DM - Session Completed Successfully")); + } + return false; + } else if(sLine == RSP_ERROR) { + result = ERROR; + return false; + } else if(sLine == RSP_OK) { + //The Device will reboot now, so reset the connection + if(stepCb) { + stepCb(Json::Value("RTN Info: Resetting Radio")); + } + + //TODO: Investigate a better way of to handle + // recapturing the radio port after reset + + //Sleep for a few seconds while resetting + MTS::Thread::sleep(5000); + + //Try to reconnect to radio + if(!this->resetConnection(10000)) { + printError("%s| Unable to obtain radio after reset", this->getName().c_str()); + if(stepCb) { + stepCb(Json::Value("RTN Error: Unable to obtain radio after reset")); + } + result = ERROR; + return false; + } + } + + //Set cursors for next iteration + if(next != std::string::npos) { + pos = next; + } + end = allData.find(NL, pos); + } + + printTrace("%s| HFA Reset Callback Finished", this->getName().c_str()); + return true; + }; + + std::string sCmd("AT#SPRTN=\""); + sCmd += jArgs["msl"].asString() + "\""; + sendCommand(sCmd, isNeedMoreData, 5 * 60000); + return result; +} + +CellularRadio::CODE CdmaRadio::activate(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| Activation", getName().c_str()); + + std::string sActivationCmd; + std::string sCarrier; + getCarrier(sCarrier); + + if(sCarrier == "Aeris") { + + if(!jArgs["msid"].isString()) { + printError("%s| Arguments missing \"msid\"", getName().c_str()); + return INVALID_ARGS; + } + + if(!jArgs["mdn"].isString()) { + printError("%s| Arguments missing \"mdn\"", getName().c_str()); + return INVALID_ARGS; + } + + std::string sMsid = jArgs["msid"].asString(); + std::string sMdn = jArgs["mdn"].asString(); + if(sMdn.size() != 10) { + printError("%s| MDN not valid. Expected length of 10: [%s][%d]", getName().c_str(), sMdn.c_str(), sMdn.size()); + return INVALID_ARGS; + } + + if(sMsid.size() != 10) { + printError("%s| MIN not valid. Expected length of 10: [%s][%d]", getName().c_str(), sMsid.c_str(), sMsid.size()); + return INVALID_ARGS; + } + + //Set MDN & MSID + CellularRadio::CODE code; + code = setMdn(jArgs); + if(code != SUCCESS) { + return code; + } + + code = setMsid(jArgs); + if(code != SUCCESS) { + return code; + } + + resetRadio(10000); + + return SUCCESS; + + } else if(sCarrier == "Verizon") { + sActivationCmd = "AT+CDV*22899\r"; + } else { + return NOT_APPLICABLE; + } + + CellularRadio::CODE result = FAILURE; + std::size_t pos = 0; + std::size_t end = 0; + + IsNeedMoreData isNeedMoreData = [&stepCb, &result, &pos, &end, this](const std::string& iterationData, const std::string& allData)->bool { + //Verizon Activation + /* Expected Events: + * OK + * #OTASP: 0 //Start OTASP + * #OTASP: 1 //Start OTASP Commit + * #OTASP: 2 //End OTASP + * + * ERRORS: + * NO CARRIER //Account Plan Not Active + * #OTASP: 5 //Activation Failed + */ + + + if(iterationData.empty()) { + //No new data + return true; + } + + end = allData.find(NL, pos); + printTrace("%s| Activation Reset Callback Started", this->getName().c_str()); + + while(end != std::string::npos) { + size_t next; + std::string sLine = MTS::Text::getLine(allData, pos, next); + + printTrace("%s| Line: [%s]", this->getName().c_str(), sLine.c_str()); + + if(sLine == RSP_OK) { + if(stepCb) { + stepCb(Json::Value("Activation Info: Over-the-Air Programming in Process")); + } + } else if(sLine == "#OTASP: 0") { + if(stepCb) { + stepCb(Json::Value("Activation Info: Saving Radio Configurations")); + } + } else if(sLine == "#OTASP: 1") { + if(stepCb) { + stepCb(Json::Value("Activation Info: Restarting Radio")); + } + } else if(sLine == "#OTASP: 2") { + if(stepCb) { + stepCb(Json::Value("Activation Info: Activation Completed Successfully")); + } + //Sleep for a few seconds while radio resets + MTS::Thread::sleep(5000); + this->resetConnection(10000); + result = SUCCESS; + return false; + } else if(sLine == "#OTASP: 5") { + if(stepCb) { + stepCb(Json::Value("Activation Error: Activation Failed")); + } + return false; + } else if(sLine == "NO CARRIER") { + if(stepCb) { + stepCb(Json::Value("Activation Error: Account Plan May Not Be Active")); + } + result = ERROR; + return false; + } else if(sLine == RSP_ERROR) { + result = ERROR; + return false; + } + + //Set cursors for next iteration + if(next != std::string::npos) { + pos = next; + } + end = allData.find(NL, pos); + } + + printTrace("%s| Activation Callback Finished", this->getName().c_str()); + return true; + }; + + sendCommand(sActivationCmd, isNeedMoreData, 5 * 60000); + return result; +} + +CellularRadio::CODE CdmaRadio::getNetworkStatus(Json::Value& jData) { + printTrace("%s| Get Network Status", getName().c_str()); + + getCommonNetworkStats(jData); + + std::string sCarrier; + getCarrier(sCarrier); + + if(sCarrier == VALUE_CARRIER_SPRINT) { + Json::Value& jDebug = jData["debug"]; + std::string sCmd("AT$DEBUG?"); + std::string sResult = MTS::Text::trim(sendCommand(sCmd)); + if (sResult.find(RSP_OK) != std::string::npos) { + std::vector<std::string> vCategories = MTS::Text::split(sResult, "\r\n\r\n"); + for(size_t i = 0 ; i < vCategories.size(); i++) { + std::vector<std::string> vLine = MTS::Text::split(vCategories[i], "\r\n"); + if(vLine[0] == "1x Engineering") { + Json::Value& j1x = jDebug["1xrtt"]; + splitAndAssign(vLine[1], "State", j1x, "state"); + splitAndAssign(vLine[3], "Channel", j1x, "channel"); + splitAndAssign(vLine[4], "Band Class", j1x, "bandClass"); + splitAndAssign(vLine[5], "SID", j1x, "sid"); + splitAndAssign(vLine[6], "NID", j1x, "nid"); + splitAndAssign(vLine[7], "Base ID", j1x, "baseId"); + splitAndAssign(vLine[8], "PN", j1x, "pn"); + splitAndAssign(vLine[9], "P_rev", j1x, "pRev"); + splitAndAssign(vLine[10], "Lat", j1x, "lat"); + splitAndAssign(vLine[11], "Lon", j1x, "lon"); + splitAndAssign(vLine[12], "Rx Pwr", j1x, "rxPwr"); + splitAndAssign(vLine[13], "Rx Ec/Io", j1x, "rxEcIo"); + splitAndAssign(vLine[14], "Rx FER", j1x, "rxFer"); + splitAndAssign(vLine[15], "Tx Pwr", j1x, "txPwr"); + splitAndAssign(vLine[16], "Active Set", j1x, "activeSet"); + splitAndAssign(vLine[17], "Neighbor Set", j1x, "neighborSet"); + } else if(vLine[0] == "EVDO Engineering") { + Json::Value& jEvdo = jDebug["evdo"]; + splitAndAssign(vLine[1], "State", jEvdo, "state"); + splitAndAssign(vLine[2], "Mac Index", jEvdo, "macIndex"); + splitAndAssign(vLine[3], "Channel", jEvdo, "channel"); + splitAndAssign(vLine[4], "Color Code", jEvdo, "colorCode"); + splitAndAssign(vLine[5], "Sector ID", jEvdo, "sectorId"); + splitAndAssign(vLine[6], "PN", jEvdo, "pn"); + splitAndAssign(vLine[7], "Rx Pwr", jEvdo, "rxPwr"); + splitAndAssign(vLine[8], "Rx PER", jEvdo, "rxPer"); + splitAndAssign(vLine[9], "Pilot Energy", jEvdo, "pilotEnergy"); + splitAndAssign(vLine[10], "DRC", jEvdo, "drc"); + splitAndAssign(vLine[11], "SINR", jEvdo, "sinr"); + splitAndAssign(vLine[12], "AN-AAA", jEvdo, "anAaa"); + splitAndAssign(vLine[13], "IP Address", jEvdo, "ipAddress"); + } else if(vLine[0] == "Configuration") { + Json::Value& jConf = jDebug["configuration"]; + splitAndAssign(vLine[1], "Technology", jConf, "technology"); + splitAndAssign(vLine[2], "1x Diversity", jConf, "1xDiversity"); + splitAndAssign(vLine[3], "EVDO Diversity", jConf, "evdoDiversity"); + splitAndAssign(vLine[4], "QLIC", jConf, "qlic"); + splitAndAssign(vLine[5], "PRL", jConf, "prl"); + splitAndAssign(vLine[6], "Chipset", jConf, "chipset"); + splitAndAssign(vLine[7], "AMSS version", jConf, "amssVersion"); + splitAndAssign(vLine[8], "Device version", jConf, "deviceVersion"); + splitAndAssign(vLine[9], "Hardware version", jConf, "hardwareVersion"); + splitAndAssign(vLine[10], "Browser", jConf, "browser"); + splitAndAssign(vLine[11], "Multimedia Version", jConf, "multimediaVersion"); + } + } + + } else { + printDebug("%s| SPRINT Network Status command returned unexpected response: [%s][%s]", getName().c_str(), sCmd.c_str(), sResult.c_str()); + } + } + + + printTrace("%s| Network Status:\n%s\n", getName().c_str(), jData.toStyledString().c_str()); + + return SUCCESS; +} + +std::string CdmaRadio::getMeidLastSix() { + std::string sMeid; + if(getMeid(sMeid) != SUCCESS || sMeid.size() != 14) { + return ""; + } + return sMeid.substr(8); +} diff --git a/src/MTS_IO_CellularRadio.cpp b/src/MTS_IO_CellularRadio.cpp new file mode 100644 index 0000000..adea939 --- /dev/null +++ b/src/MTS_IO_CellularRadio.cpp @@ -0,0 +1,1522 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_CellularRadio.cpp + \brief A brief description + \date Nov 5, 2014 + \author sgodinez + + A more elaborate description +*/ + +/*! + \file MTS_CELL_CellularRadio.cpp + \brief A brief description + \date Nov 4, 2014 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_CellularRadio.h> +#include <mts/MTS_IO_MccMncTable.h> +#include <mts/MTS_Thread.h> +#include <mts/MTS_Timer.h> +#include <mts/MTS_Logger.h> +#include <mts/MTS_Text.h> +#include <map> +#include <cstring> +#include <sstream> +#include <sys/file.h> +#include <errno.h> +#include <unistd.h> + + +using namespace MTS::IO; + +const char CellularRadio::ETX = 0x03; //Ends socket connection +const char CellularRadio::DLE = 0x10; //Escapes ETX and DLE within Payload +const char CellularRadio::CR = 0x0D; +const char CellularRadio::NL = 0x0A; +const char CellularRadio::CTRL_Z = 0x1A; + +const std::string CellularRadio::RSP_ERROR("ERROR"); +const std::string CellularRadio::RSP_OK("OK"); + + +const std::string CellularRadio::DEFAULT_RADIO_PORT("/dev/modem_at1"); +const std::string CellularRadio::DEFAULT_RADIO_DIR("/var/run/radio/"); +const std::string CellularRadio::VALUE_UNKNOWN("Unknown"); +const std::string CellularRadio::VALUE_UNAVAILABLE("Unavailable"); +const std::string CellularRadio::VALUE_NOT_SUPPORTED("Not Supported"); + +const std::string CellularRadio::VALUE_NOT_REGISTERED("NOT REGISTERED"); +const std::string CellularRadio::VALUE_REGISTERED("REGISTERED"); +const std::string CellularRadio::VALUE_SEARCHING("SEARCHING"); +const std::string CellularRadio::VALUE_DENIED("DENIED"); +const std::string CellularRadio::VALUE_ROAMING("ROAMING"); + +//Static Data +const std::string CellularRadio::KEY_TYPE("type"); //!< GSM or CDMA +const std::string CellularRadio::KEY_CODE("code"); //!< Product Code : H5, H6, C2, EV3, G3 +const std::string CellularRadio::KEY_MODEL("model"); //!< Model : HE910, LE910, CE910, DE910, GE910 +const std::string CellularRadio::KEY_MANUFACTURER("manufacturer"); //!< Manufacturer: Telit +const std::string CellularRadio::KEY_HARDWARE("hardware"); //!< Radio Hardware Version +const std::string CellularRadio::KEY_FIRMWARE("firmware"); //!< Radio Firmware Version + +const std::string CellularRadio::KEY_CARRIER("carrier"); //!< Cellular Service Provider (Home Network) +const std::string CellularRadio::VALUE_CARRIER_VERIZON("Verizon"); +const std::string CellularRadio::VALUE_CARRIER_AERIS("Aeris"); +const std::string CellularRadio::VALUE_CARRIER_SPRINT("Sprint"); +const std::string CellularRadio::VALUE_CARRIER_ATT("AT&T"); +const std::string CellularRadio::VALUE_CARRIER_TMOBILE("T-Mobile"); + +const std::string CellularRadio::KEY_IMEI("imei"); //!< International Mobile Station Equipment Identity +const std::string CellularRadio::KEY_MEID("meid"); //!< Mobile Equipment Identifier +const std::string CellularRadio::KEY_IMSI("imsi"); //!< International Mobile Subscriber Identity +const std::string CellularRadio::KEY_MSID("msid"); //!< Mobil Station ID / Mobile Identification Number (MSID/MIN) (CDMA-Only) +const std::string CellularRadio::KEY_MDN("mdn"); //!< Mobile Directory Number : Actual phone number dialed to reach radio +const std::string CellularRadio::KEY_ICCID("iccid"); //!< Integrated Circuit Card Identifier +const std::string CellularRadio::KEY_MSL("msl"); //!< Master Subsidy Lock + +//Dynamic Data +const std::string CellularRadio::KEY_ROAMING("roaming"); //!< Indicates whether or not using Home Network +const std::string CellularRadio::KEY_DATETIME("datetime"); //!< Date and Time from tower +const std::string CellularRadio::KEY_SERVICE("service"); //!< Service Connection Type [GPRS, EGPRS, WCDMA, HSDPA, 1xRTT, EVDO] +const std::string CellularRadio::KEY_NETWORK("network"); //!< Cellular Service Provider +const std::string CellularRadio::KEY_CID("cid"); //!< Cellular ID (Tower) in HEX +const std::string CellularRadio::KEY_LAC("lac"); //!< Location Area Code in HEX +const std::string CellularRadio::KEY_RAC("rac"); //!< Routing Area Code in HEX +const std::string CellularRadio::KEY_RSSI("rssi"); //!< Signal Strength +const std::string CellularRadio::KEY_RSSIDBM("rssidBm"); //!< Signal Strength in dBm +const std::string CellularRadio::KEY_MCC("mcc"); //!< Country Code +const std::string CellularRadio::KEY_MNC("mnc"); //!< Operator Code +const std::string CellularRadio::KEY_CHANNEL("channel"); //!< ARFCN or UARFCN Assigned Radio Channel +const std::string CellularRadio::KEY_TXPWR("txpwr"); //!< Transmit Power +const std::string CellularRadio::KEY_PSC("psc"); //!< Active Primary Synchronization Code (PSC) +const std::string CellularRadio::KEY_ECIO("ecio"); //!< Active Ec/Io (chip energy per total wideband power in dBm) +const std::string CellularRadio::KEY_RSCP("rscp"); //!< Active RSCP (Received Signal Code Power in dBm) +const std::string CellularRadio::KEY_DRX("drx"); //!< Discontinuous reception cycle length (ms) +const std::string CellularRadio::KEY_MM("mm"); //!< Mobility Management State +const std::string CellularRadio::KEY_RR("rr"); //!< Radio Resource State +const std::string CellularRadio::KEY_NOM("nom"); //!< Network Operator Mode +const std::string CellularRadio::KEY_ABND("abnd"); //!< Active Band +const std::string CellularRadio::KEY_BLER("bler"); //!< Block Error Rate (percentage) +const std::string CellularRadio::KEY_SD("sd"); //!< Service Domain +const std::string CellularRadio::KEY_DEBUG("debug"); //!< Debug Information + +const std::string CellularRadio::KEY_MIP("mipProfile"); //!< Mobile IP Information +const std::string CellularRadio::KEY_MIP_ID("id"); //!< Mobile IP ID +const std::string CellularRadio::KEY_MIP_ENABLED("enabled"); //!< Mobile IP Enabled/Disabled +const std::string CellularRadio::KEY_MIP_NAI("nai"); //!< Network Access Identifier +const std::string CellularRadio::KEY_MIP_HOMEADDRESS("homeAddress"); //!< Home Address +const std::string CellularRadio::KEY_MIP_PRIMARYHA("primaryAddress"); //!< Primary Home Agent +const std::string CellularRadio::KEY_MIP_SECONDARYHA("secondaryAddress"); //!< Secondary Home Agent +const std::string CellularRadio::KEY_MIP_MNAAASPI("mnAaaSpi"); //!< Mobile Node Authentication, Authorization, and Accounting Server Security Parameter Index +const std::string CellularRadio::KEY_MIP_MNHASPI("mnHaSpi"); //!< Mobile Node Home Agent Security Server Parameter Index +const std::string CellularRadio::KEY_MIP_REVTUN("revTun"); //!< Reverse Tunneling Enabled +const std::string CellularRadio::KEY_MIP_MNAAASS("mnAaaSs"); //!< Mobile Node Authentication, Authorization, and Accounting Server Shared Secret +const std::string CellularRadio::KEY_MIP_MNHASS("mnHaSs"); //!< Mobile Node Home Agent Shared Secret + +const std::string CellularRadio::VALUE_TYPE_GSM("GSM"); +const std::string CellularRadio::VALUE_TYPE_LTE("LTE"); +const std::string CellularRadio::VALUE_TYPE_CDMA("CDMA"); + +const std::string CellularRadio::VALUE_SD_NO_SERVICE("NO SERVICE"); +const std::string CellularRadio::VALUE_SD_CS_ONLY("CS ONLY"); +const std::string CellularRadio::VALUE_SD_PS_ONLY("PS ONLY"); +const std::string CellularRadio::VALUE_SD_CSPS("CS+PS"); + +const std::string CellularRadio::VALUE_ABND_GSM_850("GSM 850"); +const std::string CellularRadio::VALUE_ABND_GSM_900("GSM 900"); +const std::string CellularRadio::VALUE_ABND_DCS_1800("DCS 1800"); +const std::string CellularRadio::VALUE_ABND_PCS_1900("PCS 1900"); + +const std::vector<std::string> CellularRadio::DEFAULT_BAIL_STRINGS = { CellularRadio::RSP_OK, CellularRadio::RSP_ERROR }; + +CellularRadio::CellularRadio(const std::string& sName, const std::string& sRadioPort) +: m_sName(sName) +, m_sRadioPort(sRadioPort) +, m_bEchoEnabled(false) +, m_bEnableEchoOnClose(false) +{ + m_apIo.reset(new MTS::IO::SerialConnection( + MTS::IO::SerialConnection::Builder(m_sRadioPort) + .baudRate(115200) + .useLockFile() + .build())); +} + + +CellularRadio::~CellularRadio() { + shutdown(); + m_apIo.reset(); +} + +bool CellularRadio::initialize(uint32_t iTimeoutMillis) { + if(!m_apIo->open(iTimeoutMillis)) { + printError("%s| Failed to open radio port [%s]", m_sName.c_str(), m_sRadioPort.c_str()); + return false; + } + + bool bEnabled; + CODE eCode = getEcho(bEnabled); + if(eCode == SUCCESS && bEnabled) { + printDebug("%s| Disabling 'echo'", m_sName.c_str()); + setEcho(false); + m_bEnableEchoOnClose = true; + } + + return true; +} + +bool CellularRadio::resetRadio(uint32_t iTimeoutMillis) { + + printInfo("%s| Rebooting radio", m_sName.c_str()); + if(sendBasicCommand("AT#REBOOT") == SUCCESS) { + if(iTimeoutMillis > 5000) { + MTS::Thread::sleep(5000); + iTimeoutMillis -= 5000; + } + return resetConnection(iTimeoutMillis); + } + + return false; +} + +bool CellularRadio::resetConnection(uint32_t iTimeoutMillis) { + //Close Current Connection + if(!m_apIo.isNull()) { + m_apIo->close(); + } + + m_apIo.reset(new MTS::IO::SerialConnection( + MTS::IO::SerialConnection::Builder(m_sRadioPort) + .baudRate(115200) + .useLockFile() + .build())); + + //Try to obtain the device port over the given period of time + MTS::Timer oTimer; + oTimer.start(); + uint64_t iCurrentTime = 0; + while(iCurrentTime < iTimeoutMillis) { + + if(!m_apIo->open(iTimeoutMillis - iCurrentTime)) { + printWarning("%s| Failed to re-open radio port [%s]", m_sName.c_str(), m_sRadioPort.c_str()); + } else { + printInfo("%s| Successfully re-opened radio port [%s]", m_sName.c_str(), m_sRadioPort.c_str()); + break; + } + + ::usleep(500000); //500 millis + iCurrentTime = oTimer.getMillis(); + } + oTimer.stop(); + return !m_apIo->isClosed(); +} + +void CellularRadio::shutdown() { + + if(!m_apIo.isNull()) { + if(m_bEnableEchoOnClose) { + printDebug("%s| Enabling 'echo'", m_sName.c_str()); + setEcho(true); + m_bEnableEchoOnClose = false; + } + m_apIo->close(); + } +} + +const std::string& CellularRadio::getName() const { + return m_sName; +} + + +CellularRadio::CODE CellularRadio::getModel(std::string& sModel) { + printTrace("%s| Get Model", m_sName.c_str()); + //Always returns SUCCESS because the model should be m_sName + sModel = m_sName; + std::string sCmd("ATI4"); + std::string sResult = CellularRadio::sendCommand(m_apIo, sCmd); + if (sResult.find("OK") == std::string::npos) { + printWarning("%s| Unable to get model from radio. Returning [%s]", m_sName.c_str(), m_sName.c_str()); + return SUCCESS; + } else { + sModel = CellularRadio::extractModelFromResult(sResult); + if(sModel.size() == 0) { + printWarning("%s| Unable to get model from radio. Returning [%s]", m_sName.c_str(), m_sName.c_str()); + return SUCCESS; + } + } + + printDebug("%s| Extracted [%s] from [%s] query", m_sName.c_str(), sModel.c_str(), sCmd.c_str()); + if(sModel != m_sName) { + printWarning("%s| Model identified [%s] does not match expected [%s]. Returning [%s]", + m_sName.c_str(), sModel.c_str(), m_sName.c_str(), sModel.c_str()); + } + + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::convertModelToMtsShortCode(const std::string& sModel, std::string& sCode) { + CODE eCode = FAILURE; + + if(sModel.find("HE910-D") == 0) { + sCode = "H5"; + eCode = SUCCESS; + } else if (sModel.find("HE910-EUD") == 0) { + sCode = "H6"; + eCode = SUCCESS; + } else if (sModel.find("LE910-NAG") == 0) { + sCode = "LAT1"; + eCode = SUCCESS; + } else if (sModel.find("LE910-SVG") == 0) { + sCode = "VW2"; + eCode = SUCCESS; + } else if (sModel.find("LE910-EUG") == 0) { + sCode = "LEU1"; + eCode = SUCCESS; + } else if (sModel.find("GE910") == 0) { + sCode = "G3"; + eCode = SUCCESS; + } else if (sModel.find("CE910") == 0) { + sCode = "C2"; + eCode = SUCCESS; + } else if (sModel.find("DE910") == 0) { + sCode = "EV3"; + eCode = SUCCESS; + } else { + sCode = VALUE_NOT_SUPPORTED; + printError("RADIO| Could not identify MTS short code from model. [%s]", sModel.c_str()); + eCode = ERROR; + } + return eCode; +} + +CellularRadio::CODE CellularRadio::convertServiceDomainToString(SERVICEDOMAIN eSd, std::string& sSd) { + CODE eCode = FAILURE; + switch(eSd) { + case NO_SERVICE: sSd = VALUE_SD_NO_SERVICE; eCode = SUCCESS; break; + case CS_ONLY: sSd = VALUE_SD_CS_ONLY; eCode = SUCCESS; break; + case PS_ONLY: sSd = VALUE_SD_PS_ONLY; eCode = SUCCESS; break; + case CSPS: sSd = VALUE_SD_CSPS; eCode = SUCCESS; break; + default: sSd = VALUE_UNKNOWN; eCode = FAILURE; break; + } + return eCode; +} + +CellularRadio::CODE CellularRadio::convertActiveBandToString(ACTIVEBAND eBand, std::string& sBand) { + CODE eCode = FAILURE; + switch(eBand) { + case GSM_850: sBand = VALUE_ABND_GSM_850; eCode = SUCCESS; break; + case GSM_900: sBand = VALUE_ABND_GSM_900; eCode = SUCCESS; break; + case DCS_1800: sBand = VALUE_ABND_DCS_1800; eCode = SUCCESS; break; + case PCS_1900: sBand = VALUE_ABND_PCS_1900; eCode = SUCCESS; break; + default: sBand = VALUE_UNKNOWN; eCode = FAILURE; break; + } + return eCode; +} + +CellularRadio::CODE CellularRadio::convertModelToType(const std::string& sModel, std::string& sType) { + CODE eCode = FAILURE; + sType = VALUE_NOT_SUPPORTED; + + if(sModel.find("HE910-D") == 0) { + sType = VALUE_TYPE_GSM; + eCode = SUCCESS; + } else if (sModel.find("HE910-EUD") == 0) { + sType = VALUE_TYPE_GSM; + eCode = SUCCESS; + } else if (sModel.find("LE910-NAG") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("LE910-SVG") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("LE910-EUG") == 0) { + sType = VALUE_TYPE_LTE; + eCode = SUCCESS; + } else if (sModel.find("GE910") == 0) { + sType = VALUE_TYPE_GSM; + eCode = SUCCESS; + } else if (sModel.find("CE910") == 0) { + sType = VALUE_TYPE_CDMA; + eCode = SUCCESS; + } else if (sModel.find("DE910") == 0) { + sType = VALUE_TYPE_CDMA; + eCode = SUCCESS; + } else { + sType = VALUE_TYPE_GSM; + eCode = ERROR; + printError("RADIO| Could not identify type from model. [%s]. Assuming [%s]", sModel.c_str(), sType.c_str()); + } + return eCode; +} + +CellularRadio::CODE CellularRadio::getFirmware(std::string& sFirmware) { + printTrace("%s| Get Firmware", m_sName.c_str()); + sFirmware = VALUE_NOT_SUPPORTED; + std::string sCmd("AT+CGMR"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t pos = sResult.find(RSP_OK); + if (pos == std::string::npos) { + printWarning("%s| Unable to get firmware from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + sFirmware = MTS::Text::trim(sResult.substr(0, pos)); + if(sFirmware.size() == 0) { + printWarning("%s| Unable to get firmware from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + m_sFirmware = sFirmware; + + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::getHardware(std::string& sHardware) { + printTrace("%s| Get Hardware", m_sName.c_str()); + sHardware = VALUE_NOT_SUPPORTED; + + if(m_sFirmware.size() == 0) { + getFirmware(m_sFirmware); + } + + if(getHardwareVersionFromFirmware(m_sFirmware, sHardware)) { + return SUCCESS; + } + return FAILURE; +} + +CellularRadio::CODE CellularRadio::getManufacturer(std::string& sManufacturer) { + printTrace("%s| Get Manufacturer", m_sName.c_str()); + sManufacturer = VALUE_NOT_SUPPORTED; + std::string sCmd("AT+GMI"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t pos = sResult.find(RSP_OK); + if (pos == std::string::npos) { + printWarning("%s| Unable to get manufacturer from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + sManufacturer = MTS::Text::trim(sResult.substr(0, pos)); + if(sManufacturer.size() == 0) { + printWarning("%s| Unable to get manufacturer from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::getImei(std::string& sImei) { + printTrace("%s| Get IMEI", m_sName.c_str()); + sImei = VALUE_NOT_SUPPORTED; + std::string sCmd("AT+CGSN"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t pos = sResult.find(RSP_OK); + if (pos == std::string::npos) { + printWarning("%s| Unable to get IMEI from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + sImei = MTS::Text::trim(sResult.substr(0, pos)); + if(sImei.size() == 0) { + printWarning("%s| Unable to get IMEI from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::getMeid(std::string& sMeid) { + printTrace("%s| Get MEID", m_sName.c_str()); + return getImei(sMeid); +} + +CellularRadio::CODE CellularRadio::getImsi(std::string& sImsi) { + printTrace("%s| Get IMSI", m_sName.c_str()); + sImsi = VALUE_NOT_SUPPORTED; + std::string sCmd("AT+CIMI"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t pos = sResult.find(RSP_OK); + if (pos == std::string::npos) { + printWarning("%s| Unable to get IMSI from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + sImsi = MTS::Text::trim(sResult.substr(0, pos)); + if(sImsi.size() == 0) { + printWarning("%s| Unable to get IMSI from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::getSimStatus(std::string& sSimStatus) { + printTrace("%s| Get SIM Status", getName().c_str()); + sSimStatus = VALUE_UNKNOWN; + return FAILURE; +} + +CellularRadio::CODE CellularRadio::getIccid(std::string& sIccid) { + printTrace("%s| Get ICCID", m_sName.c_str()); + sIccid = VALUE_NOT_SUPPORTED; + std::string sCmd("AT#CCID"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to get ICCID from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + size_t start = sResult.find("#CCID:"); + if(start != std::string::npos) { + start += sizeof("#CCID:"); + sIccid = MTS::Text::trim(sResult.substr(start, end-start)); + if(sIccid.size() == 0) { + printWarning("%s| Unable to get ICCID from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + } + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::getService(std::string& sService) { + printTrace("%s| Get Service", m_sName.c_str()); + sService = VALUE_NOT_SUPPORTED; + std::string sCmd("AT#PSNT?"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to get Service from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + size_t start = sResult.find(","); + if(start != std::string::npos) { + start += 1; //comma + std::string sPsnt = MTS::Text::trim(sResult.substr(start, end-start)); + int32_t iService; + sscanf(sPsnt.c_str(), "%d", &iService); + + switch(iService) { + case 0: sService = "GPRS"; break; + case 1: sService = "EGPRS"; break; + case 2: sService = "WCDMA"; break; + case 3: sService = "HSDPA"; break; + default: sService = VALUE_UNKNOWN; break; + } + + printDebug("%s| Service ID: [%d][%s]", m_sName.c_str(), iService, sService.c_str()); + } + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::getLac(std::string& sLac) { + Json::Value jData; + + printTrace("%s| Get LAC", m_sName.c_str()); + sLac = VALUE_NOT_SUPPORTED; + + if(getNetworkStatus(jData) == SUCCESS) { + if(jData.isMember(KEY_LAC)) { + sLac = jData[KEY_LAC].asString(); + return SUCCESS; + } + } + + return FAILURE; +} + +CellularRadio::CODE CellularRadio::getMdn(std::string& sMdn) { + printTrace("%s| Get MDN", m_sName.c_str()); + sMdn = VALUE_NOT_SUPPORTED; + std::string sCmd("AT+CNUM"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to get MDN from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + size_t start = sResult.find("CNUM:"); + if(start != std::string::npos) { + start += sizeof("CNUM:"); + std::vector<std::string> vParts = MTS::Text::split(sResult.substr(start, end - start), ','); + if(vParts.size() != 3) { + printWarning("%s| Unable to parse MDN from response [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + sMdn = MTS::Text::strip(vParts[1], '"'); + if(sMdn.size() == 0) { + printWarning("%s| Unable to get MDN from radio using command [%s]. MDN may not be set.", m_sName.c_str(), sCmd.c_str()); + } + } else { + sMdn = ""; + printWarning("%s| Unable to get MDN from radio using command [%s]. MDN may not be set.", m_sName.c_str(), sCmd.c_str()); + } + + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::getMsid(std::string& sMsid) { + printTrace("%s| Get MSID", m_sName.c_str()); + sMsid = ""; + + std::string sImsi; + if(getImsi(sImsi) == SUCCESS) { + if(sImsi.size() >= 10) { + sMsid = sImsi.substr(sImsi.size() - 10); + printTrace("IMSI: [%s] MEID [%s]", sImsi.c_str(), sMsid.c_str()); + return SUCCESS; + } + } + printWarning("%s| Unable to get MSID from radio", m_sName.c_str()); + return FAILURE; +} + +CellularRadio::CODE CellularRadio::getType(std::string& sType) { + printTrace("%s| Get Type", m_sName.c_str()); + sType = VALUE_NOT_SUPPORTED; + return FAILURE; +} + +CellularRadio::CODE CellularRadio::getCarrier(std::string& sCarrier) { + printTrace("%s| Get Carrier", m_sName.c_str()); + if(m_sCarrier == "") { + Json::Value jData; + if(getNetworkStatus(jData) == SUCCESS) { + if(jData.isMember(KEY_MCC) && jData.isMember(KEY_MNC)) { + std::string sMcc = jData[KEY_MCC].asString(); + std::string sMnc = jData[KEY_MNC].asString(); + Json::Value jLookup = MccMncTable::getInstance()->lookup(sMcc, sMnc); + printTrace("%s| MCC-MNC Lookup: [%s][%s][%s]", m_sName.c_str(), + sMcc.c_str(), sMnc.c_str(), jLookup.toStyledString().c_str()); + if(jLookup.isMember(KEY_CARRIER)) { + m_sCarrier = jLookup[KEY_CARRIER].asString(); + } else { + printWarning("%s| MCC-MNC Lookup did not contain carrier", m_sName.c_str()); + return FAILURE; + } + } else { + printWarning("%s| Network Status did no contain MCC or MNC", m_sName.c_str()); + return FAILURE; + } + } else { + return FAILURE; + } + } + + sCarrier = m_sCarrier; + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::getTower(std::string& sTower) { + Json::Value jData; + + printTrace("%s| Get Tower", m_sName.c_str()); + sTower = VALUE_NOT_SUPPORTED; + + if(getNetworkStatus(jData) == SUCCESS) { + if(jData.isMember(KEY_CID)) { + sTower = jData[KEY_CID].asString(); + return SUCCESS; + } + } + return FAILURE; +} + +CellularRadio::CODE CellularRadio::getTime(std::string& sDate, std::string& sTime, std::string& sTimeZone) { + Json::Value jData; + + printTrace("%s| Get Time", m_sName.c_str()); + sDate = ""; + sTime = ""; + sTimeZone = ""; + + std::string sCmd("AT+CCLK?"); + std::string sResult = CellularRadio::sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to get Time from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + size_t start = sResult.find("CCLK: "); + if(start != std::string::npos) { + start += sizeof("CCLK: "); + std::string sValue = MTS::Text::trim(sResult.substr(start, end - start)); + sValue = MTS::Text::strip(sValue, '"'); + + std::vector<std::string> vParts = MTS::Text::split(sValue, ','); + if(vParts.size() != 2) { + printWarning("%s| Unable to parse Date from response [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + + + std::vector<std::string> vDateParts = MTS::Text::split(vParts[0], '/'); + if(vDateParts.size() != 3) { + printWarning("%s| Unable to parse Date from response [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + + //The Date format is YY/MM/DD -> Change to MM/DD/YY + sDate = vDateParts[1] + "/" + vDateParts[2] + "/" + vDateParts[0]; + + vParts = MTS::Text::split(vParts[1], '-'); + if(vParts.size() != 2) { + printWarning("%s| Unable to parse Time from response [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + sTime = vParts[0]; + + int32_t iZoneUnits; //the difference, expressed in quarters of an hour, between the local time and GMT + if(!MTS::Text::parse(iZoneUnits, MTS::Text::strip(vParts[1], '+'))) { + printWarning("%s| Unable to parse Time Zone from response [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + + int32_t iZone = iZoneUnits/4; //Divide by 4 to get hours difference + int32_t iZonePartial = (iZoneUnits % 4) * 15; //Remainder in minutes + std::string sPlusSign = "+"; + if(iZonePartial < 0) { + //Remove negative sign from partial and clear plus sign component + iZonePartial *= -1; + sPlusSign = ""; + } + std::stringstream ss; + ss << sPlusSign << iZone; + if(iZonePartial != 0) { + ss << ":" << iZonePartial; + } + + sTimeZone = ss.str(); + return SUCCESS; + + } else { + printWarning("%s| Unable to get Time from radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + } + + return FAILURE; +} + +CellularRadio::CODE CellularRadio::getRoaming(bool& bRoaming) { + Json::Value jData; + + printTrace("%s| Get Roaming", m_sName.c_str()); + bRoaming = false; + + REGISTRATION eReg; + if(getRegistration(eReg) == SUCCESS) { + bRoaming = (eReg == ROAMING); + return SUCCESS; + } + return FAILURE; +} + +CellularRadio::CODE CellularRadio::getNetwork(std::string& sNetwork) { + Json::Value jData; + + printTrace("%s| Get Network", m_sName.c_str()); + sNetwork = VALUE_NOT_SUPPORTED; + + if(getNetworkStatus(jData) == SUCCESS) { + if(jData.isMember(KEY_NETWORK)) { + sNetwork = jData[KEY_NETWORK].asString(); + return SUCCESS; + } + } + return FAILURE; +} + +CellularRadio::CODE CellularRadio::getSignalStrength(int32_t& rssi) { + printTrace("%s| Get Signal Strength", m_sName.c_str()); + std::string sCmd("AT+CSQ"); + std::string sResult = sendCommand(sCmd); + if (sResult.find("+CSQ: ") == std::string::npos) { + printDebug("%s| Signal Strength command returned unexpected response: [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + + size_t start = sResult.find(':'); + size_t stop = sResult.find(',', start); + if(start == std::string::npos || stop == std::string::npos) { + printDebug("%s| Signal Strength command returned malformed response: [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + std::string signal = sResult.substr(start + 2, stop - start - 2); + + sscanf(signal.c_str(), "%d", &rssi); + printDebug("%s| Signal Strength: [%d]", m_sName.c_str(), rssi); + + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::convertSignalStrengthTodBm(const int32_t& iRssi, int32_t& iDbm) { + + //Telit Conversion + if(iRssi < 0 || iRssi == 99) { + return FAILURE; + } + + if(iRssi == 0) { + iDbm = -113; + } else if(iRssi == 1) { + iDbm = -111; + } else if(iRssi <= 30) { + //28 steps between 2 and 30 + //54 dbm between 53 and 109 + float stepSize = 54.0 / 28.0; + iDbm = -109 + (int)(stepSize * (iRssi-2)); + } else { + iDbm = -51; + } + + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::convertdBmToSignalStrength(const int32_t& iDBm, int32_t& iRssi) { + //Telit Conversion + if(iDBm <= -113) { + iRssi = 0; + } else if(iDBm <= -111) { + iRssi = 1; + } else if(iDBm <= -53) { + //54 dbm between -109 and -53 + //28 steps between 2 and 30 + float stepSize = 28.0/54.0; + iRssi = ((iDBm + 109)*stepSize) + 2; + } else { + iRssi = 31; + } + + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::getEcho(bool& bEnabled) { + printTrace("%s| Echo Test", m_sName.c_str()); + std::string sResult = sendCommand("AT"); + if(sResult.size() == 0) { + return NO_RESPONSE; + } + + if(sResult.find("AT") != std::string::npos) { + bEnabled = true; + } else { + bEnabled = false; + } + m_bEchoEnabled = bEnabled; + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::setEcho(bool bEnabled) { + CODE eCode = FAILURE; + if(bEnabled) { + eCode = sendBasicCommand("ATE1"); + m_bEchoEnabled = (eCode == SUCCESS ) ? true : m_bEchoEnabled; + } else { + eCode = sendBasicCommand("ATE0"); + m_bEchoEnabled = (eCode == SUCCESS ) ? false : m_bEchoEnabled; + } + + return eCode; +} + +CellularRadio::CODE CellularRadio::getStaticInformation(Json::Value& jData) { + printTrace("%s| Get Static Information", m_sName.c_str()); + + printTrace("%s| Static Information:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); + + return FAILURE; +} + +/* AT#RFSTS - NETWORK STATUS + + (GSM network) + #RFSTS:<PLMN>,<ARFCN>,<RSSI>,<LAC>,<RAC>,<TXPWR>,<MM>,<RR>,<NOM>,<CID>,<IMSI>,<NetNameAsc>,<SD>,<ABND> + Where: + <PLMN> - Country code and operator code(MCC, MNC) + <ARFCN> - GSM Assigned Radio Channel + <RSSI> - Received Signal Strength Indication + <LAC> - Localization Area Code + <RAC> - Routing Area Code + <TXPWR> - Tx Power + <MM> - Mobility Management state + <RR> - Radio Resource state + <NOM> - Network Operator Mode + <CID> - Cell ID + <IMSI> - International Mobile Subscriber Identity + <NetNameAsc> - Operator name + <SD> - Service Domain + 0 - No Service + 1 - CS only + 2 - PS only + 3 - CS+PS + <ABND> - Active Band + 1 - GSM 850 + 2 - GSM 900 + 3 - DCS 1800 + 4 - PCS 1900 + + + (WCDMA network) + #RFSTS: + <PLMN>,<UARFCN>,<PSC>,<Ec/Io>,<RSCP>, RSSI>,<LAC>,<RAC>,<TXPWR>,<DRX>,<MM>,<RRC>,<NOM>,<BLER>,<CID>,<IMSI>, + <NetNameAsc>,<SD>,<nAST>[,<nUARFCN><nPSC>,<nEc/Io>] + Where: + <PLMN> - Country code and operator code(MCC, MNC) + <UARFCN> - UMTS Assigned Radio Channel + <PSC> - Active PSC(Primary Synchronization Code) + <Ec/Io> - Active Ec/Io(chip energy per total wideband power in dBm) + <RSCP> - Active RSCP (Received Signal Code Power in dBm) + <RSSI> - Received Signal Strength Indication + <LAC> - Localization Area Code + <RAC> - Routing Area Code + <TXPWR> - Tx Power + <DRX> - Discontinuous reception cycle Length (cycle length in ms) + <MM> - Mobility Management state + <RR> - Radio Resource state + <NOM> - Network Operator Mode + <BLER> - Block Error Rate (e.g., 005 means 0.5 %) + <CID> - Cell ID + <IMSI> - International Mobile Station ID + <NetNameAsc> - Operator name + <SD> - Service Domain (see above) + <nAST> - Number of Active Set (Maximum 6) + <nUARFCN> UARFCN of n th active set + <nPSC> PSC of n th active set + <nEc/Io > Ec/Io of n th active Set + + (LTE Network) + #RFSTS: + <PLMN> - + <EARFCN> - + <RSRP> - + <RSSI> - + <RSRQ> - + <TAC> - + [<TXPWR>] - + <DRX> - + <MM> - + <RRC> - + <CID> - + <IMSI> - + [<NetNameAsc>] - + <SD> - + <ABND> - +*/ +CellularRadio::CODE CellularRadio::getNetworkStatus(Json::Value& jData) { + int32_t iValue; + std::string sValue; + const uint32_t GSM_NETWORK_FORMAT = 14; + const uint32_t WCDMA_NETWORK_FORMAT = 19; + const uint32_t LTE_NETWORK_FORMAT = 16; + + printTrace("%s| Get Network Status", m_sName.c_str()); + std::string sCmd("AT#RFSTS"); + std::string sResult = sendCommand(sCmd); + if (sResult.find("#RFSTS:") == std::string::npos) { + printDebug("%s| Network Status command returned unexpected response: [%s][%s]", m_sName.c_str(), sCmd.c_str(), sResult.c_str()); + return FAILURE; + } + + size_t start = sResult.find(":") + 1; //Position right after "#RFSTS:" + std::vector<std::string> vParts = MTS::Text::split(MTS::Text::trim(sResult.substr(start)), ","); + + if(vParts.size() >= 3) { + //Country Code and Operator Code + std::vector<std::string> vPLMN = MTS::Text::split(vParts[0], ' '); + if(vPLMN.size() == 2) { + jData[KEY_MCC] = MTS::Text::strip(vPLMN[0], '"'); + jData[KEY_MNC] = MTS::Text::strip(vPLMN[1], '"'); + } + + jData[KEY_CHANNEL] = vParts[1]; + } else { + //Unknown Format + return FAILURE; + } + + if(vParts.size() == GSM_NETWORK_FORMAT ) { + //Parse as GSM Network Format + jData[KEY_RSSIDBM] = vParts[2]; + jData[KEY_LAC] = vParts[3]; + jData[KEY_RAC] = vParts[4]; + jData[KEY_TXPWR] = vParts[5]; + jData[KEY_MM] = vParts[6]; + jData[KEY_RR] = vParts[7]; + jData[KEY_NOM] = vParts[8]; + jData[KEY_CID] = vParts[9]; + jData[KEY_IMSI] = MTS::Text::strip(vParts[10], '"'); + jData[KEY_NETWORK] = MTS::Text::strip(vParts[11], '"'); + if(MTS::Text::parse(iValue, vParts[12]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) { + jData[KEY_SD] = sValue; + } + if(MTS::Text::parse(iValue, vParts[13]) && convertActiveBandToString((ACTIVEBAND)iValue, sValue) == SUCCESS) { + jData[KEY_ABND] = sValue; + } + } else if(vParts.size() >= WCDMA_NETWORK_FORMAT) { + Json::Value jDebug; + + //Parse as WCDMA Network Format + + jDebug[KEY_PSC] = vParts[2]; + jDebug[KEY_ECIO] = vParts[3]; + jDebug[KEY_RSCP] = vParts[4]; + + jData[KEY_RSSIDBM] = vParts[5]; + jData[KEY_LAC] = vParts[6]; + jData[KEY_RAC] = vParts[7]; + + jDebug[KEY_TXPWR] = vParts[8]; + jDebug[KEY_DRX] = vParts[9]; + jDebug[KEY_MM] = vParts[10]; + jDebug[KEY_RR] = vParts[11]; + jDebug[KEY_NOM] = vParts[12]; + + if(vParts[13].size() != 0) { + jDebug[KEY_BLER] = vParts[13]; + } else { + jDebug[KEY_BLER] = "000"; + } + + jData[KEY_CID] = vParts[14]; + jData[KEY_IMSI] = MTS::Text::strip(vParts[15], '"'); + jData[KEY_NETWORK] = MTS::Text::strip(vParts[16], '"'); + + if(MTS::Text::parse(iValue, vParts[17]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) { + jDebug[KEY_SD] = sValue; + } + //Ignoring Active Set Values + // <nAST> - Number of Active Set (Maximum 6) + // <nUARFCN> - UARFCN of n th active set + // <nPSC> - PSC of n th active set + // <nEc/Io > - Ec/Io of n th active Set + + jData[KEY_DEBUG] = jDebug; + } else if(vParts.size() >= LTE_NETWORK_FORMAT) { + Json::Value jDebug; + + //Parse as WCDMA Network Format + + jDebug["rsrp"] = vParts[2]; + jDebug[KEY_RSSIDBM] = vParts[3]; + jDebug["rsrq"] = vParts[4]; + + jData["tac"] = vParts[5]; + jDebug[KEY_TXPWR] = vParts[6]; + //Odd empty index at 7 + jData[KEY_DRX] = vParts[8]; + + jDebug[KEY_MM] = vParts[9]; + jDebug["rrc"] = vParts[10]; + jDebug[KEY_CID] = vParts[11]; + jData[KEY_IMSI] = MTS::Text::strip(vParts[12], '"'); + jData[KEY_NETWORK] = MTS::Text::strip(vParts[13], '"'); + + if(MTS::Text::parse(iValue, vParts[13]) && convertServiceDomainToString((SERVICEDOMAIN)iValue, sValue) == SUCCESS) { + jDebug[KEY_SD] = sValue; + } + //Ignoring Active Set Values + // <nAST> - Number of Active Set (Maximum 6) + // <nUARFCN> - UARFCN of n th active set + // <nPSC> - PSC of n th active set + // <nEc/Io > - Ec/Io of n th active Set + + jData[KEY_DEBUG] = jDebug; + } + + getCommonNetworkStats(jData); + + printTrace("%s| Network Status:\n%s\n", m_sName.c_str(), jData.toStyledString().c_str()); + + return SUCCESS; +} + +void CellularRadio::getCommonNetworkStats(Json::Value& jData) { + + bool bRoaming = false; + if(getRoaming(bRoaming) == SUCCESS) { + jData[KEY_ROAMING] = bRoaming; + } + + int32_t iRssi; + if(getSignalStrength(iRssi) == SUCCESS) { + jData[KEY_RSSI] = iRssi; + int32_t dBm; + if(!jData.isMember(KEY_RSSIDBM) && convertSignalStrengthTodBm(iRssi, dBm) == SUCCESS) { + //Add RSSI in dBm format + jData[KEY_RSSIDBM] = MTS::Text::format(dBm); + } + } + + std::string sService; + if(getService(sService) == SUCCESS) { + jData[KEY_SERVICE] = sService; + } + std::string sDate, sTime, sTimeZone; + if(getTime(sDate, sTime, sTimeZone) == SUCCESS) { + + jData[KEY_DATETIME] = sDate + " " + sTime + " GMT" + sTimeZone; + } +} + +void CellularRadio::initMipProfile(Json::Value& jData) { + jData[KEY_MIP_ID] = 0; + jData[KEY_MIP_ENABLED] = false; + jData[KEY_MIP_NAI] = VALUE_UNKNOWN; + jData[KEY_MIP_HOMEADDRESS] = VALUE_UNKNOWN; + jData[KEY_MIP_PRIMARYHA] = VALUE_UNKNOWN; + jData[KEY_MIP_SECONDARYHA] = VALUE_UNKNOWN; + jData[KEY_MIP_MNAAASPI] = VALUE_UNKNOWN; + jData[KEY_MIP_MNHASPI] = VALUE_UNKNOWN; + jData[KEY_MIP_MNAAASS] = false; + jData[KEY_MIP_MNHASS] = false; +} + +CellularRadio::CODE CellularRadio::getRegistration(REGISTRATION& eRegistration) { + std::string sCmd("AT+CREG?"); + std::string sResult = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, 5000); + if (sResult.find("+CREG: ") == std::string::npos) { + if(sResult.size() == 0) { + printDebug("%s| Registration command returned no response: [%s]", m_sName.c_str()); + return NO_RESPONSE; + } + printDebug("%s| Registration command returned unexpected response: [%s]", m_sName.c_str(), sResult.c_str()); + return FAILURE; + } + + size_t start = sResult.find(','); + size_t stop = sResult.find(' ', start); + std::string sRegStat = sResult.substr(start + 1, stop - start - 1); + int32_t value; + sscanf(sRegStat.c_str(), "%d", &value); + eRegistration = (REGISTRATION)value; + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::convertRegistrationToString(REGISTRATION eRegistration, std::string& sRegistration) { + + CODE eCode = FAILURE; + switch (eRegistration) { + case NOT_REGISTERED: sRegistration = VALUE_NOT_REGISTERED; eCode = SUCCESS; break; + case REGISTERED: sRegistration = VALUE_REGISTERED; eCode = SUCCESS; break; + case SEARCHING: sRegistration = VALUE_SEARCHING; eCode = SUCCESS; break; + case DENIED: sRegistration = VALUE_DENIED; eCode = SUCCESS; break; + case UNKNOWN: sRegistration = VALUE_UNKNOWN; eCode = SUCCESS; break; + case ROAMING: sRegistration = VALUE_ROAMING; eCode = SUCCESS; break; + } + return eCode; +} + +CellularRadio::CODE CellularRadio::validateMsl(const Json::Value& jArgs) { + printTrace("%s| Validate MSL", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMdn(const Json::Value& jArgs) { + printTrace("%s| Set MDN", m_sName.c_str()); + + if(!jArgs["mdn"].isString()) { + return INVALID_ARGS; + } + + std::string sCmd("AT#SNUM=1,\""); + sCmd += jArgs["mdn"].asString() + "\""; + + std::string sResult = sendCommand(sCmd); + size_t end = sResult.find(RSP_OK); + if (end == std::string::npos) { + printWarning("%s| Unable to set MDN for radio using command [%s]", m_sName.c_str(), sCmd.c_str()); + return FAILURE; + } + + return SUCCESS; +} + +CellularRadio::CODE CellularRadio::setMsid(const Json::Value& jArgs) { + printTrace("%s| Set MSID", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::getMipProfile(Json::Value& jMipProfile) { + printTrace("%s| Get MIP Active Profile", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipActiveProfile(const Json::Value& jArgs) { + printTrace("%s| Set MIP Active Profile", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipNai(const Json::Value& jArgs) { + printTrace("%s| Set MIP NAI", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipHomeIp(const Json::Value& jArgs) { + printTrace("%s| Set MIP Home IP", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipPrimaryHa(const Json::Value& jArgs) { + printTrace("%s| Set MIP Primary HA", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipSecondaryHa(const Json::Value& jArgs) { + printTrace("%s| Set MIP Secondary HA", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipMnAaaSpi(const Json::Value& jArgs) { + printTrace("%s| Set MIP MN-AAA SPI", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipMnHaSpi(const Json::Value& jArgs) { + printTrace("%s| Set MIP MN-HA SPI", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipRevTun(const Json::Value& jArgs) { + printTrace("%s| Set MIP Rev Tun", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipMnAaaSs(const Json::Value& jArgs) { + printTrace("%s| Set MIP MN-AAA SS", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::setMipMnHaSs(const Json::Value& jArgs) { + printTrace("%s| Set MIP MN-HA SS", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::updateDc(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| Update Device Configuration", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::updatePrl(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| Update Preferred Roaming List", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::updateFumo(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| Update Firmware Update Management Object", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::resetHfa(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| HFA Reset", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::activate(const Json::Value& jArgs, UpdateCb& stepCb) { + printTrace("%s| Activation", m_sName.c_str()); + + return NOT_APPLICABLE; +} + +CellularRadio::CODE CellularRadio::sendBasicCommand(const std::string& sCmd, int32_t iTimeoutMillis, const char& ESC) { + std::string response = sendCommand(sCmd, DEFAULT_BAIL_STRINGS, iTimeoutMillis, ESC); + if (response.size() == 0) { + return NO_RESPONSE; + } else if (response.find(RSP_OK) != std::string::npos) { + return SUCCESS; + } else if (response.find(RSP_ERROR) != std::string::npos) { + return ERROR; + } else { + return FAILURE; + } +} + +std::string CellularRadio::sendCommand(const std::string& sCmd, const std::vector<std::string>& vBail, int32_t timeoutMillis, const char& ESC) { + return sendCommand(m_apIo, sCmd, vBail, timeoutMillis, ESC); +} + +std::string CellularRadio::sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, const std::string& sCmd, + const std::vector<std::string>& vBail, int32_t timeoutMillis, const char& ESC) { + IsNeedMoreData isNeedMoreData = [&vBail](const std::string& iterationData, const std::string& allData)->bool { + for(size_t i = 0; i < vBail.size(); i++) { + const std::string& sBail = vBail[i]; + if(sBail.size() > 0) { + if(allData.find(sBail) != std::string::npos) { + //Return when bail string is found + printTrace("RADIO| Found bail string [%s]", sBail.c_str()); + return false; + } + } + } + return true; + }; + + return sendCommand(apIo, sCmd, isNeedMoreData, timeoutMillis, ESC); +} + +std::string CellularRadio::sendCommand(const std::string& sCmd, MTS::IO::CellularRadio::IsNeedMoreData& isNeedMoreData, int32_t timeoutMillis, const char& ESC) { + return sendCommand(m_apIo, sCmd, isNeedMoreData, timeoutMillis, ESC); +} + +std::string CellularRadio::sendCommand(MTS::AutoPtr<MTS::IO::Connection>& apIo, const std::string& sCmd, + IsNeedMoreData& isNeedMoreData, int32_t timeoutMillis, const char& ESC) { + if(MTS::Logger::getPrintLevel() >= MTS::Logger::PrintLevel::TRACE_LEVEL) { + printTrace("RADIO| Sending command [%s]", sCmd.c_str()); + } + if(apIo.isNull()) { + printError("RADIO| IO is not set in sendCommand"); + return ""; + } + + int32_t iResult; + if(ESC == 0x00) { + iResult = apIo->write(sCmd.data(), sCmd.size()); + } else { + std::string sNewCmd(sCmd); + sNewCmd.push_back(ESC); + iResult = apIo->write(sNewCmd.data(), sNewCmd.size()); + } + + if(iResult == -1) { + printError("RADIO| Failed to send command to radio"); + return ""; + } + + bool done = false; + const uint32_t capacity = 1024; + char buffer[capacity]; + std::string sResult; + Timer timer; + timer.start(); + do { + int32_t iterationTimeout = 100; + int bytesRead = apIo->read((char*)buffer, capacity, iterationTimeout); + if(bytesRead == -1) { + printError("RADIO| Failed to read from radio"); + break; + } + + std::string sIteration((char*)buffer, bytesRead); + sResult += sIteration; + + if(isNeedMoreData && !isNeedMoreData(sIteration, sResult)) { + printTrace("RADIO| No more data needed"); + return sResult; + } + if(timeoutMillis >= 0) { + done = (timer.getMillis() >= (uint64_t)timeoutMillis); + } else { + //Do not stop looping until bail string is found + } + } while(!done); + + //Timed out + return sResult; +} + +CellularRadio::CODE CellularRadio::test(MTS::AutoPtr<MTS::IO::Connection>& apIo, uint32_t timeoutSeconds) { + printTrace("RADIO| Basic Test"); + uint32_t count = 0; + std::string sCmd("AT"); + do { + std::string sResult = sendCommand(apIo, sCmd); + if (sResult.find(RSP_OK) == std::string::npos) { + printTrace("RADIO| Waiting for basic radio communication [%s] ...", sResult.c_str()); + } else { + break; + } + count++; + } while (count < timeoutSeconds); + + if(count == timeoutSeconds) { + printWarning("RADIO| Basic radio communication FAILED"); + return NO_RESPONSE; + } + return SUCCESS; +} + +std::string CellularRadio::extractModelFromResult(const std::string& sResult) { + std::string sModel(CellularRadio::VALUE_NOT_SUPPORTED); + if(sResult.find("HE910-D") != std::string::npos) { + sModel = "HE910-D"; + } else if(sResult.find("HE910-EUD") != std::string::npos) { + sModel = "HE910-EUD"; + } else if(sResult.find("LE910-NAG") != std::string::npos) { + sModel = "LE910-NAG"; + } else if(sResult.find("LE910-SVG") != std::string::npos) { + sModel = "LE910-SVG"; + } else if(sResult.find("LE910-EUG") != std::string::npos) { + sModel = "LE910-EUG"; + } else if(sResult.find("GE910") != std::string::npos) { + sModel = "GE910"; + } else if(sResult.find("DE910-DUAL") != std::string::npos) { + sModel = "DE910-DUAL"; + } else if(sResult.find("CE910") != std::string::npos) { + sModel = "CE910"; + } + return sModel; +} + +std::string CellularRadio::getCodeAsString(CODE eCode) { + switch(eCode) { + case SUCCESS: + return "SUCCESS"; + case ERROR: + return "ERROR"; + case FAILURE: + return "FAILURE"; + case NO_RESPONSE: + return "NO RESPONSE"; + default: + return "UNKNOWN"; + } +} + +bool CellularRadio::splitAndAssign(const std::string& sLine, const std::string& sKey, Json::Value& jParent, const std::string& sJsonKey, Json::ValueType eType) { + + std::vector<std::string> vParts = MTS::Text::split(sLine, ":", 2); + + if(vParts.size() == 2 && vParts[0] == sKey) { + if(eType == Json::ValueType::stringValue) { + jParent[sJsonKey] = MTS::Text::trim(vParts[1]); + } else if (eType == Json::ValueType::intValue || eType == Json::ValueType::uintValue) { + //TODO: + printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); + return false; + } else if(eType == Json::ValueType::realValue) { + //TODO: + printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); + return false; + } else if(eType == Json::ValueType::booleanValue) { + //TODO: + printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); + return false; + } else { + printWarning("%s| Unable to parse requested type from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); + return false; + } + } else { + printWarning("%s| Unable to parse %s from line [%s]", getName().c_str(), sKey.c_str(), sLine.c_str()); + return false; + } + + return true; +} + +bool CellularRadio::getCarrierFromFirmware(const std::string& sFirmware, std::string& sCarrier) { + // Telit Radios + // H.ab.zyx => 3 Main Components + // "H" = Hardware -> 15 = DE910 family, 18 = CE910 family, 12 = HE910 family + // "a" = Hardware version + // "b" = Software Major Version + // "z" = is the product type, i.e. DUAL or SC + // "y" = is the carrier variant + // "x" = is the firmware version + // Telit will do their best to keep the carrier variant as "0" for Sprint, "1" for Aeris, and "2" for Verizon. + + const uint32_t CARRIER_INDEX = 1; //y in [zyx] + + bool bResult = false; + std::vector<std::string> vParts = MTS::Text::split(sFirmware, '.'); + + if(vParts.size() == 3) { + //CDMA firmware version notation + if(vParts[0] == "15" || vParts[0] == "18") { + //DE910 or CE910 -> Good good + std::string sID = vParts[2]; + if(sID.size() == 3) { + char cId = sID[CARRIER_INDEX]; + + //Good good + if(cId == '0') { + sCarrier = VALUE_CARRIER_SPRINT; + bResult = true; + } + if(cId == '1') { + sCarrier = VALUE_CARRIER_AERIS; + bResult = true; + } + if(cId == '2') { + sCarrier = VALUE_CARRIER_VERIZON; + bResult = true; + } + } + } + } + + return bResult; +} + +bool CellularRadio::getHardwareVersionFromFirmware(const std::string& sFirmware, std::string& sHardware) { + // Telit Radios + // H.ab.zyx => 3 Main Components + // "H" = Hardware -> 15 = DE910 family, 18 = CE910 family, 12 = HE910 family + // "a" = Hardware version + // "b" = Software Major Version + // "z" = is the product type, i.e. DUAL or SC + // "y" = is the carrier variant + // "x" = is the firmware version + // Telit will do their best to keep the carrier variant as "0" for Sprint, "1" for Aeris, and "2" for Verizon. + + const uint32_t HARDWARE_INDEX = 0; //a in [ab] + + bool bResult = false; + std::vector<std::string> vParts = MTS::Text::split(sFirmware, '.'); + + if(vParts.size() == 3) { + //GSM Hardware Version + if(!(vParts[0] == "15" || vParts[0] == "18")) { + //Not DE910 or CE910 -> Good good + std::string sVersion = vParts[1]; + if(sVersion.size() == 2) { + sHardware = "1."; + sHardware += sVersion[HARDWARE_INDEX]; + bResult = true; + } + } + } + + return bResult; + +} diff --git a/src/MTS_IO_CellularRadioFactory.cpp b/src/MTS_IO_CellularRadioFactory.cpp new file mode 100644 index 0000000..3a5cb74 --- /dev/null +++ b/src/MTS_IO_CellularRadioFactory.cpp @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_CellularRadioFactory.cpp + \brief A brief description + \date Nov 5, 2014 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_CellularRadioFactory.h> +#include <mts/MTS_IO_HE910DRadio.h> +#include <mts/MTS_IO_HE910EUDRadio.h> +#include <mts/MTS_IO_LE910NAGRadio.h> +#include <mts/MTS_IO_LE910SVGRadio.h> +#include <mts/MTS_IO_LE910EUGRadio.h> +#include <mts/MTS_IO_GE910Radio.h> +#include <mts/MTS_IO_CE910Radio.h> +#include <mts/MTS_IO_DE910Radio.h> +#include <mts/MTS_Logger.h> + +using namespace MTS::IO; + +CellularRadioFactory::CellularRadioFactory() { + m_mCreationMap[HE910DRadio::MODEL_NAME] = &CellularRadioFactory::createHE910D; + m_mCreationMap[HE910EUDRadio::MODEL_NAME] = &CellularRadioFactory::createHE910EUD; + m_mCreationMap[LE910NAGRadio::MODEL_NAME] = &CellularRadioFactory::createLE910NAG; + m_mCreationMap[LE910SVGRadio::MODEL_NAME] = &CellularRadioFactory::createLE910SVG; + m_mCreationMap[LE910EUGRadio::MODEL_NAME] = &CellularRadioFactory::createLE910EUG; + m_mCreationMap[GE910Radio::MODEL_NAME] = &CellularRadioFactory::createGE910; + m_mCreationMap[DE910Radio::MODEL_NAME] = &CellularRadioFactory::createDE910; + m_mCreationMap[CE910Radio::MODEL_NAME] = &CellularRadioFactory::createCE910; +} + +MTS::IO::CellularRadio* CellularRadioFactory::create(const std::string& sModel, const std::string& sPort) { + + std::string model(sModel); + + if(model.size() == 0) { + model = identifyRadio(sPort); + } + + if(m_mCreationMap.count(model)) { + //Call this object's function via a function pointer + return (this->*m_mCreationMap[model])(sPort); + } + + printWarning("[CELLULARRADIOFACTORY] Unknown radio [%s]. Attempting HE910 version.", model.c_str()); + + return new HE910DRadio(sPort); +} + +std::string CellularRadioFactory::identifyRadio(const std::string& sPort) { + MTS::AutoPtr<Connection> apIo; + + //Attempt to open port to radio + apIo.reset(new SerialConnection(SerialConnection::Builder(sPort).baudRate(115200).useLockFile().build())); + while(!apIo->open(30000)) { + printError("CellularRadioFactory| Failed to open radio port [%s]", sPort.c_str()); + return CellularRadio::VALUE_UNKNOWN; + } + + //Attempt basic radio communication + if(CellularRadio::test(apIo) != CellularRadio::SUCCESS) { + printError("CellularRadioFactory| Failed to communicate with radio on port [%s]", sPort.c_str()); + apIo->close(); + return CellularRadio::VALUE_UNKNOWN; + } + + //Get model + int count = 0; + std::string sCmd("ATI4"); + std::string sResult; + do { + sResult = CellularRadio::sendCommand(apIo, sCmd, CellularRadio::DEFAULT_BAIL_STRINGS, 1000, CellularRadio::CR); + if (sResult.find("OK") == std::string::npos) { + printDebug("RADIO| Attempting to get radio model [%s] ...", sResult.c_str()); + } else { + break; + } + count++; + } while (count < 30); + + if(count == 30) { + printDebug("RADIO| Unable to get radio model"); + apIo->close(); + return CellularRadio::VALUE_UNKNOWN; + } + + std::string sModel = CellularRadio::extractModelFromResult(sResult); + printDebug("RADIO| Extracted [%s] from ATI4 query", sModel.c_str()); + apIo->close(); + return sModel; +} + +CellularRadio* CellularRadioFactory::createHE910D(const std::string& sPort) { + return new HE910DRadio(sPort); +} + +CellularRadio* CellularRadioFactory::createHE910EUD(const std::string& sPort) { + return new HE910EUDRadio(sPort); +} + +CellularRadio* CellularRadioFactory::createLE910NAG(const std::string& sPort) { + return new LE910NAGRadio(sPort); +} + +CellularRadio* CellularRadioFactory::createLE910SVG(const std::string& sPort) { + return new LE910SVGRadio(sPort); +} + +CellularRadio* CellularRadioFactory::createLE910EUG(const std::string& sPort) { + return new LE910EUGRadio(sPort); +} + +CellularRadio* CellularRadioFactory::createGE910(const std::string& sPort) { + return new GE910Radio(sPort); +} + +CellularRadio* CellularRadioFactory::createDE910(const std::string& sPort) { + return new DE910Radio(sPort); +} + +CellularRadio* CellularRadioFactory::createCE910(const std::string& sPort) { + return new CE910Radio(sPort); +} diff --git a/src/MTS_IO_Connection.cpp b/src/MTS_IO_Connection.cpp new file mode 100644 index 0000000..36a91ed --- /dev/null +++ b/src/MTS_IO_Connection.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_Connection.cpp + \brief A brief description + \date Jan 15, 2013 + \author sgodinez + + A more elaborate description than necessary. +*/ + + +#include <mts/MTS_IO_Connection.h> +#include <mts/MTS_Buffer.h> +#include <sys/select.h> + +using namespace MTS; +using namespace MTS::IO; + +int32_t Connection::BLOCKING = -1; + +Connection::Connection(const std::string& name) +: m_sName(name) +, m_bClosed(true) +, m_bCloseable(true) { + m_apLock.reset(new Lock()); + m_apReadLock.reset(new Lock()); + m_apWriteLock.reset(new Lock()); +} + +Connection::~Connection() { + m_apWriteLock.reset(); + m_apReadLock.reset(); + m_apLock.reset(); +} + +const std::string& Connection::getName() const { + return m_sName; +} + +bool Connection::open(const int32_t& timeoutMillis) { + bool bOpened = true; + m_apLock->lock(); + if (m_bClosed) { + bOpened = doOpen(timeoutMillis); + if (bOpened) { + m_bClosed = false; + } + } + m_apLock->unlock(); + return bOpened; +} + +void Connection::close() { + m_apLock->lock(); + if (m_bCloseable) { + doClose(); + m_bClosed = true; + } + m_apLock->unlock(); +} + +bool Connection::isClosed() const { + m_apLock->lock(); + bool bResult = m_bClosed; + m_apLock->unlock(); + return bResult; +} + +void Connection::setCloseable(bool bCloseable) { + m_apLock->lock(); + m_bCloseable = bCloseable; + m_apLock->unlock(); +} + +bool Connection::isCloseable() const { + m_apLock->lock(); + bool bResult = m_bCloseable; + m_apLock->unlock(); + return bResult; +} + +int Connection::read(std::string& sBuffer, const uint32_t& iSize, int32_t& timeoutMillis) { + int result = -1; + if (isClosed()) { + return result; + } else { + char buffer[iSize]; + m_apReadLock->lock(); + result = doRead(buffer, iSize, timeoutMillis); + m_apReadLock->unlock(); + if(result > 0) { + sBuffer = std::string(buffer, result); + } + } + + return result; +} + +int Connection::read(Buffer& oBuffer, const uint32_t& iSize, int32_t& timeoutMillis) { + int result = -1; + if (isClosed()) { + return result; + } else { + oBuffer.setCapacity(iSize); + m_apReadLock->lock(); + result = doRead((char*)oBuffer.getBuffer(), iSize, timeoutMillis); + m_apReadLock->unlock(); + } + + return result; +} + +int Connection::read(char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis) { + int result = -1; + if (isClosed()) { + return result; + } else { + m_apReadLock->lock(); + result = doRead(pBuffer, iSize, timeoutMillis); + m_apReadLock->unlock(); + } + return result; +} + +int Connection::write(const char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis) { + int result = -1; + if (isClosed()) { + return result; + } else { + m_apWriteLock->lock(); + result = doWrite(pBuffer, iSize, timeoutMillis); + m_apWriteLock->unlock(); + } + return result; +} + diff --git a/src/MTS_IO_DE910Radio.cpp b/src/MTS_IO_DE910Radio.cpp new file mode 100644 index 0000000..766d7d1 --- /dev/null +++ b/src/MTS_IO_DE910Radio.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_DE910Radio.cpp + \brief A brief description + \date Nov 6, 2014 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_DE910Radio.h> + +using namespace MTS::IO; + +const std::string DE910Radio::MODEL_NAME("DE910-DUAL"); + +DE910Radio::DE910Radio(const std::string& sPort) +: CdmaRadio(MODEL_NAME, sPort) +{ + +} + diff --git a/src/MTS_IO_GE910Radio.cpp b/src/MTS_IO_GE910Radio.cpp new file mode 100644 index 0000000..013837b --- /dev/null +++ b/src/MTS_IO_GE910Radio.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_GE910Radio.cpp + \brief A brief description + \date Nov 6, 2014 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_GE910Radio.h> + +using namespace MTS::IO; + +const std::string GE910Radio::MODEL_NAME("GE910"); + +GE910Radio::GE910Radio(const std::string& sPort) +: CellularRadio(MODEL_NAME, sPort) +{ + +} + diff --git a/src/MTS_IO_HE910DRadio.cpp b/src/MTS_IO_HE910DRadio.cpp new file mode 100644 index 0000000..b159a9c --- /dev/null +++ b/src/MTS_IO_HE910DRadio.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_HE910DRadio.cpp + \brief A brief description + \date Nov 6, 2014 + \author sgodinez + + A more elaborate description +*/ + + +#include <mts/MTS_IO_HE910DRadio.h> + +using namespace MTS::IO; + +const std::string HE910DRadio::MODEL_NAME("HE910-D"); + +HE910DRadio::HE910DRadio(const std::string& sPort) +: HE910Radio(MODEL_NAME, sPort) +{ + +} diff --git a/src/MTS_IO_HE910EUDRadio.cpp b/src/MTS_IO_HE910EUDRadio.cpp new file mode 100644 index 0000000..4ae7e19 --- /dev/null +++ b/src/MTS_IO_HE910EUDRadio.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_HE910EUDRadio.cpp + \brief A brief description + \date Nov 6, 2014 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_HE910EUDRadio.h> + +using namespace MTS::IO; + +const std::string HE910EUDRadio::MODEL_NAME("HE910-EUD"); + +HE910EUDRadio::HE910EUDRadio(const std::string& sPort) +: HE910Radio(MODEL_NAME, sPort) +{ + +} + + diff --git a/src/MTS_IO_HE910Radio.cpp b/src/MTS_IO_HE910Radio.cpp new file mode 100644 index 0000000..3a7851a --- /dev/null +++ b/src/MTS_IO_HE910Radio.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_HE910Radio.cpp + \brief A brief description + \date Nov 6, 2014 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_HE910Radio.h> + +using namespace MTS::IO; + +HE910Radio::HE910Radio(const std::string& sHE910Model, const std::string& sPort) +: CellularRadio(sHE910Model, sPort) +{ + +} + + diff --git a/src/MTS_IO_LE910EUGRadio.cpp b/src/MTS_IO_LE910EUGRadio.cpp new file mode 100644 index 0000000..c3e54c3 --- /dev/null +++ b/src/MTS_IO_LE910EUGRadio.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_LE910EUGRadio.cpp + \brief A brief description + \date Jan 19, 2015 + \author sgodinez + + A more elaborate description +*/ + + +#include <mts/MTS_IO_LE910EUGRadio.h> + +using namespace MTS::IO; + +const std::string LE910EUGRadio::MODEL_NAME("LE910-EUG"); + +LE910EUGRadio::LE910EUGRadio(const std::string& sPort) +: LE910Radio(MODEL_NAME, sPort) +{ + +} diff --git a/src/MTS_IO_LE910NAGRadio.cpp b/src/MTS_IO_LE910NAGRadio.cpp new file mode 100644 index 0000000..c2f8bf5 --- /dev/null +++ b/src/MTS_IO_LE910NAGRadio.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_LE910NAGRadio.cpp + \brief A brief description + \date Jan 19, 2015 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_LE910NAGRadio.h> + +using namespace MTS::IO; + +const std::string LE910NAGRadio::MODEL_NAME("LE910-NAG"); + +LE910NAGRadio::LE910NAGRadio(const std::string& sPort) +: LE910Radio(MODEL_NAME, sPort) +{ + +} + +CellularRadio::CODE LE910NAGRadio::getCarrier(std::string& sCarrier) { + sCarrier = "AT&T"; + return SUCCESS; +} diff --git a/src/MTS_IO_LE910Radio.cpp b/src/MTS_IO_LE910Radio.cpp new file mode 100644 index 0000000..cbff249 --- /dev/null +++ b/src/MTS_IO_LE910Radio.cpp @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_LE910Radio.cpp + \brief A brief description + \date Nov 6, 2014 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_LE910Radio.h> + +using namespace MTS::IO; + +LE910Radio::LE910Radio(const std::string& sLE910Model, const std::string& sPort) +: CellularRadio(sLE910Model, sPort) +{ + +} + diff --git a/src/MTS_IO_LE910SVGRadio.cpp b/src/MTS_IO_LE910SVGRadio.cpp new file mode 100644 index 0000000..ee9b3f8 --- /dev/null +++ b/src/MTS_IO_LE910SVGRadio.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_LE910SVGRadio.cpp + \brief A brief description + \date Jan 19, 2015 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_LE910SVGRadio.h> + +using namespace MTS::IO; + +const std::string LE910SVGRadio::MODEL_NAME("LE910-SVG"); + +LE910SVGRadio::LE910SVGRadio(const std::string& sPort) +: LE910Radio(MODEL_NAME, sPort) +{ + +} + +CellularRadio::CODE LE910SVGRadio::getCarrier(std::string& sCarrier) { + sCarrier = "Verizon"; + return SUCCESS; +} diff --git a/src/MTS_IO_LockFile.cpp b/src/MTS_IO_LockFile.cpp new file mode 100644 index 0000000..c013699 --- /dev/null +++ b/src/MTS_IO_LockFile.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_LockFile.cpp + \brief A brief description + \date Oct 8, 2014 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_LockFile.h> +#include <mts/MTS_Timer.h> +#include <mts/MTS_Logger.h> +#include <mts/MTS_System.h> +#include <mts/MTS_Text.h> +#include <sys/file.h> +#include <sys/stat.h> +#include <errno.h> +#include <string.h> +#include <unistd.h> + +using namespace MTS::IO; + +LockFile::LockFile(const std::string& sFile) +: m_sFile(sFile) +, m_iLockFd(-1) +{ + +} + +LockFile::~LockFile() { + unlock(); +} + +bool LockFile::lock(uint32_t attemptMillis) { + if(isLocked()) { + return true; + } + + MTS::Timer timer; + + timer.start(); + while(timer.getMillis() < attemptMillis) { + m_iLockFd =::open(m_sFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0644); + if (m_iLockFd < 0) { + // device already locked -> bail out + printWarning("LockFile| Failed to Lock [%s] [%d][%s]", m_sFile.c_str(), errno, strerror(errno)); + + //Check if lock file's process still exists + std::string sResult; + if(MTS::System::readFile(m_sFile, sResult) == 0 && sResult.size() > 0) { + struct stat sts; + std::string sProc = "/proc/" + MTS::Text::trim(sResult); + if (stat(sProc.c_str(), &sts) == -1 && errno == ENOENT) { + printWarning("LockFile| Current Lock's Process [%s] does not exist. Removing lock.", sResult.c_str()); + // process doesn't exist -> remove file + ::unlink(m_sFile.c_str()); + } + } + + } else { + //TODO: Investigate using flock in addition to minicom-style lock : flock(m_iLockFd, LOCK_EX | LOCK_NB); + + // %4d to make concurrent mgetty (if any) happy. + // Mgetty treats 4-bytes lock files as binary, + // not text, PID. Making 5+ char file. Brrr... + char buf[256] = {0}; + sprintf(buf, "%4d\n", getpid()); + write(m_iLockFd, buf, strlen(buf)); + close(m_iLockFd); + return true; + } + uint32_t randomSleepTime = ((rand() % 10) + 1) * 100000; //Sleep from 100ms to 1 Second + ::usleep(randomSleepTime); + } + return false; +} + +void LockFile::unlock() { + if(isLocked()) { + ::unlink(m_sFile.c_str()); + //TODO: flock cleanup : flock(m_iLockFd, LOCK_UN); + m_iLockFd = -1; + } +} + +bool LockFile::isLocked() { + return m_iLockFd >= 0; +} + diff --git a/src/MTS_IO_MccMncTable.cpp b/src/MTS_IO_MccMncTable.cpp new file mode 100644 index 0000000..8ac3f62 --- /dev/null +++ b/src/MTS_IO_MccMncTable.cpp @@ -0,0 +1,1723 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_MccMncTable.cpp + \brief Auto-Generated MCC-MNC Lookup Table + \date 2014-12-11 + \author sgodinez + + An Auto-Generated MCC-MNC Lookup Table +*/ + +#include <mts/MTS_IO_MccMncTable.h> +#include <mts/MTS_Logger.h> +#include <mts/MTS_Text.h> + +using namespace MTS::IO; + +MTS::AutoPtr<MTS::Lock> MccMncTable::m_apLock(new MTS::Lock()); +MccMncTable* MccMncTable::m_pInstance = NULL; + +MccMncTable* MccMncTable::getInstance() { + if(m_pInstance == NULL) { + m_apLock->lock(); + if (m_pInstance == NULL) { + m_pInstance = new MccMncTable(); + } + m_apLock->unlock(); + } + return m_pInstance; +} + +MccMncTable::MccMncTable() { + createTable(); +} + +Json::Value MccMncTable::lookup(const std::string& sMcc, const std::string& sMnc) { + uint32_t iMcc, iMnc; + printTrace("[MCCMNC] MCCx[%s] MNCx[%s]", sMcc.c_str(), sMnc.c_str()); + if(!MTS::Text::parseHex(iMcc, sMcc)) { return Json::Value::null; } + if(!MTS::Text::parseHex(iMnc, sMnc)) { return Json::Value::null; } + printTrace("[MCCMNC] MCC0X[%d] MNC0X[%d]", iMcc, iMnc); + if (m_mTable.count(iMcc)) { + if(m_mTable[iMcc].count(iMnc)) { + std::vector<std::string> vJson = MTS::Text::split(m_mTable[iMcc][iMnc], ','); + Json::Value j; + j["iso"] = vJson[0]; + j["country"] = vJson[1]; + j["code"] = vJson[2]; + j["carrier"] = vJson[3]; + return j; + } + } + + return Json::Value::null; +} + +void MccMncTable::createTable() { + std::string sData; + m_mTable[649][2191] = "ge,Abkhazia,7,A-Mobile"; + m_mTable[649][1679] = "ge,Abkhazia,7,A-Mobile"; + m_mTable[649][1663] = "ge,Abkhazia,7,Aquafon"; + m_mTable[1042][2191] = "af,Afghanistan,93,Afghan Telecom Corp. (AT)"; + m_mTable[1042][2063] = "af,Afghanistan,93,Afghan Telecom Corp. (AT)"; + m_mTable[1042][31] = "af,Afghanistan,93,Afghan Wireless/AWCC"; + m_mTable[1042][1039] = "af,Afghanistan,93,Areeba/MTN"; + m_mTable[1042][1295] = "af,Afghanistan,93,Etisalat"; + m_mTable[1042][527] = "af,Afghanistan,93,Roshan"; + m_mTable[630][31] = "al,Albania,355,AMC Mobil"; + m_mTable[630][63] = "al,Albania,355,Eagle Mobile"; + m_mTable[630][79] = "al,Albania,355,PLUS Communication Sh.a"; + m_mTable[630][47] = "al,Albania,355,Vodafone"; + m_mTable[1539][31] = "dz,Algeria,213,ATM Mobils"; + m_mTable[1539][47] = "dz,Algeria,213,Orascom / DJEZZY"; + m_mTable[1539][63] = "dz,Algeria,213,Oreedo/Wataniya / Nedjma"; + m_mTable[1348][287] = "as,American Samoa,684,Blue Sky Communications"; + m_mTable[531][63] = "ad,Andorra,376,Mobiland"; + m_mTable[1585][79] = "ao,Angola,244,MoviCel"; + m_mTable[1585][47] = "ao,Angola,244,Unitel"; + m_mTable[869][2112] = "ai,Anguilla,1264,Cable and Wireless"; + m_mTable[869][16] = "ai,Anguilla,1264,Digicell / Wireless Vent. Ltd"; + m_mTable[836][48] = "ag,Antigua and Barbuda,1268,APUA PCS"; + m_mTable[836][2336] = "ag,Antigua and Barbuda,1268,C & W"; + m_mTable[836][2352] = "ag,Antigua and Barbuda,1268,DigiCel/Cing. Wireless"; + m_mTable[1826][784] = "ar,Argentina Republic,54,Claro/ CTI/AMX"; + m_mTable[1826][816] = "ar,Argentina Republic,54,Claro/ CTI/AMX"; + m_mTable[1826][800] = "ar,Argentina Republic,54,Claro/ CTI/AMX"; + m_mTable[1826][16] = "ar,Argentina Republic,54,Compania De Radiocomunicaciones Moviles SA"; + m_mTable[1826][112] = "ar,Argentina Republic,54,Movistar/Telefonica"; + m_mTable[1826][32] = "ar,Argentina Republic,54,Nextel"; + m_mTable[1826][833] = "ar,Argentina Republic,54,Telecom Personal S.A."; + m_mTable[643][31] = "am,Armenia,374,ArmenTel/Beeline"; + m_mTable[643][79] = "am,Armenia,374,Karabakh Telecom"; + m_mTable[643][271] = "am,Armenia,374,Orange"; + m_mTable[643][95] = "am,Armenia,374,Vivacell"; + m_mTable[867][527] = "aw,Aruba,297,Digicel"; + m_mTable[867][31] = "aw,Aruba,297,Setar GSM"; + m_mTable[1285][335] = "au,Australia,61,AAPT Ltd."; + m_mTable[1285][591] = "au,Australia,61,Advanced Comm Tech Pty."; + m_mTable[1285][159] = "au,Australia,61,Airnet Commercial Australia Ltd.."; + m_mTable[1285][79] = "au,Australia,61,Department of Defense"; + m_mTable[1285][623] = "au,Australia,61,Dialogue Communications Pty Ltd"; + m_mTable[1285][303] = "au,Australia,61,H3G Ltd."; + m_mTable[1285][111] = "au,Australia,61,H3G Ltd."; + m_mTable[1285][2191] = "au,Australia,61,Localstar Holding Pty. Ltd"; + m_mTable[1285][415] = "au,Australia,61,Lycamobile Pty Ltd"; + m_mTable[1285][143] = "au,Australia,61,Railcorp/Vodafone"; + m_mTable[1285][2463] = "au,Australia,61,Railcorp/Vodafone"; + m_mTable[1285][319] = "au,Australia,61,Railcorp/Vodafone"; + m_mTable[1285][2319] = "au,Australia,61,Singtel Optus"; + m_mTable[1285][47] = "au,Australia,61,Singtel Optus"; + m_mTable[1285][31] = "au,Australia,61,Telstra Corp. Ltd."; + m_mTable[1285][287] = "au,Australia,61,Telstra Corp. Ltd."; + m_mTable[1285][1823] = "au,Australia,61,Telstra Corp. Ltd."; + m_mTable[1285][1839] = "au,Australia,61,Telstra Corp. Ltd."; + m_mTable[1285][95] = "au,Australia,61,The Ozitel Network Pty."; + m_mTable[1285][367] = "au,Australia,61,Victorian Rail Track Corp. (VicTrack)"; + m_mTable[1285][63] = "au,Australia,61,Vodafone"; + m_mTable[1285][127] = "au,Australia,61,Vodafone"; + m_mTable[562][31] = "at,Austria,43,A1 MobilKom"; + m_mTable[562][287] = "at,Austria,43,A1 MobilKom"; + m_mTable[562][159] = "at,Austria,43,A1 MobilKom"; + m_mTable[562][47] = "at,Austria,43,A1 MobilKom"; + m_mTable[562][351] = "at,Austria,43,T-Mobile/Telering"; + m_mTable[562][15] = "at,Austria,43,Fix Line"; + m_mTable[562][335] = "at,Austria,43,H3G"; + m_mTable[562][271] = "at,Austria,43,H3G"; + m_mTable[562][111] = "at,Austria,43,A1/Orange/One Connect"; + m_mTable[562][303] = "at,Austria,43,A1/Orange/One Connect"; + m_mTable[562][95] = "at,Austria,43,A1/Orange/One Connect"; + m_mTable[562][127] = "at,Austria,43,T-Mobile/Telering"; + m_mTable[562][79] = "at,Austria,43,T-Mobile/Telering"; + m_mTable[562][63] = "at,Austria,43,T-Mobile/Telering"; + m_mTable[562][143] = "at,Austria,43,Telefonica"; + m_mTable[1024][31] = "az,Azerbaijan,994,Azercell Telekom B.M."; + m_mTable[1024][79] = "az,Azerbaijan,994,Azerfon."; + m_mTable[1024][63] = "az,Azerbaijan,994,Caspian American Telecommunications LLC (CATEL)"; + m_mTable[1024][47] = "az,Azerbaijan,994,J.V. Bakcell GSM 2000"; + m_mTable[868][783] = "bs,Bahamas,1242,Bahamas Telco. Comp."; + m_mTable[868][927] = "bs,Bahamas,1242,Bahamas Telco. Comp."; + m_mTable[868][912] = "bs,Bahamas,1242,Bahamas Telco. Comp."; + m_mTable[868][63] = "bs,Bahamas,1242,Smart Communications"; + m_mTable[1062][31] = "bh,Bahrain,973,Batelco"; + m_mTable[1062][47] = "bh,Bahrain,973,ZAIN/Vodafone"; + m_mTable[1062][79] = "bh,Bahrain,973,VIVA"; + m_mTable[1136][47] = "bd,Bangladesh,880,Robi/Aktel"; + m_mTable[1136][95] = "bd,Bangladesh,880,Citycell"; + m_mTable[1136][111] = "bd,Bangladesh,880,Citycell"; + m_mTable[1136][31] = "bd,Bangladesh,880,GrameenPhone"; + m_mTable[1136][63] = "bd,Bangladesh,880,Orascom"; + m_mTable[1136][79] = "bd,Bangladesh,880,TeleTalk"; + m_mTable[1136][127] = "bd,Bangladesh,880,Airtel/Warid"; + m_mTable[834][1536] = "bb,Barbados,1246,C & W BET Ltd."; + m_mTable[834][2064] = "bb,Barbados,1246,Cingular Wireless"; + m_mTable[834][1872] = "bb,Barbados,1246,Digicel"; + m_mTable[834][80] = "bb,Barbados,1246,Digicel"; + m_mTable[834][2080] = "bb,Barbados,1246,Sunbeach"; + m_mTable[599][63] = "by,Belarus,375,BelCel JV"; + m_mTable[599][79] = "by,Belarus,375,BeST"; + m_mTable[599][31] = "by,Belarus,375,Mobile Digital Communications"; + m_mTable[599][47] = "by,Belarus,375,MTS"; + m_mTable[518][527] = "be,Belgium,32,Base/KPN"; + m_mTable[518][31] = "be,Belgium,32,Belgacom/Proximus"; + m_mTable[518][111] = "be,Belgium,32,Lycamobile Belgium"; + m_mTable[518][271] = "be,Belgium,32,Mobistar/Orange"; + m_mTable[518][47] = "be,Belgium,32,SNCT/NMBS"; + m_mTable[518][95] = "be,Belgium,32,Telenet BidCo NV"; + m_mTable[1794][1663] = "bz,Belize,501,DigiCell"; + m_mTable[1794][1679] = "bz,Belize,501,International Telco (INTELCO)"; + m_mTable[1558][79] = "bj,Benin,229,Bell Benin/BBCOM"; + m_mTable[1558][47] = "bj,Benin,229,Etisalat/MOOV"; + m_mTable[1558][95] = "bj,Benin,229,GloMobile"; + m_mTable[1558][31] = "bj,Benin,229,Libercom"; + m_mTable[1558][63] = "bj,Benin,229,MTN/Spacetel"; + m_mTable[848][0] = "bm,Bermuda,1441,Bermuda Digital Communications Ltd (BDC)"; + m_mTable[848][2463] = "bm,Bermuda,1441,CellOne Ltd"; + m_mTable[848][271] = "bm,Bermuda,1441,DigiCel / Cingular"; + m_mTable[848][47] = "bm,Bermuda,1441,M3 Wireless Ltd"; + m_mTable[848][31] = "bm,Bermuda,1441,Telecommunications (Bermuda & West Indies) Ltd (Digicel Bermuda)"; + m_mTable[1026][287] = "bt,Bhutan,975,B-Mobile"; + m_mTable[1026][383] = "bt,Bhutan,975,Bhutan Telecom Ltd (BTL)"; + m_mTable[1026][1919] = "bt,Bhutan,975,TashiCell"; + m_mTable[1846][47] = "bo,Bolivia,591,Entel Pcs"; + m_mTable[1846][31] = "bo,Bolivia,591,Nuevatel"; + m_mTable[1846][63] = "bo,Bolivia,591,TELECEL BOLIVIA"; + m_mTable[536][2319] = "ba,Bosnia & Herzegov.,387,BH Mobile"; + m_mTable[536][63] = "ba,Bosnia & Herzegov.,387,Eronet Mobile"; + m_mTable[536][95] = "ba,Bosnia & Herzegov.,387,M-Tel"; + m_mTable[1618][79] = "bw,Botswana,267,beMOBILE"; + m_mTable[1618][31] = "bw,Botswana,267,Mascom Wireless (Pty) Ltd."; + m_mTable[1618][47] = "bw,Botswana,267,Orange"; + m_mTable[1828][303] = "br,Brazil,55,Claro/Albra/America Movil"; + m_mTable[1828][911] = "br,Brazil,55,Claro/Albra/America Movil"; + m_mTable[1828][95] = "br,Brazil,55,Claro/Albra/America Movil"; + m_mTable[1828][31] = "br,Brazil,55,Vivo S.A./Telemig"; + m_mTable[1828][847] = "br,Brazil,55,CTBC Celular SA (CTBC)"; + m_mTable[1828][831] = "br,Brazil,55,CTBC Celular SA (CTBC)"; + m_mTable[1828][815] = "br,Brazil,55,CTBC Celular SA (CTBC)"; + m_mTable[1828][143] = "br,Brazil,55,TIM"; + m_mTable[1828][927] = "br,Brazil,55,Nextel (Telet)"; + m_mTable[1828][15] = "br,Brazil,55,Nextel (Telet)"; + m_mTable[1828][591] = "br,Brazil,55,Amazonia Celular S/A"; + m_mTable[1828][783] = "br,Brazil,55,Oi (TNL PCS / Oi)"; + m_mTable[1828][799] = "br,Brazil,55,Oi (TNL PCS / Oi)"; + m_mTable[1828][367] = "br,Brazil,55,Brazil Telcom"; + m_mTable[1828][351] = "br,Brazil,55,Sercontel Cel"; + m_mTable[1828][127] = "br,Brazil,55,CTBC/Triangulo"; + m_mTable[1828][415] = "br,Brazil,55,Vivo S.A./Telemig"; + m_mTable[1828][47] = "br,Brazil,55,TIM"; + m_mTable[1828][79] = "br,Brazil,55,TIM"; + m_mTable[1828][63] = "br,Brazil,55,TIM"; + m_mTable[1828][895] = "br,Brazil,55,Unicel do Brasil Telecomunicacoes Ltda"; + m_mTable[1828][271] = "br,Brazil,55,Vivo S.A./Telemig"; + m_mTable[1828][111] = "br,Brazil,55,Vivo S.A./Telemig"; + m_mTable[1828][575] = "br,Brazil,55,Vivo S.A./Telemig"; + m_mTable[1828][287] = "br,Brazil,55,Vivo S.A./Telemig"; + m_mTable[840][1392] = "vg,British Virgin Islands,284,Caribbean Cellular"; + m_mTable[840][1904] = "vg,British Virgin Islands,284,Digicel"; + m_mTable[840][368] = "vg,British Virgin Islands,284,LIME"; + m_mTable[1320][47] = "bn,Brunei,673,b-mobile"; + m_mTable[1320][287] = "bn,Brunei,673,Datastream (DTSCom)"; + m_mTable[1320][31] = "bn,Brunei,673,Telekom Brunei Bhd (TelBru)"; + m_mTable[644][111] = "bg,Bulgaria,359,BTC Mobile EOOD (vivatel)"; + m_mTable[644][63] = "bg,Bulgaria,359,BTC Mobile EOOD (vivatel)"; + m_mTable[644][95] = "bg,Bulgaria,359,Cosmo Mobile EAD/Globul"; + m_mTable[644][31] = "bg,Bulgaria,359,MobilTel AD"; + m_mTable[1555][63] = "bf,Burkina Faso,226,TeleCel"; + m_mTable[1555][31] = "bf,Burkina Faso,226,TeleMob-OnaTel"; + m_mTable[1555][47] = "bf,Burkina Faso,226,AirTel/ZAIN/CelTel"; + m_mTable[1044][31] = "mm,Burma,95,Myanmar Post & Teleco."; + m_mTable[1602][47] = "bi,Burundi,257,Africel / Safaris"; + m_mTable[1602][143] = "bi,Burundi,257,HiTs Telecom"; + m_mTable[1602][63] = "bi,Burundi,257,Onatel / Telecel"; + m_mTable[1602][127] = "bi,Burundi,257,Smart Mobile / LACELL"; + m_mTable[1602][31] = "bi,Burundi,257,Spacetel / Econet"; + m_mTable[1602][2095] = "bi,Burundi,257,U-COM"; + m_mTable[1110][79] = "kh,Cambodia,855,Cambodia Advance Communications Co. Ltd (CADCOMMS)"; + m_mTable[1110][47] = "kh,Cambodia,855,Hello/Malaysia Telcom"; + m_mTable[1110][143] = "kh,Cambodia,855,Metfone"; + m_mTable[1110][399] = "kh,Cambodia,855,MFone/Camshin"; + m_mTable[1110][31] = "kh,Cambodia,855,Mobitel/Cam GSM"; + m_mTable[1110][63] = "kh,Cambodia,855,QB/Cambodia Adv. Comms."; + m_mTable[1110][95] = "kh,Cambodia,855,Smart Mobile"; + m_mTable[1110][111] = "kh,Cambodia,855,Smart Mobile"; + m_mTable[1110][159] = "kh,Cambodia,855,Sotelco Ltd (Beeline Cambodia)"; + m_mTable[1572][31] = "cm,Cameroon,237,MTN"; + m_mTable[1572][79] = "cm,Cameroon,237,Nextel"; + m_mTable[1572][47] = "cm,Cameroon,237,Orange"; + m_mTable[770][1618] = "ca,Canada,1,BC Tel Mobility"; + m_mTable[770][1584] = "ca,Canada,1,Bell Aliant"; + m_mTable[770][1552] = "ca,Canada,1,Bell Mobility"; + m_mTable[770][1617] = "ca,Canada,1,Bell Mobility"; + m_mTable[770][1648] = "ca,Canada,1,CityWest Mobility"; + m_mTable[770][865] = "ca,Canada,1,Clearnet"; + m_mTable[770][864] = "ca,Canada,1,Clearnet"; + m_mTable[770][896] = "ca,Canada,1,DMTS Mobility"; + m_mTable[770][1808] = "ca,Canada,1,Globalstar Canada"; + m_mTable[770][1600] = "ca,Canada,1,Latitude Wireless"; + m_mTable[770][880] = "ca,Canada,1,FIDO (Rogers AT&T/ Microcell)"; + m_mTable[770][800] = "ca,Canada,1,mobilicity"; + m_mTable[770][1794] = "ca,Canada,1,MT&T Mobility"; + m_mTable[770][1621] = "ca,Canada,1,MTS Mobility"; + m_mTable[770][1632] = "ca,Canada,1,MTS Mobility"; + m_mTable[770][1793] = "ca,Canada,1,NB Tel Mobility"; + m_mTable[770][1795] = "ca,Canada,1,New Tel Mobility"; + m_mTable[770][1888] = "ca,Canada,1,Public Mobile"; + m_mTable[770][1623] = "ca,Canada,1,Quebectel Mobility"; + m_mTable[770][1824] = "ca,Canada,1,Rogers AT&T Wireless"; + m_mTable[770][1664] = "ca,Canada,1,Sask Tel Mobility"; + m_mTable[770][1620] = "ca,Canada,1,Sask Tel Mobility"; + m_mTable[770][1622] = "ca,Canada,1,Tbay Mobility"; + m_mTable[770][544] = "ca,Canada,1,Telus Mobility"; + m_mTable[770][1619] = "ca,Canada,1,Telus Mobility"; + m_mTable[770][1280] = "ca,Canada,1,Videotron"; + m_mTable[770][1168] = "ca,Canada,1,WIND"; + m_mTable[1573][31] = "cv,Cape Verde,238,CV Movel"; + m_mTable[1573][47] = "cv,Cape Verde,238,T+ Telecom"; + m_mTable[838][80] = "ky,Cayman Islands,1345,Digicel Cayman Ltd"; + m_mTable[838][6] = "ky,Cayman Islands,1345,Digicel Ltd."; + m_mTable[838][320] = "ky,Cayman Islands,1345,LIME / Cable & Wirel."; + m_mTable[1571][31] = "cf,Central African Rep.,236,Centrafr. Telecom+"; + m_mTable[1571][79] = "cf,Central African Rep.,236,Nationlink"; + m_mTable[1571][63] = "cf,Central African Rep.,236,Orange/Celca"; + m_mTable[1571][47] = "cf,Central African Rep.,236,Telecel Centraf."; + m_mTable[1570][79] = "td,Chad,235,Salam/Sotel"; + m_mTable[1570][47] = "td,Chad,235,Tchad Mobile"; + m_mTable[1570][63] = "td,Chad,235,Tigo/Milicom/Tchad Mobile"; + m_mTable[1570][31] = "td,Chad,235,Zain/Airtel/Celtel"; + m_mTable[1840][111] = "cl,Chile,56,Blue Two Chile SA"; + m_mTable[1840][287] = "cl,Chile,56,Celupago SA"; + m_mTable[1840][351] = "cl,Chile,56,Cibeles Telecom SA"; + m_mTable[1840][63] = "cl,Chile,56,Claro"; + m_mTable[1840][271] = "cl,Chile,56,Entel PCS"; + m_mTable[1840][31] = "cl,Chile,56,Entel Telefonia Mov"; + m_mTable[1840][335] = "cl,Chile,56,Netline Telefonica Movil Ltda"; + m_mTable[1840][159] = "cl,Chile,56,Nextel SA"; + m_mTable[1840][95] = "cl,Chile,56,Nextel SA"; + m_mTable[1840][79] = "cl,Chile,56,Nextel SA"; + m_mTable[1840][127] = "cl,Chile,56,TELEFONICA"; + m_mTable[1840][47] = "cl,Chile,56,TELEFONICA"; + m_mTable[1840][303] = "cl,Chile,56,Telestar Movil SA"; + m_mTable[1840][15] = "cl,Chile,56,TESAM SA"; + m_mTable[1840][319] = "cl,Chile,56,Tribe Mobile SPA"; + m_mTable[1840][143] = "cl,Chile,56,VTR Banda Ancha SA"; + m_mTable[1120][127] = "cn,China,86,China Mobile GSM"; + m_mTable[1120][15] = "cn,China,86,China Mobile GSM"; + m_mTable[1120][47] = "cn,China,86,China Mobile GSM"; + m_mTable[1120][79] = "cn,China,86,China Space Mobile Satellite Telecommunications Co. Ltd (China Spacecom)"; + m_mTable[1120][63] = "cn,China,86,China Telecom"; + m_mTable[1120][95] = "cn,China,86,China Telecom"; + m_mTable[1120][111] = "cn,China,86,China Unicom"; + m_mTable[1120][31] = "cn,China,86,China Unicom"; + m_mTable[1842][304] = "co,Colombia,57,Avantel SAS"; + m_mTable[1842][258] = "co,Colombia,57,Movistar"; + m_mTable[1842][259] = "co,Colombia,57,TIGO/Colombia Movil"; + m_mTable[1842][1] = "co,Colombia,57,TIGO/Colombia Movil"; + m_mTable[1842][257] = "co,Colombia,57,Comcel S.A. Occel S.A./Celcaribe"; + m_mTable[1842][2] = "co,Colombia,57,Edatel S.A."; + m_mTable[1842][291] = "co,Colombia,57,Movistar"; + m_mTable[1842][273] = "co,Colombia,57,TIGO/Colombia Movil"; + m_mTable[1842][322] = "co,Colombia,57,UNE EPM Telecomunicaciones SA ESP"; + m_mTable[1842][32] = "co,Colombia,57,UNE EPM Telecomunicaciones SA ESP"; + m_mTable[1842][340] = "co,Colombia,57,Virgin Mobile Colombia SAS"; + m_mTable[1620][31] = "km,Comoros,269,HURI - SNPT"; + m_mTable[1584][2159] = "cd,Congo Dem. Rep.,243,Orange RDC sarl"; + m_mTable[1584][95] = "cd,Congo Dem. Rep.,243,SuperCell"; + m_mTable[1584][2207] = "cd,Congo Dem. Rep.,243,TIGO/Oasis"; + m_mTable[1584][31] = "cd,Congo Dem. Rep.,243,Vodacom"; + m_mTable[1584][2191] = "cd,Congo Dem. Rep.,243,Yozma Timeturns sprl (YTT)"; + m_mTable[1584][47] = "cd,Congo Dem. Rep.,243,ZAIN CelTel"; + m_mTable[1577][31] = "cg,Congo Republic,242,Airtel Congo SA"; + m_mTable[1577][47] = "cg,Congo Republic,242,Zain/Celtel"; + m_mTable[1577][271] = "cg,Congo Republic,242,MTN/Libertis"; + m_mTable[1577][127] = "cg,Congo Republic,242,Warid"; + m_mTable[1352][31] = "ck,Cook Islands,682,Telecom Cook Islands"; + m_mTable[1810][63] = "cr,Costa Rica,506,Claro"; + m_mTable[1810][47] = "cr,Costa Rica,506,ICE"; + m_mTable[1810][31] = "cr,Costa Rica,506,ICE"; + m_mTable[1810][79] = "cr,Costa Rica,506,Movistar"; + m_mTable[1810][527] = "cr,Costa Rica,506,Virtualis"; + m_mTable[537][31] = "hr,Croatia,385,T-Mobile/Cronet"; + m_mTable[537][47] = "hr,Croatia,385,Tele2"; + m_mTable[537][271] = "hr,Croatia,385,VIPnet d.o.o."; + m_mTable[872][31] = "cu,Cuba,53,C-COM"; + m_mTable[866][2399] = "cw,Curacao,599,EOCG Wireless NV"; + m_mTable[866][1695] = "cw,Curacao,599,Polycom N.V./ Digicel"; + m_mTable[640][271] = "cy,Cyprus,357,MTN/Areeba"; + m_mTable[640][527] = "cy,Cyprus,357,PrimeTel PLC"; + m_mTable[640][31] = "cy,Cyprus,357,Vodafone/CyTa"; + m_mTable[560][143] = "cz,Czech Rep.,420,Compatel s.r.o."; + m_mTable[560][47] = "cz,Czech Rep.,420,O2"; + m_mTable[560][31] = "cz,Czech Rep.,420,T-Mobile / RadioMobil"; + m_mTable[560][95] = "cz,Czech Rep.,420,Travel Telekommunikation s.r.o."; + m_mTable[560][79] = "cz,Czech Rep.,420,Ufone"; + m_mTable[560][2463] = "cz,Czech Rep.,420,Vodafone"; + m_mTable[560][63] = "cz,Czech Rep.,420,Vodafone"; + m_mTable[568][95] = "dk,Denmark,45,ApS KBUS"; + m_mTable[568][575] = "dk,Denmark,45,Banedanmark"; + m_mTable[568][655] = "dk,Denmark,45,CoolTEL ApS"; + m_mTable[568][111] = "dk,Denmark,45,Hi3G"; + m_mTable[568][303] = "dk,Denmark,45,Lycamobile Ltd"; + m_mTable[568][63] = "dk,Denmark,45,Mach Connectivity ApS"; + m_mTable[568][127] = "dk,Denmark,45,"; + m_mTable[568][79] = "dk,Denmark,45,NextGen Mobile Ltd (CardBoardFish)"; + m_mTable[568][271] = "dk,Denmark,45,TDC Denmark"; + m_mTable[568][31] = "dk,Denmark,45,TDC Denmark"; + m_mTable[568][1919] = "dk,Denmark,45,Telenor/Sonofon"; + m_mTable[568][47] = "dk,Denmark,45,Telenor/Sonofon"; + m_mTable[568][527] = "dk,Denmark,45,Telia"; + m_mTable[568][783] = "dk,Denmark,45,Telia"; + m_mTable[1592][31] = "dj,Djibouti,253,Djibouti Telecom SA (Evatis)"; + m_mTable[870][272] = "dm,Dominica,1767,C & W"; + m_mTable[870][32] = "dm,Dominica,1767,Cingular Wireless/Digicel"; + m_mTable[870][80] = "dm,Dominica,1767,Wireless Ventures (Dominica) Ltd (Digicel Dominica)"; + m_mTable[880][47] = "do,Dominican Republic,1809,Claro"; + m_mTable[880][31] = "do,Dominican Republic,1809,Orange"; + m_mTable[880][63] = "do,Dominican Republic,1809,TRIcom"; + m_mTable[880][79] = "do,Dominican Republic,1809,Trilogy Dominicana S. A."; + m_mTable[1856][47] = "ec,Ecuador,593,Alegro/Telcsa"; + m_mTable[1856][15] = "ec,Ecuador,593,MOVISTAR/OteCel"; + m_mTable[1856][31] = "ec,Ecuador,593,Porta/Conecel"; + m_mTable[1538][31] = "eg,Egypt,20,EMS - Mobinil"; + m_mTable[1538][63] = "eg,Egypt,20,ETISALAT"; + m_mTable[1538][47] = "eg,Egypt,20,Vodafone/Mirsfone"; + m_mTable[1798][31] = "sv,El Salvador,503,CLARO/CTE"; + m_mTable[1798][47] = "sv,El Salvador,503,Digicel"; + m_mTable[1798][95] = "sv,El Salvador,503,INTELFON SA de CV"; + m_mTable[1798][79] = "sv,El Salvador,503,Telefonica"; + m_mTable[1798][63] = "sv,El Salvador,503,Telemovil"; + m_mTable[1575][63] = "gq,Equatorial Guinea,240,HiTs-GE"; + m_mTable[1575][31] = "gq,Equatorial Guinea,240,ORANGE/GETESA"; + m_mTable[1623][31] = "er,Eritrea,291,Eritel"; + m_mTable[584][31] = "ee,Estonia,372,EMT GSM"; + m_mTable[584][47] = "ee,Estonia,372,Radiolinja Eesti"; + m_mTable[584][63] = "ee,Estonia,372,Tele2 Eesti AS"; + m_mTable[584][79] = "ee,Estonia,372,Top Connect OU"; + m_mTable[1590][31] = "et,Ethiopia,251,ETH/MTN"; + m_mTable[1872][1] = "fk,Falkland Islands (Malvinas),500,Cable and Wireless South Atlantic Ltd (Falkland Islands"; + m_mTable[648][63] = "fo,Faroe Islands,298,Edge Mobile Sp/F"; + m_mTable[648][31] = "fo,Faroe Islands,298,Faroese Telecom"; + m_mTable[648][47] = "fo,Faroe Islands,298,Kall GSM"; + m_mTable[1346][47] = "fj,Fiji,679,DigiCell"; + m_mTable[1346][31] = "fj,Fiji,679,Vodafone"; + m_mTable[580][335] = "fi,Finland,358,Alands"; + m_mTable[580][623] = "fi,Finland,358,Compatel Ltd"; + m_mTable[580][319] = "fi,Finland,358,DNA/Finnet"; + m_mTable[580][63] = "fi,Finland,358,DNA/Finnet"; + m_mTable[580][303] = "fi,Finland,358,DNA/Finnet"; + m_mTable[580][79] = "fi,Finland,358,DNA/Finnet"; + m_mTable[580][543] = "fi,Finland,358,Elisa/Saunalahti"; + m_mTable[580][95] = "fi,Finland,358,Elisa/Saunalahti"; + m_mTable[580][2095] = "fi,Finland,358,ID-Mobile"; + m_mTable[580][287] = "fi,Finland,358,Mundio Mobile (Finland) Ltd"; + m_mTable[580][159] = "fi,Finland,358,Nokia Oyj"; + m_mTable[580][271] = "fi,Finland,358,TDC Oy Finland"; + m_mTable[580][2335] = "fi,Finland,358,TeliaSonera"; + m_mTable[520][639] = "fr,France,33,AFONE SA"; + m_mTable[520][2351] = "fr,France,33,Association Plate-forme Telecom"; + m_mTable[520][655] = "fr,France,33,Astrium"; + m_mTable[520][543] = "fr,France,33,Bouygues Telecom"; + m_mTable[520][527] = "fr,France,33,Bouygues Telecom"; + m_mTable[520][2191] = "fr,France,33,Bouygues Telecom"; + m_mTable[520][335] = "fr,France,33,Lliad/FREE Mobile"; + m_mTable[520][127] = "fr,France,33,GlobalStar"; + m_mTable[520][111] = "fr,France,33,GlobalStar"; + m_mTable[520][95] = "fr,France,33,GlobalStar"; + m_mTable[520][671] = "fr,France,33,Orange"; + m_mTable[520][367] = "fr,France,33,Lliad/FREE Mobile"; + m_mTable[520][351] = "fr,France,33,Lliad/FREE Mobile"; + m_mTable[520][607] = "fr,France,33,Lycamobile SARL"; + m_mTable[520][63] = "fr,France,33,MobiquiThings"; + m_mTable[520][591] = "fr,France,33,MobiquiThings"; + m_mTable[520][799] = "fr,France,33,Mundio Mobile (France) Ltd"; + m_mTable[520][623] = "fr,France,33,NRJ"; + m_mTable[520][2207] = "fr,France,33,Virgin Mobile/Omer"; + m_mTable[520][575] = "fr,France,33,Virgin Mobile/Omer"; + m_mTable[520][47] = "fr,France,33,Orange"; + m_mTable[520][31] = "fr,France,33,Orange"; + m_mTable[520][2335] = "fr,France,33,Orange"; + m_mTable[520][287] = "fr,France,33,S.F.R."; + m_mTable[520][271] = "fr,France,33,S.F.R."; + m_mTable[520][159] = "fr,France,33,S.F.R."; + m_mTable[520][319] = "fr,France,33,S.F.R."; + m_mTable[520][79] = "fr,France,33,SISTEER"; + m_mTable[520][15] = "fr,France,33,Tel/Tel"; + m_mTable[520][559] = "fr,France,33,Transatel SA"; + m_mTable[832][527] = "fg,French Guiana,594,Bouygues/DigiCel"; + m_mTable[832][31] = "fg,French Guiana,594,Orange Caribe"; + m_mTable[832][47] = "fg,French Guiana,594,Outremer Telecom"; + m_mTable[832][63] = "fg,French Guiana,594,TelCell GSM"; + m_mTable[832][287] = "fg,French Guiana,594,TelCell GSM"; + m_mTable[1351][351] = "pf,French Polynesia,689,Pacific Mobile Telecom (PMT)"; + m_mTable[1351][527] = "pf,French Polynesia,689,Tikiphone"; + m_mTable[1576][79] = "ga,Gabon,241,Azur/Usan S.A."; + m_mTable[1576][31] = "ga,Gabon,241,Libertis S.A."; + m_mTable[1576][47] = "ga,Gabon,241,MOOV/Telecel"; + m_mTable[1576][63] = "ga,Gabon,241,ZAIN/Celtel Gabon S.A."; + m_mTable[1543][47] = "gm,Gambia,220,Africel"; + m_mTable[1543][63] = "gm,Gambia,220,Comium"; + m_mTable[1543][31] = "gm,Gambia,220,Gamcel"; + m_mTable[1543][79] = "gm,Gambia,220,Q-Cell"; + m_mTable[642][31] = "ge,Georgia,995,Geocell Ltd."; + m_mTable[642][63] = "ge,Georgia,995,Iberiatel Ltd."; + m_mTable[642][47] = "ge,Georgia,995,Magti GSM Ltd."; + m_mTable[642][79] = "ge,Georgia,995,MobiTel/Beeline"; + m_mTable[642][95] = "ge,Georgia,995,Silknet"; + m_mTable[610][383] = "de,Germany,49,E-Plus"; + m_mTable[610][271] = "de,Germany,49,DB Netz AG"; + //MCC(262) MNC(N/A) ISO(de) Country Code(Germany) Country(49) Carrier(Debitel) + m_mTable[610][63] = "de,Germany,49,E-Plus"; + m_mTable[610][95] = "de,Germany,49,E-Plus"; + m_mTable[610][1919] = "de,Germany,49,E-Plus"; + m_mTable[610][303] = "de,Germany,49,E-Plus"; + m_mTable[610][335] = "de,Germany,49,Group 3G UMTS"; + m_mTable[610][1087] = "de,Germany,49,Lycamobile"; + m_mTable[610][319] = "de,Germany,49,Mobilcom"; + m_mTable[610][287] = "de,Germany,49,O2"; + m_mTable[610][127] = "de,Germany,49,O2"; + m_mTable[610][143] = "de,Germany,49,O2"; + //MCC(262) MNC(N/A) ISO(de) Country Code(Germany) Country(49) Carrier(Talkline) + m_mTable[610][111] = "de,Germany,49,T-mobile/Telekom"; + m_mTable[610][31] = "de,Germany,49,T-mobile/Telekom"; + m_mTable[610][367] = "de,Germany,49,Telogic/ViStream"; + m_mTable[610][159] = "de,Germany,49,Vodafone D2"; + m_mTable[610][79] = "de,Germany,49,Vodafone D2"; + m_mTable[610][47] = "de,Germany,49,Vodafone D2"; + m_mTable[1568][79] = "gh,Ghana,233,Expresso Ghana Ltd"; + m_mTable[1568][127] = "gh,Ghana,233,GloMobile"; + m_mTable[1568][63] = "gh,Ghana,233,Milicom/Tigo"; + m_mTable[1568][31] = "gh,Ghana,233,MTN"; + m_mTable[1568][47] = "gh,Ghana,233,Vodafone"; + m_mTable[1568][111] = "gh,Ghana,233,Airtel/ZAIN"; + m_mTable[614][111] = "gi,Gibraltar,350,CTS Mobile"; + m_mTable[614][159] = "gi,Gibraltar,350,eazi telecom"; + m_mTable[614][31] = "gi,Gibraltar,350,Gibtel GSM"; + m_mTable[514][127] = "gr,Greece,30,AMD Telecom SA"; + m_mTable[514][47] = "gr,Greece,30,Cosmote"; + m_mTable[514][31] = "gr,Greece,30,Cosmote"; + m_mTable[514][79] = "gr,Greece,30,Organismos Sidirodromon Ellados (OSE)"; + m_mTable[514][63] = "gr,Greece,30,OTE Hellenic Telecommunications Organization SA"; + m_mTable[514][271] = "gr,Greece,30,Tim/Wind"; + m_mTable[514][159] = "gr,Greece,30,Tim/Wind"; + m_mTable[514][95] = "gr,Greece,30,Vodafone"; + m_mTable[656][31] = "gl,Greenland,299,Tele Greenland"; + m_mTable[850][272] = "gd,Grenada,1473,Cable & Wireless"; + m_mTable[850][48] = "gd,Grenada,1473,Digicel"; + m_mTable[850][80] = "gd,Grenada,1473,Digicel"; + m_mTable[832][143] = "gp,Guadeloupe,590,Dauphin Telecom SU (Guadeloupe Telecom) (Guadeloupe"; + m_mTable[832][271] = "gp,Guadeloupe,590,"; + m_mTable[784][880] = "gu,Guam,1671,Docomo"; + m_mTable[784][1136] = "gu,Guam,1671,Docomo"; + m_mTable[784][320] = "gu,Guam,1671,GTA Wireless"; + m_mTable[784][51] = "gu,Guam,1671,Guam Teleph. Auth."; + m_mTable[784][50] = "gu,Guam,1671,IT&E OverSeas"; + m_mTable[785][592] = "gu,Guam,1671,Wave Runner LLC"; + m_mTable[1796][31] = "gt,Guatemala,502,SERCOM"; + m_mTable[1796][63] = "gt,Guatemala,502,Telefonica"; + m_mTable[1796][47] = "gt,Guatemala,502,TIGO/COMCEL"; + m_mTable[1553][79] = "gn,Guinea,224,Areeba - MTN"; + m_mTable[1553][95] = "gn,Guinea,224,Celcom"; + m_mTable[1553][63] = "gn,Guinea,224,Intercel"; + m_mTable[1553][31] = "gn,Guinea,224,Orange/Spacetel"; + m_mTable[1553][47] = "gn,Guinea,224,SotelGui"; + m_mTable[1586][31] = "gw,Guinea-Bissau,245,GuineTel"; + m_mTable[1586][63] = "gw,Guinea-Bissau,245,Orange"; + m_mTable[1586][47] = "gw,Guinea-Bissau,245,SpaceTel"; + m_mTable[1848][47] = "gy,Guyana,592,Cellink Plus"; + m_mTable[1848][31] = "gy,Guyana,592,DigiCel"; + m_mTable[882][31] = "ht,Haiti,509,Comcel"; + m_mTable[882][47] = "ht,Haiti,509,Digicel"; + m_mTable[882][63] = "ht,Haiti,509,National Telecom SA (NatCom)"; + m_mTable[1800][1039] = "hn,Honduras,504,Digicel"; + m_mTable[1800][783] = "hn,Honduras,504,HonduTel"; + m_mTable[1800][31] = "hn,Honduras,504,SERCOM/CLARO"; + m_mTable[1800][47] = "hn,Honduras,504,Telefonica/CELTEL"; + m_mTable[1108][319] = "hk,Hongkong China,852,China Mobile/Peoples"; + m_mTable[1108][303] = "hk,Hongkong China,852,China Mobile/Peoples"; + m_mTable[1108][159] = "hk,Hongkong China,852,China Motion"; + m_mTable[1108][127] = "hk,Hongkong China,852,China Unicom Ltd"; + m_mTable[1108][287] = "hk,Hongkong China,852,China-HongKong Telecom Ltd (CHKTL)"; + m_mTable[1108][31] = "hk,Hongkong China,852,Citic Telecom Ltd."; + m_mTable[1108][47] = "hk,Hongkong China,852,CSL Ltd."; + m_mTable[1108][15] = "hk,Hongkong China,852,CSL Ltd."; + m_mTable[1108][399] = "hk,Hongkong China,852,CSL Ltd."; + m_mTable[1108][271] = "hk,Hongkong China,852,CSL/New World PCS Ltd."; + m_mTable[1108][335] = "hk,Hongkong China,852,H3G/Hutchinson"; + m_mTable[1108][95] = "hk,Hongkong China,852,H3G/Hutchinson"; + m_mTable[1108][79] = "hk,Hongkong China,852,H3G/Hutchinson"; + m_mTable[1108][63] = "hk,Hongkong China,852,H3G/Hutchinson"; + m_mTable[1108][415] = "hk,Hongkong China,852,HKT/PCCW"; + m_mTable[1108][527] = "hk,Hongkong China,852,HKT/PCCW"; + m_mTable[1108][671] = "hk,Hongkong China,852,HKT/PCCW"; + m_mTable[1108][367] = "hk,Hongkong China,852,HKT/PCCW"; + m_mTable[1108][1151] = "hk,Hongkong China,852,shared by private TETRA systems"; + m_mTable[1108][1039] = "hk,Hongkong China,852,shared by private TETRA systems"; + m_mTable[1108][143] = "hk,Hongkong China,852,Trident Telecom Ventures Ltd."; + m_mTable[1108][383] = "hk,Hongkong China,852,Vodafone/SmarTone"; + m_mTable[1108][351] = "hk,Hongkong China,852,Vodafone/SmarTone"; + m_mTable[1108][111] = "hk,Hongkong China,852,Vodafone/SmarTone"; + m_mTable[534][31] = "hu,Hungary,36,Pannon/Telenor"; + m_mTable[534][783] = "hu,Hungary,36,T-mobile/Magyar"; + m_mTable[534][1823] = "hu,Hungary,36,UPC Magyarorszag Kft."; + m_mTable[534][1807] = "hu,Hungary,36,Vodafone"; + m_mTable[628][159] = "is,Iceland,354,Amitelo"; + m_mTable[628][127] = "is,Iceland,354,IceCell"; + m_mTable[628][143] = "is,Iceland,354,Landssiminn"; + m_mTable[628][31] = "is,Iceland,354,Landssiminn"; + m_mTable[628][287] = "is,Iceland,354,NOVA"; + m_mTable[628][79] = "is,Iceland,354,VIKING/IMC"; + m_mTable[628][63] = "is,Iceland,354,Vodafone/Tal hf"; + m_mTable[628][47] = "is,Iceland,354,Vodafone/Tal hf"; + m_mTable[628][95] = "is,Iceland,354,Vodafone/Tal hf"; + m_mTable[1028][655] = "in,India,91,Aircel"; + m_mTable[1028][607] = "in,India,91,Aircel"; + m_mTable[1028][383] = "in,India,91,Aircel"; + m_mTable[1028][1071] = "in,India,91,Aircel"; + m_mTable[1028][831] = "in,India,91,Aircel"; + m_mTable[1028][671] = "in,India,91,Aircel"; + m_mTable[1028][31] = "in,India,91,Aircel Digilink India"; + m_mTable[1028][351] = "in,India,91,Aircel Digilink India"; + m_mTable[1028][1551] = "in,India,91,Aircel Digilink India"; + m_mTable[1029][1343] = "in,India,91,AirTel"; + m_mTable[1028][2159] = "in,India,91,Barakhamba Sales & Serv."; + m_mTable[1028][319] = "in,India,91,Barakhamba Sales & Serv."; + m_mTable[1028][1919] = "in,India,91,BSNL"; + m_mTable[1028][1615] = "in,India,91,BSNL"; + m_mTable[1028][1359] = "in,India,91,BSNL"; + m_mTable[1028][1823] = "in,India,91,BSNL"; + m_mTable[1028][1903] = "in,India,91,BSNL"; + m_mTable[1028][1583] = "in,India,91,BSNL"; + m_mTable[1028][1343] = "in,India,91,BSNL"; + m_mTable[1028][1439] = "in,India,91,BSNL"; + m_mTable[1028][1887] = "in,India,91,BSNL"; + m_mTable[1028][1311] = "in,India,91,BSNL"; + m_mTable[1028][1423] = "in,India,91,BSNL"; + m_mTable[1028][2079] = "in,India,91,BSNL"; + m_mTable[1028][1871] = "in,India,91,BSNL"; + m_mTable[1028][911] = "in,India,91,BSNL"; + m_mTable[1028][1407] = "in,India,91,BSNL"; + m_mTable[1028][2063] = "in,India,91,BSNL"; + m_mTable[1028][1855] = "in,India,91,BSNL"; + m_mTable[1028][847] = "in,India,91,BSNL"; + m_mTable[1028][1647] = "in,India,91,BSNL"; + m_mTable[1028][1375] = "in,India,91,BSNL"; + m_mTable[1028][1839] = "in,India,91,BSNL"; + m_mTable[1029][271] = "in,India,91,Bharti Airtel Limited (Delhi)"; + m_mTable[1028][1951] = "in,India,91,CellOne A&N"; + m_mTable[1028][2095] = "in,India,91,Escorts Telecom Ltd."; + m_mTable[1028][2207] = "in,India,91,Escorts Telecom Ltd."; + m_mTable[1028][2191] = "in,India,91,Escorts Telecom Ltd."; + m_mTable[1028][2175] = "in,India,91,Escorts Telecom Ltd."; + m_mTable[1028][415] = "in,India,91,Escotel Mobile Communications"; + m_mTable[1028][1391] = "in,India,91,Escotel Mobile Communications"; + m_mTable[1028][303] = "in,India,91,Escotel Mobile Communications"; + m_mTable[1029][95] = "in,India,91,Fascel Limited"; + m_mTable[1028][95] = "in,India,91,Fascel"; + m_mTable[1028][1807] = "in,India,91,Hexacom India"; + m_mTable[1028][367] = "in,India,91,Hexcom India"; + m_mTable[1028][1935] = "in,India,91,Idea Cellular Ltd."; + m_mTable[1028][127] = "in,India,91,Idea Cellular Ltd."; + m_mTable[1028][79] = "in,India,91,Idea Cellular Ltd."; + m_mTable[1028][591] = "in,India,91,Idea Cellular Ltd."; + m_mTable[1028][559] = "in,India,91,Idea Cellular Ltd."; + m_mTable[1028][1679] = "in,India,91,Mahanagar Telephone Nigam"; + m_mTable[1028][1695] = "in,India,91,Mahanagar Telephone Nigam"; + m_mTable[1028][2111] = "in,India,91,Reliable Internet Services"; + m_mTable[1028][1295] = "in,India,91,Reliance Telecom Private"; + m_mTable[1028][1663] = "in,India,91,Reliance Telecom Private"; + m_mTable[1028][399] = "in,India,91,Reliance Telecom Private"; + m_mTable[1028][2143] = "in,India,91,Reliance Telecom Private"; + m_mTable[1028][159] = "in,India,91,Reliance Telecom Private"; + m_mTable[1028][879] = "in,India,91,Reliance Telecom Private"; + m_mTable[1028][1327] = "in,India,91,Reliance Telecom Private"; + m_mTable[1028][1055] = "in,India,91,RPG Cellular"; + m_mTable[1028][335] = "in,India,91,Spice"; + m_mTable[1028][1103] = "in,India,91,Spice"; + m_mTable[1028][287] = "in,India,91,Sterling Cellular Ltd."; + m_mTable[1028][783] = "in,India,91,Usha Martin Telecom"; + m_mTable[1296][143] = "id,Indonesia,62,Axis/Natrindo"; + m_mTable[1296][2207] = "id,Indonesia,62,H3G CP"; + m_mTable[1296][31] = "id,Indonesia,62,Indosat/Satelindo/M3"; + m_mTable[1296][543] = "id,Indonesia,62,Indosat/Satelindo/M3"; + m_mTable[1296][15] = "id,Indonesia,62,PT Pasifik Satelit Nusantara (PSN)"; + m_mTable[1296][639] = "id,Indonesia,62,PT Sampoerna Telekomunikasi Indonesia (STI)"; + m_mTable[1296][655] = "id,Indonesia,62,PT Smartfren Telecom Tbk"; + m_mTable[1296][159] = "id,Indonesia,62,PT Smartfren Telecom Tbk"; + m_mTable[1296][287] = "id,Indonesia,62,PT. Excelcom"; + m_mTable[1296][271] = "id,Indonesia,62,Telkomsel"; + m_mTable[2305][319] = "n/a,International Networks,882,Antarctica"; + m_mTable[1074][415] = "ir,Iran,98,Mobile Telecommunications Company of Esfahan JV-PJS (MTCE)"; + m_mTable[1074][1807] = "ir,Iran,98,MTCE"; + m_mTable[1074][863] = "ir,Iran,98,MTN/IranCell"; + m_mTable[1074][815] = "ir,Iran,98,Taliya"; + m_mTable[1074][287] = "ir,Iran,98,TCI / MCI"; + m_mTable[1074][335] = "ir,Iran,98,TKC/KFZO"; + m_mTable[1048][95] = "iq,Iraq,964,Asia Cell"; + m_mTable[1048][2351] = "iq,Iraq,964,Itisaluna and Kalemat"; + m_mTable[1048][1039] = "iq,Iraq,964,Korek"; + m_mTable[1048][2095] = "iq,Iraq,964,Korek"; + m_mTable[1048][1119] = "iq,Iraq,964,Mobitel (Iraq-Kurdistan) and Moutiny"; + m_mTable[1048][527] = "iq,Iraq,964,ZAIN/Atheer"; + m_mTable[1048][783] = "iq,Iraq,964,Orascom Telecom"; + m_mTable[1048][143] = "iq,Iraq,964,Sanatel"; + m_mTable[626][79] = "ie,Ireland,353,Access Telecom Ltd."; + m_mTable[626][159] = "ie,Ireland,353,Clever Communications Ltd"; + m_mTable[626][127] = "ie,Ireland,353,eircom Ltd"; + m_mTable[626][95] = "ie,Ireland,353,H3G"; + m_mTable[626][287] = "ie,Ireland,353,Liffey Telecom"; + m_mTable[626][319] = "ie,Ireland,353,Lycamobile"; + m_mTable[626][63] = "ie,Ireland,353,Meteor Mobile Ltd."; + m_mTable[626][47] = "ie,Ireland,353,O2/Digifone"; + m_mTable[626][31] = "ie,Ireland,353,Vodafone Eircell"; + m_mTable[1061][335] = "il,Israel,972,Alon Cellular Ltd"; + m_mTable[1061][47] = "il,Israel,972,Cellcom ltd."; + m_mTable[1061][143] = "il,Israel,972,Golan Telekom"; + m_mTable[1061][351] = "il,Israel,972,Home Cellular Ltd"; + m_mTable[1061][127] = "il,Israel,972,Hot Mobile/Mirs"; + m_mTable[1061][1919] = "il,Israel,972,Hot Mobile/Mirs"; + m_mTable[1061][31] = "il,Israel,972,Orange/Partner Co. Ltd."; + m_mTable[1061][63] = "il,Israel,972,Pelephone"; + m_mTable[1061][367] = "il,Israel,972,Rami Levy Hashikma Marketing Communications Ltd"; + m_mTable[546][847] = "it,Italy,39,BT Italia SpA"; + m_mTable[546][47] = "it,Italy,39,Elsacom"; + m_mTable[546][2463] = "it,Italy,39,Hi3G"; + m_mTable[546][831] = "it,Italy,39,Hi3G"; + m_mTable[546][1919] = "it,Italy,39,IPSE 2000"; + m_mTable[546][863] = "it,Italy,39,Lycamobile Srl"; + m_mTable[546][127] = "it,Italy,39,Noverca Italia Srl"; + m_mTable[546][783] = "it,Italy,39,RFI Rete Ferroviaria Italiana SpA"; + m_mTable[546][1167] = "it,Italy,39,Telecom Italia Mobile SpA"; + m_mTable[546][1087] = "it,Italy,39,Telecom Italia Mobile SpA"; + m_mTable[546][31] = "it,Italy,39,TIM"; + m_mTable[546][271] = "it,Italy,39,Vodafone"; + m_mTable[546][111] = "it,Italy,39,Vodafone"; + m_mTable[546][2191] = "it,Italy,39,WIND (Blu) -"; + m_mTable[546][1103] = "it,Italy,39,WIND (Blu) -"; + m_mTable[1554][127] = "ci,Ivory Coast,225,Aircomm SA"; + m_mTable[1554][47] = "ci,Ivory Coast,225,Atlantik Tel./Moov"; + m_mTable[1554][79] = "ci,Ivory Coast,225,Comium"; + m_mTable[1554][31] = "ci,Ivory Coast,225,Comstar"; + m_mTable[1554][95] = "ci,Ivory Coast,225,MTN"; + m_mTable[1554][63] = "ci,Ivory Coast,225,Orange"; + m_mTable[1554][111] = "ci,Ivory Coast,225,OriCell"; + m_mTable[824][272] = "jm,Jamaica,1876,Cable & Wireless"; + m_mTable[824][32] = "jm,Jamaica,1876,Cable & Wireless"; + m_mTable[824][384] = "jm,Jamaica,1876,Cable & Wireless"; + m_mTable[824][80] = "jm,Jamaica,1876,DIGICEL/Mossel"; + m_mTable[1088][15] = "jp,Japan,81,eMobile"; + m_mTable[1088][1343] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1919] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][143] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1839] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1359] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1951] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][127] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1855] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1375] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][2191] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1295] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1871] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1807] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][2207] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1311] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1887] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1391] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1089][1807] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1327] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1903] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][1823] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][607] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1615] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][895] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][639] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][47] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][559] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][1087] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][799] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][2175] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][383] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][2351] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1631] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][879] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][655] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][63] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][303] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1423] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][2335] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][815] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1567] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][399] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][2367] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][1039] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1647] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][863] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][671] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][159] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1183] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][831] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1551] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][415] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][2319] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][2383] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][1055] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1663] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][335] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][783] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][271] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1583] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][927] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][591] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][31] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][527] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][1119] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][2447] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][1071] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1679] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][351] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][623] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][287] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1599] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][911] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][319] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][575] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][543] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][1103] = "jp,Japan,81,NTT Docomo"; + m_mTable[1089][2463] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][847] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1695] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][367] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][2463] = "jp,Japan,81,NTT Docomo"; + m_mTable[1088][1935] = "jp,Japan,81,Okinawa Cellular Telephone"; + m_mTable[1089][1615] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][1135] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][2431] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][1071] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][2319] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1089][1631] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][2351] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][2447] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][1087] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][2367] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][1167] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][111] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1089][1567] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][1103] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][2383] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][79] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1089][1583] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][1119] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][2415] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][1039] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1089][1599] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][1151] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][2399] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][1055] = "jp,Japan,81,SoftBank Mobile Corp"; + m_mTable[1088][2111] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][2143] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][2079] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][2063] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][2159] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][2127] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1088][2095] = "jp,Japan,81,KDDI Corporation"; + m_mTable[1046][1919] = "jo,Jordan,962,Orange/Petra"; + m_mTable[1046][63] = "jo,Jordan,962,Umniah Mobile Co."; + m_mTable[1046][47] = "jo,Jordan,962,Xpress"; + m_mTable[1046][31] = "jo,Jordan,962,ZAIN /J.M.T.S"; + m_mTable[1025][31] = "kz,Kazakhstan,7,Beeline/KaR-Tel LLP"; + m_mTable[1025][127] = "kz,Kazakhstan,7,Dalacom/Altel"; + m_mTable[1025][47] = "kz,Kazakhstan,7,K-Cell"; + m_mTable[1025][1919] = "kz,Kazakhstan,7,Tele2/NEO/MTS"; + m_mTable[1593][95] = "ke,Kenya,254,Econet Wireless"; + m_mTable[1593][127] = "ke,Kenya,254,Orange"; + m_mTable[1593][47] = "ke,Kenya,254,Safaricom Ltd."; + m_mTable[1593][63] = "ke,Kenya,254,Zain/Celtel Ltd."; + m_mTable[1349][159] = "ki,Kiribati,686,Kiribati Frigate"; + m_mTable[1127][403] = "kp,Korea N. Dem. People's Rep.,850,Sun Net"; + m_mTable[1104][47] = "kr,Korea S Republic of,82,KT Freetel Co. Ltd."; + m_mTable[1104][79] = "kr,Korea S Republic of,82,KT Freetel Co. Ltd."; + m_mTable[1104][143] = "kr,Korea S Republic of,82,KT Freetel Co. Ltd."; + m_mTable[1104][111] = "kr,Korea S Republic of,82,LG Telecom"; + m_mTable[1104][63] = "kr,Korea S Republic of,82,SK Telecom"; + m_mTable[1104][95] = "kr,Korea S Republic of,82,SK Telecom Co. Ltd"; + m_mTable[1049][79] = "kw,Kuwait,965,Viva"; + m_mTable[1049][63] = "kw,Kuwait,965,Wantaniya"; + m_mTable[1049][47] = "kw,Kuwait,965,Zain"; + m_mTable[1079][63] = "kg,Kyrgyzstan,996,AkTel LLC"; + m_mTable[1079][31] = "kg,Kyrgyzstan,996,Beeline/Bitel"; + m_mTable[1079][95] = "kg,Kyrgyzstan,996,MEGACOM"; + m_mTable[1079][159] = "kg,Kyrgyzstan,996,O!/NUR Telecom"; + m_mTable[1111][47] = "la,Laos P.D.R.,856,ETL Mobile"; + m_mTable[1111][31] = "la,Laos P.D.R.,856,Lao Tel"; + m_mTable[1111][143] = "la,Laos P.D.R.,856,Tigo/Millicom"; + m_mTable[1111][63] = "la,Laos P.D.R.,856,UNITEL/LAT"; + m_mTable[583][95] = "lv,Latvia,371,Bite"; + m_mTable[583][31] = "lv,Latvia,371,Latvian Mobile Phone"; + m_mTable[583][159] = "lv,Latvia,371,SIA Camel Mobile"; + m_mTable[583][143] = "lv,Latvia,371,SIA IZZI"; + m_mTable[583][127] = "lv,Latvia,371,SIA Master Telecom"; + m_mTable[583][111] = "lv,Latvia,371,SIA Rigatta"; + m_mTable[583][47] = "lv,Latvia,371,Tele2"; + m_mTable[583][63] = "lv,Latvia,371,TRIATEL/Telekom Baltija"; + m_mTable[1045][815] = "lb,Lebanon,961,Cellis"; + m_mTable[1045][863] = "lb,Lebanon,961,Cellis"; + m_mTable[1045][831] = "lb,Lebanon,961,Cellis"; + m_mTable[1045][847] = "lb,Lebanon,961,FTML Cellis"; + m_mTable[1045][927] = "lb,Lebanon,961,MIC2/LibanCell"; + m_mTable[1045][911] = "lb,Lebanon,961,MIC2/LibanCell"; + m_mTable[1045][895] = "lb,Lebanon,961,MIC2/LibanCell"; + m_mTable[1045][31] = "lb,Lebanon,961,MIC1 (Alfa)"; + m_mTable[1045][63] = "lb,Lebanon,961,MIC2/LibanCell"; + m_mTable[1045][879] = "lb,Lebanon,961,MIC2/LibanCell"; + m_mTable[1617][47] = "ls,Lesotho,266,Econet/Ezi-cel"; + m_mTable[1617][31] = "ls,Lesotho,266,Vodacom Lesotho"; + m_mTable[1560][127] = "lr,Liberia,231,Celcom"; + m_mTable[1560][63] = "lr,Liberia,231,Celcom"; + m_mTable[1560][79] = "lr,Liberia,231,Comium BVI"; + m_mTable[1560][47] = "lr,Liberia,231,Libercell"; + m_mTable[1560][527] = "lr,Liberia,231,LibTelco"; + m_mTable[1560][31] = "lr,Liberia,231,Lonestar"; + m_mTable[1542][47] = "ly,Libya,218,Al-Madar"; + m_mTable[1542][31] = "ly,Libya,218,Al-Madar"; + m_mTable[1542][111] = "ly,Libya,218,Hatef"; + m_mTable[1542][15] = "ly,Libya,218,Libyana"; + m_mTable[1542][63] = "ly,Libya,218,Libyana"; + m_mTable[661][111] = "li,Liechtenstein,423,CUBIC (Liechtenstein"; + m_mTable[661][127] = "li,Liechtenstein,423,First Mobile AG"; + m_mTable[661][95] = "li,Liechtenstein,423,Mobilkom AG"; + m_mTable[661][47] = "li,Liechtenstein,423,Orange"; + m_mTable[661][31] = "li,Liechtenstein,423,Swisscom FL AG"; + m_mTable[661][1919] = "li,Liechtenstein,423,Alpmobile/Tele2"; + m_mTable[582][47] = "lt,Lithuania,370,Bite"; + m_mTable[582][31] = "lt,Lithuania,370,Omnitel"; + m_mTable[582][63] = "lt,Lithuania,370,Tele2"; + m_mTable[624][1919] = "lu,Luxembourg,352,Millicom Tango GSM"; + m_mTable[624][31] = "lu,Luxembourg,352,P+T LUXGSM"; + m_mTable[624][2463] = "lu,Luxembourg,352,VOXmobile S.A."; + m_mTable[1109][79] = "mo,Macao China,853,C.T.M. TELEMOVEL+"; + m_mTable[1109][31] = "mo,Macao China,853,C.T.M. TELEMOVEL+"; + m_mTable[1109][47] = "mo,Macao China,853,China Telecom"; + m_mTable[1109][95] = "mo,Macao China,853,Hutchison Telephone (Macau) Company Ltd"; + m_mTable[1109][63] = "mo,Macao China,853,Hutchison Telephone (Macau) Company Ltd"; + m_mTable[1109][111] = "mo,Macao China,853,Smartone Mobile"; + m_mTable[1109][15] = "mo,Macao China,853,Smartone Mobile"; + m_mTable[660][1887] = "mk,Macedonia,389,MTS/Cosmofone"; + m_mTable[660][47] = "mk,Macedonia,389,MTS/Cosmofone"; + m_mTable[660][31] = "mk,Macedonia,389,T-Mobile/Mobimak"; + m_mTable[660][63] = "mk,Macedonia,389,VIP Mobile"; + m_mTable[1606][31] = "mg,Madagascar,261,MADACOM"; + m_mTable[1606][47] = "mg,Madagascar,261,Orange/Soci"; + m_mTable[1606][63] = "mg,Madagascar,261,Sacel"; + m_mTable[1606][79] = "mg,Madagascar,261,Telma"; + m_mTable[1616][31] = "mw,Malawi,265,TNM/Telekom Network Ltd."; + m_mTable[1616][271] = "mw,Malawi,265,Zain/Celtel ltd."; + m_mTable[1282][31] = "my,Malaysia,60,Art900"; + m_mTable[1282][337] = "my,Malaysia,60,Baraka Telecom Sdn Bhd"; + m_mTable[1282][415] = "my,Malaysia,60,CelCom"; + m_mTable[1282][319] = "my,Malaysia,60,CelCom"; + m_mTable[1282][367] = "my,Malaysia,60,Digi Telecommunications"; + m_mTable[1282][271] = "my,Malaysia,60,Digi Telecommunications"; + m_mTable[1282][527] = "my,Malaysia,60,Electcoms Wireless Sdn Bhd"; + m_mTable[1282][383] = "my,Malaysia,60,Maxis"; + m_mTable[1282][303] = "my,Malaysia,60,Maxis"; + m_mTable[1282][287] = "my,Malaysia,60,MTX Utara"; + m_mTable[1282][339] = "my,Malaysia,60,Packet One Networks (Malaysia) Sdn Bhd"; + m_mTable[1282][341] = "my,Malaysia,60,Samata Communications Sdn Bhd"; + m_mTable[1282][340] = "my,Malaysia,60,Talk Focus Sdn Bhd"; + m_mTable[1282][399] = "my,Malaysia,60,U Mobile"; + m_mTable[1282][338] = "my,Malaysia,60,YES"; + m_mTable[1138][31] = "mv,Maldives,960,Dhiraagu/C&W"; + m_mTable[1138][47] = "mv,Maldives,960,Wataniya/WMOBILE"; + m_mTable[1552][31] = "ml,Mali,223,Malitel"; + m_mTable[1552][47] = "ml,Mali,223,Orange/IKATEL"; + m_mTable[632][543] = "mt,Malta,356,GO/Mobisle"; + m_mTable[632][1919] = "mt,Malta,356,Melita"; + m_mTable[632][31] = "mt,Malta,356,Vodafone"; + m_mTable[832][303] = "mq,Martinique (French Department of),596,UTS Caraibe"; + m_mTable[1545][47] = "mr,Mauritania,222,Chinguitel SA"; + m_mTable[1545][31] = "mr,Mauritania,222,Mattel"; + m_mTable[1545][271] = "mr,Mauritania,222,Mauritel"; + m_mTable[1559][271] = "mu,Mauritius,230,Emtel Ltd"; + m_mTable[1559][47] = "mu,Mauritius,230,Mahanagar Telephone"; + m_mTable[1559][63] = "mu,Mauritius,230,Mahanagar Telephone"; + m_mTable[1559][31] = "mu,Mauritius,230,Orange/Cellplus"; + m_mTable[820][15] = "mx,Mexico,52,Axtel"; + m_mTable[820][1295] = "mx,Mexico,52,IUSACell/UneFon"; + m_mTable[820][80] = "mx,Mexico,52,IUSACell/UneFon"; + m_mTable[820][64] = "mx,Mexico,52,IUSACell/UneFon"; + m_mTable[820][79] = "mx,Mexico,52,IUSACell/UneFon"; + m_mTable[820][63] = "mx,Mexico,52,Movistar/Pegaso"; + m_mTable[820][48] = "mx,Mexico,52,Movistar/Pegaso"; + m_mTable[820][16] = "mx,Mexico,52,NEXTEL"; + m_mTable[820][31] = "mx,Mexico,52,NEXTEL"; + m_mTable[820][144] = "mx,Mexico,52,NEXTEL"; + m_mTable[820][128] = "mx,Mexico,52,Operadora Unefon SA de CV"; + m_mTable[820][112] = "mx,Mexico,52,Operadora Unefon SA de CV"; + m_mTable[820][96] = "mx,Mexico,52,SAI PCS"; + m_mTable[820][32] = "mx,Mexico,52,TelCel/America Movil"; + m_mTable[820][47] = "mx,Mexico,52,TelCel/America Movil"; + m_mTable[1360][31] = "fm,Micronesia,691,FSM Telecom"; + m_mTable[601][79] = "md,Moldova,373,Eventis Mobile"; + m_mTable[601][95] = "md,Moldova,373,IDC/Unite"; + m_mTable[601][63] = "md,Moldova,373,IDC/Unite"; + m_mTable[601][2463] = "md,Moldova,373,IDC/Unite"; + m_mTable[601][47] = "md,Moldova,373,Moldcell"; + m_mTable[601][31] = "md,Moldova,373,Orange/Voxtel"; + m_mTable[530][271] = "mc,Monaco,377,Monaco Telecom"; + m_mTable[530][31] = "mc,Monaco,377,Monaco Telecom"; + m_mTable[1064][2447] = "mn,Mongolia,976,G-Mobile Corporation Ltd"; + m_mTable[1064][2463] = "mn,Mongolia,976,Mobicom"; + m_mTable[1064][15] = "mn,Mongolia,976,Skytel Co. Ltd"; + m_mTable[1064][2191] = "mn,Mongolia,976,Unitel"; + m_mTable[663][47] = "me,Montenegro,382,Monet/T-mobile"; + m_mTable[663][63] = "me,Montenegro,382,Mtel"; + m_mTable[663][31] = "me,Montenegro,382,Promonte GSM"; + m_mTable[852][2144] = "ms,Montserrat,1664,Cable & Wireless"; + m_mTable[1540][31] = "ma,Morocco,212,IAM/Itissallat"; + m_mTable[1540][47] = "ma,Morocco,212,INWI/WANA"; + m_mTable[1540][15] = "ma,Morocco,212,Medi Telecom"; + m_mTable[1603][31] = "mz,Mozambique,258,mCel"; + m_mTable[1603][63] = "mz,Mozambique,258,Movitel"; + m_mTable[1603][79] = "mz,Mozambique,258,Vodacom"; + m_mTable[1609][63] = "na,Namibia,264,Leo / Orascom"; + m_mTable[1609][31] = "na,Namibia,264,MTC"; + m_mTable[1609][47] = "na,Namibia,264,Switch/Nam. Telec."; + m_mTable[1065][47] = "np,Nepal,977,Ncell"; + m_mTable[1065][31] = "np,Nepal,977,NT Mobile / Namaste"; + m_mTable[1065][79] = "np,Nepal,977,Smart Cell"; + m_mTable[516][335] = "nl,Netherlands,31,6GMOBILE BV"; + m_mTable[516][575] = "nl,Netherlands,31,Aspider Solutions"; + m_mTable[516][95] = "nl,Netherlands,31,Elephant Talk Communications Premium Rate Services Netherlands BV"; + m_mTable[516][383] = "nl,Netherlands,31,Intercity Mobile Communications BV"; + m_mTable[516][271] = "nl,Netherlands,31,KPN Telecom B.V."; + m_mTable[516][143] = "nl,Netherlands,31,KPN Telecom B.V."; + m_mTable[516][1695] = "nl,Netherlands,31,KPN Telecom B.V."; + m_mTable[516][303] = "nl,Netherlands,31,KPN/Telfort"; + m_mTable[516][655] = "nl,Netherlands,31,Lancelot BV"; + m_mTable[516][159] = "nl,Netherlands,31,Lycamobile Ltd"; + m_mTable[516][111] = "nl,Netherlands,31,Mundio/Vectone Mobile"; + m_mTable[516][543] = "nl,Netherlands,31,NS Railinfrabeheer B.V."; + m_mTable[516][591] = "nl,Netherlands,31,Private Mobility Nederland BV"; + m_mTable[516][2447] = "nl,Netherlands,31,T-Mobile B.V."; + m_mTable[516][367] = "nl,Netherlands,31,T-Mobile B.V."; + m_mTable[516][527] = "nl,Netherlands,31,T-mobile/former Orange"; + m_mTable[516][47] = "nl,Netherlands,31,Tele2"; + m_mTable[516][127] = "nl,Netherlands,31,Teleena Holding BV"; + m_mTable[516][1679] = "nl,Netherlands,31,Unify Mobile"; + m_mTable[516][399] = "nl,Netherlands,31,UPC Nederland BV"; + m_mTable[516][79] = "nl,Netherlands,31,Vodafone Libertel"; + m_mTable[516][63] = "nl,Netherlands,31,Voiceworks Mobile BV"; + m_mTable[516][351] = "nl,Netherlands,31,Ziggo BV"; + m_mTable[866][1584] = "an,Netherlands Antilles,599,Cingular Wireless"; + m_mTable[866][1311] = "an,Netherlands Antilles,599,TELCELL GSM"; + m_mTable[866][2335] = "an,Netherlands Antilles,599,SETEL GSM"; + m_mTable[866][2385] = "an,Netherlands Antilles,599,UTS Wireless"; + m_mTable[1350][31] = "nc,New Caledonia,687,OPT Mobilis"; + m_mTable[1328][655] = "nz,New Zealand,64,2degrees"; + m_mTable[1328][95] = "nz,New Zealand,64,NZ Telecom CDMA"; + m_mTable[1328][47] = "nz,New Zealand,64,NZ Telecom CDMA"; + m_mTable[1328][79] = "nz,New Zealand,64,Telstra"; + m_mTable[1328][591] = "nz,New Zealand,64,Two Degrees Mobile Ltd"; + m_mTable[1328][31] = "nz,New Zealand,64,Vodafone"; + m_mTable[1328][63] = "nz,New Zealand,64,Walker Wireless Ltd."; + m_mTable[1808][543] = "ni,Nicaragua,505,Empresa Nicaraguense de Telecomunicaciones SA (ENITEL)"; + m_mTable[1808][783] = "ni,Nicaragua,505,Movistar"; + m_mTable[1808][1855] = "ni,Nicaragua,505,Claro"; + m_mTable[1556][63] = "ne,Niger,227,Etisalat/TeleCel"; + m_mTable[1556][79] = "ne,Niger,227,Orange/Sahelc."; + m_mTable[1556][31] = "ne,Niger,227,Orange/Sahelc."; + m_mTable[1556][47] = "ne,Niger,227,Zain/CelTel"; + m_mTable[1569][527] = "ng,Nigeria,234,Airtel/ZAIN/Econet"; + m_mTable[1569][1551] = "ng,Nigeria,234,ETISALAT"; + m_mTable[1569][1295] = "ng,Nigeria,234,Glo Mobile"; + m_mTable[1569][1039] = "ng,Nigeria,234,M-Tel/Nigeria Telecom. Ltd."; + m_mTable[1569][783] = "ng,Nigeria,234,MTN"; + m_mTable[1569][2463] = "ng,Nigeria,234,Starcomms"; + m_mTable[1569][31] = "ng,Nigeria,234,Visafone"; + m_mTable[1569][607] = "ng,Nigeria,234,Visafone"; + m_mTable[1365][31] = "nu,Niue,683,Niue Telecom"; + m_mTable[578][159] = "no,Norway,47,Com4 AS"; + m_mTable[578][543] = "no,Norway,47,Jernbaneverket (GSM-R)"; + m_mTable[578][527] = "no,Norway,47,Jernbaneverket (GSM-R)"; + m_mTable[578][575] = "no,Norway,47,Lycamobile Ltd"; + m_mTable[578][47] = "no,Norway,47,Netcom"; + m_mTable[578][559] = "no,Norway,47,Network Norway AS"; + m_mTable[578][95] = "no,Norway,47,Network Norway AS"; + m_mTable[578][111] = "no,Norway,47,ICE Nordisk Mobiltelefon AS"; + m_mTable[578][143] = "no,Norway,47,TDC Mobil A/S"; + m_mTable[578][79] = "no,Norway,47,Tele2"; + m_mTable[578][31] = "no,Norway,47,Telenor"; + m_mTable[578][303] = "no,Norway,47,Telenor"; + m_mTable[578][63] = "no,Norway,47,Teletopia"; + m_mTable[578][127] = "no,Norway,47,Ventelo AS"; + m_mTable[1058][63] = "om,Oman,968,Nawras"; + m_mTable[1058][47] = "om,Oman,968,Oman Mobile/GTO"; + m_mTable[1040][143] = "pk,Pakistan,92,Instaphone"; + m_mTable[1040][31] = "pk,Pakistan,92,Mobilink"; + m_mTable[1040][111] = "pk,Pakistan,92,Telenor"; + m_mTable[1040][63] = "pk,Pakistan,92,UFONE/PAKTel"; + m_mTable[1040][127] = "pk,Pakistan,92,Warid Telecom"; + m_mTable[1040][79] = "pk,Pakistan,92,ZONG/CMPak"; + m_mTable[1362][2063] = "pw,Palau (Republic of),680,Palau Mobile Corp. (PMC) (Palau"; + m_mTable[1362][31] = "pw,Palau (Republic of),680,Palau National Communications Corp. (PNCC) (Palau"; + m_mTable[1061][95] = "ps,Palestinian Territory,970,Jawwal"; + m_mTable[1061][111] = "ps,Palestinian Territory,970,Wataniya Mobile"; + m_mTable[1812][31] = "pa,Panama,507,Cable & Wireless S.A."; + m_mTable[1812][63] = "pa,Panama,507,Claro"; + m_mTable[1812][79] = "pa,Panama,507,Digicel"; + m_mTable[1812][32] = "pa,Panama,507,Movistar"; + m_mTable[1812][47] = "pa,Panama,507,Movistar"; + m_mTable[1335][63] = "pg,Papua New Guinea,675,Digicel"; + m_mTable[1335][47] = "pg,Papua New Guinea,675,GreenCom PNG Ltd"; + m_mTable[1335][31] = "pg,Papua New Guinea,675,Pacific Mobile"; + m_mTable[1860][47] = "py,Paraguay,595,Claro/Hutchison"; + m_mTable[1860][63] = "py,Paraguay,595,Compa"; + m_mTable[1860][31] = "py,Paraguay,595,Hola/VOX"; + m_mTable[1860][95] = "py,Paraguay,595,TIM/Nucleo/Personal"; + m_mTable[1860][79] = "py,Paraguay,595,Tigo/Telecel"; + m_mTable[1814][271] = "pe,Peru,51,Claro /Amer.Mov./TIM"; + m_mTable[1814][527] = "pe,Peru,51,Claro /Amer.Mov./TIM"; + m_mTable[1814][31] = "pe,Peru,51,GlobalStar"; + m_mTable[1814][47] = "pe,Peru,51,GlobalStar"; + m_mTable[1814][111] = "pe,Peru,51,Movistar"; + m_mTable[1814][127] = "pe,Peru,51,Nextel"; + m_mTable[1301][15] = "ph,Philippines,63,Fix Line"; + m_mTable[1301][47] = "ph,Philippines,63,Globe Telecom"; + m_mTable[1301][31] = "ph,Philippines,63,Globe Telecom"; + m_mTable[1301][2191] = "ph,Philippines,63,Next Mobile"; + m_mTable[1301][399] = "ph,Philippines,63,RED Mobile/Cure"; + m_mTable[1301][63] = "ph,Philippines,63,Smart"; + m_mTable[1301][95] = "ph,Philippines,63,SUN/Digitel"; + m_mTable[608][383] = "pl,Poland,48,Aero2 SP."; + m_mTable[608][399] = "pl,Poland,48,AMD Telecom."; + m_mTable[608][911] = "pl,Poland,48,CallFreedom Sp. z o.o."; + m_mTable[608][303] = "pl,Poland,48,Cyfrowy POLSAT S.A."; + m_mTable[608][143] = "pl,Poland,48,e-Telko"; + m_mTable[608][159] = "pl,Poland,48,Lycamobile"; + m_mTable[608][367] = "pl,Poland,48,Mobyland"; + m_mTable[608][879] = "pl,Poland,48,Mundio Mobile Sp. z o.o."; + m_mTable[608][127] = "pl,Poland,48,Play/P4"; + m_mTable[608][287] = "pl,Poland,48,NORDISK Polska"; + m_mTable[608][95] = "pl,Poland,48,Orange/IDEA/Centertel"; + m_mTable[608][63] = "pl,Poland,48,Orange/IDEA/Centertel"; + m_mTable[608][863] = "pl,Poland,48,PKP Polskie Linie Kolejowe S.A."; + m_mTable[608][111] = "pl,Poland,48,Play/P4"; + m_mTable[608][2447] = "pl,Poland,48,Play/P4"; + m_mTable[608][31] = "pl,Poland,48,Polkomtel/Plus"; + m_mTable[608][319] = "pl,Poland,48,Sferia"; + m_mTable[608][335] = "pl,Poland,48,Sferia"; + m_mTable[608][271] = "pl,Poland,48,Sferia"; + m_mTable[608][847] = "pl,Poland,48,T-Mobile/ERA"; + m_mTable[608][47] = "pl,Poland,48,T-Mobile/ERA"; + m_mTable[608][351] = "pl,Poland,48,Tele2"; + m_mTable[608][79] = "pl,Poland,48,Tele2"; + m_mTable[616][79] = "pt,Portugal,351,CTT - Correios de Portugal SA"; + m_mTable[616][127] = "pt,Portugal,351,Optimus"; + m_mTable[616][63] = "pt,Portugal,351,Optimus"; + m_mTable[616][111] = "pt,Portugal,351,TMN"; + m_mTable[616][31] = "pt,Portugal,351,Vodafone"; + m_mTable[816][287] = "pr,Puerto Rico,1787,Puerto Rico Telephone Company Inc. (PRTC)"; + m_mTable[816][272] = "pr,Puerto Rico,1787,Puerto Rico Telephone Company Inc. (PRTC)"; + m_mTable[1063][31] = "qa,Qatar,974,Qtel"; + m_mTable[1063][47] = "qa,Qatar,974,Vodafone"; + m_mTable[1607][15] = "re,Reunion,262,Orange"; + m_mTable[1607][47] = "re,Reunion,262,Outremer Telecom"; + m_mTable[1607][271] = "re,Reunion,262,SFR"; + m_mTable[550][63] = "ro,Romania,40,Cosmote"; + m_mTable[550][287] = "ro,Romania,40,Enigma Systems"; + m_mTable[550][271] = "ro,Romania,40,Orange"; + m_mTable[550][95] = "ro,Romania,40,RCS&RDS Digi Mobile"; + m_mTable[550][47] = "ro,Romania,40,Romtelecom SA"; + m_mTable[550][111] = "ro,Romania,40,Telemobil/Zapp"; + m_mTable[550][31] = "ro,Romania,40,Vodafone"; + m_mTable[550][79] = "ro,Romania,40,Telemobil/Zapp"; + m_mTable[592][303] = "ru,Russian Federation,79,Baykal Westcom"; + m_mTable[592][655] = "ru,Russian Federation,79,BeeLine/VimpelCom"; + m_mTable[592][271] = "ru,Russian Federation,79,DTC/Don Telecom"; + m_mTable[592][319] = "ru,Russian Federation,79,Kuban GSM"; + m_mTable[592][863] = "ru,Russian Federation,79,LLC Ekaterinburg-2000"; + m_mTable[592][47] = "ru,Russian Federation,79,Megafon"; + m_mTable[592][31] = "ru,Russian Federation,79,MTS"; + m_mTable[592][63] = "ru,Russian Federation,79,NCC"; + m_mTable[592][367] = "ru,Russian Federation,79,NTC"; + m_mTable[592][415] = "ru,Russian Federation,79,OJSC Altaysvyaz"; + m_mTable[592][287] = "ru,Russian Federation,79,Orensot"; + m_mTable[592][2351] = "ru,Russian Federation,79,Printelefone"; + m_mTable[592][79] = "ru,Russian Federation,79,Sibchallenge"; + m_mTable[592][1103] = "ru,Russian Federation,79,StavTelesot"; + m_mTable[592][527] = "ru,Russian Federation,79,Tele2/ECC/Volgogr."; + m_mTable[592][2367] = "ru,Russian Federation,79,Telecom XXL"; + m_mTable[592][927] = "ru,Russian Federation,79,UralTel"; + m_mTable[592][383] = "ru,Russian Federation,79,UralTel"; + m_mTable[592][2463] = "ru,Russian Federation,79,VimpelCom"; + m_mTable[592][95] = "ru,Russian Federation,79,Yenisey Telecom"; + m_mTable[592][351] = "ru,Russian Federation,79,ZAO SMARTS"; + m_mTable[592][127] = "ru,Russian Federation,79,ZAO SMARTS"; + m_mTable[1589][335] = "rw,Rwanda,250,Airtel Rwanda Ltd"; + m_mTable[1589][271] = "rw,Rwanda,250,MTN/Rwandacell"; + m_mTable[1589][319] = "rw,Rwanda,250,TIGO"; + m_mTable[854][272] = "kn,Saint Kitts and Nevis,1869,Cable & Wireless"; + m_mTable[854][1295] = "kn,Saint Kitts and Nevis,1869,Digicel"; + m_mTable[854][1807] = "kn,Saint Kitts and Nevis,1869,UTS Cariglobe"; + m_mTable[856][272] = "lc,Saint Lucia,1758,Cable & Wireless"; + m_mTable[856][783] = "lc,Saint Lucia,1758,Cingular Wireless"; + m_mTable[856][1295] = "lc,Saint Lucia,1758,Digicel (St Lucia) Limited"; + m_mTable[1353][639] = "ws,Samoa,685,Samoatel Mobile"; + m_mTable[1353][31] = "ws,Samoa,685,Telecom Samoa Cellular Ltd."; + m_mTable[658][31] = "sm,San Marino,378,Prima Telecom"; + m_mTable[1574][31] = "st,Sao Tome & Principe,239,CSTmovel"; + m_mTable[2305][335] = "n/a,Satellite Networks,870,AeroMobile"; + m_mTable[2305][287] = "n/a,Satellite Networks,870,InMarSAT"; + m_mTable[2305][303] = "n/a,Satellite Networks,870,Maritime Communications Partner AS"; + m_mTable[2305][95] = "n/a,Satellite Networks,870,Thuraya Satellite"; + m_mTable[1056][127] = "sa,Saudi Arabia,966,Zain"; + m_mTable[1056][63] = "sa,Saudi Arabia,966,Etihad/Etisalat/Mobily"; + m_mTable[1056][31] = "sa,Saudi Arabia,966,STC/Al Jawal"; + m_mTable[1056][79] = "sa,Saudi Arabia,966,Zain"; + m_mTable[1544][63] = "sn,Senegal,221,Expresso/Sudatel"; + m_mTable[1544][31] = "sn,Senegal,221,Orange/Sonatel"; + m_mTable[1544][47] = "sn,Senegal,221,Sentel GSM"; + m_mTable[544][63] = "rs,Serbia,381,MTS/Telekom Srbija"; + m_mTable[544][47] = "rs,Serbia,381,Telenor/Mobtel"; + m_mTable[544][31] = "rs,Serbia,381,Telenor/Mobtel"; + m_mTable[544][95] = "rs,Serbia,381,VIP Mobile"; + m_mTable[1587][271] = "sc,Seychelles,248,Airtel"; + m_mTable[1587][31] = "sc,Seychelles,248,C&W"; + m_mTable[1587][47] = "sc,Seychelles,248,Smartcom"; + m_mTable[1561][63] = "sl,Sierra Leone,232,Africel"; + m_mTable[1561][31] = "sl,Sierra Leone,232,Zain/Celtel"; + m_mTable[1561][79] = "sl,Sierra Leone,232,Comium"; + m_mTable[1561][95] = "sl,Sierra Leone,232,Africel"; + m_mTable[1561][47] = "sl,Sierra Leone,232,Tigo/Millicom"; + m_mTable[1561][607] = "sl,Sierra Leone,232,Mobitel"; + m_mTable[1317][303] = "sg,Singapore,65,GRID Communications Pte Ltd"; + m_mTable[1317][63] = "sg,Singapore,65,MobileOne Ltd"; + m_mTable[1317][47] = "sg,Singapore,65,Singtel"; + m_mTable[1317][31] = "sg,Singapore,65,Singtel"; + m_mTable[1317][127] = "sg,Singapore,65,Singtel"; + m_mTable[1317][111] = "sg,Singapore,65,Starhub"; + m_mTable[1317][95] = "sg,Singapore,65,Starhub"; + m_mTable[561][111] = "sk,Slovakia,421,O2"; + m_mTable[561][95] = "sk,Slovakia,421,Orange"; + m_mTable[561][31] = "sk,Slovakia,421,Orange"; + m_mTable[561][351] = "sk,Slovakia,421,Orange"; + m_mTable[561][47] = "sk,Slovakia,421,T-Mobile"; + m_mTable[561][79] = "sk,Slovakia,421,T-Mobile"; + m_mTable[561][2463] = "sk,Slovakia,421,Zeleznice Slovenskej republiky (ZSR)"; + m_mTable[659][1055] = "si,Slovenia,386,Mobitel"; + m_mTable[659][1039] = "si,Slovenia,386,SI.Mobil"; + m_mTable[659][271] = "si,Slovenia,386,Slovenske zeleznice d.o.o."; + m_mTable[659][1615] = "si,Slovenia,386,T-2 d.o.o."; + m_mTable[659][1807] = "si,Slovenia,386,TusMobil/VEGA"; + m_mTable[1344][47] = "sb,Solomon Islands,677,bemobile"; + m_mTable[1344][271] = "sb,Solomon Islands,677,BREEZE"; + m_mTable[1344][31] = "sb,Solomon Islands,677,BREEZE"; + m_mTable[1591][783] = "so,Somalia,252,Golis"; + m_mTable[1591][415] = "so,Somalia,252,HorTel"; + m_mTable[1591][271] = "so,Somalia,252,Nationlink"; + m_mTable[1591][1551] = "so,Somalia,252,Nationlink"; + m_mTable[1591][79] = "so,Somalia,252,Somafone"; + m_mTable[1591][2095] = "so,Somalia,252,Telcom Mobile Somalia"; + m_mTable[1591][31] = "so,Somalia,252,Telesom"; + m_mTable[1621][47] = "za,South Africa,27,8.ta"; + m_mTable[1621][543] = "za,South Africa,27,Cape Town Metropolitan"; + m_mTable[1621][127] = "za,South Africa,27,Cell C"; + m_mTable[1621][271] = "za,South Africa,27,MTN"; + m_mTable[1621][303] = "za,South Africa,27,MTN"; + m_mTable[1621][111] = "za,South Africa,27,Sentech"; + m_mTable[1621][31] = "za,South Africa,27,Vodacom"; + m_mTable[1621][415] = "za,South Africa,27,Wireless Business Solutions (Pty) Ltd"; + m_mTable[1625][63] = "ss,South Sudan (Republic of),211,Gemtel Ltd (South Sudan"; + m_mTable[1625][47] = "ss,South Sudan (Republic of),211,MTN South Sudan (South Sudan"; + m_mTable[1625][79] = "ss,South Sudan (Republic of),211,Network of The World Ltd (NOW) (South Sudan"; + m_mTable[1625][111] = "ss,South Sudan (Republic of),211,Zain South Sudan (South Sudan"; + m_mTable[532][575] = "es,Spain,34,Lycamobile SL"; + m_mTable[532][559] = "es,Spain,34,Movistar"; + m_mTable[532][351] = "es,Spain,34,BT Espana SAU"; + m_mTable[532][399] = "es,Spain,34,Cableuropa SAU (ONO)"; + m_mTable[532][143] = "es,Spain,34,Euskaltel SA"; + m_mTable[532][527] = "es,Spain,34,fonYou Wireless SL"; + m_mTable[532][543] = "es,Spain,34,Jazz Telecom SAU"; + m_mTable[532][623] = "es,Spain,34,Lleida"; + m_mTable[532][607] = "es,Spain,34,Lycamobile SL"; + m_mTable[532][127] = "es,Spain,34,Movistar"; + m_mTable[532][95] = "es,Spain,34,Movistar"; + m_mTable[532][287] = "es,Spain,34,Orange"; + m_mTable[532][159] = "es,Spain,34,Orange"; + m_mTable[532][63] = "es,Spain,34,Orange"; + m_mTable[532][383] = "es,Spain,34,R Cable y Telec. Galicia SA"; + m_mTable[532][415] = "es,Spain,34,Simyo/KPN"; + m_mTable[532][367] = "es,Spain,34,Telecable de Asturias SA"; + m_mTable[532][639] = "es,Spain,34,Truphone"; + m_mTable[532][31] = "es,Spain,34,Vodafone"; + m_mTable[532][111] = "es,Spain,34,Vodafone Enabler Espana SL"; + m_mTable[532][79] = "es,Spain,34,Yoigo"; + m_mTable[1043][95] = "lk,Sri Lanka,94,Bharti Airtel"; + m_mTable[1043][63] = "lk,Sri Lanka,94,Etisalat/Tigo"; + m_mTable[1043][143] = "lk,Sri Lanka,94,H3G Hutchison"; + m_mTable[1043][31] = "lk,Sri Lanka,94,Mobitel Ltd."; + m_mTable[1043][47] = "lk,Sri Lanka,94,MTN/Dialog"; + m_mTable[776][31] = "pm,St. Pierre & Miquelon,508,Ameris"; + m_mTable[864][272] = "vc,St. Vincent & Gren.,1784,C & W"; + m_mTable[864][271] = "vc,St. Vincent & Gren.,1784,Cingular"; + m_mTable[864][256] = "vc,St. Vincent & Gren.,1784,Cingular"; + m_mTable[864][80] = "vc,St. Vincent & Gren.,1784,Digicel"; + m_mTable[864][1807] = "vc,St. Vincent & Gren.,1784,Digicel"; + m_mTable[1588][15] = "sd,Sudan,249,Canar Telecom"; + m_mTable[1588][47] = "sd,Sudan,249,MTN"; + m_mTable[1588][559] = "sd,Sudan,249,MTN"; + m_mTable[1588][351] = "sd,Sudan,249,Sudani One"; + m_mTable[1588][127] = "sd,Sudan,249,Sudani One"; + m_mTable[1588][95] = "sd,Sudan,249,Vivacell"; + m_mTable[1588][143] = "sd,Sudan,249,Vivacell"; + m_mTable[1588][111] = "sd,Sudan,249,ZAIN/Mobitel"; + m_mTable[1588][31] = "sd,Sudan,249,ZAIN/Mobitel"; + m_mTable[1862][63] = "sr,Suriname,597,Digicel"; + m_mTable[1862][31] = "sr,Suriname,597,Telesur"; + m_mTable[1862][47] = "sr,Suriname,597,Telecommunicatiebedrijf Suriname (TELESUR)"; + m_mTable[1862][79] = "sr,Suriname,597,UNIQA"; + m_mTable[1619][271] = "sz,Swaziland,268,Swazi MTN"; + m_mTable[1619][31] = "sz,Swaziland,268,SwaziTelecom"; + m_mTable[576][863] = "se,Sweden,46,42 Telecom AB"; + m_mTable[576][367] = "se,Sweden,46,42 Telecom AB"; + m_mTable[576][623] = "se,Sweden,46,Beepsend"; + m_mTable[576][783] = "se,Sweden,46,NextGen Mobile Ltd (CardBoardFish)"; + m_mTable[576][655] = "se,Sweden,46,CoolTEL Aps"; + m_mTable[576][607] = "se,Sweden,46,Digitel Mobile Srl"; + m_mTable[576][559] = "se,Sweden,46,Eu Tel AB"; + m_mTable[576][639] = "se,Sweden,46,Fogg Mobile AB"; + m_mTable[576][399] = "se,Sweden,46,Generic Mobile Systems Sweden AB"; + m_mTable[576][383] = "se,Sweden,46,Gotalandsnatet AB"; + m_mTable[576][47] = "se,Sweden,46,H3G Access AB"; + m_mTable[576][79] = "se,Sweden,46,H3G Access AB"; + m_mTable[576][879] = "se,Sweden,46,ID Mobile"; + m_mTable[576][575] = "se,Sweden,46,Infobip Ltd."; + m_mTable[576][287] = "se,Sweden,46,Lindholmen Science Park AB"; + m_mTable[576][303] = "se,Sweden,46,Lycamobile Ltd"; + m_mTable[576][671] = "se,Sweden,46,Mercury International Carrier Services"; + m_mTable[576][415] = "se,Sweden,46,Mundio Mobile (Sweden) Ltd"; + m_mTable[576][271] = "se,Sweden,46,Spring Mobil AB"; + m_mTable[576][95] = "se,Sweden,46,Svenska UMTS-N"; + m_mTable[576][335] = "se,Sweden,46,TDC Sverige AB"; + m_mTable[576][127] = "se,Sweden,46,Tele2 Sverige AB"; + m_mTable[576][111] = "se,Sweden,46,Telenor (Vodafone)"; + m_mTable[576][591] = "se,Sweden,46,Telenor (Vodafone)"; + m_mTable[576][143] = "se,Sweden,46,Telenor (Vodafone)"; + m_mTable[576][31] = "se,Sweden,46,Telia Mobile"; + m_mTable[576][319] = "se,Sweden,46,Ventelo Sverige AB"; + m_mTable[576][527] = "se,Sweden,46,Wireless Maingate AB"; + m_mTable[576][351] = "se,Sweden,46,Wireless Maingate Nordic AB"; + m_mTable[552][1311] = "ch,Switzerland,41,BebbiCell AG"; + m_mTable[552][159] = "ch,Switzerland,41,Comfone AG"; + m_mTable[552][95] = "ch,Switzerland,41,Comfone AG"; + m_mTable[552][127] = "ch,Switzerland,41,TDC Sunrise"; + m_mTable[552][1359] = "ch,Switzerland,41,Lycamobile AG"; + m_mTable[552][1327] = "ch,Switzerland,41,Mundio Mobile AG"; + m_mTable[552][63] = "ch,Switzerland,41,Orange"; + m_mTable[552][31] = "ch,Switzerland,41,Swisscom"; + m_mTable[552][303] = "ch,Switzerland,41,TDC Sunrise"; + m_mTable[552][47] = "ch,Switzerland,41,TDC Sunrise"; + m_mTable[552][143] = "ch,Switzerland,41,TDC Sunrise"; + m_mTable[552][1343] = "ch,Switzerland,41,upc cablecom GmbH"; + m_mTable[1047][47] = "sy,Syrian Arab Republic,963,MTN/Spacetel"; + m_mTable[1047][159] = "sy,Syrian Arab Republic,963,Syriatel Holdings"; + m_mTable[1047][31] = "sy,Syrian Arab Republic,963,Syriatel Holdings"; + m_mTable[1126][1679] = "tw,Taiwan,886,ACeS Taiwan - ACeS Taiwan Telecommunications Co Ltd"; + m_mTable[1126][95] = "tw,Taiwan,886,Asia Pacific Telecom Co. Ltd (APT)"; + m_mTable[1126][287] = "tw,Taiwan,886,Chunghwa Telecom LDM"; + m_mTable[1126][2351] = "tw,Taiwan,886,Chunghwa Telecom LDM"; + m_mTable[1126][127] = "tw,Taiwan,886,Far EasTone"; + m_mTable[1126][47] = "tw,Taiwan,886,Far EasTone"; + m_mTable[1126][111] = "tw,Taiwan,886,Far EasTone"; + m_mTable[1126][63] = "tw,Taiwan,886,Far EasTone"; + m_mTable[1126][31] = "tw,Taiwan,886,Far EasTone"; + m_mTable[1126][271] = "tw,Taiwan,886,Global Mobile Corp."; + m_mTable[1126][1391] = "tw,Taiwan,886,International Telecom Co. Ltd (FITEL)"; + m_mTable[1126][2191] = "tw,Taiwan,886,KG Telecom"; + m_mTable[1126][2431] = "tw,Taiwan,886,Taiwan Cellular"; + m_mTable[1126][2367] = "tw,Taiwan,886,Mobitai"; + m_mTable[1126][2463] = "tw,Taiwan,886,TransAsia"; + m_mTable[1126][2207] = "tw,Taiwan,886,VIBO"; + m_mTable[1126][159] = "tw,Taiwan,886,VMAX Telecom Co. Ltd"; + m_mTable[1078][79] = "tk,Tajikistan,992,Babilon-M"; + m_mTable[1078][95] = "tk,Tajikistan,992,Bee Line"; + m_mTable[1078][47] = "tk,Tajikistan,992,CJSC Indigo Tajikistan"; + m_mTable[1078][303] = "tk,Tajikistan,992,Tcell/JC Somoncom"; + m_mTable[1078][63] = "tk,Tajikistan,992,MLT/TT mobile"; + m_mTable[1078][31] = "tk,Tajikistan,992,Tcell/JC Somoncom"; + m_mTable[1600][143] = "tz,Tanzania,255,Benson Informatics Ltd"; + m_mTable[1600][111] = "tz,Tanzania,255,Dovetel (T) Ltd"; + m_mTable[1600][159] = "tz,Tanzania,255,ExcellentCom (T) Ltd"; + m_mTable[1600][287] = "tz,Tanzania,255,Smile Communications Tanzania Ltd"; + m_mTable[1600][127] = "tz,Tanzania,255,Tanzania Telecommunications Company Ltd (TTCL)"; + m_mTable[1600][47] = "tz,Tanzania,255,TIGO/MIC"; + m_mTable[1600][31] = "tz,Tanzania,255,Tri Telecomm. Ltd."; + m_mTable[1600][79] = "tz,Tanzania,255,Vodacom Ltd"; + m_mTable[1600][95] = "tz,Tanzania,255,ZAIN/Celtel"; + m_mTable[1600][63] = "tz,Tanzania,255,Zantel/Zanzibar Telecom"; + m_mTable[1312][527] = "th,Thailand,66,ACeS Thailand - ACeS Regional Services Co Ltd"; + m_mTable[1312][351] = "th,Thailand,66,ACT Mobile"; + m_mTable[1312][63] = "th,Thailand,66,Advanced Wireless Networks/AWN"; + m_mTable[1312][31] = "th,Thailand,66,AIS/Advanced Info Service"; + m_mTable[1312][575] = "th,Thailand,66,Digital Phone Co."; + m_mTable[1312][15] = "th,Thailand,66,Hutch/CAT CDMA"; + m_mTable[1312][399] = "th,Thailand,66,Total Access (DTAC)"; + m_mTable[1312][95] = "th,Thailand,66,Total Access (DTAC)"; + m_mTable[1312][79] = "th,Thailand,66,True Move/Orange"; + m_mTable[1312][2463] = "th,Thailand,66,True Move/Orange"; + m_mTable[1300][31] = "tp,Timor-Leste,670,Telin/ Telkomcel"; + m_mTable[1300][47] = "tp,Timor-Leste,670,Timor Telecom"; + m_mTable[1557][47] = "tg,Togo,228,Telecel/MOOV"; + m_mTable[1557][63] = "tg,Togo,228,Telecel/MOOV"; + m_mTable[1557][31] = "tg,Togo,228,Togo Telecom/TogoCELL"; + m_mTable[1337][1087] = "to,Tonga,676,Shoreline Communication"; + m_mTable[1337][31] = "to,Tonga,676,Tonga Communications"; + m_mTable[884][297] = "tt,Trinidad and Tobago,1868,Bmobile/TSTT"; + m_mTable[884][304] = "tt,Trinidad and Tobago,1868,Digicel"; + m_mTable[884][320] = "tt,Trinidad and Tobago,1868,LaqTel Ltd."; + m_mTable[1541][31] = "tn,Tunisia,216,Orange"; + m_mTable[1541][63] = "tn,Tunisia,216,Oreedo/Orascom"; + m_mTable[1541][47] = "tn,Tunisia,216,TuniCell/Tunisia Telecom"; + m_mTable[646][79] = "tr,Turkey,90,AVEA/Aria"; + m_mTable[646][63] = "tr,Turkey,90,AVEA/Aria"; + m_mTable[646][31] = "tr,Turkey,90,Turkcell"; + m_mTable[646][47] = "tr,Turkey,90,Vodafone-Telsim"; + m_mTable[1080][31] = "tm,Turkmenistan,993,Barash Communication"; + m_mTable[1080][47] = "tm,Turkmenistan,993,TM-Cell"; + m_mTable[886][848] = "tc,Turks and Caicos Islands,1649,Cable & Wireless (TCI) Ltd"; + m_mTable[886][80] = "tc,Turks and Caicos Islands,1649,Digicel TCI Ltd"; + m_mTable[886][850] = "tc,Turks and Caicos Islands,1649,IslandCom Communications Ltd."; + m_mTable[1363][31] = "tv,Tuvalu,688,Tuvalu Telecommunication Corporation (TTC)"; + m_mTable[1601][31] = "ug,Uganda,256,Celtel"; + m_mTable[1601][1647] = "ug,Uganda,256,i-Tel Ltd"; + m_mTable[1601][783] = "ug,Uganda,256,K2 Telecom Ltd"; + m_mTable[1601][271] = "ug,Uganda,256,MTN Ltd."; + m_mTable[1601][335] = "ug,Uganda,256,Orange"; + m_mTable[1601][831] = "ug,Uganda,256,Smile Communications Uganda Ltd"; + m_mTable[1601][399] = "ug,Uganda,256,Suretelecom Uganda Ltd"; + m_mTable[1601][287] = "ug,Uganda,256,Uganda Telecom Ltd."; + m_mTable[1601][559] = "ug,Uganda,256,Airtel/Warid"; + m_mTable[597][111] = "ua,Ukraine,380,Astelit/LIFE"; + m_mTable[597][95] = "ua,Ukraine,380,Golden Telecom"; + m_mTable[597][927] = "ua,Ukraine,380,Golden Telecom"; + m_mTable[597][79] = "ua,Ukraine,380,Intertelecom Ltd (IT)"; + m_mTable[597][1663] = "ua,Ukraine,380,KyivStar"; + m_mTable[597][63] = "ua,Ukraine,380,KyivStar"; + m_mTable[597][543] = "ua,Ukraine,380,Telesystems Of Ukraine CJSC (TSU)"; + m_mTable[597][127] = "ua,Ukraine,380,TriMob LLC"; + m_mTable[597][1295] = "ua,Ukraine,380,UMC/MTS"; + m_mTable[597][47] = "ua,Ukraine,380,Beeline"; + m_mTable[597][31] = "ua,Ukraine,380,UMC/MTS"; + m_mTable[597][1679] = "ua,Ukraine,380,Beeline"; + m_mTable[1060][63] = "ae,United Arab Emirates,971,DU"; + m_mTable[1073][47] = "ae,United Arab Emirates,971,Etisalat"; + m_mTable[1060][47] = "ae,United Arab Emirates,971,Etisalat"; + m_mTable[1072][47] = "ae,United Arab Emirates,971,Etisalat"; + m_mTable[564][63] = "gb,United Kingdom,44,Airtel/Vodafone"; + m_mTable[564][1903] = "gb,United Kingdom,44,BT Group"; + m_mTable[564][1919] = "gb,United Kingdom,44,BT Group"; + m_mTable[564][127] = "gb,United Kingdom,44,Cable and Wireless"; + m_mTable[564][2351] = "gb,United Kingdom,44,Cable and Wireless"; + m_mTable[564][879] = "gb,United Kingdom,44,Cable and Wireless Isle of Man"; + m_mTable[564][399] = "gb,United Kingdom,44,Cloud9/wire9 Tel."; + m_mTable[565][47] = "gb,United Kingdom,44,Everyth. Ev.wh."; + m_mTable[564][383] = "gb,United Kingdom,44,FlexTel"; + m_mTable[564][1375] = "gb,United Kingdom,44,Guernsey Telecoms"; + m_mTable[564][335] = "gb,United Kingdom,44,HaySystems"; + m_mTable[564][527] = "gb,United Kingdom,44,Hutchinson 3G"; + m_mTable[564][2383] = "gb,United Kingdom,44,Hutchinson 3G"; + m_mTable[564][1887] = "gb,United Kingdom,44,Inquam Telecom Ltd"; + m_mTable[564][1295] = "gb,United Kingdom,44,Jersey Telecom"; + m_mTable[564][863] = "gb,United Kingdom,44,JSC Ingenicum"; + m_mTable[564][623] = "gb,United Kingdom,44,Lycamobile"; + m_mTable[564][1423] = "gb,United Kingdom,44,Manx Telecom"; + m_mTable[564][31] = "gb,United Kingdom,44,Mapesbury C. Ltd"; + m_mTable[564][655] = "gb,United Kingdom,44,Marthon Telecom"; + m_mTable[564][271] = "gb,United Kingdom,44,O2 Ltd."; + m_mTable[564][47] = "gb,United Kingdom,44,O2 Ltd."; + m_mTable[564][287] = "gb,United Kingdom,44,O2 Ltd."; + m_mTable[564][143] = "gb,United Kingdom,44,OnePhone"; + m_mTable[564][367] = "gb,United Kingdom,44,Opal Telecom"; + m_mTable[564][847] = "gb,United Kingdom,44,Everyth. Ev.wh./Orange"; + m_mTable[564][831] = "gb,United Kingdom,44,Everyth. Ev.wh./Orange"; + m_mTable[564][415] = "gb,United Kingdom,44,PMN/Teleware"; + m_mTable[564][303] = "gb,United Kingdom,44,Railtrack Plc"; + m_mTable[564][559] = "gb,United Kingdom,44,Routotelecom"; + m_mTable[564][591] = "gb,United Kingdom,44,Stour Marine"; + m_mTable[564][895] = "gb,United Kingdom,44,Synectiv Ltd."; + m_mTable[564][799] = "gb,United Kingdom,44,Everyth. Ev.wh./T-Mobile"; + m_mTable[564][783] = "gb,United Kingdom,44,Everyth. Ev.wh./T-Mobile"; + m_mTable[564][815] = "gb,United Kingdom,44,Everyth. Ev.wh./T-Mobile"; + m_mTable[564][639] = "gb,United Kingdom,44,Vodafone"; + m_mTable[564][159] = "gb,United Kingdom,44,Tismi"; + m_mTable[564][607] = "gb,United Kingdom,44,Truphone"; + m_mTable[564][1311] = "gb,United Kingdom,44,Jersey Telecom"; + m_mTable[564][575] = "gb,United Kingdom,44,Vectofone Mobile Wifi"; + m_mTable[564][351] = "gb,United Kingdom,44,Vodafone"; + m_mTable[564][2335] = "gb,United Kingdom,44,Vodafone"; + m_mTable[564][1935] = "gb,United Kingdom,44,Wave Telecom Ltd"; + m_mTable[784][80] = "us,United States,1,"; + m_mTable[784][2176] = "us,United States,1,"; + m_mTable[784][2128] = "us,United States,1,Aeris Comm. Inc."; + m_mTable[784][1600] = "us,United States,1,"; + m_mTable[784][1296] = "us,United States,1,Airtel Wireless LLC"; + m_mTable[784][400] = "us,United States,1,Unknown"; + m_mTable[786][144] = "us,United States,1,Allied Wireless Communications Corporation"; + m_mTable[785][304] = "us,United States,1,"; + m_mTable[784][1808] = "us,United States,1,Arctic Slope Telephone Association Cooperative Inc."; + m_mTable[784][336] = "us,United States,1,AT&T Wireless Inc."; + m_mTable[784][1664] = "us,United States,1,AT&T Wireless Inc."; + m_mTable[784][112] = "us,United States,1,AT&T Wireless Inc."; + m_mTable[784][1376] = "us,United States,1,AT&T Wireless Inc."; + m_mTable[784][1040] = "us,United States,1,AT&T Wireless Inc."; + m_mTable[784][896] = "us,United States,1,AT&T Wireless Inc."; + m_mTable[784][368] = "us,United States,1,AT&T Wireless Inc."; + m_mTable[784][2432] = "us,United States,1,AT&T Wireless Inc."; + m_mTable[785][2064] = "us,United States,1,Bluegrass Wireless LLC"; + m_mTable[785][2048] = "us,United States,1,Bluegrass Wireless LLC"; + m_mTable[785][1088] = "us,United States,1,Bluegrass Wireless LLC"; + m_mTable[784][2304] = "us,United States,1,Cable & Communications Corp."; + m_mTable[785][1424] = "us,United States,1,California RSA No. 3 Limited Partnership"; + m_mTable[785][1280] = "us,United States,1,Cambridge Telephone Company Inc."; + m_mTable[784][2096] = "us,United States,1,Caprock Cellular Ltd."; + m_mTable[785][630] = "us,United States,1,Verizon Wireless"; + m_mTable[785][1153] = "us,United States,1,Verizon Wireless"; + m_mTable[785][1158] = "us,United States,1,Verizon Wireless"; + m_mTable[784][19] = "us,United States,1,Verizon Wireless"; + m_mTable[785][641] = "us,United States,1,Verizon Wireless"; + m_mTable[785][624] = "us,United States,1,Verizon Wireless"; + m_mTable[785][646] = "us,United States,1,Verizon Wireless"; + m_mTable[785][629] = "us,United States,1,Verizon Wireless"; + m_mTable[785][1152] = "us,United States,1,Verizon Wireless"; + m_mTable[784][18] = "us,United States,1,Verizon Wireless"; + m_mTable[785][640] = "us,United States,1,Verizon Wireless"; + m_mTable[785][1157] = "us,United States,1,Verizon Wireless"; + m_mTable[785][272] = "us,United States,1,Verizon Wireless"; + m_mTable[785][645] = "us,United States,1,Verizon Wireless"; + m_mTable[785][628] = "us,United States,1,Verizon Wireless"; + m_mTable[785][912] = "us,United States,1,Verizon Wireless"; + m_mTable[784][16] = "us,United States,1,Verizon Wireless"; + m_mTable[785][633] = "us,United States,1,Verizon Wireless"; + m_mTable[785][1156] = "us,United States,1,Verizon Wireless"; + m_mTable[785][1161] = "us,United States,1,Verizon Wireless"; + m_mTable[784][2320] = "us,United States,1,Verizon Wireless"; + m_mTable[785][644] = "us,United States,1,Verizon Wireless"; + m_mTable[785][627] = "us,United States,1,Verizon Wireless"; + m_mTable[785][649] = "us,United States,1,Verizon Wireless"; + m_mTable[784][4] = "us,United States,1,Verizon Wireless"; + m_mTable[785][632] = "us,United States,1,Verizon Wireless"; + m_mTable[785][1155] = "us,United States,1,Verizon Wireless"; + m_mTable[785][1160] = "us,United States,1,Verizon Wireless"; + m_mTable[784][2192] = "us,United States,1,Verizon Wireless"; + m_mTable[785][643] = "us,United States,1,Verizon Wireless"; + m_mTable[785][626] = "us,United States,1,Verizon Wireless"; + m_mTable[785][648] = "us,United States,1,Verizon Wireless"; + m_mTable[785][631] = "us,United States,1,Verizon Wireless"; + m_mTable[785][1154] = "us,United States,1,Verizon Wireless"; + m_mTable[785][1159] = "us,United States,1,Verizon Wireless"; + m_mTable[784][1424] = "us,United States,1,Verizon Wireless"; + m_mTable[785][642] = "us,United States,1,Verizon Wireless"; + m_mTable[785][625] = "us,United States,1,Verizon Wireless"; + m_mTable[785][647] = "us,United States,1,Verizon Wireless"; + m_mTable[786][624] = "us,United States,1,Cellular Network Partnership LLC"; + m_mTable[784][864] = "us,United States,1,Cellular Network Partnership LLC"; + m_mTable[786][640] = "us,United States,1,Cellular Network Partnership LLC"; + m_mTable[785][400] = "us,United States,1,"; + m_mTable[784][48] = "us,United States,1,"; + m_mTable[785][288] = "us,United States,1,Choice Phone LLC"; + m_mTable[784][1152] = "us,United States,1,Choice Phone LLC"; + m_mTable[784][1584] = "us,United States,1,"; + m_mTable[784][1056] = "us,United States,1,Cincinnati Bell Wireless LLC"; + m_mTable[784][384] = "us,United States,1,Cingular Wireless"; + m_mTable[784][1568] = "us,United States,1,Coleman County Telco /Trans TX"; + m_mTable[785][64] = "us,United States,1,"; + m_mTable[784][1551] = "us,United States,1,Consolidated Telcom"; + m_mTable[784][111] = "us,United States,1,Consolidated Telcom"; + m_mTable[786][896] = "us,United States,1,"; + m_mTable[784][2352] = "us,United States,1,"; + m_mTable[785][576] = "us,United States,1,"; + m_mTable[784][128] = "us,United States,1,"; + m_mTable[784][1792] = "us,United States,1,Cross Valliant Cellular Partnership"; + m_mTable[786][48] = "us,United States,1,Cross Wireless Telephone Co."; + m_mTable[785][320] = "us,United States,1,Cross Wireless Telephone Co."; + m_mTable[785][1312] = "us,United States,1,"; + m_mTable[786][64] = "us,United States,1,Custer Telephone Cooperative Inc."; + m_mTable[784][1088] = "us,United States,1,Dobson Cellular Systems"; + m_mTable[784][2448] = "us,United States,1,E.N.M.R. Telephone Coop."; + m_mTable[784][1872] = "us,United States,1,East Kentucky Network LLC"; + m_mTable[786][304] = "us,United States,1,East Kentucky Network LLC"; + m_mTable[786][288] = "us,United States,1,East Kentucky Network LLC"; + m_mTable[784][144] = "us,United States,1,Edge Wireless LLC"; + m_mTable[784][1552] = "us,United States,1,Elkhart TelCo. / Epic Touch Co."; + m_mTable[785][528] = "us,United States,1,"; + m_mTable[785][785] = "us,United States,1,Farmers"; + m_mTable[785][1120] = "us,United States,1,Fisher Wireless Services Inc."; + m_mTable[785][880] = "us,United States,1,GCI Communication Corp."; + m_mTable[784][1072] = "us,United States,1,GCI Communication Corp."; + m_mTable[784][2336] = "us,United States,1,Get Mobile Inc."; + m_mTable[784][2416] = "us,United States,1,"; + m_mTable[785][832] = "us,United States,1,Illinois Valley Cellular RSA 2 Partnership"; + m_mTable[785][48] = "us,United States,1,"; + m_mTable[785][1040] = "us,United States,1,Iowa RSA No. 2 Limited Partnership"; + m_mTable[786][368] = "us,United States,1,Iowa RSA No. 2 Limited Partnership"; + m_mTable[784][1904] = "us,United States,1,Iowa Wireless Services LLC"; + m_mTable[784][1616] = "us,United States,1,Jasper"; + m_mTable[784][2160] = "us,United States,1,Kaplan Telephone Company Inc."; + m_mTable[786][384] = "us,United States,1,Keystone Wireless LLC"; + m_mTable[784][1680] = "us,United States,1,Keystone Wireless LLC"; + m_mTable[785][784] = "us,United States,1,Lamar County Cellular"; + m_mTable[784][22] = "us,United States,1,Leap Wireless International Inc."; + m_mTable[785][144] = "us,United States,1,"; + m_mTable[784][64] = "us,United States,1,Matanuska Tel. Assn. Inc."; + m_mTable[784][1920] = "us,United States,1,Message Express Co. / Airlink PCS"; + m_mTable[785][1632] = "us,United States,1,"; + m_mTable[785][816] = "us,United States,1,Michigan Wireless LLC"; + m_mTable[785][0] = "us,United States,1,"; + m_mTable[784][1024] = "us,United States,1,Minnesota South. Wirel. Co. / Hickory"; + m_mTable[786][544] = "us,United States,1,Missouri RSA No 5 Partnership"; + m_mTable[786][16] = "us,United States,1,Missouri RSA No 5 Partnership"; + m_mTable[785][2336] = "us,United States,1,Missouri RSA No 5 Partnership"; + m_mTable[785][32] = "us,United States,1,Missouri RSA No 5 Partnership"; + m_mTable[785][16] = "us,United States,1,Missouri RSA No 5 Partnership"; + m_mTable[784][848] = "us,United States,1,Mohave Cellular LP"; + m_mTable[784][1392] = "us,United States,1,MTPCS LLC"; + m_mTable[784][656] = "us,United States,1,NEP Cellcorp Inc."; + m_mTable[784][847] = "us,United States,1,Nevada Wireless LLC"; + m_mTable[785][896] = "us,United States,1,"; + m_mTable[784][1536] = "us,United States,1,New-Cell Inc."; + m_mTable[785][256] = "us,United States,1,"; + m_mTable[785][768] = "us,United States,1,Nexus Communications Inc."; + m_mTable[784][304] = "us,United States,1,North Carolina RSA 3 Cellular Tel. Co."; + m_mTable[786][560] = "us,United States,1,North Dakota Network Company"; + m_mTable[785][1552] = "us,United States,1,North Dakota Network Company"; + m_mTable[784][1104] = "us,United States,1,Northeast Colorado Cellular Inc."; + m_mTable[785][1808] = "us,United States,1,Northeast Wireless Networks LLC"; + m_mTable[784][1648] = "us,United States,1,Northstar"; + m_mTable[784][17] = "us,United States,1,Northstar"; + m_mTable[785][1056] = "us,United States,1,Northwest Missouri Cellular Limited Partnership"; + m_mTable[784][1344] = "us,United States,1,"; + m_mTable[784][1888] = "us,United States,1,Panhandle Telephone Cooperative Inc."; + m_mTable[784][1408] = "us,United States,1,PCS ONE"; + m_mTable[785][368] = "us,United States,1,PetroCom"; + m_mTable[785][1648] = "us,United States,1,Pine Belt Cellular Inc."; + m_mTable[785][128] = "us,United States,1,"; + m_mTable[784][1936] = "us,United States,1,"; + m_mTable[784][256] = "us,United States,1,Plateau Telecommunications Inc."; + m_mTable[784][2368] = "us,United States,1,Poka Lambro Telco Ltd."; + m_mTable[785][1840] = "us,United States,1,"; + m_mTable[785][1344] = "us,United States,1,"; + m_mTable[784][1280] = "us,United States,1,Public Service Cellular Inc."; + m_mTable[785][1072] = "us,United States,1,RSA 1 Limited Partnership"; + m_mTable[786][352] = "us,United States,1,RSA 1 Limited Partnership"; + m_mTable[785][848] = "us,United States,1,Sagebrush Cellular Inc."; + m_mTable[785][2320] = "us,United States,1,"; + m_mTable[784][1135] = "us,United States,1,SIMMETRY"; + m_mTable[785][608] = "us,United States,1,SLO Cellular Inc / Cellular One of San Luis"; + m_mTable[784][800] = "us,United States,1,Smith Bagley Inc."; + m_mTable[784][351] = "us,United States,1,Unknown"; + m_mTable[790][17] = "us,United States,1,Southern Communications Services Inc."; + m_mTable[786][1328] = "us,United States,1,Sprint Spectrum"; + m_mTable[785][2160] = "us,United States,1,Sprint Spectrum"; + m_mTable[785][1168] = "us,United States,1,Sprint Spectrum"; + m_mTable[784][288] = "us,United States,1,Sprint Spectrum"; + m_mTable[790][16] = "us,United States,1,Sprint Spectrum"; + m_mTable[786][400] = "us,United States,1,Sprint Spectrum"; + m_mTable[785][2176] = "us,United States,1,Sprint Spectrum"; + m_mTable[784][512] = "us,United States,1,T-Mobile"; + m_mTable[784][592] = "us,United States,1,T-Mobile"; + m_mTable[784][352] = "us,United States,1,T-Mobile"; + m_mTable[784][576] = "us,United States,1,T-Mobile"; + m_mTable[784][1632] = "us,United States,1,T-Mobile"; + m_mTable[784][560] = "us,United States,1,T-Mobile"; + m_mTable[784][799] = "us,United States,1,T-Mobile"; + m_mTable[784][544] = "us,United States,1,T-Mobile"; + m_mTable[784][624] = "us,United States,1,T-Mobile"; + m_mTable[784][528] = "us,United States,1,T-Mobile"; + m_mTable[784][608] = "us,United States,1,T-Mobile"; + m_mTable[784][2048] = "us,United States,1,T-Mobile"; + m_mTable[784][768] = "us,United States,1,T-Mobile"; + m_mTable[784][640] = "us,United States,1,T-Mobile"; + m_mTable[784][816] = "us,United States,1,T-Mobile"; + m_mTable[784][784] = "us,United States,1,T-Mobile"; + m_mTable[785][1856] = "us,United States,1,"; + m_mTable[784][1856] = "us,United States,1,Telemetrix Inc."; + m_mTable[784][335] = "us,United States,1,Testing"; + m_mTable[784][2384] = "us,United States,1,Unknown"; + m_mTable[784][2144] = "us,United States,1,Texas RSA 15B2 Limited Partnership"; + m_mTable[785][2096] = "us,United States,1,Thumb Cellular Limited Partnership"; + m_mTable[785][80] = "us,United States,1,Thumb Cellular Limited Partnership"; + m_mTable[784][1120] = "us,United States,1,TMP Corporation"; + m_mTable[784][1168] = "us,United States,1,Triton PCS"; + m_mTable[786][656] = "us,United States,1,Uintah Basin Electronics Telecommunications Inc."; + m_mTable[785][2144] = "us,United States,1,Uintah Basin Electronics Telecommunications Inc."; + m_mTable[784][2400] = "us,United States,1,Uintah Basin Electronics Telecommunications Inc."; + m_mTable[784][32] = "us,United States,1,Union Telephone Co."; + m_mTable[785][544] = "us,United States,1,United States Cellular Corp."; + m_mTable[784][1840] = "us,United States,1,United States Cellular Corp."; + m_mTable[785][1616] = "us,United States,1,United Wireless Communications Inc."; + m_mTable[784][911] = "us,United States,1,USA 3650 AT&T"; + m_mTable[784][1312] = "us,United States,1,VeriSign"; + m_mTable[784][3] = "us,United States,1,Unknown"; + m_mTable[784][575] = "us,United States,1,Unknown"; + m_mTable[784][591] = "us,United States,1,Unknown"; + m_mTable[784][607] = "us,United States,1,Unknown"; + m_mTable[784][1328] = "us,United States,1,West Virginia Wireless"; + m_mTable[784][623] = "us,United States,1,Unknown"; + m_mTable[784][832] = "us,United States,1,Westlink Communications LLC"; + m_mTable[785][336] = "us,United States,1,"; + m_mTable[785][112] = "us,United States,1,Wisconsin RSA #7 Limited Partnership"; + m_mTable[784][912] = "us,United States,1,Yorkville Telephone Cooperative"; + m_mTable[1864][63] = "uy,Uruguay,598,Ancel/Antel"; + m_mTable[1864][31] = "uy,Uruguay,598,Ancel/Antel"; + m_mTable[1864][271] = "uy,Uruguay,598,Claro/AM Wireless"; + m_mTable[1864][127] = "uy,Uruguay,598,MOVISTAR"; + m_mTable[1076][79] = "uz,Uzbekistan,998,Bee Line/Unitel"; + m_mTable[1076][31] = "uz,Uzbekistan,998,Buztel"; + m_mTable[1076][127] = "uz,Uzbekistan,998,MTS/Uzdunrobita"; + m_mTable[1076][95] = "uz,Uzbekistan,998,Ucell/Coscom"; + m_mTable[1076][47] = "uz,Uzbekistan,998,Uzmacom"; + m_mTable[1345][95] = "vu,Vanuatu,678,DigiCel"; + m_mTable[1345][31] = "vu,Vanuatu,678,SMILE"; + m_mTable[1844][63] = "ve,Venezuela,58,DigiTel C.A."; + m_mTable[1844][47] = "ve,Venezuela,58,DigiTel C.A."; + m_mTable[1844][31] = "ve,Venezuela,58,DigiTel C.A."; + m_mTable[1844][111] = "ve,Venezuela,58,Movilnet C.A."; + m_mTable[1844][79] = "ve,Venezuela,58,Movistar/TelCel"; + m_mTable[1106][127] = "vn,Viet Nam,84,Beeline"; + m_mTable[1106][31] = "vn,Viet Nam,84,Mobifone"; + m_mTable[1106][63] = "vn,Viet Nam,84,S-Fone/Telecom"; + m_mTable[1106][95] = "vn,Viet Nam,84,VietnaMobile"; + m_mTable[1106][111] = "vn,Viet Nam,84,Viettel Mobile"; + m_mTable[1106][79] = "vn,Viet Nam,84,Viettel Mobile"; + m_mTable[1106][143] = "vn,Viet Nam,84,Viettel Mobile"; + m_mTable[1106][47] = "vn,Viet Nam,84,Vinaphone"; + m_mTable[886][1295] = "vi,Virgin Islands U.S.,1340,Digicel"; + m_mTable[1057][79] = "ye,Yemen,967,HITS/Y Unitel"; + m_mTable[1057][47] = "ye,Yemen,967,MTN/Spacetel"; + m_mTable[1057][31] = "ye,Yemen,967,Sabaphone"; + m_mTable[1057][63] = "ye,Yemen,967,Yemen Mob. CDMA"; + m_mTable[1605][63] = "zm,Zambia,260,Cell Z/MTS"; + m_mTable[1605][47] = "zm,Zambia,260,MTN/Telecel"; + m_mTable[1605][31] = "zm,Zambia,260,Airtel/Zain/Celtel"; + m_mTable[1608][79] = "zw,Zimbabwe,263,Econet"; + m_mTable[1608][31] = "zw,Zimbabwe,263,Net One"; + m_mTable[1608][63] = "zw,Zimbabwe,263,Telecel"; +} + diff --git a/src/MTS_IO_SerialConnection.cpp b/src/MTS_IO_SerialConnection.cpp new file mode 100644 index 0000000..8f0b8e3 --- /dev/null +++ b/src/MTS_IO_SerialConnection.cpp @@ -0,0 +1,545 @@ +/* + * Copyright (C) 2015 by Multi-Tech Systems + * + * This file is part of libmts_io. + * + * libmts_io 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 of the License, or + * (at your option) any later version. + * + * libmts_io 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 libmts_io. If not, see <http://www.gnu.org/licenses/>. + * + */ + +/*! + \file MTS_IO_SerialConnection.cpp + \brief A brief description + \date Jan 15, 2013 + \author sgodinez + + A more elaborate description +*/ + +#include <mts/MTS_IO_SerialConnection.h> +#include <mts/MTS_Text.h> +#include <mts/MTS_Logger.h> +#include <unistd.h> + +#ifdef WIN32 + +#else +#include <fcntl.h> /* File control definitions */ +#include <errno.h> /* Error number definitions */ +#include <termios.h> /* POSIX terminal control definitions */ +#include <string.h> /* String function definitions */ +#endif + +using namespace MTS::IO; + +SerialConnection::Builder::Builder(const std::string& sPortName) +: m_sPortName(sPortName) +, m_iBaudRate(9600) +, m_eType(RS232) +, m_eParity(OFF) +, m_eDataBits(B8) +, m_eStopBits(B1) +, m_bBuilt(false) +{ + +} + +SerialConnection::Builder& SerialConnection::Builder::type(const ETYPE& eType) { + m_eType = eType; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::rs232() { + m_eType = RS232; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::rs422() { + m_eType = RS422; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::rs485() { + m_eType = RS485; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::parity(const EPARITY& eParity) { + m_eParity = eParity; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::parityOff() { + m_eParity = OFF; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::parityOdd() { + m_eParity = ODD; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::parityEven() { + m_eParity = EVEN; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::dataBits(const EDATABITS& eDataBits) { + m_eDataBits = eDataBits; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::fiveDataBits() { + m_eDataBits = B5; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::sixDataBits() { + m_eDataBits = B6; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::sevenDataBits() { + m_eDataBits = B7; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::eightDataBits() { + m_eDataBits = B8; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::stopBits(const ESTOPBITS& eStopBits) { + m_eStopBits = eStopBits; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::oneStopBit() { + m_eStopBits = B1; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::twoStopBits() { + m_eStopBits = B2; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::baudRate(uint32_t iBaud) { + m_iBaudRate = iBaud; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::useLockFile(bool bEnabled) { + m_bLockFile = bEnabled; + return *this; +} + +SerialConnection::Builder& SerialConnection::Builder::build() { + m_bBuilt = true; + return *this; +} + +const std::string& SerialConnection::Builder::getPortName() const { + return m_sPortName; +} + +const uint32_t& SerialConnection::Builder::getBaudRate() const { + return m_iBaudRate; +} + +SerialConnection::ETYPE SerialConnection::Builder::getType() const { + return m_eType; +} + +SerialConnection::EPARITY SerialConnection::Builder::getParity() const { + return m_eParity; +} + +SerialConnection::EDATABITS SerialConnection::Builder::getDataBits() const { + return m_eDataBits; +} + +SerialConnection::ESTOPBITS SerialConnection::Builder::getStopBits() const { + return m_eStopBits; +} + +bool SerialConnection::Builder::isUsingLockFile() const { + return m_bLockFile; +} + +std::string SerialConnection::Builder::getTypeAsString() const { + std::string sType; + switch(m_eType) { + case RS232: + sType = "RS232"; + break; + case RS422: + sType = "RS422"; + break; + case RS485: + sType = "RS485"; + break; + default: + break; + } + return sType; +} + +SerialConnection::Builder& SerialConnection::Builder::flowControl(const SerialConnection::FLOW_CONTROL& eFlowControl) { + m_eFlowControl = eFlowControl; + return *this; +} + +SerialConnection::FLOW_CONTROL SerialConnection::Builder::getFlowControl() const { + return m_eFlowControl; +} + +bool SerialConnection::Builder::isBuilt() const { + return m_bBuilt; +} + +SerialConnection::SerialConnection(const Builder& oBuilder) +: Connection(oBuilder.getTypeAsString()) +, m_sPortName(oBuilder.getPortName()) +, m_iBaudRate(oBuilder.getBaudRate()) +, m_eType(oBuilder.getType()) +, m_eParity(oBuilder.getParity()) +, m_eDataBits(oBuilder.getDataBits()) +, m_eStopBits(oBuilder.getStopBits()) +, m_eFlowControl(oBuilder.getFlowControl()) +{ + if(!oBuilder.isBuilt()) { + //Throw Exception? + } +#ifdef WIN32 + m_iHandle = INVALID_HANDLE_VALUE; +#else + m_iHandle = -1; +#endif + m_apHandleLock.reset(new Lock()); + if(oBuilder.isUsingLockFile()) { + std::vector<std::string> vParts = MTS::Text::split(m_sPortName, "/"); + m_apLockFile.reset(new LockFile("/var/lock/LCK.." + vParts[vParts.size()-1])); + } +} + +SerialConnection::~SerialConnection() { + doClose(); + m_apHandleLock.reset(); +} + +const std::string& SerialConnection::getPortName() const { + return m_sPortName; +} + +uint32_t SerialConnection::getBaudRate() const { + return m_iBaudRate; +} + +int SerialConnection::getFileDescriptor() { + m_apHandleLock->lock(); + int h = m_iHandle; + m_apHandleLock->unlock(); + return h; +} + +bool SerialConnection::doOpen(const int32_t& timeoutMillis) { + m_apHandleLock->lock(); + + if (m_iHandle != -1) { + m_apHandleLock->unlock(); + return true; + } + if(!m_apLockFile.isNull() && !m_apLockFile->lock(timeoutMillis)) { + printError("SERIAL| Failed to obtain file lock"); + m_apHandleLock->unlock(); + return false; + } + +#ifdef WIN32 + +#else + m_iHandle = ::open(m_sPortName.c_str(), O_RDWR | O_NOCTTY ); + if (m_iHandle == -1) { + printWarning("SERIAL| Failed to open port [%s] [%d]", m_sPortName.c_str(), errno); + if(!m_apLockFile.isNull()) { + m_apLockFile->unlock(); + } + m_apHandleLock->unlock(); + return false; + } + + int result = tcgetattr(m_iHandle, &m_stPrevOptions); + if (result == -1) { + printWarning("SERIAL| Failed to get attributes on port [%s] [%d]", m_sPortName.c_str(), errno); + } + + termios options = m_stPrevOptions; + + //Set to Raw Mode + cfmakeraw(&options); + + //Set the Baud Rate + speed_t speed = B9600; + switch (m_iBaudRate) { + case 300: + speed = B300; + break; + case 600: + speed = B600; + break; + case 1200: + speed = B1200; + break; + case 2400: + speed = B2400; + break; + case 4800: + speed = B4800; + break; + case 9600: + speed = B9600; + break; + case 19200: + speed = B19200; + break; + case 38400: + speed = B38400; + break; + case 57600: + speed = B57600; + break; + case 115200: + speed = B115200; + break; + case 230400: + speed = B230400; + break; + case 460800: + speed = B460800; + break; + case 921600: + speed = B921600; + break; + default: + printWarning("SERIAL| Baud Rate [%d] not supported. Defaulting to 9600.", m_iBaudRate); + m_iBaudRate = 9600; + speed = B9600; + break; + } + + result = cfsetispeed(&options, speed); + if (result == -1) { + printWarning("SERIAL| Failed to set input speed of [%d] on port [%s] [%d]", m_iBaudRate, m_sPortName.c_str(), errno); + goto CLEANUP; + } + result = cfsetospeed(&options, speed); + if (result == -1) { + printWarning("SERIAL| Failed to set output speed of [%d] on port [%s] [%d]", m_iBaudRate, m_sPortName.c_str(), errno); + goto CLEANUP; + } + + //Set Parity, Stop Bits, and Data Length + switch(m_eParity) { + case ODD: + options.c_cflag |= ( PARODD | PARENB ); + break; + + case EVEN: + options.c_cflag |= PARENB; + break; + + case OFF: + default: + options.c_cflag &= ~PARENB; + break; + } + + options.c_cflag &= ~CSIZE; + switch(m_eDataBits) { + case B5: + options.c_cflag |= CS5; + break; + + case B6: + options.c_cflag |= CS6; + break; + + case B7: + options.c_cflag |= CS7; + break; + + case B8: + default: + options.c_cflag |= CS8; + break; + } + + switch(m_eStopBits) { + case B2: + options.c_cflag &= CSTOPB; + break; + + case B1: + default: + options.c_cflag &= ~CSTOPB; + break; + } + + switch (m_eFlowControl) { + case RTS_CTS: + options.c_cflag &= CRTSCTS; + break; + case NONE: + default: + options.c_cflag &= ~(IXON | IXOFF | IXANY); + break; + } + + //Set Control Modes + options.c_cc[VMIN] = 0; + options.c_cc[VTIME] = 2; // tenths of seconds + + result = tcsetattr(m_iHandle, TCSANOW, &options); + if (result == -1) { + printWarning("SERIAL| Failed to set configurations on port [%s] [%d]", m_sPortName.c_str(), errno); + goto CLEANUP; + } + result = tcflush(m_iHandle, TCIOFLUSH); + if (result == -1) { + printWarning("SERIAL| Failed to flush port [%s] [%d]", m_sPortName.c_str(), errno); + goto CLEANUP; + } +#endif + m_apHandleLock->unlock(); + printInfo("SERIAL| %s connection opened on %s @ %d", getName().c_str(), m_sPortName.c_str(), m_iBaudRate); + return true; +CLEANUP: + cleanup(); + m_apHandleLock->unlock(); + return false; +} + +void SerialConnection::doClose() { + m_apHandleLock->lock(); + cleanup(); + m_apHandleLock->unlock(); +} + +int SerialConnection::doRead(char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis) { + int32_t result = -1; +#ifdef WIN32 + +#else + + int h = getFileDescriptor(); + + if (h == -1) { + printError("SERIAL| bad handle on port %s", m_sPortName.c_str()); + return result; + } + + if(timeoutMillis < 0) { + result = ::read(h, pBuffer, iSize); + } else { + fd_set readfs; + struct timeval stTimeout; + stTimeout.tv_usec = ((timeoutMillis%1000) * 1000); + stTimeout.tv_sec = timeoutMillis/1000; + + FD_ZERO(&readfs); + FD_SET(h, &readfs); + int res = select(h + 1, &readfs, NULL, NULL, &stTimeout); + if(res == -1) { + result = -1; + } else if (res == 0) { + //Timeout Occured + //printTrace("SERIAL| read timed out on port [%s]", m_sPortName.c_str()); + result = 0; + } else { + if (FD_ISSET(h, &readfs)) { + result = ::read(h, pBuffer, iSize); + } else { + //socket closed? + result = -1; + } + } + timeoutMillis = (stTimeout.tv_usec / 1000) + (stTimeout.tv_sec * 1000); + } +#endif + if (result < 0) { + printWarning("SERIAL| failed to read from %s [%d]", m_sPortName.c_str(), errno); + } + return result; +} + +int SerialConnection::doWrite(const char* pBuffer, const uint32_t& iSize, int32_t& timeoutMillis) { + int32_t result = -1; +#ifdef WIN32 + +#else + + int h = getFileDescriptor(); + + if (h == -1) { + printError("SERIAL| bad handle on port %s", m_sPortName.c_str()); + return result; + } + + if(timeoutMillis < 0) { + result = ::write(h, pBuffer, iSize); + } else { + //No difference between timeout and no timeout + result = ::write(h, pBuffer, iSize); + } + +#endif + if (result < 0) { + printWarning("SERIAL| failed to write to %s [%d]", m_sPortName.c_str(), errno); + } + return result; +} + +void SerialConnection::cleanup() { +#ifdef WIN32 + CloseHandle(m_iHandle); + m_iHandle = INVALID_HANDLE_VALUE; +#else + if(m_iHandle >= 0) { + int result = tcsetattr(m_iHandle, TCSANOW, &m_stPrevOptions); + if (result == -1) { + printWarning("SERIAL| Failed to revert configurations on port [%s] [%d]", m_sPortName.c_str(), errno); + } + ::close(m_iHandle); + m_iHandle = -1; + } +#endif + if(!m_apLockFile.isNull()) { + m_apLockFile->unlock(); + } +} + +void SerialConnection::drain() { + int result = tcdrain(m_iHandle); + if (result == -1) { + printWarning("SERIAL| Failed to drain port [%s] [%d]", m_sPortName.c_str(), errno); + } +} + +void SerialConnection::flush() { + int result = tcflush(m_iHandle, TCIOFLUSH); + if (result == -1) { + printWarning("SERIAL| Failed to flush port [%s] [%d]", m_sPortName.c_str(), errno); + } +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..64428e9 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,9 @@ +project (TestRunnerClient) + +include_directories (../include) +link_directories (..) + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -DCPPUNIT_MAIN=main") + +add_executable (TestRunnerClient TestRunnerClient.cpp ) +target_link_libraries (TestRunnerClient cppunit mts mts_io ssl rt pthread) diff --git a/test/TestRunnerClient.cpp b/test/TestRunnerClient.cpp new file mode 100644 index 0000000..fcb9c75 --- /dev/null +++ b/test/TestRunnerClient.cpp @@ -0,0 +1,566 @@ +/******************************************************************************* + * Copyright (c) 2008 Gerhard Leonhartsberger. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ + +#include "TestRunnerClient.h" + +#ifdef CPPUNIT_MAIN + +#include "cppunit/XmlOutputter.h" +#include "cppunit/TextOutputter.h" +#include "cppunit/TestSuite.h" +#include "cppunit/TestResult.h" +#include "cppunit/TestFailure.h" +#include "cppunit/SourceLine.h" +#include "cppunit/Exception.h" +#include "cppunit/extensions/TestFactoryRegistry.h" +#include "cppunit/extensions/TestDecorator.h" +#include "cppunit/ui/text/TestRunner.h" + +#include <iostream> +#include <sstream> +#include <typeinfo> +#include <vector> + +#include <errno.h> +#include <unistd.h> +#include <sys/time.h> + +#ifdef _WIN32 // Bugzilla 40710 +#include <windows.h> +#include <winbase.h> +#include <winsock.h> +#else +#include <netinet/in.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netdb.h> +#endif + +#define MAX_HOSTNAME_SIZE 255 + +/* + * CppUnitServer protocol constants + */ +static const std::string TRACE_START = "%TRACES "; +static const std::string TRACE_END = "%TRACEE "; +static const std::string TEST_RUN_START = "%TESTC "; +static const std::string TEST_START = "%TESTS "; +static const std::string TEST_END = "%TESTE "; +static const std::string TEST_ERROR = "%ERROR "; +static const std::string TEST_FAILED = "%FAILED "; +static const std::string TEST_RUN_END = "%RUNTIME"; +static const std::string TEST_STOPPED = "%TSTSTP "; +static const std::string TEST_TREE = "%TSTTREE"; + +TestRunnerClient::TestRunnerClient() +{ + fTestResult = 0; + fClientSocket = -1; + fPort = 0; + fKeepAlive = 0; + fDebugMode = 0; + + fHost = (char *) malloc(MAX_HOSTNAME_SIZE); + strcpy(fHost, ""); +} + +TestRunnerClient::~TestRunnerClient() { + + if (fHost != NULL) { + free(fHost); + } +} + +int TestRunnerClient::Run() +{ + if (fDebugMode) + { + std::cerr << "TestRunnerClient: Starting client." << std::endl; + } + + if (Connect() == -1) { + return -1; + } + + InstallListeners(); + + RunTests(); + + UninstallListeners(); + + if(fTestResult != NULL) + { + fTestResult->stop(); + fTestResult= NULL; + } + + ShutDown(); + + return 0; +} + +void TestRunnerClient::Init(int n, char *args[]) +{ + ParseCommandLine(n, args); + DefineHostName(); +} + +void TestRunnerClient::ParseCommandLine(int n, char *args[]) +{ + // parse all arguments passed by args + for(int i = 0; i < n; i++) + { + std::string arg(args[i]); + + // port option + std::string portOption("-port="); + int pos = arg.find(portOption); + if(pos> -1) + { + std::string v = arg.substr(pos + portOption.length(), arg.length()); + fPort = atoi(v.c_str()); + } + + // debug option + std::string debugOption("-debug"); + pos = arg.find(debugOption); + if(pos> - 1) + { + fDebugMode = 1; + } + } +} + +void TestRunnerClient::DefineHostName() +{ + // set fHost to hostname or localhost + int ret = gethostname(fHost, MAX_HOSTNAME_SIZE); + if (ret == -1) + { + strcpy(fHost, "localhost"); + } +} + +int TestRunnerClient::Connect() +{ + +#ifdef _WIN32 // Bugzilla 40710 + if (fDebugMode) + { + std::cerr << "TestRunnerClient: Starting Windows Sockets WSAStartup()." << std:endl; + } + + // start up Windows Sockets + WSADATA WSAData; + int result = WSAStartup (MAKEWORD(1, 1), &WSAData); + if (result != NO_ERROR) + { + std::cerr << "TestRunnerClient: WSAStartup() failed! Error code: " << result << std::endl; + return -1; + } +#endif + + if (fDebugMode) + { + std::cerr << "TestRunnerClient: Trying to connect to " << fHost << ":" << fPort << std::endl; + } + + fClientSocket = socket(AF_INET, SOCK_STREAM, 0); + if (fClientSocket == -1) + { + std::cerr << "TestRunnerClient: Socket creation failed! error code: " << fClientSocket << std::endl; + return -1; + } + + struct hostent *host = gethostbyname(fHost); + if (host == NULL) + { + std::cerr << "TestRunnerClient: Cannot find host address for " << fHost << "." << std::endl; + fClientSocket = -1; + return -1; + } + + struct sockaddr_in name; + memset((void *)&name, 0, sizeof(struct sockaddr_in)); + name.sin_family = AF_INET; + name.sin_port = htons(fPort); + + memcpy(&name.sin_addr, host->h_addr, host->h_length); + + if (fDebugMode) { + std::cerr << "TestRunnerClient: Waiting for the JVM to listen ... (trying 3 times)" << std::endl; + } + + int ret = -1; + int j = 0; + while ((j < 3) && (ret == -1)) + { + ret = ::connect(fClientSocket, (struct sockaddr *) &name, sizeof(struct sockaddr_in)); + if (ret == -1) + { + if (fDebugMode) { + std::cerr << "TestRunnerClient: Connection request, waiting 1 second. " + << ((j-3)*-1) << " times left." << std::endl; + } + PrivateSleep(1000); + j++; + } + } + if (ret == -1) + { + std::cerr << "TestRunnerClient: No connection established. Error code: " << errno << std::endl; + fClientSocket = -1; + return -1; + } + + if (fDebugMode) { + std::cerr << "TestRunnerClient: Connection established." << std::endl; + } + return 0; +} + +void TestRunnerClient::InstallListeners() +{ + fTestResult = new CppUnit::TestResult(); + fTestResult->addListener(this); + fTestResult->addListener(&resultCollector); +} + +void TestRunnerClient::UninstallListeners() +{ + fTestResult->removeListener(this); +} + +void TestRunnerClient::RunTests() +{ + + CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); + CppUnit::Test *suite = registry.makeTest(); + int count = suite->countTestCases(); + NotifyTestRunStarted(count); + + if (count == 0) + { + NotifyTestRunEnded(0); + } + + long startTime = CurrentTimeMillis(); + if (fDebugMode) + { + std::cerr <<"TestRunnerClient: Start sending test case tree ..." << std::endl; + } + + SendTestTree(suite); + + int elapsedTime = CurrentTimeMillis() - startTime; + if (fDebugMode) { + std::cerr << "TestRunnerClient: Done sending test case tree. Elapsed time is " + << elapsedTime << "ms." << std::endl; + } + + long testStartTime = CurrentTimeMillis(); + if (fDebugMode) { + std::cerr << "TestRunnerClient: Test start time is " << testStartTime + << "ms." << std::endl; + } + + suite->run(fTestResult); + + if (fTestResult == NULL || fTestResult->shouldStop()) + { + NotifyTestRunStopped(CurrentTimeMillis() - testStartTime); + } + else + { + NotifyTestRunEnded(CurrentTimeMillis() - testStartTime); + } +} + +void TestRunnerClient::ShutDown() +{ + if (fClientSocket != -1) + { + if (fDebugMode) { + std::cerr << "TestRunnerClient: Closing connection to CppUnit sever at " + << fHost << ":" << fPort << std::endl; + } + +#ifdef _WIN32 // Bugzilla 40710 + // TODO: std:err output for error return codes + closesocket(fClientSocket); + WSACleanup(); +#else + int result = close(fClientSocket); + if (result != 0) + { + std::cerr << "TestRunnerClient: Close connection error: " << errno << std::endl; + } +#endif + + fClientSocket = -1; + } +} + +void TestRunnerClient::Stop() +{ + if (fTestResult != NULL) + { + fTestResult->stop(); + } +} + +void TestRunnerClient::SendTestTree(CppUnit::Test *test) +{ + if (typeid(*test) == typeid(CppUnit::TestDecorator)) + { + class TmpClass : public CppUnit::TestDecorator { + + public: + TmpClass(Test *t):CppUnit::TestDecorator(t) + { + // nothing to do + } + + ~TmpClass() // Bugzilla 39894 + { + // nothing to do + } + + CppUnit::Test *getTest() + { + return m_test; + } + }; + + TmpClass *t = (TmpClass *)test; + SendTestTree(t->getTest()); + } + else if (typeid(*test) == typeid(CppUnit::TestSuite)) + { + CppUnit::TestSuite *suite = (CppUnit::TestSuite *)test; + const std::vector<CppUnit::Test *> &x = suite->getTests(); + + std::ostringstream os; + os << suite->getName() << ",true," << x.size(); + NotifyTestTreeEntry(os.str()); + + for(unsigned int i=0; i < x.size(); i++) + { + SendTestTree(x[i]); + } + } + else + { + std::ostringstream os; + os << test->getName() << ",false," << test->countTestCases(); + NotifyTestTreeEntry(os.str()); + } +} + +void TestRunnerClient::SendMessage(std::string msg) +{ + if (fClientSocket == -1) + { + return; + } + +#ifdef _WIN32 // Bugzilla 40710 + send (fClientSocket, msg.c_str(), msg.length(), 0); + send (fClientSocket, "\n", 1, 0); +#else + write(fClientSocket, msg.c_str(), msg.length()); + write(fClientSocket, "\n", 1); +#endif + + if (fDebugMode) + { + std::cerr << "TestRunnerClient: Sent message \"" << msg << "\"" + << std::endl; + } +} + +void TestRunnerClient::NotifyTestRunStarted(int testCount) +{ + std::ostringstream os; + os << TEST_RUN_START << testCount; + SendMessage(os.str()); +} + +void TestRunnerClient::NotifyTestRunEnded(long elapsedTime) +{ + std::ostringstream os; + os << TEST_RUN_END << elapsedTime; + SendMessage(os.str()); +} + +void TestRunnerClient::NotifyTestRunStopped(long elapsedTime) +{ + std::ostringstream os; + os << TEST_STOPPED << elapsedTime; + SendMessage(os.str()); +} + +void TestRunnerClient::NotifyTestTreeEntry(std::string treeEntry) +{ + SendMessage(TEST_TREE + treeEntry); +} + +void TestRunnerClient::NotifyTestStarted(std::string testName) +{ + SendMessage(TEST_START + testName); +} + +void TestRunnerClient::NotifyTestEnded(std::string testName) +{ + SendMessage(TEST_END + testName); +} + +void TestRunnerClient::NotifyTestFailed(std::string status, std::string testName, std::string trace) +{ + SendMessage(status + testName); + SendMessage(TRACE_START); + SendMessage(trace); + SendMessage(TRACE_END); +} + +// From TestListener +void TestRunnerClient::startTest(CppUnit::Test *test) +{ + NotifyTestStarted(test->getName()); +} + +// From TestListener +void TestRunnerClient::addFailure(const CppUnit::TestFailure &failure) +{ + if(failure.isError()) + { + NotifyTestFailed(TEST_ERROR,failure.failedTestName(),GetTrace(failure)); + } + else + { + NotifyTestFailed(TEST_FAILED,failure.failedTestName(),GetTrace(failure)); + } +} + +// From TestListener +void TestRunnerClient::endTest(CppUnit::Test *test) +{ + NotifyTestEnded(test->getName()); +} + +std::string TestRunnerClient::GetTrace(const CppUnit::TestFailure &failure) +{ + std::ostringstream os; + + CppUnit::Exception *e=failure.thrownException(); + if(e->sourceLine().lineNumber()!=-1) + { + os << "File " << e->sourceLine().fileName() << ":" << e->sourceLine().lineNumber() << "\n"; + } + else + { + os << "File Unknown:1\n"; + } + /* TODO: expected, actual value implementation + if(typeid(*e)==typeid(CppUnit::NotEqualException)) + { + CppUnit::NotEqualException *ne=(CppUnit::NotEqualException *)e; + + os << "Expected Value: " << ne->expectedValue() << "\n"; + os << "Actual Value: " << ne->expectedValue() << "\n"; + os << "Additional Message: " << ne->additionalMessage() << "\n"; + } + else + { + End */ + os << "Message: " << std::string(e->what()) << "\n"; + /* } */ + + return(os.str()); +} + +long TestRunnerClient::CurrentTimeMillis() +{ +#ifdef _WIN32 // Bugzilla 40710 + unsigned long long p; + __asm__ __volatile__ ("rdtsc" : "=A" (p)); + return (unsigned long)p; +#else + struct timeval tv; + gettimeofday(&tv, NULL); + + return((long)(tv.tv_sec*1000) + (tv.tv_usec/1000)); +#endif +} + +void TestRunnerClient::PrivateSleep(int millisecs) +{ + struct timeval delta; + delta.tv_sec = (millisecs * 1000L) / 1000000L; + delta.tv_usec = (millisecs * 1000L) % 1000000L; + select (0, NULL, NULL, NULL, &delta); +} + +CppUnit::TestResultCollector& TestRunnerClient::getResultCollector() { + return resultCollector; +} + +/*! + * This is the main routine. The TestRunnerClient is initialized and run. The + * CppUnit tests are created, executed, and sent to the CppUnitServer. + * If no connection to the CppUnitServer was established the CppUnit tests are + * displayed on the console. + * + * @return <code>0</code> if the results of the CppUnit tests were sent to the + * CppUnitServer successfully. + * <code>-1</code> if a connection could not be established to the + * CppUnitServer. + */ +int CPPUNIT_MAIN(int n, char *arg[]) +{ + std::ofstream xmlFileOut("cppunit_results.xml"); + + TestRunnerClient client; + client.Init(n, arg); + int ret = client.Run(); + if (ret == -1) + { + //The Test Runner Client has failed + //Create the event manager and test controller + + CppUnit::TestResult controller; + + // Add a listener that collects test result + CppUnit::TestResultCollector result; + controller.addListener ( &result ); + + CppUnit::XmlOutputter xmlOutputter ( &result, xmlFileOut ); + CppUnit::TestFactoryRegistry ®istry = CppUnit::TestFactoryRegistry::getRegistry(); + CppUnit::Test *suite = registry.makeTest(); + + CppUnit::TextUi::TestRunner *runner = new CppUnit::TextUi::TestRunner(); + runner->addTest(suite); + runner->run(controller); + + // Output to XML + xmlOutputter.write(); + } else { + + CppUnit::TextOutputter textOutputter (&client.getResultCollector(), std::cout); + textOutputter.write(); + + // Output to XML + CppUnit::XmlOutputter xmlOutputter ( &client.getResultCollector(), xmlFileOut ); + xmlOutputter.write(); + } + + + xmlFileOut.close(); +} + +#endif /*CPPUNIT_MAIN*/ diff --git a/test/TestRunnerClient.h b/test/TestRunnerClient.h new file mode 100644 index 0000000..4dc4460 --- /dev/null +++ b/test/TestRunnerClient.h @@ -0,0 +1,147 @@ +/******************************************************************************* + * Copyright (c) 2008 Gerhard Leonhartsberger. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + *******************************************************************************/ + +#ifndef TESTRUNNERSERVER_H_ +#define TESTRUNNERSERVER_H_ + +#ifdef CPPUNIT_MAIN + +#include "cppunit/TestResultCollector.h" +#include "cppunit/TestListener.h" + +#include <vector> +#include <string> +#include <string.h> +#include <stdlib.h> + + +/*! + * Class <code>TestRunnerClient</code> handles the network connection to the + * <code>CppUnitServer</code> and executes all registered CppUnit tests. + * <p> + * The meta data of the CppUnit tests and the test results are sent to the + * <code>CppUnitServer</code> for displaying. + * </p> + * <p> + * For debugging purposes class <code>TestRunnerClient</code> displays debug + * messages on <code>std.cerr</code>. The debug modus is activated by specifying + * <code>debug</code> command line option. The command line is parsed by method + * <code>Init()</code>. + * </p> + * <p> + * Note: This class is not intended to be subclassed by clients. This class is + * based on the original <code>RemoteTestRunner</code> class provided by + * <code>org.eclipse.cdt.cppunit</code>. + * </p> + * + * @author Gerhard Leonhartsberger + */ +class TestRunnerClient: public CppUnit::TestListener +{ +private: + CppUnit::TestResult *fTestResult; + CppUnit::TestResultCollector resultCollector; + int fClientSocket; + char *fHost; + int fPort; + int fDebugMode; + int fKeepAlive; + +public: + TestRunnerClient(); + virtual ~TestRunnerClient(); + + CppUnit::TestResultCollector& getResultCollector(); + + /*! + * Initializes the <code>TestRunnerClient</code>. + * <p> + * The given <code>args</code> are parsed. The syntax for the arguments is + * defined in EBNF as follows: <code>{-option=value}</code> + * </p> + * + * @param n The number of arguments. + * @param args The argument values. Valid options are: + * <li><code>-debug</code> When present the TestRunnerClient + * is run in debug modus and displays debug messages.</li> + * <li><code>-port=number</code> Defines the port where + * CppUnitServer is listening for client connections.</li> + */ + void Init(int n,char *args[]); + + /*! + * Runs the TestRunnerClient. A trial to connect to the CppUnitServer is done. + * The test results are sent to the CppUnitServer. + * + * @return The return value is <code>0</code> when the CppUnitServer was connected successfully + * otherwise the return value is <code>-1</code>. + */ + int Run(); + + /*! + * Stops processing <code>CppUnit</code> from executing tests. + */ + void Stop(); + + /*! + * Method defined in <code>CppUnit::TestListener</code>. + */ + void startTest(CppUnit::Test *test); + + /*! + * Method defined in <code>CppUnit::TestListener</code>. + */ + void addFailure(const CppUnit::TestFailure &failure); + + /*! + * Method defined in <code>CppUnit::TestListener</code>. + */ + void endTest(CppUnit::Test *test); + +private: + int Connect(); + void RunTests(); + void ShutDown(); + + // utility methods + void ParseCommandLine(int n, char *args[]); + void DefineHostName(); + void InstallListeners(); + void UninstallListeners(); + + /*! + * Sends the given test to the CppUnitView. + * <p> + * In case of test is of type CppUnit::Test the following protocol is sent: + * <code>TSTTREE name, false, testCaseCount</code> + * </p> + * <p> + * In case of test is of type CppUnit::TestSuite the following protocol is sent: + * TSTTREE name, true, testCount + * </p> + * @param test the CppUnit test + */ + void SendTestTree(CppUnit::Test *test); + void SendMessage(std::string msg); + + // Notification methods + void NotifyTestRunStarted(int testCount); + void NotifyTestRunEnded(long elapsedTime); + void NotifyTestRunStopped(long elapsedTime); + void NotifyTestTreeEntry(std::string treeEntry); + void NotifyTestStarted(std::string testName); + void NotifyTestEnded(std::string testName); + void NotifyTestFailed(std::string status, std::string testName, std::string trace); + + std::string GetTrace(const CppUnit::TestFailure &failure); + long CurrentTimeMillis(); + void PrivateSleep(int millisecs); +}; + +#endif /*CPPUNIT_MAIN*/ +#endif /*TESTRUNNERSERVER_H_*/ @@ -0,0 +1 @@ +VERSION=0.1 |