From 258ce38ac75dd0a22e34e49a8c0f34e73ebc0ae5 Mon Sep 17 00:00:00 2001 From: Franz <dabuuschti@hotmail.de> Date: Tue, 26 Jul 2011 14:29:38 +0200 Subject: [PATCH] added libxbee library --- thirdParty/libxbee/LICENSE | 674 +++++ thirdParty/libxbee/README | 39 + thirdParty/libxbee/api.c | 2433 +++++++++++++++++ thirdParty/libxbee/api.h | 254 ++ .../libxbee/doc/man/man3/libxbee.3.html | 127 + .../libxbee/doc/man/man3/xbee_con.3.html | 26 + .../libxbee/doc/man/man3/xbee_end.3.html | 27 + .../libxbee/doc/man/man3/xbee_endcon.3.html | 4 + .../libxbee/doc/man/man3/xbee_flushcon.3.html | 4 + .../doc/man/man3/xbee_getanalog.3.html | 140 + .../doc/man/man3/xbee_getdigital.3.html | 134 + .../doc/man/man3/xbee_getpacket.3.html | 130 + .../doc/man/man3/xbee_hasanalog.3.html | 4 + .../doc/man/man3/xbee_hasdigital.3.html | 4 + .../libxbee/doc/man/man3/xbee_logit.3.html | 27 + .../libxbee/doc/man/man3/xbee_newcon.3.html | 201 ++ .../doc/man/man3/xbee_nsenddata.3.html | 4 + .../libxbee/doc/man/man3/xbee_pkt.3.html | 107 + .../libxbee/doc/man/man3/xbee_senddata.3.html | 129 + .../libxbee/doc/man/man3/xbee_setup.3.html | 142 + .../libxbee/doc/man/man3/xbee_setupAPI.3.html | 4 + .../libxbee/doc/man/man3/xbee_setuplog.3.html | 4 + .../doc/man/man3/xbee_setuplogAPI.3.html | 4 + .../doc/man/man3/xbee_vsenddata.3.html | 4 + thirdParty/libxbee/main.c | 229 ++ thirdParty/libxbee/man/man3/libxbee.3 | 91 + thirdParty/libxbee/man/man3/xbee_con.3 | 22 + thirdParty/libxbee/man/man3/xbee_end.3 | 23 + thirdParty/libxbee/man/man3/xbee_endcon.3 | 1 + thirdParty/libxbee/man/man3/xbee_flushcon.3 | 1 + thirdParty/libxbee/man/man3/xbee_getanalog.3 | 96 + thirdParty/libxbee/man/man3/xbee_getdigital.3 | 91 + thirdParty/libxbee/man/man3/xbee_getpacket.3 | 88 + thirdParty/libxbee/man/man3/xbee_hasanalog.3 | 1 + thirdParty/libxbee/man/man3/xbee_hasdigital.3 | 1 + thirdParty/libxbee/man/man3/xbee_logit.3 | 23 + thirdParty/libxbee/man/man3/xbee_newcon.3 | 152 + thirdParty/libxbee/man/man3/xbee_nsenddata.3 | 1 + thirdParty/libxbee/man/man3/xbee_pkt.3 | 79 + thirdParty/libxbee/man/man3/xbee_purgecon.3 | 1 + thirdParty/libxbee/man/man3/xbee_senddata.3 | 86 + thirdParty/libxbee/man/man3/xbee_setup.3 | 108 + thirdParty/libxbee/man/man3/xbee_setupAPI.3 | 1 + thirdParty/libxbee/man/man3/xbee_setuplog.3 | 1 + .../libxbee/man/man3/xbee_setuplogAPI.3 | 1 + thirdParty/libxbee/man/man3/xbee_vsenddata.3 | 1 + thirdParty/libxbee/notes/Notepad++ Style.xml | 36 + thirdParty/libxbee/notes/v1-v2.txt | 29 + thirdParty/libxbee/pdf/api.c.pdf | Bin 0 -> 75665 bytes thirdParty/libxbee/pdf/api.h.pdf | Bin 0 -> 11188 bytes thirdParty/libxbee/pdf/main.c.pdf | Bin 0 -> 8923 bytes thirdParty/libxbee/pdf/xbee.h.pdf | Bin 0 -> 11925 bytes thirdParty/libxbee/sample/README | 12 + thirdParty/libxbee/sample/analog.c | 71 + thirdParty/libxbee/sample/api.c | 42 + thirdParty/libxbee/sample/atis.c | 81 + thirdParty/libxbee/sample/atsetup.c | 157 ++ thirdParty/libxbee/sample/callback.c | 88 + thirdParty/libxbee/sample/digital.c | 146 + thirdParty/libxbee/sample/digitalout.c | 128 + thirdParty/libxbee/sample/multi.c | 100 + thirdParty/libxbee/sample/scan.c | 144 + thirdParty/libxbee/sample/scan_adv.c | 589 ++++ thirdParty/libxbee/sample/simple.c | 68 + thirdParty/libxbee/sample/talk_to_me.c | 82 + thirdParty/libxbee/sample/vb6/README.txt | 8 + thirdParty/libxbee/sample/vb6/demo/Form1.frm | 64 + thirdParty/libxbee/sample/vb6/demo/demo.bas | 19 + thirdParty/libxbee/sample/vb6/demo/demo.vbp | 33 + thirdParty/libxbee/sample/vb6/libxbee.bas | 285 ++ .../libxbee/sample/vb6/talk_to_me/Form1.frm | 1197 ++++++++ .../sample/vb6/talk_to_me/talk_to_me.bas | 431 +++ .../sample/vb6/talk_to_me/talk_to_me.vbp | 33 + thirdParty/libxbee/sample/xbee2_rx.c | 60 + thirdParty/libxbee/sample/xbee2_tx.c | 54 + thirdParty/libxbee/win32.README.txt | 31 + thirdParty/libxbee/xbee.h | 218 ++ thirdParty/libxbee/xsys/README | 1 + thirdParty/libxbee/xsys/linux.c | 148 + thirdParty/libxbee/xsys/linux.h | 57 + thirdParty/libxbee/xsys/pdf/linux.c.pdf | Bin 0 -> 8394 bytes thirdParty/libxbee/xsys/pdf/linux.h.pdf | Bin 0 -> 5205 bytes thirdParty/libxbee/xsys/pdf/win32.c.pdf | Bin 0 -> 14179 bytes thirdParty/libxbee/xsys/pdf/win32.def.pdf | Bin 0 -> 3538 bytes thirdParty/libxbee/xsys/pdf/win32.dll.c.pdf | Bin 0 -> 7893 bytes thirdParty/libxbee/xsys/pdf/win32.h.pdf | Bin 0 -> 5959 bytes thirdParty/libxbee/xsys/pdf/win32.rc.pdf | Bin 0 -> 4744 bytes thirdParty/libxbee/xsys/win32.c | 279 ++ thirdParty/libxbee/xsys/win32.def | 71 + thirdParty/libxbee/xsys/win32.dll.c | 131 + thirdParty/libxbee/xsys/win32.h | 73 + thirdParty/libxbee/xsys/win32.rc | 47 + 92 files changed, 10737 insertions(+) create mode 100644 thirdParty/libxbee/LICENSE create mode 100644 thirdParty/libxbee/README create mode 100644 thirdParty/libxbee/api.c create mode 100644 thirdParty/libxbee/api.h create mode 100644 thirdParty/libxbee/doc/man/man3/libxbee.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_con.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_end.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_endcon.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_flushcon.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_getanalog.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_getdigital.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_getpacket.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_hasanalog.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_hasdigital.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_logit.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_newcon.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_nsenddata.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_pkt.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_senddata.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_setup.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_setupAPI.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_setuplog.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_setuplogAPI.3.html create mode 100644 thirdParty/libxbee/doc/man/man3/xbee_vsenddata.3.html create mode 100644 thirdParty/libxbee/main.c create mode 100644 thirdParty/libxbee/man/man3/libxbee.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_con.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_end.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_endcon.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_flushcon.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_getanalog.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_getdigital.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_getpacket.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_hasanalog.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_hasdigital.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_logit.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_newcon.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_nsenddata.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_pkt.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_purgecon.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_senddata.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_setup.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_setupAPI.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_setuplog.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_setuplogAPI.3 create mode 100644 thirdParty/libxbee/man/man3/xbee_vsenddata.3 create mode 100644 thirdParty/libxbee/notes/Notepad++ Style.xml create mode 100644 thirdParty/libxbee/notes/v1-v2.txt create mode 100644 thirdParty/libxbee/pdf/api.c.pdf create mode 100644 thirdParty/libxbee/pdf/api.h.pdf create mode 100644 thirdParty/libxbee/pdf/main.c.pdf create mode 100644 thirdParty/libxbee/pdf/xbee.h.pdf create mode 100644 thirdParty/libxbee/sample/README create mode 100644 thirdParty/libxbee/sample/analog.c create mode 100644 thirdParty/libxbee/sample/api.c create mode 100644 thirdParty/libxbee/sample/atis.c create mode 100644 thirdParty/libxbee/sample/atsetup.c create mode 100644 thirdParty/libxbee/sample/callback.c create mode 100644 thirdParty/libxbee/sample/digital.c create mode 100644 thirdParty/libxbee/sample/digitalout.c create mode 100644 thirdParty/libxbee/sample/multi.c create mode 100644 thirdParty/libxbee/sample/scan.c create mode 100644 thirdParty/libxbee/sample/scan_adv.c create mode 100644 thirdParty/libxbee/sample/simple.c create mode 100644 thirdParty/libxbee/sample/talk_to_me.c create mode 100644 thirdParty/libxbee/sample/vb6/README.txt create mode 100644 thirdParty/libxbee/sample/vb6/demo/Form1.frm create mode 100644 thirdParty/libxbee/sample/vb6/demo/demo.bas create mode 100644 thirdParty/libxbee/sample/vb6/demo/demo.vbp create mode 100644 thirdParty/libxbee/sample/vb6/libxbee.bas create mode 100644 thirdParty/libxbee/sample/vb6/talk_to_me/Form1.frm create mode 100644 thirdParty/libxbee/sample/vb6/talk_to_me/talk_to_me.bas create mode 100644 thirdParty/libxbee/sample/vb6/talk_to_me/talk_to_me.vbp create mode 100644 thirdParty/libxbee/sample/xbee2_rx.c create mode 100644 thirdParty/libxbee/sample/xbee2_tx.c create mode 100644 thirdParty/libxbee/win32.README.txt create mode 100644 thirdParty/libxbee/xbee.h create mode 100644 thirdParty/libxbee/xsys/README create mode 100644 thirdParty/libxbee/xsys/linux.c create mode 100644 thirdParty/libxbee/xsys/linux.h create mode 100644 thirdParty/libxbee/xsys/pdf/linux.c.pdf create mode 100644 thirdParty/libxbee/xsys/pdf/linux.h.pdf create mode 100644 thirdParty/libxbee/xsys/pdf/win32.c.pdf create mode 100644 thirdParty/libxbee/xsys/pdf/win32.def.pdf create mode 100644 thirdParty/libxbee/xsys/pdf/win32.dll.c.pdf create mode 100644 thirdParty/libxbee/xsys/pdf/win32.h.pdf create mode 100644 thirdParty/libxbee/xsys/pdf/win32.rc.pdf create mode 100644 thirdParty/libxbee/xsys/win32.c create mode 100644 thirdParty/libxbee/xsys/win32.def create mode 100644 thirdParty/libxbee/xsys/win32.dll.c create mode 100644 thirdParty/libxbee/xsys/win32.h create mode 100644 thirdParty/libxbee/xsys/win32.rc diff --git a/thirdParty/libxbee/LICENSE b/thirdParty/libxbee/LICENSE new file mode 100644 index 0000000000..94a9ed024d --- /dev/null +++ b/thirdParty/libxbee/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state 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 program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/thirdParty/libxbee/README b/thirdParty/libxbee/README new file mode 100644 index 0000000000..a5dbbfe0f3 --- /dev/null +++ b/thirdParty/libxbee/README @@ -0,0 +1,39 @@ +Welcome to libxbee! + +I have proveded sample code in the ./sample directory. Hopefully this will help +get you up and running with libxbee. If you would like samples showing a different +aspect of libxbee, then please do not hesitate to file an 'issue' on the project +site, and I will get to it ASAP: + http://code.google.com/p/libxbee/issues/list + + +Documentation is avaliable via the man page system once you have installed the +library, or as HTML in the 'doc' directory. + $ man libxbee + + +Please note that this project is still in development, so should not be used for +any purpose other than learning/playing/testing etc... Basically don't use it to +make money, and then hold me responsible if it breaks! + +Feel free to contact me directly with any queries: + attie@attie.co.uk + + +For those of you that are planning to use this on an embedded board, I have +included a small makefile (umakefile) that has only the information needed to +compile the library. I suggest you use this instead! + +=== Installation === +To install simply type: + $ make install + +For more information, or if you can't install it, please see the wiki: + http://code.google.com/p/libxbee/wiki/install_libxbee + + +=== Usage === +If you are compiling the object file directly into your executable instead +of making use of the shared library, you must include the following link +flags: + -lpthread -lrt diff --git a/thirdParty/libxbee/api.c b/thirdParty/libxbee/api.c new file mode 100644 index 0000000000..ef5923b568 --- /dev/null +++ b/thirdParty/libxbee/api.c @@ -0,0 +1,2433 @@ +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +const char *SVN_REV = "$Id: api.c 508 2011-06-12 23:22:34Z attie@attie.co.uk $"; +char svn_rev[128] = "\0"; + +#include "api.h" + +const char *xbee_svn_version(void) { + if (svn_rev[0] == '\0') { + char *t; + sprintf(svn_rev,"r%s",&SVN_REV[11]); + t = strrchr(svn_rev,' '); + if (t) { + t[0] = '\0'; + } + } + return svn_rev; +} + +const char *xbee_build_info(void) { + return "Built on " __DATE__ " @ " __TIME__ " for " HOST_OS; +} + +/* ################################################################# */ +/* ### Memory Handling ############################################# */ +/* ################################################################# */ + +/* malloc wrapper function */ +static void *Xmalloc2(xbee_hnd xbee, size_t size) { + void *t; + t = malloc(size); + if (!t) { + /* uhoh... thats pretty bad... */ + xbee_perror("libxbee:malloc()"); + exit(1); + } + return t; +} + +/* calloc wrapper function */ +static void *Xcalloc2(xbee_hnd xbee, size_t size) { + void *t; + t = calloc(1, size); + if (!t) { + /* uhoh... thats pretty bad... */ + xbee_perror("libxbee:calloc()"); + exit(1); + } + return t; +} + +/* realloc wrapper function */ +static void *Xrealloc2(xbee_hnd xbee, void *ptr, size_t size) { + void *t; + t = realloc(ptr,size); + if (!t) { + /* uhoh... thats pretty bad... */ + fprintf(stderr,"libxbee:realloc(): Returned NULL\n"); + exit(1); + } + return t; +} + +/* free wrapper function (uses the Xfree macro and sets the pointer to NULL after freeing it) */ +static void Xfree2(void **ptr) { + if (!*ptr) return; + free(*ptr); + *ptr = NULL; +} + +/* ################################################################# */ +/* ### Helper Functions ############################################ */ +/* ################################################################# */ + +/* ################################################################# + returns 1 if the packet has data for the digital input else 0 */ +int xbee_hasdigital(xbee_pkt *pkt, int sample, int input) { + int mask = 0x0001; + if (input < 0 || input > 7) return 0; + if (sample >= pkt->samples) return 0; + + mask <<= input; + return !!(pkt->IOdata[sample].IOmask & mask); +} + +/* ################################################################# + returns 1 if the digital input is high else 0 (or 0 if no digital data present) */ +int xbee_getdigital(xbee_pkt *pkt, int sample, int input) { + int mask = 0x0001; + if (!xbee_hasdigital(pkt,sample,input)) return 0; + + mask <<= input; + return !!(pkt->IOdata[sample].IOdigital & mask); +} + +/* ################################################################# + returns 1 if the packet has data for the analog input else 0 */ +int xbee_hasanalog(xbee_pkt *pkt, int sample, int input) { + int mask = 0x0200; + if (input < 0 || input > 5) return 0; + if (sample >= pkt->samples) return 0; + + mask <<= input; + return !!(pkt->IOdata[sample].IOmask & mask); +} + +/* ################################################################# + returns analog input as a voltage if vRef is non-zero, else raw value (or 0 if no analog data present) */ +double xbee_getanalog(xbee_pkt *pkt, int sample, int input, double Vref) { + if (!xbee_hasanalog(pkt,sample,input)) return 0; + + if (Vref) return (Vref / 1023) * pkt->IOdata[sample].IOanalog[input]; + return pkt->IOdata[sample].IOanalog[input]; +} + +/* ################################################################# */ +/* ### XBee Functions ############################################## */ +/* ################################################################# */ + +static void xbee_logf(xbee_hnd xbee, const char *logformat, const char *file, + const int line, const char *function, char *format, ...) { + char buf[128]; + va_list ap; + if (!xbee) return; + if (!xbee->log) return; + va_start(ap,format); + vsnprintf(buf,127,format,ap); + va_end(ap); + fprintf(xbee->log,logformat,file,line,function,buf); +} +void xbee_logitf(char *format, ...) { + char buf[128]; + va_list ap; + va_start(ap,format); + vsnprintf(buf,127,format,ap); + va_end(ap); + xbee_logit(buf); +} +void _xbee_logitf(xbee_hnd xbee, char *format, ...) { + char buf[128]; + va_list ap; + va_start(ap,format); + vsnprintf(buf,127,format,ap); + va_end(ap); + _xbee_logit(xbee, buf); +} +void xbee_logit(char *str) { + _xbee_logit(default_xbee, str); +} +void _xbee_logit(xbee_hnd xbee, char *str) { + if (!xbee) return; + if (!xbee->log) return; + xbee_mutex_lock(xbee->logmutex); + fprintf(xbee->log,LOG_FORMAT"\n",__FILE__,__LINE__,__FUNCTION__,str); + xbee_mutex_unlock(xbee->logmutex); +} + +/* ################################################################# + xbee_sendAT - INTERNAL + allows for an at command to be send, and the reply to be captured */ +static int xbee_sendAT(xbee_hnd xbee, char *command, char *retBuf, int retBuflen) { + return xbee_sendATdelay(xbee, 0, command, retBuf, retBuflen); +} +static int xbee_sendATdelay(xbee_hnd xbee, int guardTime, char *command, char *retBuf, int retBuflen) { + struct timeval to; + + int ret; + int bufi = 0; + + /* if there is a guardTime given, then use it and a bit more */ + if (guardTime) usleep(guardTime * 1200); + + /* get rid of any pre-command sludge... */ + memset(&to, 0, sizeof(to)); + ret = xbee_select(xbee,&to); + if (ret > 0) { + char t[128]; + while (xbee_read(xbee,t,127)); + } + + /* send the requested command */ + xbee_log("sendATdelay: Sending '%s'", command); + xbee_write(xbee,command, strlen(command)); + + /* if there is a guardTime, then use it */ + if (guardTime) { + usleep(guardTime * 900); + + /* get rid of any post-command sludge... */ + memset(&to, 0, sizeof(to)); + ret = xbee_select(xbee,&to); + if (ret > 0) { + char t[128]; + while (xbee_read(xbee,t,127)); + } + } + + /* retrieve the data */ + memset(retBuf, 0, retBuflen); + memset(&to, 0, sizeof(to)); + if (guardTime) { + /* select on the xbee fd... wait at most 0.2 the guardTime for the response */ + to.tv_usec = guardTime * 200; + } else { + /* or 250ms */ + to.tv_usec = 250000; + } + if ((ret = xbee_select(xbee,&to)) == -1) { + xbee_perror("libxbee:xbee_sendATdelay()"); + exit(1); + } + + if (!ret) { + /* timed out, and there is nothing to be read */ + xbee_log("sendATdelay: No Data to read - Timeout..."); + return 1; + } + + /* check for any dribble... */ + do { + /* if there is actually no space in the retBuf then break out */ + if (bufi >= retBuflen - 1) { + break; + } + + /* read as much data as is possible into retBuf */ + if ((ret = xbee_read(xbee,&retBuf[bufi], retBuflen - bufi - 1)) == 0) { + break; + } + + /* advance the 'end of string' pointer */ + bufi += ret; + + /* wait at most 150ms for any more data */ + memset(&to, 0, sizeof(to)); + to.tv_usec = 150000; + if ((ret = xbee_select(xbee,&to)) == -1) { + xbee_perror("libxbee:xbee_sendATdelay()"); + exit(1); + } + + /* loop while data was read */ + } while (ret); + + if (!bufi) { + xbee_log("sendATdelay: No response..."); + return 1; + } + + /* terminate the string */ + retBuf[bufi] = '\0'; + + xbee_log("sendATdelay: Recieved '%s'",retBuf); + return 0; +} + + +/* ################################################################# + xbee_start + sets up the correct API mode for the xbee + cmdSeq = CC + cmdTime = GT */ +static int xbee_startAPI(xbee_hnd xbee) { + char buf[256]; + + if (xbee->cmdSeq == 0 || xbee->cmdTime == 0) return 1; + + /* setup the command sequence string */ + memset(buf,xbee->cmdSeq,3); + buf[3] = '\0'; + + /* try the command sequence */ + if (xbee_sendATdelay(xbee, xbee->cmdTime, buf, buf, sizeof(buf))) { + /* if it failed... try just entering 'AT' which should return OK */ + if (xbee_sendAT(xbee, "AT\r", buf, 4) || strncmp(buf,"OK\r",3)) return 1; + } else if (strncmp(&buf[strlen(buf)-3],"OK\r",3)) { + /* if data was returned, but it wasn't OK... then something went wrong! */ + return 1; + } + + /* get the current API mode */ + if (xbee_sendAT(xbee, "ATAP\r", buf, 3)) return 1; + buf[1] = '\0'; + xbee->oldAPI = atoi(buf); + + if (xbee->oldAPI != 2) { + /* if it wasnt set to mode 2 already, then set it to mode 2 */ + if (xbee_sendAT(xbee, "ATAP2\r", buf, 4) || strncmp(buf,"OK\r",3)) return 1; + } + + /* quit from command mode, ready for some packets! :) */ + if (xbee_sendAT(xbee, "ATCN\r", buf, 4) || strncmp(buf,"OK\r",3)) return 1; + + return 0; +} + +/* ################################################################# + xbee_end + resets the API mode to the saved value - you must have called xbee_setup[log]API */ +int xbee_end(void) { + return _xbee_end(default_xbee); +} +int _xbee_end(xbee_hnd xbee) { + int ret = 1; + xbee_con *con, *ncon; + xbee_pkt *pkt, *npkt; + xbee_hnd xbeet; + + ISREADYR(0); + xbee_log("Stopping libxbee instance..."); + + /* unlink the instance from list... */ + xbee_log("Unlinking instance from list..."); + xbee_mutex_lock(xbee_hnd_mutex); + if (xbee == default_xbee) { + default_xbee = default_xbee->next; + if (!default_xbee) { + xbee_mutex_destroy(xbee_hnd_mutex); + } + } else { + xbeet = default_xbee; + while (xbeet) { + if (xbeet->next == xbee) { + xbeet->next = xbee->next; + break; + } + xbeet = xbeet->next; + } + } + if (default_xbee) xbee_mutex_unlock(xbee_hnd_mutex); + + /* if the api mode was not 2 to begin with then put it back */ + if (xbee->oldAPI == 2) { + xbee_log("XBee was already in API mode 2, no need to reset"); + ret = 0; + } else { + int to = 5; + + con = _xbee_newcon(xbee,'I',xbee_localAT); + con->callback = NULL; + con->waitforACK = 1; + _xbee_senddata(xbee,con,"AP%c",xbee->oldAPI); + + pkt = NULL; + + while (!pkt && to--) { + pkt = _xbee_getpacketwait(xbee,con); + } + if (pkt) { + ret = pkt->status; + Xfree(pkt); + } + _xbee_endcon(xbee,con); + } + + /* xbee_* functions may no longer run... */ + xbee->xbee_ready = 0; + + /* nullify everything */ + + /* stop listening for data... either after timeout or next char read which ever is first */ + xbee->run = 0; + + xbee_thread_cancel(xbee->listent,0); + xbee_thread_join(xbee->listent); + + xbee_thread_cancel(xbee->threadt,0); + xbee_thread_join(xbee->threadt); + + /* free all connections */ + con = xbee->conlist; + xbee->conlist = NULL; + while (con) { + ncon = con->next; + Xfree(con); + con = ncon; + } + + /* free all packets */ + xbee->pktlast = NULL; + pkt = xbee->pktlist; + xbee->pktlist = NULL; + while (pkt) { + npkt = pkt->next; + Xfree(pkt); + pkt = npkt; + } + + /* destroy mutexes */ + xbee_mutex_destroy(xbee->conmutex); + xbee_mutex_destroy(xbee->pktmutex); + xbee_mutex_destroy(xbee->sendmutex); + + /* close the serial port */ + Xfree(xbee->path); + if (xbee->tty) xbee_close(xbee->tty); + + /* close log and tty */ + if (xbee->log) { + fflush(xbee->log); + xbee_close(xbee->log); + } + xbee_mutex_destroy(xbee->logmutex); + + Xfree(xbee); + + return ret; +} + +/* ################################################################# + xbee_setup + opens xbee serial port & creates xbee listen thread + the xbee must be configured for API mode 2 + THIS MUST BE CALLED BEFORE ANY OTHER XBEE FUNCTION */ +int xbee_setup(char *path, int baudrate) { + return xbee_setuplogAPI(path,baudrate,0,0,0); +} +xbee_hnd _xbee_setup(char *path, int baudrate) { + return _xbee_setuplogAPI(path,baudrate,0,0,0); +} +int xbee_setuplog(char *path, int baudrate, int logfd) { + return xbee_setuplogAPI(path,baudrate,logfd,0,0); +} +xbee_hnd _xbee_setuplog(char *path, int baudrate, int logfd) { + return _xbee_setuplogAPI(path,baudrate,logfd,0,0); +} +int xbee_setupAPI(char *path, int baudrate, char cmdSeq, int cmdTime) { + return xbee_setuplogAPI(path,baudrate,0,cmdSeq,cmdTime); +} +xbee_hnd _xbee_setupAPI(char *path, int baudrate, char cmdSeq, int cmdTime) { + return _xbee_setuplogAPI(path,baudrate,0,cmdSeq,cmdTime); +} +int xbee_setuplogAPI(char *path, int baudrate, int logfd, char cmdSeq, int cmdTime) { + if (default_xbee) return 0; + default_xbee = _xbee_setuplogAPI(path,baudrate,logfd,cmdSeq,cmdTime); + return (default_xbee?0:-1); +} +xbee_hnd _xbee_setuplogAPI(char *path, int baudrate, int logfd, char cmdSeq, int cmdTime) { + int ret; + xbee_hnd xbee = NULL; + + /* create a new instance */ + xbee = Xcalloc(sizeof(struct xbee_hnd)); + xbee->next = NULL; + + xbee_mutex_init(xbee->logmutex); +#ifdef DEBUG + if (!logfd) logfd = 2; +#endif + if (logfd) { + xbee->logfd = dup(logfd); + xbee->log = fdopen(xbee->logfd,"w"); + if (!xbee->log) { + /* errno == 9 is bad file descriptor (probrably not provided) */ + if (errno != 9) xbee_perror("xbee_setup(): Failed opening logfile"); + xbee->logfd = 0; + } else { +#ifdef __GNUC__ /* ---- */ + /* set to line buffer - ensure lines are written to file when complete */ + setvbuf(xbee->log,NULL,_IOLBF,BUFSIZ); +#else /* -------------- */ + /* Win32 is rubbish... so we have to completely disable buffering... */ + setvbuf(xbee->log,NULL,_IONBF,BUFSIZ); +#endif /* ------------- */ + } + } + + xbee_logS("---------------------------------------------------------------------"); + xbee_logI("libxbee Starting..."); + xbee_logI("SVN Info: %s",xbee_svn_version()); + xbee_logI("Build Info: %s",xbee_build_info()); + xbee_logE("---------------------------------------------------------------------"); + + /* setup the connection stuff */ + xbee->conlist = NULL; + + /* setup the packet stuff */ + xbee->pktlist = NULL; + xbee->pktlast = NULL; + xbee->pktcount = 0; + xbee->run = 1; + + /* setup the mutexes */ + if (xbee_mutex_init(xbee->conmutex)) { + xbee_perror("xbee_setup():xbee_mutex_init(conmutex)"); + if (xbee->log) xbee_close(xbee->log); + Xfree(xbee); + return NULL; + } + if (xbee_mutex_init(xbee->pktmutex)) { + xbee_perror("xbee_setup():xbee_mutex_init(pktmutex)"); + if (xbee->log) xbee_close(xbee->log); + xbee_mutex_destroy(xbee->conmutex); + Xfree(xbee); + return NULL; + } + if (xbee_mutex_init(xbee->sendmutex)) { + xbee_perror("xbee_setup():xbee_mutex_init(sendmutex)"); + if (xbee->log) xbee_close(xbee->log); + xbee_mutex_destroy(xbee->conmutex); + xbee_mutex_destroy(xbee->pktmutex); + Xfree(xbee); + return NULL; + } + + /* take a copy of the XBee device path */ + if ((xbee->path = Xmalloc(sizeof(char) * (strlen(path) + 1))) == NULL) { + xbee_perror("xbee_setup():Xmalloc(path)"); + if (xbee->log) xbee_close(xbee->log); + xbee_mutex_destroy(xbee->conmutex); + xbee_mutex_destroy(xbee->pktmutex); + xbee_mutex_destroy(xbee->sendmutex); + Xfree(xbee); + return NULL; + } + strcpy(xbee->path,path); + if (xbee->log) xbee_log("Opening serial port '%s'...",xbee->path); + + /* call the relevant init function */ + if ((ret = init_serial(xbee,baudrate)) != 0) { + xbee_log("Something failed while opening the serial port..."); + if (xbee->log) xbee_close(xbee->log); + xbee_mutex_destroy(xbee->conmutex); + xbee_mutex_destroy(xbee->pktmutex); + xbee_mutex_destroy(xbee->sendmutex); + Xfree(xbee->path); + Xfree(xbee); + return NULL; + } + + /* when xbee_end() is called, if this is not 2 then ATAP will be set to this value */ + xbee->oldAPI = 2; + xbee->cmdSeq = cmdSeq; + xbee->cmdTime = cmdTime; + if (xbee->cmdSeq && xbee->cmdTime) { + if (xbee_startAPI(xbee)) { + if (xbee->log) { + xbee_log("Couldn't communicate with XBee..."); + xbee_close(xbee->log); + } + xbee_mutex_destroy(xbee->conmutex); + xbee_mutex_destroy(xbee->pktmutex); + xbee_mutex_destroy(xbee->sendmutex); + Xfree(xbee->path); +#ifdef __GNUC__ /* ---- */ + close(xbee->ttyfd); +#endif /* ------------- */ + xbee_close(xbee->tty); + Xfree(xbee); + return NULL; + } + } + + /* allow the listen thread to start */ + xbee->xbee_ready = -1; + + /* can start xbee_listen thread now */ + if (xbee_thread_create(xbee->listent, xbee_listen_wrapper, xbee)) { + xbee_perror("xbee_setup():xbee_thread_create(listent)"); + if (xbee->log) xbee_close(xbee->log); + xbee_mutex_destroy(xbee->conmutex); + xbee_mutex_destroy(xbee->pktmutex); + xbee_mutex_destroy(xbee->sendmutex); + Xfree(xbee->path); +#ifdef __GNUC__ /* ---- */ + close(xbee->ttyfd); +#endif /* ------------- */ + xbee_close(xbee->tty); + Xfree(xbee); + return NULL; + } + + /* can start xbee_thread_watch thread thread now */ + if (xbee_thread_create(xbee->threadt, xbee_thread_watch, xbee)) { + xbee_perror("xbee_setup():xbee_thread_create(threadt)"); + if (xbee->log) xbee_close(xbee->log); + xbee_mutex_destroy(xbee->conmutex); + xbee_mutex_destroy(xbee->pktmutex); + xbee_mutex_destroy(xbee->sendmutex); + Xfree(xbee->path); +#ifdef __GNUC__ /* ---- */ + close(xbee->ttyfd); +#endif /* ------------- */ + xbee_close(xbee->tty); + Xfree(xbee); + return NULL; + } + + usleep(500); + while (xbee->xbee_ready != -2) { + usleep(500); + xbee_log("Waiting for xbee_listen() to be ready..."); + } + + /* allow other functions to be used! */ + xbee->xbee_ready = 1; + + xbee_log("Linking xbee instance..."); + if (!default_xbee) { + xbee_mutex_init(xbee_hnd_mutex); + xbee_mutex_lock(xbee_hnd_mutex); + default_xbee = xbee; + xbee_mutex_unlock(xbee_hnd_mutex); + } else { + xbee_hnd xbeet; + xbee_mutex_lock(xbee_hnd_mutex); + xbeet = default_xbee; + while (xbeet->next) { + xbeet = xbeet->next; + } + xbeet->next = xbee; + xbee_mutex_unlock(xbee_hnd_mutex); + } + + xbee_log("libxbee: Started!"); + + return xbee; +} + +/* ################################################################# + xbee_con + produces a connection to the specified device and frameID + if a connection had already been made, then this connection will be returned */ +xbee_con *xbee_newcon(unsigned char frameID, xbee_types type, ...) { + xbee_con *ret; + va_list ap; + + /* xbee_vnewcon() wants a va_list... */ + va_start(ap, type); + /* hand it over :) */ + ret = _xbee_vnewcon(default_xbee, frameID, type, ap); + va_end(ap); + return ret; +} +xbee_con *_xbee_newcon(xbee_hnd xbee, unsigned char frameID, xbee_types type, ...) { + xbee_con *ret; + va_list ap; + + /* xbee_vnewcon() wants a va_list... */ + va_start(ap, type); + /* hand it over :) */ + ret = _xbee_vnewcon(xbee, frameID, type, ap); + va_end(ap); + return ret; +} +xbee_con *_xbee_vnewcon(xbee_hnd xbee, unsigned char frameID, xbee_types type, va_list ap) { + xbee_con *con, *ocon; + unsigned char tAddr[8]; + int t; + int i; + + ISREADYR(NULL); + + if (!type || type == xbee_unknown) type = xbee_localAT; /* default to local AT */ + else if (type == xbee_remoteAT) type = xbee_64bitRemoteAT; /* if remote AT, default to 64bit */ + + /* if: 64 bit address expected (2 ints) */ + if ((type == xbee_64bitRemoteAT) || + (type == xbee_64bitData) || + (type == xbee_64bitIO) || + (type == xbee2_data)) { + t = va_arg(ap, int); + tAddr[0] = (t >> 24) & 0xFF; + tAddr[1] = (t >> 16) & 0xFF; + tAddr[2] = (t >> 8) & 0xFF; + tAddr[3] = (t ) & 0xFF; + t = va_arg(ap, int); + tAddr[4] = (t >> 24) & 0xFF; + tAddr[5] = (t >> 16) & 0xFF; + tAddr[6] = (t >> 8) & 0xFF; + tAddr[7] = (t ) & 0xFF; + + /* if: 16 bit address expected (1 int) */ + } else if ((type == xbee_16bitRemoteAT) || + (type == xbee_16bitData) || + (type == xbee_16bitIO)) { + t = va_arg(ap, int); + tAddr[0] = (t >> 8) & 0xFF; + tAddr[1] = (t ) & 0xFF; + tAddr[2] = 0; + tAddr[3] = 0; + tAddr[4] = 0; + tAddr[5] = 0; + tAddr[6] = 0; + tAddr[7] = 0; + + /* otherwise clear the address */ + } else { + memset(tAddr,0,8); + } + + /* lock the connection mutex */ + xbee_mutex_lock(xbee->conmutex); + + /* are there any connections? */ + if (xbee->conlist) { + con = xbee->conlist; + while (con) { + /* if: looking for a modemStatus, and the types match! */ + if ((type == xbee_modemStatus) && + (con->type == type)) { + xbee_mutex_unlock(xbee->conmutex); + return con; + + /* if: looking for a txStatus and frameIDs match! */ + } else if ((type == xbee_txStatus) && + (con->type == type) && + (frameID == con->frameID)) { + xbee_mutex_unlock(xbee->conmutex); + return con; + + /* if: looking for a localAT, and the frameIDs match! */ + } else if ((type == xbee_localAT) && + (con->type == type) && + (frameID == con->frameID)) { + xbee_mutex_unlock(xbee->conmutex); + return con; + + /* if: connection types match, the frameIDs match, and the addresses match! */ + } else if ((type == con->type) && + (frameID == con->frameID) && + (!memcmp(tAddr,con->tAddr,8))) { + xbee_mutex_unlock(xbee->conmutex); + return con; + } + + /* if there are more, move along, dont want to loose that last item! */ + if (con->next == NULL) break; + con = con->next; + } + + /* keep hold of the last connection... we will need to link it up later */ + ocon = con; + } + + /* unlock the connection mutex */ + xbee_mutex_unlock(xbee->conmutex); + + /* create a new connection and set its attributes */ + con = Xcalloc(sizeof(xbee_con)); + con->type = type; + /* is it a 64bit connection? */ + if ((type == xbee_64bitRemoteAT) || + (type == xbee_64bitData) || + (type == xbee_64bitIO) || + (type == xbee2_data)) { + con->tAddr64 = TRUE; + } + con->atQueue = 0; /* queue AT commands? */ + con->txDisableACK = 0; /* disable ACKs? */ + con->txBroadcastPAN = 0; /* broadcast? */ + con->frameID = frameID; + con->waitforACK = 0; + memcpy(con->tAddr,tAddr,8); /* copy in the remote address */ + xbee_mutex_init(con->callbackmutex); + xbee_mutex_init(con->callbackListmutex); + xbee_mutex_init(con->Txmutex); + xbee_sem_init(con->waitforACKsem); + + if (xbee->log) { + switch(type) { + case xbee_localAT: + xbee_log("New local AT connection!"); + break; + case xbee_16bitRemoteAT: + case xbee_64bitRemoteAT: + xbee_logc("New %d-bit remote AT connection! (to: ",(con->tAddr64?64:16)); + for (i=0;i<(con->tAddr64?8:2);i++) { + fprintf(xbee->log,(i?":%02X":"%02X"),tAddr[i]); + } + fprintf(xbee->log,")"); + xbee_logcf(); + break; + case xbee_16bitData: + case xbee_64bitData: + xbee_logc("New %d-bit data connection! (to: ",(con->tAddr64?64:16)); + for (i=0;i<(con->tAddr64?8:2);i++) { + fprintf(xbee->log,(i?":%02X":"%02X"),tAddr[i]); + } + fprintf(xbee->log,")"); + xbee_logcf(); + break; + case xbee_16bitIO: + case xbee_64bitIO: + xbee_logc("New %d-bit IO connection! (to: ",(con->tAddr64?64:16)); + for (i=0;i<(con->tAddr64?8:2);i++) { + fprintf(xbee->log,(i?":%02X":"%02X"),tAddr[i]); + } + fprintf(xbee->log,")"); + xbee_logcf(); + break; + case xbee2_data: + xbee_logc("New Series 2 data connection! (to: "); + for (i=0;i<8;i++) { + fprintf(xbee->log,(i?":%02X":"%02X"),tAddr[i]); + } + fprintf(xbee->log,")"); + xbee_logcf(); + break; + case xbee_txStatus: + xbee_log("New Tx status connection!"); + break; + case xbee_modemStatus: + xbee_log("New modem status connection!"); + break; + case xbee_unknown: + default: + xbee_log("New unknown connection!"); + } + } + + /* lock the connection mutex */ + xbee_mutex_lock(xbee->conmutex); + + /* make it the last in the list */ + con->next = NULL; + /* add it to the list */ + if (xbee->conlist) { + ocon->next = con; + } else { + xbee->conlist = con; + } + + /* unlock the mutex */ + xbee_mutex_unlock(xbee->conmutex); + return con; +} + +/* ################################################################# + xbee_conflush + removes any packets that have been collected for the specified + connection */ +void xbee_purgecon(xbee_con *con) { + _xbee_purgecon(default_xbee, con); +} +void _xbee_purgecon(xbee_hnd xbee, xbee_con *con) { + xbee_pkt *r, *p, *n; + + ISREADYP(); + + /* lock the packet mutex */ + xbee_mutex_lock(xbee->pktmutex); + + /* if: there are packets */ + if ((p = xbee->pktlist) != NULL) { + r = NULL; + /* get all packets for this connection */ + do { + /* does the packet match the connection? */ + if (xbee_matchpktcon(xbee,p,con)) { + /* if it was the first packet */ + if (!r) { + /* move the chain along */ + xbee->pktlist = p->next; + } else { + /* otherwise relink the list */ + r->next = p->next; + } + xbee->pktcount--; + + /* free this packet! */ + n = p->next; + Xfree(p); + /* move on */ + p = n; + } else { + /* move on */ + r = p; + p = p->next; + } + } while (p); + xbee->pktlast = r; + } + + /* unlock the packet mutex */ + xbee_mutex_unlock(xbee->pktmutex); +} + +/* ################################################################# + xbee_endcon + close the unwanted connection + free wrapper function (uses the Xfree macro and sets the pointer to NULL after freeing it) */ +void xbee_endcon2(xbee_con **con, int alreadyUnlinked) { + _xbee_endcon2(default_xbee, con, alreadyUnlinked); +} +void _xbee_endcon2(xbee_hnd xbee, xbee_con **con, int alreadyUnlinked) { + xbee_con *t, *u; + + ISREADYP(); + + /* lock the connection mutex */ + xbee_mutex_lock(xbee->conmutex); + + u = t = xbee->conlist; + while (t && t != *con) { + u = t; + t = t->next; + } + if (!t) { + /* this could be true if comming from the destroySelf signal... */ + if (!alreadyUnlinked) { + /* invalid connection given... */ + if (xbee->log) { + xbee_log("Attempted to close invalid connection..."); + } + /* unlock the connection mutex */ + xbee_mutex_unlock(xbee->conmutex); + return; + } + } else { + /* extract this connection from the list */ + if (t == xbee->conlist) { + xbee->conlist = t->next; + } else { + u->next = t->next; + } + } + + /* unlock the connection mutex */ + xbee_mutex_unlock(xbee->conmutex); + + /* check if a callback thread is running... */ + if (t->callback && xbee_mutex_trylock(t->callbackmutex)) { + /* if it is running... tell it to destroy the connection on completion */ + xbee_log("Attempted to close a connection with active callbacks... " + "Connection will be destroyed when callbacks have completeted..."); + t->destroySelf = 1; + return; + } + + /* remove all packets for this connection */ + _xbee_purgecon(xbee,t); + + /* destroy the callback mutex */ + xbee_mutex_destroy(t->callbackmutex); + xbee_mutex_destroy(t->callbackListmutex); + xbee_mutex_destroy(t->Txmutex); + xbee_sem_destroy(t->waitforACKsem); + + /* free the connection! */ + Xfree(*con); +} + +/* ################################################################# + xbee_senddata + send the specified data to the provided connection */ +int xbee_senddata(xbee_con *con, char *format, ...) { + int ret; + va_list ap; + + /* xbee_vsenddata() wants a va_list... */ + va_start(ap, format); + /* hand it over :) */ + ret = _xbee_vsenddata(default_xbee, con, format, ap); + va_end(ap); + return ret; +} +int _xbee_senddata(xbee_hnd xbee, xbee_con *con, char *format, ...) { + int ret; + va_list ap; + + /* xbee_vsenddata() wants a va_list... */ + va_start(ap, format); + /* hand it over :) */ + ret = _xbee_vsenddata(xbee, con, format, ap); + va_end(ap); + return ret; +} + +int xbee_vsenddata(xbee_con *con, char *format, va_list ap) { + return _xbee_vsenddata(default_xbee, con, format, ap); +} +int _xbee_vsenddata(xbee_hnd xbee, xbee_con *con, char *format, va_list ap) { + unsigned char data[128]; /* max payload is 100 bytes... plus a bit of fluff... */ + int length; + + /* make up the data and keep the length, its possible there are nulls in there */ + length = vsnprintf((char *)data, 128, format, ap); + + /* hand it over :) */ + return _xbee_nsenddata(xbee, con, (char *)data, length); +} + +/* returns: + 1 - if NAC was recieved + 0 - if packet was successfully sent (or just sent if waitforACK is off) + -1 - if there was an error building the packet + -2 - if the connection type was unknown */ +int xbee_nsenddata(xbee_con *con, char *data, int length) { + return _xbee_nsenddata(default_xbee, con, data, length); +} +int _xbee_nsenddata(xbee_hnd xbee, xbee_con *con, char *data, int length) { + t_data *pkt; + int i; + unsigned char buf[128]; /* max payload is 100 bytes... plus a bit for the headers etc... */ + + ISREADYR(-1); + + if (!con) return -1; + if (con->type == xbee_unknown) return -1; + if (length > 127) return -1; + + if (xbee->log) { + xbee_logS("--== TX Packet ============--"); + xbee_logIc("Connection Type: "); + switch (con->type) { + case xbee_unknown: fprintf(xbee->log,"Unknown"); break; + case xbee_localAT: fprintf(xbee->log,"Local AT"); break; + case xbee_remoteAT: fprintf(xbee->log,"Remote AT"); break; + case xbee_16bitRemoteAT: fprintf(xbee->log,"Remote AT (16-bit)"); break; + case xbee_64bitRemoteAT: fprintf(xbee->log,"Remote AT (64-bit)"); break; + case xbee_16bitData: fprintf(xbee->log,"Data (16-bit)"); break; + case xbee_64bitData: fprintf(xbee->log,"Data (64-bit)"); break; + case xbee_16bitIO: fprintf(xbee->log,"IO (16-bit)"); break; + case xbee_64bitIO: fprintf(xbee->log,"IO (64-bit)"); break; + case xbee2_data: fprintf(xbee->log,"Series 2 Data"); break; + case xbee2_txStatus: fprintf(xbee->log,"Series 2 Tx Status"); break; + case xbee_txStatus: fprintf(xbee->log,"Tx Status"); break; + case xbee_modemStatus: fprintf(xbee->log,"Modem Status"); break; + } + xbee_logIcf(); + switch (con->type) { + case xbee_localAT: case xbee_remoteAT: case xbee_txStatus: case xbee_modemStatus: + break; + default: + xbee_logIc("Destination: "); + for (i=0;i<(con->tAddr64?8:2);i++) { + fprintf(xbee->log,(i?":%02X":"%02X"),con->tAddr[i]); + } + xbee_logIcf(); + } + xbee_logI("Length: %d",length); + for (i=0;i<length;i++) { + xbee_logIc("%3d | 0x%02X ",i,(unsigned char)data[i]); + if ((data[i] > 32) && (data[i] < 127)) { + fprintf(xbee->log,"'%c'",data[i]); + } else{ + fprintf(xbee->log," _"); + } + xbee_logIcf(); + } + xbee_logEf(); + } + + /* ########################################## */ + /* if: local AT */ + if (con->type == xbee_localAT) { + /* AT commands are 2 chars long (plus optional parameter) */ + if (length < 2) return -1; + if (length > 32) return -1; + + /* use the command? */ + buf[0] = ((!con->atQueue)?XBEE_LOCAL_ATREQ:XBEE_LOCAL_ATQUE); + buf[1] = con->frameID; + + /* copy in the data */ + for (i=0;i<length;i++) { + buf[i+2] = data[i]; + } + + /* setup the packet */ + pkt = xbee_make_pkt(xbee, buf, i+2); + /* send it on */ + return _xbee_send_pkt(xbee, pkt, con); + + /* ########################################## */ + /* if: remote AT */ + } else if ((con->type == xbee_16bitRemoteAT) || + (con->type == xbee_64bitRemoteAT)) { + if (length < 2) return -1; /* at commands are 2 chars long (plus optional parameter) */ + if (length > 32) return -1; + buf[0] = XBEE_REMOTE_ATREQ; + buf[1] = con->frameID; + + /* copy in the relevant address */ + if (con->tAddr64) { + memcpy(&buf[2],con->tAddr,8); + buf[10] = 0xFF; + buf[11] = 0xFE; + } else { + memset(&buf[2],0,8); + memcpy(&buf[10],con->tAddr,2); + } + /* queue the command? */ + buf[12] = ((!con->atQueue)?0x02:0x00); + + /* copy in the data */ + for (i=0;i<length;i++) { + buf[i+13] = data[i]; + } + + /* setup the packet */ + pkt = xbee_make_pkt(xbee, buf, i+13); + /* send it on */ + return _xbee_send_pkt(xbee, pkt, con); + + /* ########################################## */ + /* if: 16 or 64bit Data */ + } else if ((con->type == xbee_16bitData) || + (con->type == xbee_64bitData)) { + int offset; + if (length > 100) return -1; + + /* if: 16bit Data */ + if (con->type == xbee_16bitData) { + buf[0] = XBEE_16BIT_DATATX; + offset = 5; + /* copy in the address */ + memcpy(&buf[2],con->tAddr,2); + + /* if: 64bit Data */ + } else { /* 64bit Data */ + buf[0] = XBEE_64BIT_DATATX; + offset = 11; + /* copy in the address */ + memcpy(&buf[2],con->tAddr,8); + } + + /* copy frameID */ + buf[1] = con->frameID; + + /* disable ack? broadcast? */ + buf[offset-1] = ((con->txDisableACK)?0x01:0x00) | ((con->txBroadcastPAN)?0x04:0x00); + + /* copy in the data */ + for (i=0;i<length;i++) { + buf[i+offset] = data[i]; + } + + /* setup the packet */ + pkt = xbee_make_pkt(xbee, buf, i+offset); + /* send it on */ + return _xbee_send_pkt(xbee, pkt, con); + + /* ########################################## */ + /* if: I/O */ + } else if ((con->type == xbee_64bitIO) || + (con->type == xbee_16bitIO)) { + /* not currently implemented... is it even allowed? */ + if (xbee->log) { + xbee_log("******* TODO ********\n"); + } + + /* ########################################## */ + /* if: Series 2 Data */ + } else if (con->type == xbee2_data) { + if (length > 72) return -1; + + buf[0] = XBEE2_DATATX; + buf[1] = con->frameID; + + /* copy in the relevant address */ + memcpy(&buf[2],con->tAddr,8); + buf[10] = 0xFF; + buf[11] = 0xFE; + + /* Maximum Radius/hops */ + buf[12] = 0x00; + + /* Options */ + buf[13] = 0x00; + + /* copy in the data */ + for (i=0;i<length;i++) { + buf[i+14] = data[i]; + } + + /* setup the packet */ + pkt = xbee_make_pkt(xbee, buf, i+14); + /* send it on */ + return _xbee_send_pkt(xbee, pkt, con); + } + + return -2; +} + +/* ################################################################# + xbee_getpacket + retrieves the next packet destined for the given connection + once the packet has been retrieved, it is removed for the list! */ +xbee_pkt *xbee_getpacketwait(xbee_con *con) { + return _xbee_getpacketwait(default_xbee, con); +} +xbee_pkt *_xbee_getpacketwait(xbee_hnd xbee, xbee_con *con) { + xbee_pkt *p = NULL; + int i = 20; + + /* 50ms * 20 = 1 second */ + for (; i; i--) { + p = _xbee_getpacket(xbee, con); + if (p) break; + usleep(50000); /* 50ms */ + } + + return p; +} +xbee_pkt *xbee_getpacket(xbee_con *con) { + return _xbee_getpacket(default_xbee, con); +} +xbee_pkt *_xbee_getpacket(xbee_hnd xbee, xbee_con *con) { + xbee_pkt *l, *p, *q; + + ISREADYR(NULL); + + /* lock the packet mutex */ + xbee_mutex_lock(xbee->pktmutex); + + /* if: there are no packets */ + if ((p = xbee->pktlist) == NULL) { + xbee_mutex_unlock(xbee->pktmutex); + /*if (xbee->log) { + xbee_log("No packets avaliable..."); + }*/ + return NULL; + } + + l = NULL; + q = NULL; + /* get the first avaliable packet for this connection */ + do { + /* does the packet match the connection? */ + if (xbee_matchpktcon(xbee, p, con)) { + q = p; + break; + } + /* move on */ + l = p; + p = p->next; + } while (p); + + /* if: no packet was found */ + if (!q) { + xbee_mutex_unlock(xbee->pktmutex); + if (xbee->log) { + struct timeval tv; + xbee_logS("--== Get Packet ==========--"); + gettimeofday(&tv,NULL); + xbee_logE("Didn't get a packet @ %ld.%06ld",tv.tv_sec,tv.tv_usec); + } + return NULL; + } + + /* if it was the first packet */ + if (l) { + /* relink the list */ + l->next = p->next; + if (!l->next) xbee->pktlast = l; + } else { + /* move the chain along */ + xbee->pktlist = p->next; + if (!xbee->pktlist) { + xbee->pktlast = NULL; + } else if (!xbee->pktlist->next) { + xbee->pktlast = xbee->pktlist; + } + } + xbee->pktcount--; + + /* unlink this packet from the chain! */ + q->next = NULL; + + if (xbee->log) { + struct timeval tv; + xbee_logS("--== Get Packet ==========--"); + gettimeofday(&tv,NULL); + xbee_logI("Got a packet @ %ld.%06ld",tv.tv_sec,tv.tv_usec); + xbee_logE("Packets left: %d",xbee->pktcount); + } + + /* unlock the packet mutex */ + xbee_mutex_unlock(xbee->pktmutex); + + /* and return the packet (must be free'd by caller!) */ + return q; +} + +/* ################################################################# + xbee_matchpktcon - INTERNAL + checks if the packet matches the connection */ +static int xbee_matchpktcon(xbee_hnd xbee, xbee_pkt *pkt, xbee_con *con) { + /* if: the connection type matches the packet type OR + the connection is 16/64bit remote AT, and the packet is a remote AT response */ + if ((pkt->type == con->type) || /* -- */ + ((pkt->type == xbee_remoteAT) && /* -- */ + ((con->type == xbee_16bitRemoteAT) || + (con->type == xbee_64bitRemoteAT)))) { + + + /* if: is a modem status (there can only be 1 modem status connection) */ + if (pkt->type == xbee_modemStatus) return 1; + + /* if: the packet is a txStatus or localAT and the frameIDs match */ + if ((pkt->type == xbee_txStatus) || + (pkt->type == xbee_localAT)) { + if (pkt->frameID == con->frameID) { + return 1; + } + /* if: the packet was sent as a 16bit remoteAT, and the 16bit addresss match */ + } else if ((pkt->type == xbee_remoteAT) && + (con->type == xbee_16bitRemoteAT) && + !memcmp(pkt->Addr16,con->tAddr,2)) { + return 1; + /* if: the packet was sent as a 64bit remoteAT, and the 64bit addresss match */ + } else if ((pkt->type == xbee_remoteAT) && + (con->type == xbee_64bitRemoteAT) && + !memcmp(pkt->Addr64,con->tAddr,8)) { + return 1; + /* if: the packet is 64bit addressed, and the addresses match */ + } else if (pkt->sAddr64 && !memcmp(pkt->Addr64,con->tAddr,8)) { + return 1; + /* if: the packet is 16bit addressed, and the addresses match */ + } else if (!pkt->sAddr64 && !memcmp(pkt->Addr16,con->tAddr,2)) { + return 1; + } else if (con->type == pkt->type && + (con->type == xbee_16bitData || con->type == xbee_64bitData) && + (pkt->isBroadcastADR || pkt->isBroadcastPAN)) { + unsigned char t[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + if ((con->tAddr64 && !memcmp(con->tAddr,t,8)) || + (!con->tAddr64 && !memcmp(con->tAddr,t,2))) { + return 1; + } + } + } + return 0; +} + +/* ################################################################# + xbee_parse_io - INTERNAL + parses the data given into the packet io information */ +static int xbee_parse_io(xbee_hnd xbee, xbee_pkt *p, unsigned char *d, + int maskOffset, int sampleOffset, int sample) { + xbee_sample *s = &(p->IOdata[sample]); + + /* copy in the I/O data mask */ + s->IOmask = (((d[maskOffset]<<8) | d[maskOffset + 1]) & 0x7FFF); + + /* copy in the digital I/O data */ + s->IOdigital = (((d[sampleOffset]<<8) | d[sampleOffset+1]) & 0x01FF); + + /* advance over the digital data, if its there */ + sampleOffset += ((s->IOmask & 0x01FF)?2:0); + + /* copy in the analog I/O data */ + if (s->IOmask & 0x0200) { + s->IOanalog[0] = (((d[sampleOffset]<<8) | d[sampleOffset+1]) & 0x03FF); + sampleOffset+=2; + } + if (s->IOmask & 0x0400) { + s->IOanalog[1] = (((d[sampleOffset]<<8) | d[sampleOffset+1]) & 0x03FF); + sampleOffset+=2; + } + if (s->IOmask & 0x0800) { + s->IOanalog[2] = (((d[sampleOffset]<<8) | d[sampleOffset+1]) & 0x03FF); + sampleOffset+=2; + } + if (s->IOmask & 0x1000) { + s->IOanalog[3] = (((d[sampleOffset]<<8) | d[sampleOffset+1]) & 0x03FF); + sampleOffset+=2; + } + if (s->IOmask & 0x2000) { + s->IOanalog[4] = (((d[sampleOffset]<<8) | d[sampleOffset+1]) & 0x03FF); + sampleOffset+=2; + } + if (s->IOmask & 0x4000) { + s->IOanalog[5] = (((d[sampleOffset]<<8) | d[sampleOffset+1]) & 0x03FF); + sampleOffset+=2; + } + + if (xbee->log) { + if (s->IOmask & 0x0001) + xbee_logI("Digital 0: %c",((s->IOdigital & 0x0001)?'1':'0')); + if (s->IOmask & 0x0002) + xbee_logI("Digital 1: %c",((s->IOdigital & 0x0002)?'1':'0')); + if (s->IOmask & 0x0004) + xbee_logI("Digital 2: %c",((s->IOdigital & 0x0004)?'1':'0')); + if (s->IOmask & 0x0008) + xbee_logI("Digital 3: %c",((s->IOdigital & 0x0008)?'1':'0')); + if (s->IOmask & 0x0010) + xbee_logI("Digital 4: %c",((s->IOdigital & 0x0010)?'1':'0')); + if (s->IOmask & 0x0020) + xbee_logI("Digital 5: %c",((s->IOdigital & 0x0020)?'1':'0')); + if (s->IOmask & 0x0040) + xbee_logI("Digital 6: %c",((s->IOdigital & 0x0040)?'1':'0')); + if (s->IOmask & 0x0080) + xbee_logI("Digital 7: %c",((s->IOdigital & 0x0080)?'1':'0')); + if (s->IOmask & 0x0100) + xbee_logI("Digital 8: %c",((s->IOdigital & 0x0100)?'1':'0')); + if (s->IOmask & 0x0200) + xbee_logI("Analog 0: %d (~%.2fv)",s->IOanalog[0],(3.3/1023)*s->IOanalog[0]); + if (s->IOmask & 0x0400) + xbee_logI("Analog 1: %d (~%.2fv)",s->IOanalog[1],(3.3/1023)*s->IOanalog[1]); + if (s->IOmask & 0x0800) + xbee_logI("Analog 2: %d (~%.2fv)",s->IOanalog[2],(3.3/1023)*s->IOanalog[2]); + if (s->IOmask & 0x1000) + xbee_logI("Analog 3: %d (~%.2fv)",s->IOanalog[3],(3.3/1023)*s->IOanalog[3]); + if (s->IOmask & 0x2000) + xbee_logI("Analog 4: %d (~%.2fv)",s->IOanalog[4],(3.3/1023)*s->IOanalog[4]); + if (s->IOmask & 0x4000) + xbee_logI("Analog 5: %d (~%.2fv)",s->IOanalog[5],(3.3/1023)*s->IOanalog[5]); + } + + return sampleOffset; +} + +/* ################################################################# + xbee_listen_stop + stops the listen thread after the current packet has been processed */ +void xbee_listen_stop(xbee_hnd xbee) { + ISREADYP(); + xbee->run = 0; +} + +/* ################################################################# + xbee_listen_wrapper - INTERNAL + the xbee_listen wrapper. Prints an error when xbee_listen ends */ +static void xbee_listen_wrapper(xbee_hnd xbee) { + int ret; + + /* just falls out if the proper 'go-ahead' isn't given */ + if (xbee->xbee_ready != -1) return; + /* now allow the parent to continue */ + xbee->xbee_ready = -2; + +#ifdef _WIN32 /* ---- */ + /* win32 requires this delay... no idea why */ + usleep(1000000); +#endif /* ----------- */ + + while (xbee->run) { + ret = xbee_listen(xbee); + if (!xbee->run) break; + xbee_log("xbee_listen() returned [%d]... Restarting in 25ms!",ret); + usleep(25000); + } +} + +/* xbee_listen - INTERNAL + the xbee xbee_listen thread + reads data from the xbee and puts it into a linked list to keep the xbee buffers free */ +static int xbee_listen(xbee_hnd xbee) { +#define LISTEN_BUFLEN 1024 + unsigned char c, t, d[LISTEN_BUFLEN]; + unsigned int l, i, chksum, o; + int j; + xbee_pkt *p = NULL, *q; + xbee_con *con; + int hasCon; + + /* do this forever :) */ + while (xbee->run) { + /* clean up any undesired storage */ + if (p) Xfree(p); + + /* wait for a valid start byte */ + if ((c = xbee_getrawbyte(xbee)) != 0x7E) { + if (xbee->log) xbee_log("***** Unexpected byte (0x%02X)... *****",c); + continue; + } + if (!xbee->run) return 0; + + xbee_logSf(); + if (xbee->log) { + struct timeval tv; + xbee_logI("--== RX Packet ===========--"); + gettimeofday(&tv,NULL); + xbee_logI("Got a packet @ %ld.%06ld",tv.tv_sec,tv.tv_usec); + } + + /* get the length */ + l = xbee_getbyte(xbee) << 8; + l += xbee_getbyte(xbee); + + /* check it is a valid length... */ + if (!l) { + if (xbee->log) { + xbee_logI("Recived zero length packet!"); + } + continue; + } + if (l > 100) { + if (xbee->log) { + xbee_logI("Recived oversized packet! Length: %d",l - 1); + } + } + if (l > LISTEN_BUFLEN) { + if (xbee->log) { + xbee_logI("Recived packet larger than buffer! Discarding..."); + } + continue; + } + + if (xbee->log) { + xbee_logI("Length: %d",l - 1); + } + + /* get the packet type */ + t = xbee_getbyte(xbee); + + /* start the checksum */ + chksum = t; + + /* suck in all the data */ + for (i = 0; l > 1 && i < LISTEN_BUFLEN; l--, i++) { + /* get an unescaped byte */ + c = xbee_getbyte(xbee); + d[i] = c; + chksum += c; + if (xbee->log) { + xbee_logIc("%3d | 0x%02X | ",i,c); + if ((c > 32) && (c < 127)) fprintf(xbee->log,"'%c'",c); else fprintf(xbee->log," _ "); + + if ((t == XBEE_LOCAL_AT && i == 4) || + (t == XBEE_REMOTE_AT && i == 14) || + (t == XBEE_64BIT_DATARX && i == 10) || + (t == XBEE_16BIT_DATARX && i == 4) || + (t == XBEE_64BIT_IO && i == 13) || + (t == XBEE_16BIT_IO && i == 7)) { + /* mark the beginning of the 'data' bytes */ + fprintf(xbee->log," <-- data starts"); + } else if (t == XBEE_64BIT_IO) { + if (i == 10) fprintf(xbee->log," <-- sample count"); + else if (i == 11) fprintf(xbee->log," <-- mask (msb)"); + else if (i == 12) fprintf(xbee->log," <-- mask (lsb)"); + } else if (t == XBEE_16BIT_IO) { + if (i == 4) fprintf(xbee->log," <-- sample count"); + else if (i == 5) fprintf(xbee->log," <-- mask (msb)"); + else if (i == 6) fprintf(xbee->log," <-- mask (lsb)"); + } + xbee_logIcf(); + } + } + i--; /* it went up too many times!... */ + + /* add the checksum */ + chksum += xbee_getbyte(xbee); + + /* check if the whole packet was recieved, or something else occured... unlikely... */ + if (l>1) { + if (xbee->log) { + xbee_logE("Didn't get whole packet... :("); + } + continue; + } + + /* check the checksum */ + if ((chksum & 0xFF) != 0xFF) { + if (xbee->log) { + chksum &= 0xFF; + xbee_logE("Invalid Checksum: 0x%02X",chksum); + } + continue; + } + + /* make a new packet */ + p = Xcalloc(sizeof(xbee_pkt)); + q = NULL; + p->datalen = 0; + + /* ########################################## */ + /* if: modem status */ + if (t == XBEE_MODEM_STATUS) { + if (xbee->log) { + xbee_logI("Packet type: Modem Status (0x8A)"); + xbee_logIc("Event: "); + switch (d[0]) { + case 0x00: fprintf(xbee->log,"Hardware reset"); break; + case 0x01: fprintf(xbee->log,"Watchdog timer reset"); break; + case 0x02: fprintf(xbee->log,"Associated"); break; + case 0x03: fprintf(xbee->log,"Disassociated"); break; + case 0x04: fprintf(xbee->log,"Synchronization lost"); break; + case 0x05: fprintf(xbee->log,"Coordinator realignment"); break; + case 0x06: fprintf(xbee->log,"Coordinator started"); break; + } + fprintf(xbee->log,"... (0x%02X)",d[0]); + xbee_logIcf(); + } + p->type = xbee_modemStatus; + + p->sAddr64 = FALSE; + p->dataPkt = FALSE; + p->txStatusPkt = FALSE; + p->modemStatusPkt = TRUE; + p->remoteATPkt = FALSE; + p->IOPkt = FALSE; + + /* modem status can only ever give 1 'data' byte */ + p->datalen = 1; + p->data[0] = d[0]; + + /* ########################################## */ + /* if: local AT response */ + } else if (t == XBEE_LOCAL_AT) { + if (xbee->log) { + xbee_logI("Packet type: Local AT Response (0x88)"); + xbee_logI("FrameID: 0x%02X",d[0]); + xbee_logI("AT Command: %c%c",d[1],d[2]); + xbee_logIc("Status: "); + if (d[3] == 0x00) fprintf(xbee->log,"OK"); + else if (d[3] == 0x01) fprintf(xbee->log,"Error"); + else if (d[3] == 0x02) fprintf(xbee->log,"Invalid Command"); + else if (d[3] == 0x03) fprintf(xbee->log,"Invalid Parameter"); + fprintf(xbee->log," (0x%02X)",d[3]); + xbee_logIcf(); + } + p->type = xbee_localAT; + + p->sAddr64 = FALSE; + p->dataPkt = FALSE; + p->txStatusPkt = FALSE; + p->modemStatusPkt = FALSE; + p->remoteATPkt = FALSE; + p->IOPkt = FALSE; + + p->frameID = d[0]; + p->atCmd[0] = d[1]; + p->atCmd[1] = d[2]; + + p->status = d[3]; + + /* copy in the data */ + p->datalen = i-3; + for (;i>3;i--) p->data[i-4] = d[i]; + + /* ########################################## */ + /* if: remote AT response */ + } else if (t == XBEE_REMOTE_AT) { + if (xbee->log) { + xbee_logI("Packet type: Remote AT Response (0x97)"); + xbee_logI("FrameID: 0x%02X",d[0]); + xbee_logIc("64-bit Address: "); + for (j=0;j<8;j++) { + fprintf(xbee->log,(j?":%02X":"%02X"),d[1+j]); + } + xbee_logIcf(); + xbee_logIc("16-bit Address: "); + for (j=0;j<2;j++) { + fprintf(xbee->log,(j?":%02X":"%02X"),d[9+j]); + } + xbee_logIcf(); + xbee_logI("AT Command: %c%c",d[11],d[12]); + xbee_logIc("Status: "); + if (d[13] == 0x00) fprintf(xbee->log,"OK"); + else if (d[13] == 0x01) fprintf(xbee->log,"Error"); + else if (d[13] == 0x02) fprintf(xbee->log,"Invalid Command"); + else if (d[13] == 0x03) fprintf(xbee->log,"Invalid Parameter"); + else if (d[13] == 0x04) fprintf(xbee->log,"No Response"); + fprintf(xbee->log," (0x%02X)",d[13]); + xbee_logIcf(); + } + p->type = xbee_remoteAT; + + p->sAddr64 = FALSE; + p->dataPkt = FALSE; + p->txStatusPkt = FALSE; + p->modemStatusPkt = FALSE; + p->remoteATPkt = TRUE; + p->IOPkt = FALSE; + + p->frameID = d[0]; + + p->Addr64[0] = d[1]; + p->Addr64[1] = d[2]; + p->Addr64[2] = d[3]; + p->Addr64[3] = d[4]; + p->Addr64[4] = d[5]; + p->Addr64[5] = d[6]; + p->Addr64[6] = d[7]; + p->Addr64[7] = d[8]; + + p->Addr16[0] = d[9]; + p->Addr16[1] = d[10]; + + p->atCmd[0] = d[11]; + p->atCmd[1] = d[12]; + + p->status = d[13]; + + p->samples = 1; + + if (p->status == 0x00 && p->atCmd[0] == 'I' && p->atCmd[1] == 'S') { + /* parse the io data */ + xbee_logI("--- Sample -----------------"); + xbee_parse_io(xbee, p, d, 15, 17, 0); + xbee_logI("----------------------------"); + } else { + /* copy in the data */ + p->datalen = i-13; + for (;i>13;i--) p->data[i-14] = d[i]; + } + + /* ########################################## */ + /* if: TX status */ + } else if (t == XBEE_TX_STATUS) { + if (xbee->log) { + xbee_logI("Packet type: TX Status Report (0x89)"); + xbee_logI("FrameID: 0x%02X",d[0]); + xbee_logIc("Status: "); + if (d[1] == 0x00) fprintf(xbee->log,"Success"); + else if (d[1] == 0x01) fprintf(xbee->log,"No ACK"); + else if (d[1] == 0x02) fprintf(xbee->log,"CCA Failure"); + else if (d[1] == 0x03) fprintf(xbee->log,"Purged"); + fprintf(xbee->log," (0x%02X)",d[1]); + xbee_logIcf(); + } + p->type = xbee_txStatus; + + p->sAddr64 = FALSE; + p->dataPkt = FALSE; + p->txStatusPkt = TRUE; + p->modemStatusPkt = FALSE; + p->remoteATPkt = FALSE; + p->IOPkt = FALSE; + + p->frameID = d[0]; + + p->status = d[1]; + + /* never returns data */ + p->datalen = 0; + + /* check for any connections waiting for a status update */ + /* lock the connection mutex */ + xbee_mutex_lock(xbee->conmutex); + xbee_logI("Looking for a connection that wants a status update..."); + con = xbee->conlist; + while (con) { + if ((con->frameID == p->frameID) && + (con->ACKstatus == 0xFF)) { + xbee_logI("Found @ 0x%08X!",con); + con->ACKstatus = p->status; + xbee_sem_post(con->waitforACKsem); + } + con = con->next; + } + + /* unlock the connection mutex */ + xbee_mutex_unlock(xbee->conmutex); + + /* ########################################## */ + /* if: 16 / 64bit data recieve */ + } else if ((t == XBEE_64BIT_DATARX) || + (t == XBEE_16BIT_DATARX)) { + int offset; + if (t == XBEE_64BIT_DATARX) { /* 64bit */ + offset = 8; + } else { /* 16bit */ + offset = 2; + } + if (xbee->log) { + xbee_logI("Packet type: %d-bit RX Data (0x%02X)",((t == XBEE_64BIT_DATARX)?64:16),t); + xbee_logIc("%d-bit Address: ",((t == XBEE_64BIT_DATARX)?64:16)); + for (j=0;j<offset;j++) { + fprintf(xbee->log,(j?":%02X":"%02X"),d[j]); + } + xbee_logIcf(); + xbee_logI("RSSI: -%ddB",d[offset]); + if (d[offset + 1] & 0x02) xbee_logI("Options: Address Broadcast"); + if (d[offset + 1] & 0x04) xbee_logI("Options: PAN Broadcast"); + } + p->isBroadcastADR = !!(d[offset+1] & 0x02); + p->isBroadcastPAN = !!(d[offset+1] & 0x04); + p->dataPkt = TRUE; + p->txStatusPkt = FALSE; + p->modemStatusPkt = FALSE; + p->remoteATPkt = FALSE; + p->IOPkt = FALSE; + + if (t == XBEE_64BIT_DATARX) { /* 64bit */ + p->type = xbee_64bitData; + + p->sAddr64 = TRUE; + + p->Addr64[0] = d[0]; + p->Addr64[1] = d[1]; + p->Addr64[2] = d[2]; + p->Addr64[3] = d[3]; + p->Addr64[4] = d[4]; + p->Addr64[5] = d[5]; + p->Addr64[6] = d[6]; + p->Addr64[7] = d[7]; + } else { /* 16bit */ + p->type = xbee_16bitData; + + p->sAddr64 = FALSE; + + p->Addr16[0] = d[0]; + p->Addr16[1] = d[1]; + } + + /* save the RSSI / signal strength + this can be used with printf as: + printf("-%ddB\n",p->RSSI); */ + p->RSSI = d[offset]; + + p->status = d[offset + 1]; + + /* copy in the data */ + p->datalen = i-(offset + 1); + for (;i>offset + 1;i--) p->data[i-(offset + 2)] = d[i]; + + /* ########################################## */ + /* if: 16 / 64bit I/O recieve */ + } else if ((t == XBEE_64BIT_IO) || + (t == XBEE_16BIT_IO)) { + int offset,i2; + if (t == XBEE_64BIT_IO) { /* 64bit */ + p->type = xbee_64bitIO; + + p->sAddr64 = TRUE; + + p->Addr64[0] = d[0]; + p->Addr64[1] = d[1]; + p->Addr64[2] = d[2]; + p->Addr64[3] = d[3]; + p->Addr64[4] = d[4]; + p->Addr64[5] = d[5]; + p->Addr64[6] = d[6]; + p->Addr64[7] = d[7]; + + offset = 8; + p->samples = d[10]; + } else { /* 16bit */ + p->type = xbee_16bitIO; + + p->sAddr64 = FALSE; + + p->Addr16[0] = d[0]; + p->Addr16[1] = d[1]; + + offset = 2; + p->samples = d[4]; + } + if (p->samples > 1) { + p = Xrealloc(p, sizeof(xbee_pkt) + (sizeof(xbee_sample) * (p->samples - 1))); + } + if (xbee->log) { + xbee_logI("Packet type: %d-bit RX I/O Data (0x%02X)",((t == XBEE_64BIT_IO)?64:16),t); + xbee_logIc("%d-bit Address: ",((t == XBEE_64BIT_IO)?64:16)); + for (j = 0; j < offset; j++) { + fprintf(xbee->log,(j?":%02X":"%02X"),d[j]); + } + xbee_logIcf(); + xbee_logI("RSSI: -%ddB",d[offset]); + xbee_logI("Samples: %d",d[offset + 2]); + } + i2 = offset + 5; + + /* never returns data */ + p->datalen = 0; + + p->dataPkt = FALSE; + p->txStatusPkt = FALSE; + p->modemStatusPkt = FALSE; + p->remoteATPkt = FALSE; + p->IOPkt = TRUE; + + /* save the RSSI / signal strength + this can be used with printf as: + printf("-%ddB\n",p->RSSI); */ + p->RSSI = d[offset]; + + p->status = d[offset + 1]; + + /* each sample is split into its own packet here, for simplicity */ + for (o = 0; o < p->samples; o++) { + if (i2 >= i) { + xbee_logI("Invalid I/O data! Actually contained %d samples...",o); + p = Xrealloc(p, sizeof(xbee_pkt) + (sizeof(xbee_sample) * ((o>1)?o:1))); + p->samples = o; + break; + } + xbee_logI("--- Sample %3d -------------", o); + + /* parse the io data */ + i2 = xbee_parse_io(xbee, p, d, offset + 3, i2, o); + } + xbee_logI("----------------------------"); + + /* ########################################## */ + /* if: Series 2 Transmit status */ + } else if (t == XBEE2_TX_STATUS) { + if (xbee->log) { + xbee_logI("Packet type: Series 2 Transmit Status (0x%02X)", t); + xbee_logI("FrameID: 0x%02X",d[0]); + xbee_logI("16-bit Delivery Address: %02X:%02X",d[1],d[2]); + xbee_logI("Transmit Retry Count: %02X",d[3]); + xbee_logIc("Delivery Status: "); + if (d[4] == 0x00) fprintf(xbee->log,"Success"); + else if (d[4] == 0x02) fprintf(xbee->log,"CCA Failure"); + else if (d[4] == 0x15) fprintf(xbee->log,"Invalid Destination"); + else if (d[4] == 0x21) fprintf(xbee->log,"Network ACK Failure"); + else if (d[4] == 0x22) fprintf(xbee->log,"Not Joined to Network"); + else if (d[4] == 0x23) fprintf(xbee->log,"Self-Addressed"); + else if (d[4] == 0x24) fprintf(xbee->log,"Address Not Found"); + else if (d[4] == 0x25) fprintf(xbee->log,"Route Not Found"); + else if (d[4] == 0x74) fprintf(xbee->log,"Data Payload Too Large"); /* ??? */ + fprintf(xbee->log," (0x%02X)",d[4]); + xbee_logIcf(); + + xbee_logIc("Discovery Status: "); + if (d[5] == 0x00) fprintf(xbee->log,"No Discovery Overhead"); + else if (d[5] == 0x01) fprintf(xbee->log,"Address Discovery"); + else if (d[5] == 0x02) fprintf(xbee->log,"Route Discovery"); + else if (d[5] == 0x03) fprintf(xbee->log,"Address & Route Discovery"); + fprintf(xbee->log," (0x%02X)",d[5]); + xbee_logIcf(); + } + + p->type = xbee2_txStatus; + + p->sAddr64 = FALSE; + p->dataPkt = FALSE; + p->txStatusPkt = TRUE; + p->modemStatusPkt = FALSE; + p->remoteATPkt = FALSE; + p->IOPkt = FALSE; + + p->frameID = d[0]; + + p->status = d[4]; + + /* never returns data */ + p->datalen = 0; + + /* ########################################## */ + /* if: Series 2 data recieve */ + } else if (t == XBEE2_DATARX) { + int offset; + offset = 10; + if (xbee->log) { + xbee_logI("Packet type: Series 2 Data Rx (0x%02X)", t); + + xbee_logIc("64-bit Address: "); + for (j=0;j<8;j++) { + fprintf(xbee->log,(j?":%02X":"%02X"),d[j]); + } + xbee_logIcf(); + + xbee_logIc("16-bit Address: "); + for (j=0;j<2;j++) { + fprintf(xbee->log,(j?":%02X":"%02X"),d[j+8]); + } + xbee_logIcf(); + + if (d[offset] & 0x01) xbee_logI("Options: Packet Acknowledged"); + if (d[offset] & 0x02) xbee_logI("Options: Packet was a broadcast packet"); + if (d[offset] & 0x20) xbee_logI("Options: Packet Encrypted"); /* ??? */ + if (d[offset] & 0x40) xbee_logI("Options: Packet from end device"); /* ??? */ + } + p->dataPkt = TRUE; + p->txStatusPkt = FALSE; + p->modemStatusPkt = FALSE; + p->remoteATPkt = FALSE; + p->IOPkt = FALSE; + p->type = xbee2_data; + p->sAddr64 = TRUE; + + p->Addr64[0] = d[0]; + p->Addr64[1] = d[1]; + p->Addr64[2] = d[2]; + p->Addr64[3] = d[3]; + p->Addr64[4] = d[4]; + p->Addr64[5] = d[5]; + p->Addr64[6] = d[6]; + p->Addr64[7] = d[7]; + + p->Addr16[0] = d[8]; + p->Addr16[1] = d[9]; + + p->status = d[offset]; + + /* copy in the data */ + p->datalen = i - (offset + 1); + for (;i>offset;i--) { + p->data[i-(offset + 1)] = d[i]; + } + + /* ########################################## */ + /* if: Unknown */ + } else { + xbee_logE("Packet type: Unknown (0x%02X)",t); + continue; + } + p->next = NULL; + + /* lock the connection mutex */ + xbee_mutex_lock(xbee->conmutex); + + hasCon = 0; + if (p->isBroadcastADR || p->isBroadcastPAN) { + unsigned char t[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; + /* if the packet was broadcast, search for a broadcast accepting connection */ + con = xbee->conlist; + while (con) { + if (con->type == p->type && + (con->type == xbee_16bitData || con->type == xbee_64bitData) && + ((con->tAddr64 && !memcmp(con->tAddr,t,8)) || + (!con->tAddr64 && !memcmp(con->tAddr,t,2)))) { + hasCon = 1; + xbee_logI("Found broadcasting connection @ 0x%08X",con); + break; + } + con = con->next; + } + } + if (!hasCon || !con) { + con = xbee->conlist; + while (con) { + if (xbee_matchpktcon(xbee, p, con)) { + hasCon = 1; + break; + } + con = con->next; + } + } + + /* unlock the connection mutex */ + xbee_mutex_unlock(xbee->conmutex); + + /* if the packet doesn't have a connection, don't add it! */ + if (!hasCon) { + xbee_logE("Connectionless packet... discarding!"); + continue; + } + + /* if the connection has a callback function then it is passed the packet + and the packet is not added to the list */ + if (con && con->callback) { + t_callback_list *l, *q; + + xbee_mutex_lock(con->callbackListmutex); + l = con->callbackList; + q = NULL; + while (l) { + q = l; + l = l->next; + } + l = Xcalloc(sizeof(t_callback_list)); + l->pkt = p; + if (!con->callbackList || q == NULL) { + con->callbackList = l; + } else { + q->next = l; + } + xbee_mutex_unlock(con->callbackListmutex); + + xbee_logI("Using callback function!"); + xbee_logI(" info block @ 0x%08X",l); + xbee_logI(" function @ 0x%08X",con->callback); + xbee_logI(" connection @ 0x%08X",con); + xbee_logE(" packet @ 0x%08X",p); + + /* if the callback thread not still running, then start a new one! */ + if (!xbee_mutex_trylock(con->callbackmutex)) { + xbee_thread_t t; + int ret; + t_threadList *p, *q; + t_CBinfo info; + info.xbee = xbee; + info.con = con; + xbee_log("Starting new callback thread!"); + if ((ret = xbee_thread_create(t,xbee_callbackWrapper,&info)) != 0) { + xbee_mutex_unlock(con->callbackmutex); + /* this MAY help with future attempts... */ + xbee_sem_post(xbee->threadsem); + xbee_logS("An error occured while starting thread (%d)... Out of resources?", ret); + xbee_logE("This packet has been lost!"); + continue; + } + xbee_log("Started thread 0x%08X!", t); + xbee_mutex_lock(xbee->threadmutex); + p = xbee->threadList; + q = NULL; + while (p) { + q = p; + p = p->next; + } + p = Xcalloc(sizeof(t_threadList)); + if (q == NULL) { + xbee->threadList = p; + } else { + q->next = p; + } + p->thread = t; + p->next = NULL; + xbee_mutex_unlock(xbee->threadmutex); + } else { + xbee_logE("Using existing callback thread... callback has been scheduled."); + } + /* prevent the packet from being free'd */ + p = NULL; + continue; + } + + /* lock the packet mutex, so we can safely add the packet to the list */ + xbee_mutex_lock(xbee->pktmutex); + + /* if: the list is empty */ + if (!xbee->pktlist) { + /* start the list! */ + xbee->pktlist = p; + } else if (xbee->pktlast) { + /* add the packet to the end */ + xbee->pktlast->next = p; + } else { + /* pktlast wasnt set... look for the end and then set it */ + i = 0; + q = xbee->pktlist; + while (q->next) { + q = q->next; + i++; + } + q->next = p; + xbee->pktcount = i; + } + xbee->pktlast = p; + xbee->pktcount++; + + /* unlock the packet mutex */ + xbee_mutex_unlock(xbee->pktmutex); + + xbee_logI("--========================--"); + xbee_logE("Packets: %d",xbee->pktcount); + + p = q = NULL; + } + return 0; +} + +static void xbee_callbackWrapper(t_CBinfo *info) { + xbee_hnd xbee; + xbee_con *con; + xbee_pkt *pkt; + t_callback_list *temp; + xbee = info->xbee; + con = info->con; + /* dont forget! the callback mutex is already locked... by the parent thread :) */ + xbee_mutex_lock(con->callbackListmutex); + while (con->callbackList) { + /* shift the list along 1 */ + temp = con->callbackList; + con->callbackList = temp->next; + xbee_mutex_unlock(con->callbackListmutex); + /* get the packet */ + pkt = temp->pkt; + + xbee_logS("Starting callback function..."); + xbee_logI(" info block @ 0x%08X",temp); + xbee_logI(" function @ 0x%08X",con->callback); + xbee_logI(" connection @ 0x%08X",con); + xbee_logE(" packet @ 0x%08X",pkt); + Xfree(temp); + if (con->callback) { + con->callback(con,pkt); + xbee_log("Callback complete!"); + if (!con->noFreeAfterCB) Xfree(pkt); + } else { + xbee_pkt *q; + int i; + xbee_log("Callback function was removed! Appending packet to main list..."); + /* lock the packet mutex, so we can safely add the packet to the list */ + xbee_mutex_lock(xbee->pktmutex); + + /* if: the list is empty */ + if (!xbee->pktlist) { + /* start the list! */ + xbee->pktlist = pkt; + } else if (xbee->pktlast) { + /* add the packet to the end */ + xbee->pktlast->next = pkt; + } else { + /* pktlast wasnt set... look for the end and then set it */ + i = 0; + q = xbee->pktlist; + while (q->next) { + q = q->next; + i++; + } + q->next = pkt; + xbee->pktcount = i; + } + xbee->pktlast = pkt; + xbee->pktcount++; + + /* unlock the packet mutex */ + xbee_mutex_unlock(xbee->pktmutex); + } + + xbee_mutex_lock(con->callbackListmutex); + } + xbee_mutex_unlock(con->callbackListmutex); + + xbee_log("Callback thread ending..."); + /* releasing the thread mutex is the last thing we do! */ + xbee_mutex_unlock(con->callbackmutex); + + if (con->destroySelf) { + _xbee_endcon2(xbee,&con,1); + } + xbee_sem_post(xbee->threadsem); +} + +/* ################################################################# + xbee_thread_watch - INTERNAL + watches for dead threads and tidies up */ +static void xbee_thread_watch(xbee_hnd xbee) { + +#ifdef _WIN32 /* ---- */ + /* win32 requires this delay... no idea why */ + usleep(1000000); +#endif /* ----------- */ + + xbee_mutex_init(xbee->threadmutex); + xbee_sem_init(xbee->threadsem); + + while (xbee->run) { + t_threadList *p, *q, *t; + xbee_mutex_lock(xbee->threadmutex); + p = xbee->threadList; + q = NULL; + + while (p) { + t = p; + p = p->next; + if (!(xbee_thread_tryjoin(t->thread))) { + xbee_log("Joined with thread 0x%08X...",t->thread); + if (t == xbee->threadList) { + xbee->threadList = t->next; + } else if (q) { + q->next = t->next; + } + free(t); + } else { + q = t; + } + } + + xbee_mutex_unlock(xbee->threadmutex); + xbee_sem_wait(xbee->threadsem); + usleep(100000); /* 100ms to allow the thread to end before we try to join */ + } + + xbee_mutex_destroy(xbee->threadmutex); + xbee_sem_destroy(xbee->threadsem); +} + + +/* ################################################################# + xbee_getbyte - INTERNAL + waits for an escaped byte of data */ +static unsigned char xbee_getbyte(xbee_hnd xbee) { + unsigned char c; + + /* take a byte */ + c = xbee_getrawbyte(xbee); + /* if its escaped, take another and un-escape */ + if (c == 0x7D) c = xbee_getrawbyte(xbee) ^ 0x20; + + return (c & 0xFF); +} + +/* ################################################################# + xbee_getrawbyte - INTERNAL + waits for a raw byte of data */ +static unsigned char xbee_getrawbyte(xbee_hnd xbee) { + int ret; + unsigned char c = 0x00; + + /* the loop is just incase there actually isnt a byte there to be read... */ + do { + /* wait for a read to be possible */ + if ((ret = xbee_select(xbee,NULL)) == -1) { + xbee_perror("libxbee:xbee_getrawbyte()"); + exit(1); + } + if (!xbee->run) break; + if (ret == 0) continue; + + /* read 1 character */ + if (xbee_read(xbee,&c,1) == 0) { + /* for some reason no characters were read... */ + if (xbee_ferror(xbee) || xbee_feof(xbee)) { + xbee_log("Error or EOF detected"); + fprintf(stderr,"libxbee:xbee_read(): Error or EOF detected\n"); + exit(1); /* this should have something nicer... */ + } + /* no error... try again */ + usleep(10); + continue; + } + } while (0); + + return (c & 0xFF); +} + +/* ################################################################# + _xbee_send_pkt - INTERNAL + sends a complete packet of data */ +static int _xbee_send_pkt(xbee_hnd xbee, t_data *pkt, xbee_con *con) { + int retval = 0; + + /* lock connection mutex */ + xbee_mutex_lock(con->Txmutex); + /* lock the send mutex */ + xbee_mutex_lock(xbee->sendmutex); + + /* write and flush the data */ + xbee_write(xbee,pkt->data,pkt->length); + + /* unlock the mutex */ + xbee_mutex_unlock(xbee->sendmutex); + + xbee_logSf(); + if (xbee->log) { + int i,x,y; + /* prints packet in hex byte-by-byte */ + xbee_logIc("TX Packet:"); + for (i=0,x=0,y=0;i<pkt->length;i++,x--) { + if (x == 0) { + fprintf(xbee->log,"\n 0x%04X | ",y); + x = 0x8; + y += x; + } + if (x == 4) { + fprintf(xbee->log," "); + } + fprintf(xbee->log,"0x%02X ",pkt->data[i]); + } + xbee_logIcf(); + } + xbee_logEf(); + + if (con->waitforACK && + ((con->type == xbee_16bitData) || + (con->type == xbee_64bitData))) { + con->ACKstatus = 0xFF; /* waiting */ + xbee_log("Waiting for ACK/NAK response..."); + xbee_sem_wait1sec(con->waitforACKsem); + switch (con->ACKstatus) { + case 0: xbee_log("ACK recieved!"); break; + case 1: xbee_log("NAK recieved..."); break; + case 2: xbee_log("CCA failure..."); break; + case 3: xbee_log("Purged..."); break; + case 255: default: xbee_log("Timeout..."); + } + if (con->ACKstatus) retval = 1; /* error */ + } + + /* unlock connection mutex */ + xbee_mutex_unlock(con->Txmutex); + + /* free the packet */ + Xfree(pkt); + + return retval; +} + +/* ################################################################# + xbee_make_pkt - INTERNAL + adds delimiter field + calculates length and checksum + escapes bytes */ +static t_data *xbee_make_pkt(xbee_hnd xbee, unsigned char *data, int length) { + t_data *pkt; + unsigned int l, i, o, t, x, m; + char d = 0; + + /* check the data given isnt too long + 100 bytes maximum payload + 12 bytes header information */ + if (length > 100 + 12) return NULL; + + /* calculate the length of the whole packet + start, length (MSB), length (LSB), DATA, checksum */ + l = 3 + length + 1; + + /* prepare memory */ + pkt = Xcalloc(sizeof(t_data)); + + /* put start byte on */ + pkt->data[0] = 0x7E; + + /* copy data into packet */ + for (t = 0, i = 0, o = 1, m = 1; i <= length; o++, m++) { + /* if: its time for the checksum */ + if (i == length) d = M8((0xFF - M8(t))); + /* if: its time for the high length byte */ + else if (m == 1) d = M8(length >> 8); + /* if: its time for the low length byte */ + else if (m == 2) d = M8(length); + /* if: its time for the normal data */ + else if (m > 2) d = data[i]; + + x = 0; + /* check for any escapes needed */ + if ((d == 0x11) || /* XON */ + (d == 0x13) || /* XOFF */ + (d == 0x7D) || /* Escape */ + (d == 0x7E)) { /* Frame Delimiter */ + l++; + pkt->data[o++] = 0x7D; + x = 1; + } + + /* move data in */ + pkt->data[o] = ((!x)?d:d^0x20); + if (m > 2) { + i++; + t += d; + } + } + + /* remember the length */ + pkt->length = l; + + return pkt; +} diff --git a/thirdParty/libxbee/api.h b/thirdParty/libxbee/api.h new file mode 100644 index 0000000000..692bd7b165 --- /dev/null +++ b/thirdParty/libxbee/api.h @@ -0,0 +1,254 @@ +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <stdlib.h> + +#include <stdarg.h> + +#include <string.h> +#include <fcntl.h> +#include <errno.h> +#include <signal.h> + +#ifdef __GNUC__ /* ---- */ +#include <unistd.h> +#include <termios.h> +#define __USE_GNU +#include <pthread.h> +#undef __USE_GNU +#include <sys/time.h> +#else /* -------------- */ +#include <Windows.h> +#include <io.h> +#include <time.h> +#include <sys/timeb.h> +#endif /* ------------- */ + +#ifdef __UMAKEFILE + #define HOST_OS "Embedded" +#elif defined(__GNUC__) + #define HOST_OS "Linux" +#elif defined(_WIN32) + #define HOST_OS "Win32" +#else + #define HOST_OS "UNKNOWN" +#endif + +#define TRUE 1 +#define FALSE 0 + +#define M8(x) (x & 0xFF) + +/* various connection types */ +#define XBEE_LOCAL_AT 0x88 +#define XBEE_LOCAL_ATREQ 0x08 +#define XBEE_LOCAL_ATQUE 0x09 + +#define XBEE_REMOTE_AT 0x97 +#define XBEE_REMOTE_ATREQ 0x17 + +#define XBEE_MODEM_STATUS 0x8A + +/* XBee Series 1 stuff */ +#define XBEE_TX_STATUS 0x89 +#define XBEE_64BIT_DATATX 0x00 +#define XBEE_64BIT_DATARX 0x80 +#define XBEE_16BIT_DATATX 0x01 +#define XBEE_16BIT_DATARX 0x81 +#define XBEE_64BIT_IO 0x82 +#define XBEE_16BIT_IO 0x83 + +/* XBee Series 2 stuff */ +#define XBEE2_DATATX 0x10 +#define XBEE2_DATARX 0x90 +#define XBEE2_TX_STATUS 0x8B + +typedef struct xbee_hnd* xbee_hnd; + +#define __LIBXBEE_API_H +#include "xbee.h" + +typedef struct t_threadList t_threadList; +struct t_threadList { + xbee_thread_t thread; + t_threadList *next; +}; + +struct xbee_hnd { + xbee_file_t tty; +#ifdef __GNUC__ /* ---- */ + int ttyfd; +#else /* -------------- */ + int ttyr; + int ttyw; + int ttyeof; + + OVERLAPPED ttyovrw; + OVERLAPPED ttyovrr; + OVERLAPPED ttyovrs; +#endif /* ------------- */ + + char *path; /* serial port path */ + + xbee_mutex_t logmutex; + FILE *log; + int logfd; + + xbee_mutex_t conmutex; + xbee_con *conlist; + + xbee_mutex_t pktmutex; + xbee_pkt *pktlist; + xbee_pkt *pktlast; + int pktcount; + + xbee_mutex_t sendmutex; + + xbee_thread_t listent; + + xbee_thread_t threadt; + xbee_mutex_t threadmutex; + xbee_sem_t threadsem; + t_threadList *threadList; + + int run; + + int oldAPI; + char cmdSeq; + int cmdTime; + + /* ready flag. + needs to be set to -1 so that the listen thread can begin. */ + volatile int xbee_ready; + + xbee_hnd next; +}; +xbee_hnd default_xbee = NULL; +xbee_mutex_t xbee_hnd_mutex; + +typedef struct t_data t_data; +struct t_data { + unsigned char data[128]; + unsigned int length; +}; + +typedef struct t_LTinfo t_LTinfo; +struct t_LTinfo { + int i; + xbee_hnd xbee; +}; + +typedef struct t_CBinfo t_CBinfo; +struct t_CBinfo { + xbee_hnd xbee; + xbee_con *con; +}; + +typedef struct t_callback_list t_callback_list; +struct t_callback_list { + xbee_pkt *pkt; + t_callback_list *next; +}; + +static void *Xmalloc2(xbee_hnd xbee, size_t size); +static void *Xcalloc2(xbee_hnd xbee, size_t size); +static void *Xrealloc2(xbee_hnd xbee, void *ptr, size_t size); +static void Xfree2(void **ptr); +#define Xmalloc(x) Xmalloc2(xbee,(x)) +#define Xcalloc(x) Xcalloc2(xbee,(x)) +#define Xrealloc(x,y) Xrealloc2(xbee,(x),(y)) +#define Xfree(x) Xfree2((void **)&x) + +/* usage: + xbee_logSf() lock the log + xbee_logEf() unlock the log + + xbee_log() lock print with \n unlock # to print a single line + xbee_logc() lock print with no \n # to print a single line with a custom ending + xbee_logcf() print \n unlock # to end a custom-ended single line + + xbee_logS() lock print with \n # to start a continuous block + xbee_logI() print with \n # to continue a continuous block + xbee_logIc() print with no \n # to continue a continuous block with a custom ending + xbee_logIcf() print \n # to continue a continuous block with ended custom-ended line + xbee_logE() print with \n unlock # to end a continuous block +*/ +static void xbee_logf(xbee_hnd xbee, const char *logformat, const char *file, + const int line, const char *function, char *format, ...); +#define LOG_FORMAT "[%s:%d] %s(): %s" + +#define xbee_logSf() if (xbee->log) { xbee_mutex_lock(xbee->logmutex); } +#define xbee_logEf() if (xbee->log) { xbee_mutex_unlock(xbee->logmutex); } + +#define xbee_log(...) if (xbee->log) { xbee_logSf(); xbee_logf(xbee,LOG_FORMAT"\n",__FILE__,__LINE__,__FUNCTION__,__VA_ARGS__); xbee_logEf(); } +#define xbee_logc(...) if (xbee->log) { xbee_logSf(); xbee_logf(xbee,LOG_FORMAT ,__FILE__,__LINE__,__FUNCTION__,__VA_ARGS__); } +#define xbee_logcf() if (xbee->log) { fprintf(xbee->log, "\n"); xbee_logEf(); } + +#define xbee_logS(...) if (xbee->log) { xbee_logSf(); xbee_logf(xbee,LOG_FORMAT"\n",__FILE__,__LINE__,__FUNCTION__,__VA_ARGS__); } +#define xbee_logI(...) if (xbee->log) { xbee_logf(xbee,LOG_FORMAT"\n",__FILE__,__LINE__,__FUNCTION__,__VA_ARGS__); } +#define xbee_logIc(...) if (xbee->log) { xbee_logf(xbee,LOG_FORMAT ,__FILE__,__LINE__,__FUNCTION__,__VA_ARGS__); } +#define xbee_logIcf() if (xbee->log) { fprintf(xbee->log, "\n"); } +#define xbee_logE(...) if (xbee->log) { xbee_logf(xbee,LOG_FORMAT"\n",__FILE__,__LINE__,__FUNCTION__,__VA_ARGS__); xbee_logEf(); } + +#define xbee_perror(str) \ + if (xbee->log) xbee_logI("%s:%s",str,strerror(errno)); \ + perror(str); + +static int xbee_startAPI(xbee_hnd xbee); + +static int xbee_sendAT(xbee_hnd xbee, char *command, char *retBuf, int retBuflen); +static int xbee_sendATdelay(xbee_hnd xbee, int guardTime, char *command, char *retBuf, int retBuflen); + +static int xbee_parse_io(xbee_hnd xbee, xbee_pkt *p, unsigned char *d, + int maskOffset, int sampleOffset, int sample); + +static void xbee_thread_watch(xbee_hnd xbee); +static void xbee_listen_wrapper(xbee_hnd xbee); +static int xbee_listen(xbee_hnd xbee); +static unsigned char xbee_getbyte(xbee_hnd xbee); +static unsigned char xbee_getrawbyte(xbee_hnd xbee); +static int xbee_matchpktcon(xbee_hnd xbee, xbee_pkt *pkt, xbee_con *con); + +static t_data *xbee_make_pkt(xbee_hnd xbee, unsigned char *data, int len); +static int _xbee_send_pkt(xbee_hnd xbee, t_data *pkt, xbee_con *con); +static void xbee_callbackWrapper(t_CBinfo *info); + +/* these functions can be found in the xsys files */ +static int init_serial(xbee_hnd xbee, int baudrate); +static int xbee_select(xbee_hnd xbee, struct timeval *timeout); + +#ifdef __GNUC__ /* ---- */ +#include "xsys/linux.c" +#else /* -------------- */ +#include "xsys\win32.c" +#endif /* ------------- */ + +#ifndef Win32Message +#define Win32Message() +#endif + +#define ISREADY(a) if (!xbee || !xbee->xbee_ready) { \ + if (stderr) fprintf(stderr,"libxbee: Run xbee_setup() first!...\n"); \ + Win32Message(); \ + a; \ + } +#define ISREADYP() ISREADY(return) +#define ISREADYR(a) ISREADY(return a) diff --git a/thirdParty/libxbee/doc/man/man3/libxbee.3.html b/thirdParty/libxbee/doc/man/man3/libxbee.3.html new file mode 100644 index 0000000000..57b7f6a0c5 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/libxbee.3.html @@ -0,0 +1,127 @@ +<HTML><HEAD><TITLE>Manpage of LIBXBEE</TITLE> +</HEAD><BODY> +<H1>LIBXBEE</H1> +Section: Linux Programmer's Manual (3)<BR>Updated: 2009-11-01<BR><A HREF="#index">Index</A> +<A HREF="../index.html">Return to Main Contents</A><HR> + +<A NAME="lbAB"> </A> +<H2>NAME</H2> + +libxbee +<A NAME="lbAC"> </A> +<H2>DESCRIPTION</H2> + +libxbee is a C library to aid the use of Series 1 Digi XBee radios running in API mode (AP=2). +<P> +I have tried to keep flexibility to a maximum. +By allowing connections to individual nodes to be created you don't have to address each packet, +or filter through incomming packets to get at the one you are after. This is all taken care of +for you by +<B>libxbee!</B> + +<P> +libxbee is still in development, so if you find any bugs or have any enhancement requests, please +feel free to submit an issue on the project page: + +<PRE> +<A HREF="http://code.google.com/p/libxbee/">http://code.google.com/p/libxbee/</A> +</PRE> + + +or contact me (Attie) directly: + +<PRE> +<A HREF="mailto:attie@attie.co.uk">attie@attie.co.uk</A> +</PRE> + + +<A NAME="lbAD"> </A> +<H2>MAN PAGES</H2> + +Documentation is avaliable via the following man pages, or by example in the 'sample' folder in the SVN repository + +<P> +<B><A HREF="../man3/xbee_pkt.3.html">xbee_pkt</A></B>(3) - libxbee's packet structure + +<B><A HREF="../man3/xbee_con.3.html">xbee_con</A></B>(3) - libxbee's connection structure + +<P> +<B><A HREF="../man3/xbee_setup.3.html">xbee_setup</A></B>(3) - function to setup libxbee (and its variants) + +<B><A HREF="../man3/xbee_end.3.html">xbee_end</A></B>(3) - function to end the libxbee session and close any open handles + +<P> +<B><A HREF="../man3/xbee_logit.3.html">xbee_logit</A></B>(3) - function that allows the user to add to the xbee log output + +<P> +<B><A HREF="../man3/xbee_newcon.3.html">xbee_newcon</A></B>(3) - function to create a new connection + +<B><A HREF="../man3/xbee_flushcon.3.html">xbee_flushcon</A></B>(3) - function to flush packets from a connection + +<B><A HREF="../man3/xbee_endcon.3.html">xbee_endcon</A></B>(3) - function to end a connection + +<P> +<B><A HREF="../man3/xbee_senddata.3.html">xbee_senddata</A></B>(3) - function to send data to a remote XBee (and its variants) + +<B><A HREF="../man3/xbee_getpacket.3.html">xbee_getpacket</A></B>(3) - function to get a packet from a connection (and its variants) + +<P> +<B><A HREF="../man3/xbee_hasdigital.3.html">xbee_hasdigital</A></B>(3) - function to check if digital sample is in the packet + +<B><A HREF="../man3/xbee_getdigital.3.html">xbee_getdigital</A></B>(3) - function to get digital sample from the packet + +<P> +<B><A HREF="../man3/xbee_hasanalog.3.html">xbee_hasanalog</A></B>(3) - function to check if analog sample is in the packet + +<B><A HREF="../man3/xbee_getanalog.3.html">xbee_getanalog</A></B>(3) - function to get the analog sample from the packet + + + +<A NAME="lbAE"> </A> +<H2>SEE ALSO</H2> + +<B><A HREF="../man3/xbee_pkt.3.html">xbee_pkt</A></B>(3), + +<B><A HREF="../man3/xbee_con.3.html">xbee_con</A></B>(3), + +<B><A HREF="../man3/xbee_setup.3.html">xbee_setup</A></B>(3), + +<B><A HREF="../man3/xbee_end.3.html">xbee_end</A></B>(3), + +<B><A HREF="../man3/xbee_logit.3.html">xbee_logit</A></B>(3), + +<B><A HREF="../man3/xbee_newcon.3.html">xbee_newcon</A></B>(3), + +<B><A HREF="../man3/xbee_flushcon.3.html">xbee_flushcon</A></B>(3), + +<B><A HREF="../man3/xbee_endcon.3.html">xbee_endcon</A></B>(3), + +<B><A HREF="../man3/xbee_senddata.3.html">xbee_senddata</A></B>(3), + +<B><A HREF="../man3/xbee_getpacket.3.html">xbee_getpacket</A></B>(3), + +<B><A HREF="../man3/xbee_hasdigital.3.html">xbee_hasdigital</A></B>(3), + +<B><A HREF="../man3/xbee_getdigital.3.html">xbee_getdigital</A></B>(3), + +<B><A HREF="../man3/xbee_hasanalog.3.html">xbee_hasanalog</A></B>(3), + +<B><A HREF="../man3/xbee_getanalog.3.html">xbee_getanalog</A></B>(3) + +<P> + +<HR> +<A NAME="index"> </A><H2>Index</H2> +<DL> +<DT><A HREF="#lbAB">NAME</A><DD> +<DT><A HREF="#lbAC">DESCRIPTION</A><DD> +<DT><A HREF="#lbAD">MAN PAGES</A><DD> +<DT><A HREF="#lbAE">SEE ALSO</A><DD> +</DL> +<HR> +This document was created by +<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, +using the manual pages.<BR> +Time: 00:08:23 GMT, March 30, 2011 +</BODY> +</HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_con.3.html b/thirdParty/libxbee/doc/man/man3/xbee_con.3.html new file mode 100644 index 0000000000..9990d7f2e3 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_con.3.html @@ -0,0 +1,26 @@ +<HTML><HEAD><TITLE>Manpage of LIBXBEE</TITLE> +</HEAD><BODY> +<H1>LIBXBEE</H1> +Section: Linux Programmer's Manual (3)<BR>Updated: 2009-11-01<BR><A HREF="#index">Index</A> +<A HREF="../index.html">Return to Main Contents</A><HR> + +<A NAME="lbAB"> </A> +<H2>NAME</H2> + +libxbee +<P> +This page has not been written yet... +<P> + +<HR> +<A NAME="index"> </A><H2>Index</H2> +<DL> +<DT><A HREF="#lbAB">NAME</A><DD> +</DL> +<HR> +This document was created by +<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, +using the manual pages.<BR> +Time: 00:08:23 GMT, March 30, 2011 +</BODY> +</HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_end.3.html b/thirdParty/libxbee/doc/man/man3/xbee_end.3.html new file mode 100644 index 0000000000..7eaa6c2701 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_end.3.html @@ -0,0 +1,27 @@ +<HTML><HEAD><TITLE>Manpage of LIBXBEE</TITLE> +</HEAD><BODY> +<H1>LIBXBEE</H1> +Section: Linux Programmer's Manual (3)<BR>Updated: 2009-11-01<BR><A HREF="#index">Index</A> +<A HREF="../index.html">Return to Main Contents</A><HR> + +<A NAME="lbAB"> </A> +<H2>NAME</H2> + +libxbee +<P> +This page has not been written yet... +<P> +<P> + +<HR> +<A NAME="index"> </A><H2>Index</H2> +<DL> +<DT><A HREF="#lbAB">NAME</A><DD> +</DL> +<HR> +This document was created by +<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, +using the manual pages.<BR> +Time: 00:08:23 GMT, March 30, 2011 +</BODY> +</HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_endcon.3.html b/thirdParty/libxbee/doc/man/man3/xbee_endcon.3.html new file mode 100644 index 0000000000..d7250a3cc4 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_endcon.3.html @@ -0,0 +1,4 @@ +<HTML><HEAD><TITLE>Invalid Manpage</TITLE></HEAD> +<BODY> +<H1>Invalid Manpage</H1> +The requested file ./man/man3/xbee_endcon.3 is not a valid (unformatted) man page.</BODY></HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_flushcon.3.html b/thirdParty/libxbee/doc/man/man3/xbee_flushcon.3.html new file mode 100644 index 0000000000..1d046d7921 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_flushcon.3.html @@ -0,0 +1,4 @@ +<HTML><HEAD><TITLE>Invalid Manpage</TITLE></HEAD> +<BODY> +<H1>Invalid Manpage</H1> +The requested file ./man/man3/xbee_flushcon.3 is not a valid (unformatted) man page.</BODY></HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_getanalog.3.html b/thirdParty/libxbee/doc/man/man3/xbee_getanalog.3.html new file mode 100644 index 0000000000..1883c3262e --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_getanalog.3.html @@ -0,0 +1,140 @@ +<HTML><HEAD><TITLE>Manpage of XBEE_GETPACKET</TITLE> +</HEAD><BODY> +<H1>XBEE_GETPACKET</H1> +Section: Linux Programmer's Manual (3)<BR>Updated: 2009-11-01<BR><A HREF="#index">Index</A> +<A HREF="../index.html">Return to Main Contents</A><HR> + +<A NAME="lbAB"> </A> +<H2>NAME</H2> + +xbee_hasanalog, xbee_getanalog +<A NAME="lbAC"> </A> +<H2>SYNOPSIS</H2> + +<B>#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>></B> + +<P> +<B>int xbee_hasanalog(xbee_pkt *</B><I>pkt</I><B>,int </B><I>sample</I><B>, int </B><I>input</I><B>);</B> + +<P> +<B>double xbee_getanalog(xbee_pkt *</B><I>pkt</I><B>,int </B><I>sample</I><B>, int </B><I>input</I><B>, double </B><I>Vref</I><B>);</B> + + +<A NAME="lbAD"> </A> +<H2>DESCRIPTION</H2> + +The +<B>xbee_hasanalog</B>() + +function will check the packet for the presence of an analog sample on the specified input. +<P> +The +<B>xbee_getanalog</B>() + +function will read the packet and return the sample value for the specified analog input. +<P> +They both take 3 arguments, with the same purposes. +<P> +The argument +<I>pkt</I> + +points to a packet that was previously retrieved with +<B>xbee_getpacket</B>() + +<P> +The argument +<I>sample</I> + +selects the sample within the packet to use. +<P> +The argument +<I>input</I> + +specifies which input you are interested in testing. +<P> +<B>xbee_getanalog</B>() + +also takes a fourth argument that allows you to provide a +<I>Vref</I> + +value. This allows the function to convert the raw ADC value into a voltage for you. +<A NAME="lbAE"> </A> +<H2>RETURN VALUE</H2> + +The +<B>xbee_hasanalog</B>() + +function will return +<B>1</B> + +if the provided packet has sample data for the specified input, otherwise +<B>0</B>. + +<P> +The +<B>xbee_getanalog</B>() + +function will return the raw ADC value (0 - 1023) if the provided packet has sample data for the specified input and Vref was given as zero. +If Vref was non-zero, then the return value will be the voltage read. +A +<B>-1</B> + +will be returned if the packet does not contain sample data. +<P> +<A NAME="lbAF"> </A> +<H2>EXAMPLE</H2> + +To read sample data from previously made connection: + +<PRE> +#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>> +xbee_pkt *pkt; +double Vref = 3.3; +if ((pkt = xbee_getpacket(con)) != NULL) { + if (xbee_hasanalog(pkt,0,0)) { + printf("A0 read %fv,xbee_getanalog(pkt,0,0,Vref)); + } else { + printf("No A0 data); + } + free(pkt); +} +</PRE> + + +<A NAME="lbAG"> </A> +<H2>AUTHOR</H2> + +Attie Grande <<A HREF="mailto:attie@attie.co.uk">attie@attie.co.uk</A>> +<A NAME="lbAH"> </A> +<H2>SEE ALSO</H2> + +<B><A HREF="../man3/libxbee.3.html">libxbee</A></B>(3), + +<B><A HREF="../man3/xbee_pkt.3.html">xbee_pkt</A></B>(3), + +<B><A HREF="../man3/xbee_getpacket.3.html">xbee_getpacket</A></B>(3), + +<B><A HREF="../man3/xbee_hasdigital.3.html">xbee_hasdigital</A></B>(3), + +<B><A HREF="../man3/xbee_getdigital.3.html">xbee_getdigital</A></B>(3) + +<P> + +<HR> +<A NAME="index"> </A><H2>Index</H2> +<DL> +<DT><A HREF="#lbAB">NAME</A><DD> +<DT><A HREF="#lbAC">SYNOPSIS</A><DD> +<DT><A HREF="#lbAD">DESCRIPTION</A><DD> +<DT><A HREF="#lbAE">RETURN VALUE</A><DD> +<DT><A HREF="#lbAF">EXAMPLE</A><DD> +<DT><A HREF="#lbAG">AUTHOR</A><DD> +<DT><A HREF="#lbAH">SEE ALSO</A><DD> +</DL> +<HR> +This document was created by +<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, +using the manual pages.<BR> +Time: 00:08:23 GMT, March 30, 2011 +</BODY> +</HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_getdigital.3.html b/thirdParty/libxbee/doc/man/man3/xbee_getdigital.3.html new file mode 100644 index 0000000000..2df9136221 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_getdigital.3.html @@ -0,0 +1,134 @@ +<HTML><HEAD><TITLE>Manpage of XBEE_GETPACKET</TITLE> +</HEAD><BODY> +<H1>XBEE_GETPACKET</H1> +Section: Linux Programmer's Manual (3)<BR>Updated: 2009-11-01<BR><A HREF="#index">Index</A> +<A HREF="../index.html">Return to Main Contents</A><HR> + +<A NAME="lbAB"> </A> +<H2>NAME</H2> + +xbee_hasdigital, xbee_getdigital +<A NAME="lbAC"> </A> +<H2>SYNOPSIS</H2> + +<B>#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>></B> + +<P> +<B>int xbee_hasdigital(xbee_pkt *</B><I>pkt</I><B>, int </B><I>sample</I><B>, int </B><I>input</I><B>);</B> + +<P> +<B>int xbee_getdigital(xbee_pkt *</B><I>pkt</I><B>, int </B><I>sample</I><B>, int </B><I>input</I><B>);</B> + + +<A NAME="lbAD"> </A> +<H2>DESCRIPTION</H2> + +The +<B>xbee_hasdigital</B>() + +function will check the packet for the presence of a given sample on the specified input. +<P> +The +<B>xbee_getdigital</B>() + +function will read the packet and return the sample value for the specified input. +<P> +They both take 3 arguments, with the same purposes. +<P> +The argument +<I>pkt</I> + +points to a packet that was previously retrieved with +<B>xbee_getpacket</B>() + +<P> +The argument +<I>sample</I> + +selects the sample within the packet to use. +<P> +The argument +<I>input</I> + +specifies which input you are interested in testing. +<A NAME="lbAE"> </A> +<H2>RETURN VALUE</H2> + +The +<B>xbee_hasdigital</B>() + +function will return +<B>1</B> + +if the provided packet has sample data for the specified input, otherwise +<B>0</B>. + +<P> +The +<B>xbee_getdigital</B>() + +function will return +<B>1</B> + +if the provided packet has sample data for the specified input and the sample was HIGH. +A +<B>0</B> + +will be returned if the sample was LOW, or the packet does not contain sample data. +<P> +<A NAME="lbAF"> </A> +<H2>EXAMPLE</H2> + +To read sample data from previously made connection: + +<PRE> +#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>> +xbee_pkt *pkt; +if ((pkt = xbee_getpacket(con)) != NULL) { + if (xbee_hasdigital(pkt,0,0)) { + printf("D0 read %d,xbee_getdigital(pkt,0)); + } else { + printf("No D0 data); + } + free(pkt); +} +</PRE> + + +<A NAME="lbAG"> </A> +<H2>AUTHOR</H2> + +Attie Grande <<A HREF="mailto:attie@attie.co.uk">attie@attie.co.uk</A>> +<A NAME="lbAH"> </A> +<H2>SEE ALSO</H2> + +<B><A HREF="../man3/libxbee.3.html">libxbee</A></B>(3), + +<B><A HREF="../man3/xbee_pkt.3.html">xbee_pkt</A></B>(3), + +<B><A HREF="../man3/xbee_getpacket.3.html">xbee_getpacket</A></B>(3), + +<B><A HREF="../man3/xbee_hasanalog.3.html">xbee_hasanalog</A></B>(3), + +<B><A HREF="../man3/xbee_getanalog.3.html">xbee_getanalog</A></B>(3) + +<P> + +<HR> +<A NAME="index"> </A><H2>Index</H2> +<DL> +<DT><A HREF="#lbAB">NAME</A><DD> +<DT><A HREF="#lbAC">SYNOPSIS</A><DD> +<DT><A HREF="#lbAD">DESCRIPTION</A><DD> +<DT><A HREF="#lbAE">RETURN VALUE</A><DD> +<DT><A HREF="#lbAF">EXAMPLE</A><DD> +<DT><A HREF="#lbAG">AUTHOR</A><DD> +<DT><A HREF="#lbAH">SEE ALSO</A><DD> +</DL> +<HR> +This document was created by +<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, +using the manual pages.<BR> +Time: 00:08:23 GMT, March 30, 2011 +</BODY> +</HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_getpacket.3.html b/thirdParty/libxbee/doc/man/man3/xbee_getpacket.3.html new file mode 100644 index 0000000000..45063f7736 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_getpacket.3.html @@ -0,0 +1,130 @@ +<HTML><HEAD><TITLE>Manpage of XBEE_GETPACKET</TITLE> +</HEAD><BODY> +<H1>XBEE_GETPACKET</H1> +Section: Linux Programmer's Manual (3)<BR>Updated: 2009-11-01<BR><A HREF="#index">Index</A> +<A HREF="../index.html">Return to Main Contents</A><HR> + +<A NAME="lbAB"> </A> +<H2>NAME</H2> + +xbee_getpacket +<A NAME="lbAC"> </A> +<H2>SYNOPSIS</H2> + +<B>#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>></B> + +<P> +<B>xbee_pkt *xbee_getpacket(xbee_con *</B><I>con</I><B>);</B> + +<P> +<B>xbee_pkt *xbee_getpacketwait(xbee_con *</B><I>con</I><B>);</B> + + +<A NAME="lbAD"> </A> +<H2>DESCRIPTION</H2> + +The +<B>xbee_getpacket</B>() + +function will return the next avaliable packet for the provided connection. +It takes 1 argument. +<P> +The argument +<I>con</I> + +points to a connection made previously with +<B>xbee_newcon</B>(). + +<P> +The +<B>xbee_getpacketwait</B>() + +function behaves the same, but will wait for an internally specified time for a packet to arrive (currently around 1 second). +<A NAME="lbAE"> </A> +<H2>RETURN VALUE</H2> + +Upon successful return, this function returns the packet, having unlinked it from the internal list of packets. +You must keep hold of the packet until you are finished with it, and then you must +<B>free</B>() + +it to prevent memory leaks. +<P> +If a packet was not avaliable for the provided connection, a +<B>NULL</B> + +is returned. +<P> +If an error occured a +<B>NULL</B> + +is also returned (though unlikely). +<P> +For more information on the structure of the packet, please see +<B><A HREF="../man3/xbee_pkt.3.html">xbee_pkt</A></B>(3) + +<P> +For information on using callback functions with connections instead, please see +<B><A HREF="../man3/xbee_con.3.html">xbee_con</A></B>(3) + +<A NAME="lbAF"> </A> +<H2>EXAMPLE</H2> + +To recieve a packet from a previously made connection: + +<PRE> +#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>> +xbee_pkt *pkt; +if ((pkt = xbee_getpacket(con)) != NULL) { + /* process packet... */ + free(pkt); +} +</PRE> + + +<A NAME="lbAG"> </A> +<H2>AUTHOR</H2> + +Attie Grande <<A HREF="mailto:attie@attie.co.uk">attie@attie.co.uk</A>> +<A NAME="lbAH"> </A> +<H2>SEE ALSO</H2> + +<B><A HREF="../man3/libxbee.3.html">libxbee</A></B>(3), + +<B><A HREF="../man3/xbee_setup.3.html">xbee_setup</A></B>(3), + +<B><A HREF="../man3/xbee_newcon.3.html">xbee_newcon</A></B>(3), + +<B><A HREF="../man3/xbee_senddata.3.html">xbee_senddata</A></B>(3), + +<B><A HREF="../man3/xbee_pkt.3.html">xbee_pkt</A></B>(3), + +<B><A HREF="../man3/xbee_con.3.html">xbee_con</A></B>(3), + +<B><A HREF="../man3/xbee_hasDigital.3.html">xbee_hasDigital</A></B>(3), + +<B><A HREF="../man3/xbee_getDigital.3.html">xbee_getDigital</A></B>(3), + +<B><A HREF="../man3/xbee_hasAnalog.3.html">xbee_hasAnalog</A></B>(3), + +<B><A HREF="../man3/xbee_getAnalog.3.html">xbee_getAnalog</A></B>(3) + +<P> + +<HR> +<A NAME="index"> </A><H2>Index</H2> +<DL> +<DT><A HREF="#lbAB">NAME</A><DD> +<DT><A HREF="#lbAC">SYNOPSIS</A><DD> +<DT><A HREF="#lbAD">DESCRIPTION</A><DD> +<DT><A HREF="#lbAE">RETURN VALUE</A><DD> +<DT><A HREF="#lbAF">EXAMPLE</A><DD> +<DT><A HREF="#lbAG">AUTHOR</A><DD> +<DT><A HREF="#lbAH">SEE ALSO</A><DD> +</DL> +<HR> +This document was created by +<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, +using the manual pages.<BR> +Time: 00:08:23 GMT, March 30, 2011 +</BODY> +</HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_hasanalog.3.html b/thirdParty/libxbee/doc/man/man3/xbee_hasanalog.3.html new file mode 100644 index 0000000000..e2c495c41a --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_hasanalog.3.html @@ -0,0 +1,4 @@ +<HTML><HEAD><TITLE>Invalid Manpage</TITLE></HEAD> +<BODY> +<H1>Invalid Manpage</H1> +The requested file ./man/man3/xbee_hasanalog.3 is not a valid (unformatted) man page.</BODY></HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_hasdigital.3.html b/thirdParty/libxbee/doc/man/man3/xbee_hasdigital.3.html new file mode 100644 index 0000000000..9774f40817 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_hasdigital.3.html @@ -0,0 +1,4 @@ +<HTML><HEAD><TITLE>Invalid Manpage</TITLE></HEAD> +<BODY> +<H1>Invalid Manpage</H1> +The requested file ./man/man3/xbee_hasdigital.3 is not a valid (unformatted) man page.</BODY></HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_logit.3.html b/thirdParty/libxbee/doc/man/man3/xbee_logit.3.html new file mode 100644 index 0000000000..7eaa6c2701 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_logit.3.html @@ -0,0 +1,27 @@ +<HTML><HEAD><TITLE>Manpage of LIBXBEE</TITLE> +</HEAD><BODY> +<H1>LIBXBEE</H1> +Section: Linux Programmer's Manual (3)<BR>Updated: 2009-11-01<BR><A HREF="#index">Index</A> +<A HREF="../index.html">Return to Main Contents</A><HR> + +<A NAME="lbAB"> </A> +<H2>NAME</H2> + +libxbee +<P> +This page has not been written yet... +<P> +<P> + +<HR> +<A NAME="index"> </A><H2>Index</H2> +<DL> +<DT><A HREF="#lbAB">NAME</A><DD> +</DL> +<HR> +This document was created by +<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, +using the manual pages.<BR> +Time: 00:08:23 GMT, March 30, 2011 +</BODY> +</HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_newcon.3.html b/thirdParty/libxbee/doc/man/man3/xbee_newcon.3.html new file mode 100644 index 0000000000..32f085b268 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_newcon.3.html @@ -0,0 +1,201 @@ +<HTML><HEAD><TITLE>Manpage of XBEE_NEWCON</TITLE> +</HEAD><BODY> +<H1>XBEE_NEWCON</H1> +Section: Linux Programmer's Manual (3)<BR>Updated: 2009-11-01<BR><A HREF="#index">Index</A> +<A HREF="../index.html">Return to Main Contents</A><HR> + +<A NAME="lbAB"> </A> +<H2>NAME</H2> + +xbee_newcon +<A NAME="lbAC"> </A> +<H2>SYNOPSIS</H2> + +<B>#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>></B> + +<P> +<B>xbee_con *xbee_newcon(unsigned char </B><I>frameID</I><B>, xbee_types </B><I>type</I><B>, ...);</B> + +<P> +<B>void xbee_flushcon(xbee_con *</B><I>con</I><B>);</B> + +<P> +<B>void xbee_endcon(xbee_con *</B><I>con</I><B>);</B> + + +<A NAME="lbAD"> </A> +<H2>DESCRIPTION</H2> + +The +<B>xbee_newcon</B>() + +function will setup a new connection with the specified settings. +It takes at least 2 arguments, and possibly up to 4 depending on the +<I>type.</I> + +<P> +<B>NOTE:</B> + +Packets will only be collected when they match an active connection. +You must setup a connection in order to recieve packets. +<P> +The argument +<I>frameID</I> + +allows similar functionality to that of TCP/IP port numbers. This is 1 character (or 8-bit integer) that +identifies where the data is coming from or going to. + +The +<I>type</I> + +specifies the type of connection you would like. The following types are avaliable: +<DL COMPACT> +<DT><B>xbee_localAT</B> + +<DD> +communicates AT commands with the local XBee +<DT><B>xbee_txStatus</B> + +<DD> +recieves transmit status information from the local XBee +<DT><B>xbee_modemStatus</B> + +<DD> +recieves modem status information from the local XBee +<DT><B>xbee_16bitRemoteAT</B> + +<DD> +communicates AT commands with a remote node (using 16-bit addressing) +<DT><B>xbee_64bitRemoteAT</B> + +<DD> +communicates AT commands with a remote node (using 64-bit addressing) +<DT><B>xbee_16bitData</B> + +<DD> +sends/recieves data through a remote node (using 16-bit addressing) +<DT><B>xbee_64bitData</B> + +<DD> +sends/recieves data through a remote node (using 64-bit addressing) +<DT><B>xbee_16bitIO</B> + +<DD> +sends/recieves I/O data through a remote node (using 16-bit addressing) +<DT><B>xbee_64bitIO</B> + +<DD> +sends/recieves I/O data through a remote node (using 64-bit addressing) +</DL> +<P> + +If you are using +<B>xbee_localAT</B>, <B>xbee_txStatus</B> or <B>xbee_modemStatus</B> + +then only the +<I>frameID</I> + +and +<I>type</I> + +arguments are required. +<P> +If you are using any 16-bit connection, you must also specify 1 right aligned integer, +containing the 16-bit address (e.g. 0x1234). +<P> +If you are using any 64-bit connection, you must also specify 2 integers containing the +64-bit address, first the high 32-bits, then the low 32-bits. +<P> +The +<B>xbee_flushcon</B>() + +function is very basic. It removes any packets that have been collected in the buffer for the specified connection. +<P> +The +<B>xbee_endcon</B>() + +function is used to end a connection. This will stop collecting packets for the given connection, and remove any packets from the buffer. +<A NAME="lbAE"> </A> +<H2>RETURN VALUE</H2> + +A pointer to the connection is returned. A connection can only be made once, using the same +<I>type</I> + +, +<I>frameID</I> + +and address (if needed). The second call using the same parameters will return the same +connection. +<P> +For information on using callback functions for packet handling please see +<B><A HREF="../man3/xbee_con.3.html">xbee_con</A></B>(3) + +<A NAME="lbAF"> </A> +<H2>EXAMPLE</H2> + +To create a local AT connection: + +<PRE> +#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>> +xbee_con *con; +con = xbee_newcon('A', xbee_localAT); +</PRE> + + +<P> +To create a 16-bit Data connection: + +<PRE> +#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>> +xbee_con *con; +con = xbee_newcon('A', xbee_16bitData, 0x1234); +</PRE> + + +<P> +To create a 64-bit Data connection: + +<PRE> +#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>> +xbee_con *con; +con = xbee_newcon('A', xbee_64bitData, 0x0013A200, 0x40081826); +</PRE> + + +<A NAME="lbAG"> </A> +<H2>AUTHOR</H2> + +Attie Grande <<A HREF="mailto:attie@attie.co.uk">attie@attie.co.uk</A>> +<A NAME="lbAH"> </A> +<H2>SEE ALSO</H2> + +<B><A HREF="../man3/libxbee.3.html">libxbee</A></B>(3), + +<B><A HREF="../man3/xbee_setup.3.html">xbee_setup</A></B>(3), + +<B><A HREF="../man3/xbee_getpacket.3.html">xbee_getpacket</A></B>(3), + +<B><A HREF="../man3/xbee_con.3.html">xbee_con</A></B>(3), + +<B><A HREF="../man3/xbee_senddata.3.html">xbee_senddata</A></B>(3) + +<P> + +<HR> +<A NAME="index"> </A><H2>Index</H2> +<DL> +<DT><A HREF="#lbAB">NAME</A><DD> +<DT><A HREF="#lbAC">SYNOPSIS</A><DD> +<DT><A HREF="#lbAD">DESCRIPTION</A><DD> +<DT><A HREF="#lbAE">RETURN VALUE</A><DD> +<DT><A HREF="#lbAF">EXAMPLE</A><DD> +<DT><A HREF="#lbAG">AUTHOR</A><DD> +<DT><A HREF="#lbAH">SEE ALSO</A><DD> +</DL> +<HR> +This document was created by +<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, +using the manual pages.<BR> +Time: 00:08:23 GMT, March 30, 2011 +</BODY> +</HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_nsenddata.3.html b/thirdParty/libxbee/doc/man/man3/xbee_nsenddata.3.html new file mode 100644 index 0000000000..3da3c6f217 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_nsenddata.3.html @@ -0,0 +1,4 @@ +<HTML><HEAD><TITLE>Invalid Manpage</TITLE></HEAD> +<BODY> +<H1>Invalid Manpage</H1> +The requested file ./man/man3/xbee_nsenddata.3 is not a valid (unformatted) man page.</BODY></HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_pkt.3.html b/thirdParty/libxbee/doc/man/man3/xbee_pkt.3.html new file mode 100644 index 0000000000..1859405aa7 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_pkt.3.html @@ -0,0 +1,107 @@ +<HTML><HEAD><TITLE>Manpage of XBEE_PKT</TITLE> +</HEAD><BODY> +<H1>XBEE_PKT</H1> +Section: Linux Programmer's Manual (3)<BR>Updated: 2009-11-01<BR><A HREF="#index">Index</A> +<A HREF="../index.html">Return to Main Contents</A><HR> + +<A NAME="lbAB"> </A> +<H2>NAME</H2> + +xbee_pkt +<A NAME="lbAC"> </A> +<H2>SYNOPSIS</H2> + +<B>#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>></B> + + +<A NAME="lbAD"> </A> +<H2>DESCRIPTION</H2> + +This is the packet structure. If you want to get more advanced information from connections (such as RSSI) then this is where it lives. +<P> + +<PRE> +struct xbee_pkt { + unsigned char frameID; /* AT Status */ + unsigned char atCmd[2]; /* AT */ + unsigned char status; /* AT Data Status */ /* status / options */ + unsigned char Addr64[8]; /* AT Data */ + unsigned char Addr16[2]; /* AT Data */ + unsigned char data[128]; /* AT Data */ + unsigned char RSSI; /* Data */ + unsigned int datalen; + + /* X A5 A4 A3 A2 A1 A0 D8 D7 D6 D5 D4 D3 D2 D1 D0 */ + unsigned short IOmask; /* IO */ + + /* X X X X X X X D8 D7 D6 D5 D4 D3 D2 D1 D0 */ + unsigned short IOdata; /* IO */ + + /* X X X X X D D D D D D D D D D D */ + unsigned short IOanalog[6]; /* IO */ +}; +typedef struct xbee_pkt xbee_pkt; +</PRE> + + +<P> +Most of these fields are fairly self explanatory, however some need attention brought to them +and others need explaining. I will touch on the most important here: +<DL COMPACT> +<DT><B>atCmd</B> + +<DD> +This is the 2 character identifier for the AT command response you just recieved. +Of course if you didnt setup an AT connection, you should never see, or try to see data here. +<DT><B>Addr64</B> and <B>Addr16</B> + +<DD> +These contain the address of the XBee that you recieved the packet from. You should really know this +because you setup the connection. However remote AT packets will contain both 16 and 64 bit +addresses. +<DT><B>data</B> + +<DD> +This is the data you just recieved. Either the AT reponse, or the data from the remote XBee node. +<DT><B>datalen</B> + +<DD> +Would you be suprised if I told you this is how much data there is?... Dont try and +<B>printf</B>() + +the +<B>data</B> + +as it isn't null terminated. Use this for processing instead. + + +</DL> +<A NAME="lbAE"> </A> +<H2>AUTHOR</H2> + +Attie Grande <<A HREF="mailto:attie@attie.co.uk">attie@attie.co.uk</A>> +<A NAME="lbAF"> </A> +<H2>SEE ALSO</H2> + +<B><A HREF="../man3/libxbee.3.html">libxbee</A></B>(3), + +<B><A HREF="../man3/xbee_getpacket.3.html">xbee_getpacket</A></B>(3) + +<P> + +<HR> +<A NAME="index"> </A><H2>Index</H2> +<DL> +<DT><A HREF="#lbAB">NAME</A><DD> +<DT><A HREF="#lbAC">SYNOPSIS</A><DD> +<DT><A HREF="#lbAD">DESCRIPTION</A><DD> +<DT><A HREF="#lbAE">AUTHOR</A><DD> +<DT><A HREF="#lbAF">SEE ALSO</A><DD> +</DL> +<HR> +This document was created by +<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, +using the manual pages.<BR> +Time: 00:08:23 GMT, March 30, 2011 +</BODY> +</HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_senddata.3.html b/thirdParty/libxbee/doc/man/man3/xbee_senddata.3.html new file mode 100644 index 0000000000..31baf1c73b --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_senddata.3.html @@ -0,0 +1,129 @@ +<HTML><HEAD><TITLE>Manpage of XBEE_SENDDATA</TITLE> +</HEAD><BODY> +<H1>XBEE_SENDDATA</H1> +Section: Linux Programmer's Manual (3)<BR>Updated: 2009-11-01<BR><A HREF="#index">Index</A> +<A HREF="../index.html">Return to Main Contents</A><HR> + +<A NAME="lbAB"> </A> +<H2>NAME</H2> + +xbee_senddata, xbee_vsenddata +<A NAME="lbAC"> </A> +<H2>SYNOPSIS</H2> + +<B>#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>></B> + +<P> +<B>int xbee_senddata(xbee_con *</B><I>con</I><B>, char *</B><I>format</I><B>, ...);</B> + +<P> +<B>int xbee_nsenddata(xbee_con *</B><I>con</I><B>, char *</B><I>data</I><B>, int </B><I>length</I><B>);</B> + +<P> +<B>#include <<A HREF="file:/usr/include/stdarg.h">stdarg.h</A>></B> + +<P> +<B>int xbee_vsenddata(xbee_con *</B><I>con</I><B>, char *</B><I>format</I><B>, va_list </B><I>ap</I><B>);</B> + + +<A NAME="lbAD"> </A> +<H2>DESCRIPTION</H2> + +The +<B>xbee_senddata</B>() + +function will send data via a provided connection. +It takes at least 2 arguments, and possibly more depending on the format string. +<P> +The argument +<I>con</I> + +points to a connection made previously with +<B>xbee_newcon</B>(). + +<P> +The +<I>format</I> + +string and any following parameters are passed to +<B>sprintf</B>() + +within these functions. +Please see the +<B><A HREF="../man3/printf.3.html">printf</A></B>(3) + +man page for more information. +<P> +If you are using +<B>xbee_nsenddata</B>() + +you must provide a character array of the data, and the data's length. +<P> +If you are using +<B>xbee_vsenddata</B>() + +you must provide a va_list. See +<B><A HREF="../man3/stdarg.3.html">stdarg</A></B>(3). + +<A NAME="lbAE"> </A> +<H2>RETURN VALUE</H2> + +Upon successful completion, these functions return 0. +<P> +If an invalid packet or connection was provided, -1 is returned. +<P> +If an unknown error occured, -2 is returned. +<P> +If +<I>con</I> + +has +<I>waitforACK</I> + +enabled, then these functions return 1 when an ACK was not recieved within 1 second. +<A NAME="lbAF"> </A> +<H2>EXAMPLE</H2> + +To send the string "Hello World!" through a previously made connection: + +<PRE> +#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>> +xbee_senddata(con,"Hello World!"); +</PRE> + + +<A NAME="lbAG"> </A> +<H2>AUTHOR</H2> + +Attie Grande <<A HREF="mailto:attie@attie.co.uk">attie@attie.co.uk</A>> +<A NAME="lbAH"> </A> +<H2>SEE ALSO</H2> + +<B><A HREF="../man3/libxbee.3.html">libxbee</A></B>(3), + +<B><A HREF="../man3/xbee_setup.3.html">xbee_setup</A></B>(3), + +<B><A HREF="../man3/xbee_newcon.3.html">xbee_newcon</A></B>(3), + +<B><A HREF="../man3/xbee_getpacket.3.html">xbee_getpacket</A></B>(3) + +<P> + +<HR> +<A NAME="index"> </A><H2>Index</H2> +<DL> +<DT><A HREF="#lbAB">NAME</A><DD> +<DT><A HREF="#lbAC">SYNOPSIS</A><DD> +<DT><A HREF="#lbAD">DESCRIPTION</A><DD> +<DT><A HREF="#lbAE">RETURN VALUE</A><DD> +<DT><A HREF="#lbAF">EXAMPLE</A><DD> +<DT><A HREF="#lbAG">AUTHOR</A><DD> +<DT><A HREF="#lbAH">SEE ALSO</A><DD> +</DL> +<HR> +This document was created by +<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, +using the manual pages.<BR> +Time: 00:08:23 GMT, March 30, 2011 +</BODY> +</HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_setup.3.html b/thirdParty/libxbee/doc/man/man3/xbee_setup.3.html new file mode 100644 index 0000000000..5b69945a51 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_setup.3.html @@ -0,0 +1,142 @@ +<HTML><HEAD><TITLE>Manpage of XBEE_SETUP</TITLE> +</HEAD><BODY> +<H1>XBEE_SETUP</H1> +Section: Linux Programmer's Manual (3)<BR>Updated: 2009-11-01<BR><A HREF="#index">Index</A> +<A HREF="../index.html">Return to Main Contents</A><HR> + +<A NAME="lbAB"> </A> +<H2>NAME</H2> + +xbee_setup +<A NAME="lbAC"> </A> +<H2>SYNOPSIS</H2> + +<B>#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>></B> + +<P> +<B>int xbee_setup(char *</B><I>path</I><B>, int </B><I>baudrate</I><B>);</B> + +<P> +<B>int xbee_setuplog(char *</B><I>path</I><B>, int </B><I>baudrate</I><B>, int </B><I>logfd</I><B>);</B> + +<P> +<B>int xbee_setupAPI(char *</B><I>path</I><B>, char </B><I>cmdSeq</I><B>, int </B><I>cmdTime</I><B>);</B> + +<P> +<B>int xbee_setuplogAPI(char *</B><I>path</I><B>, int </B><I>baudrate</I><B>, int </B><I>logfd</I><B>, char </B><I>cmdSeq</I><B>, int </B><I>cmdTime</I><B>);</B> + + +<A NAME="lbAD"> </A> +<H2>DESCRIPTION</H2> + +<P> +<B>A VERSION OF THIS FUNCTION MUST BE CALLED BEFORE ANY OTHER libxbee FUNCTION!</B> + +The +<B>xbee_setup</B>() + +function will setup libxbee so that it can handle an XBee. +It takes 2 arguments. +<P> +The argument +<I>path</I> + +is the path to the serial port that the XBee is connected to (e.g. /dev/ttyUSB0). +<P> +The +<I>baudrate</I> + +is the baud rate that the local XBee is configured to run at. The following are avaliable: + +<PRE> +<B>1200</B> +<B>2400</B> +<B>4800</B> +<B>9600</B> +<B>19200</B> +<B>38400</B> +<B>57600</B> +<B>115200</B> - this is potentially unstable (read the XBee manual to find out why...) +</PRE> + + +<P> +Using +<B>xbee_setuplog</B>() + +is exactly the same, but instead you give an open file descriptor. All log messages will be written to this file (you can use stderr or stdout if you want!). +<P> +Using +<B>xbee_setupAPI</B>() + +is exactly the same, but instead you provide the 'Command Sequence' character and the 'Guard Time' that your local XBee has been configured with. +libxbee will then place your XBee in API mode 2, and when you call xbee_end() it will return your XBee to its previous API mode. +<P> +Using +<B>xbee_setuplogAPI</B>() + +is simply a combination of +<B>xbee_setuplog</B>() + +and +<B>xbee_setupAPI</B>() + +<A NAME="lbAE"> </A> +<H2>RETURN VALUE</H2> + +If any error occures, +<B>-1</B> + +is returned. Otherwise +<B>0</B> + +is returned. +<A NAME="lbAF"> </A> +<H2>EXAMPLE</H2> + +To setup libxbee to use /dev/ttyUSB0 at 57600 baud: + +<PRE> +#include <<A HREF="file:/usr/include/xbee.h">xbee.h</A>> +if (xbee_setup("/dev/ttyUSB0",57600) == -1) { + printf("Oh no...); + <A HREF="../man1/exit.1.html">exit</A>(1); +} +</PRE> + + +<A NAME="lbAG"> </A> +<H2>AUTHOR</H2> + +Attie Grande <<A HREF="mailto:attie@attie.co.uk">attie@attie.co.uk</A>> +<A NAME="lbAH"> </A> +<H2>SEE ALSO</H2> + +<B><A HREF="../man3/libxbee.3.html">libxbee</A></B>(3), + +<B><A HREF="../man3/xbee_newcon.3.html">xbee_newcon</A></B>(3), + +<B><A HREF="../man3/xbee_getpacket.3.html">xbee_getpacket</A></B>(3), + +<B><A HREF="../man3/xbee_senddata.3.html">xbee_senddata</A></B>(3) + +<P> + +<HR> +<A NAME="index"> </A><H2>Index</H2> +<DL> +<DT><A HREF="#lbAB">NAME</A><DD> +<DT><A HREF="#lbAC">SYNOPSIS</A><DD> +<DT><A HREF="#lbAD">DESCRIPTION</A><DD> +<DT><A HREF="#lbAE">RETURN VALUE</A><DD> +<DT><A HREF="#lbAF">EXAMPLE</A><DD> +<DT><A HREF="#lbAG">AUTHOR</A><DD> +<DT><A HREF="#lbAH">SEE ALSO</A><DD> +</DL> +<HR> +This document was created by +<A HREF="http://localhost/cgi-bin/man/man2html">man2html</A>, +using the manual pages.<BR> +Time: 00:08:23 GMT, March 30, 2011 +</BODY> +</HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_setupAPI.3.html b/thirdParty/libxbee/doc/man/man3/xbee_setupAPI.3.html new file mode 100644 index 0000000000..158f1857c9 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_setupAPI.3.html @@ -0,0 +1,4 @@ +<HTML><HEAD><TITLE>Invalid Manpage</TITLE></HEAD> +<BODY> +<H1>Invalid Manpage</H1> +The requested file ./man/man3/xbee_setupAPI.3 is not a valid (unformatted) man page.</BODY></HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_setuplog.3.html b/thirdParty/libxbee/doc/man/man3/xbee_setuplog.3.html new file mode 100644 index 0000000000..16accc5713 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_setuplog.3.html @@ -0,0 +1,4 @@ +<HTML><HEAD><TITLE>Invalid Manpage</TITLE></HEAD> +<BODY> +<H1>Invalid Manpage</H1> +The requested file ./man/man3/xbee_setuplog.3 is not a valid (unformatted) man page.</BODY></HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_setuplogAPI.3.html b/thirdParty/libxbee/doc/man/man3/xbee_setuplogAPI.3.html new file mode 100644 index 0000000000..801cbfaf90 --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_setuplogAPI.3.html @@ -0,0 +1,4 @@ +<HTML><HEAD><TITLE>Invalid Manpage</TITLE></HEAD> +<BODY> +<H1>Invalid Manpage</H1> +The requested file ./man/man3/xbee_setuplogAPI.3 is not a valid (unformatted) man page.</BODY></HTML> diff --git a/thirdParty/libxbee/doc/man/man3/xbee_vsenddata.3.html b/thirdParty/libxbee/doc/man/man3/xbee_vsenddata.3.html new file mode 100644 index 0000000000..5a9b7d948c --- /dev/null +++ b/thirdParty/libxbee/doc/man/man3/xbee_vsenddata.3.html @@ -0,0 +1,4 @@ +<HTML><HEAD><TITLE>Invalid Manpage</TITLE></HEAD> +<BODY> +<H1>Invalid Manpage</H1> +The requested file ./man/man3/xbee_vsenddata.3 is not a valid (unformatted) man page.</BODY></HTML> diff --git a/thirdParty/libxbee/main.c b/thirdParty/libxbee/main.c new file mode 100644 index 0000000000..7dcacafa7e --- /dev/null +++ b/thirdParty/libxbee/main.c @@ -0,0 +1,229 @@ +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xbee.h" + +int main(int argc, char *argv[]) { + xbee_con *con, *con2; + xbee_pkt *pkt, *p; + + if (xbee_setuplog("/dev/ttyUSB0",57600,2) == -1) { + perror("xbee_setuplog()"); + exit(1); + } + if (argc >= 2 && !strcmp(argv[1],"sleep")) { + for (;;) { + sleep(86400); /* sleep for a day... forever :) */ + } + } + + /*if ((con = xbee_newcon(NULL,'X',xbee_localAT)) == (void *)-1) { + printf("error creating connection...\n"); + exit(1); + } + + while(1){sleep(10);} + + xbee_senddata(con,"CH%c",0x0C); + sleep(1); + xbee_senddata(con,"ID%c%c",0x33, 0x32); + sleep(1); + xbee_senddata(con,"DH%c%c%c%c",0x00,0x00,0x00,0x00); + sleep(1); + xbee_senddata(con,"DL%c%c%c%c",0x00,0x00,0x00,0x00); + sleep(1); + xbee_senddata(con,"MY%c%c",0x00,0x00); + sleep(1); + // SH - read only + // SL - read only + xbee_senddata(con,"RR%c",0x00); + sleep(1); + xbee_senddata(con,"RN%c",0x00); + sleep(1); + xbee_senddata(con,"MM%c",0x00); + sleep(1); + xbee_senddata(con,"NT%c",0x19); + sleep(1); + xbee_senddata(con,"NO%c",0x00); + sleep(1); + xbee_senddata(con,"CE%c",0x00); + sleep(1); + xbee_senddata(con,"SC%c%c",0x1F,0xFE); + sleep(1); + xbee_senddata(con,"SD%c",0x04); + sleep(1); + xbee_senddata(con,"A1%c",0x00); + sleep(1); + xbee_senddata(con,"A2%c",0x00); + sleep(1); + // AI - read only + xbee_senddata(con,"EE%c",0x00); + sleep(1); + //xbee_senddata(con,"KY%c",0x00); + //sleep(1); + xbee_senddata(con,"NI%s","TIGGER"); + sleep(1); + xbee_senddata(con,"PL%c",0x04); + sleep(1); + xbee_senddata(con,"CA%c",0x2C); + sleep(1); + xbee_senddata(con,"SM%c",0x00); + sleep(1); + xbee_senddata(con,"ST%c%c",0x13,0x88); + sleep(1); + xbee_senddata(con,"SP%c%c",0x00,0x00); + sleep(1); + xbee_senddata(con,"DP%c%c",0x03,0xE8); + sleep(1); + xbee_senddata(con,"SO%c",0x00); + sleep(1); + xbee_senddata(con,"BD%c",0x06); + sleep(1); + xbee_senddata(con,"RO%c",0x03); + sleep(1); + xbee_senddata(con,"AP%c",0x02); + sleep(1); + xbee_senddata(con,"PR%c",0xFF); + sleep(1); + xbee_senddata(con,"D8%c",0x00); + sleep(1); + xbee_senddata(con,"D7%c",0x01); + sleep(1); + xbee_senddata(con,"D6%c",0x00); + sleep(1); + xbee_senddata(con,"D5%c",0x01); + sleep(1); + xbee_senddata(con,"D4%c",0x00); + sleep(1); + xbee_senddata(con,"D3%c",0x00); + sleep(1); + xbee_senddata(con,"D2%c",0x00); + sleep(1); + xbee_senddata(con,"D1%c",0x00); + sleep(1); + xbee_senddata(con,"D0%c",0x00); + sleep(1); + xbee_senddata(con,"IU%c",0x00); + sleep(1); + xbee_senddata(con,"IT%c",0x01); + sleep(1); + xbee_senddata(con,"IC%c",0x00); + sleep(1); + xbee_senddata(con,"IR%c%c",0x00,0x00); + sleep(1); + xbee_senddata(con,"IA%c%c%c%c%c%c%c%c",0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF); + sleep(1); + xbee_senddata(con,"T0%c",0xFF); + sleep(1); + xbee_senddata(con,"T1%c",0xFF); + sleep(1); + xbee_senddata(con,"T2%c",0xFF); + sleep(1); + xbee_senddata(con,"T3%c",0xFF); + sleep(1); + xbee_senddata(con,"T4%c",0xFF); + sleep(1); + xbee_senddata(con,"T5%c",0xFF); + sleep(1); + xbee_senddata(con,"T6%c",0xFF); + sleep(1); + xbee_senddata(con,"T7%c",0xFF); + sleep(1); + xbee_senddata(con,"P0%c",0x01); + sleep(1); + xbee_senddata(con,"P1%c",0x00); + sleep(1); + xbee_senddata(con,"PT%c",0xFF); + sleep(1); + xbee_senddata(con,"RP%c",0x28); + sleep(1); + // VR - read only + // HV - read only + // DB - read only + // EC - read only + // EA - read only + // DD - read only + xbee_senddata(con,"CT%c",0x64); + sleep(1); + xbee_senddata(con,"GT%c%c",0x03,0xE8); + sleep(1); + xbee_senddata(con,"CC%c",0x2B); + sleep(1); + + sleep(10); + */ + + /* test 64bit IO and Data */ + con = xbee_newcon('I',xbee_64bitIO, 0x0013A200, 0x403af247); + con2 = xbee_newcon('I',xbee_64bitData, 0x0013A200, 0x403af247); + + while (1) { + while ((pkt = xbee_getpacket(con)) != NULL) { + int i; + for (i = 0; i < pkt->samples; i++) { + int m; + for (m = 0; m <= 8; m++) { + if (xbee_hasdigital(pkt,i,m)) printf("D%d: %d ",m,xbee_getdigital(pkt,i,m)); + } +#define Vref 3.23 + for (m = 0; m <= 5; m++) { + if (xbee_hasanalog(pkt,i,m)) printf("A%d: %.2fv ",m,xbee_getanalog(pkt,i,m,Vref)); + } + printf("\n"); + } + if (xbee_senddata(con2, "the time is %d\r", time(NULL))) { + printf("Error: xbee_senddata\n"); + return 1; + } + free(pkt); + if (p) { + switch (p->status) { + case 0x01: printf("XBee: txStatus: No ACK\n"); break; + case 0x02: printf("XBee: txStatus: CCA Failure\n"); break; + case 0x03: printf("XBee: txStatus: Purged\n"); break; + } + free(p); + } + } + while ((pkt = xbee_getpacket(con2)) != NULL) { + printf("he said '%s'\n", pkt->data); + if (xbee_senddata(con2, "you said '%s'\r", pkt->data)) { + printf("Error: xbee_senddata\n"); + return 1; + } + free(pkt); + if (p) { + switch (p->status) { + case 0x01: printf("XBee: txStatus: No ACK\n"); break; + case 0x02: printf("XBee: txStatus: CCA Failure\n"); break; + case 0x03: printf("XBee: txStatus: Purged\n"); break; + } + free(p); + } + } + usleep(100); + } + + return 0; +} diff --git a/thirdParty/libxbee/man/man3/libxbee.3 b/thirdParty/libxbee/man/man3/libxbee.3 new file mode 100644 index 0000000000..6bcb978f6f --- /dev/null +++ b/thirdParty/libxbee/man/man3/libxbee.3 @@ -0,0 +1,91 @@ +.\" libxbee - a C library to aid the use of Digi's Series 1 XBee modules +.\" running in API mode (AP=2). +.\" +.\" Copyright (C) 2009 Attie Grande (attie@attie.co.uk) +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.TH LIBXBEE 3 2009-11-01 "GNU" "Linux Programmer's Manual" +.SH NAME +libxbee +.SH DESCRIPTION +libxbee is a C library to aid the use of Series 1 Digi XBee radios running in API mode (AP=2). +.sp +I have tried to keep flexibility to a maximum. +By allowing connections to individual nodes to be created - you don't have to address each packet, +or filter through incomming packets to get at the one you are after. This is all taken care of +for you by +.BR libxbee +! +.sp +libxbee is still in development, so if you find any bugs or have any enhancement requests, please +feel free to submit an issue on the project page: +.in +4n +.nf +http://code.google.com/p/libxbee/ +.fi +.in +or contact me (Attie) directly: +.in +4n +.nf +attie@attie.co.uk +.fi +.in +.SH "MAN PAGES" +Documentation is avaliable via the following man pages, or by example in the 'sample' folder in the SVN repository +.in +4n +.sp +.BR xbee_pkt "(3) - libxbee's packet structure" +.sp 0 +.BR xbee_con "(3) - libxbee's connection structure" +.sp +.BR xbee_setup "(3) - function to setup libxbee (and its variants)" +.sp 0 +.BR xbee_end "(3) - function to end the libxbee session and close any open handles" +.sp +.BR xbee_logit "(3) - function that allows the user to add to the xbee log output" +.sp +.BR xbee_newcon "(3) - function to create a new connection" +.sp 0 +.BR xbee_purgecon "(3) - function to purge packets from a connection" +.sp 0 +.BR xbee_endcon "(3) - function to end a connection" +.sp +.BR xbee_senddata "(3) - function to send data to a remote XBee (and its variants)" +.sp 0 +.BR xbee_getpacket "(3) - function to get a packet from a connection (and its variants)" +.sp +.BR xbee_hasdigital "(3) - function to check if digital sample is in the packet" +.sp 0 +.BR xbee_getdigital "(3) - function to get digital sample from the packet" +.sp +.BR xbee_hasanalog "(3) - function to check if analog sample is in the packet" +.sp 0 +.BR xbee_getanalog "(3) - function to get the analog sample from the packet" +.fi +.in +.SH "SEE ALSO" +.BR xbee_pkt (3), +.BR xbee_con (3), +.BR xbee_setup (3), +.BR xbee_end (3), +.BR xbee_logit (3), +.BR xbee_newcon (3), +.BR xbee_flushcon (3), +.BR xbee_endcon (3), +.BR xbee_senddata (3), +.BR xbee_getpacket (3), +.BR xbee_hasdigital (3), +.BR xbee_getdigital (3), +.BR xbee_hasanalog (3), +.BR xbee_getanalog (3) diff --git a/thirdParty/libxbee/man/man3/xbee_con.3 b/thirdParty/libxbee/man/man3/xbee_con.3 new file mode 100644 index 0000000000..37e7705044 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_con.3 @@ -0,0 +1,22 @@ +.\" libxbee - a C library to aid the use of Digi's Series 1 XBee modules +.\" running in API mode (AP=2). +.\" +.\" Copyright (C) 2009 Attie Grande (attie@attie.co.uk) +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.TH LIBXBEE 3 2009-11-01 "GNU" "Linux Programmer's Manual" +.SH NAME +libxbee +.sp +This page has not been written yet... diff --git a/thirdParty/libxbee/man/man3/xbee_end.3 b/thirdParty/libxbee/man/man3/xbee_end.3 new file mode 100644 index 0000000000..5fd1de5127 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_end.3 @@ -0,0 +1,23 @@ +.\" libxbee - a C library to aid the use of Digi's Series 1 XBee modules +.\" running in API mode (AP=2). +.\" +.\" Copyright (C) 2009 Attie Grande (attie@attie.co.uk) +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.TH LIBXBEE 3 2009-11-01 "GNU" "Linux Programmer's Manual" +.SH NAME +libxbee +.sp +This page has not been written yet... + diff --git a/thirdParty/libxbee/man/man3/xbee_endcon.3 b/thirdParty/libxbee/man/man3/xbee_endcon.3 new file mode 100644 index 0000000000..e64ccedb26 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_endcon.3 @@ -0,0 +1 @@ +.so man3/xbee_newcon.3 diff --git a/thirdParty/libxbee/man/man3/xbee_flushcon.3 b/thirdParty/libxbee/man/man3/xbee_flushcon.3 new file mode 100644 index 0000000000..e64ccedb26 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_flushcon.3 @@ -0,0 +1 @@ +.so man3/xbee_newcon.3 diff --git a/thirdParty/libxbee/man/man3/xbee_getanalog.3 b/thirdParty/libxbee/man/man3/xbee_getanalog.3 new file mode 100644 index 0000000000..f7bc1d0c72 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_getanalog.3 @@ -0,0 +1,96 @@ +.\" libxbee - a C library to aid the use of Digi's Series 1 XBee modules +.\" running in API mode (AP=2). +.\" +.\" Copyright (C) 2009 Attie Grande (attie@attie.co.uk) +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.TH XBEE_GETPACKET 3 2009-11-01 "GNU" "Linux Programmer's Manual" +.SH NAME +xbee_hasanalog, xbee_getanalog +.SH SYNOPSIS +.B #include <xbee.h> +.sp +.BI "int xbee_hasanalog(xbee_pkt *" pkt ", int " sample ", int " input ");" +.sp +.BI "double xbee_getanalog(xbee_pkt *" pkt ", int " sample ", int " input ", double " Vref ");" +.ad b +.SH DESCRIPTION +The +.BR xbee_hasanalog () +function will check the packet for the presence of an analog sample on the specified input. +.sp +The +.BR xbee_getanalog () +function will read the packet and return the sample value for the specified analog input. +.sp +They both take 3 arguments, with the same purposes. +.sp +The argument +.I pkt +points to a packet that was previously retrieved with +.BR xbee_getpacket () +.sp +The argument +.I sample +selects the sample within the packet to use. +.sp +The argument +.I input +specifies which input you are interested in testing. +.sp +.BR xbee_getanalog () +also takes a fourth argument that allows you to provide a +.I Vref +value. This allows the function to convert the raw ADC value into a voltage for you. +.SH "RETURN VALUE" +The +.BR xbee_hasanalog () +function will return +.B 1 +if the provided packet has sample data for the specified input, otherwise +.BR 0 . +.sp +The +.BR xbee_getanalog () +function will return the raw ADC value (0 - 1023) if the provided packet has sample data for the specified input and Vref was given as zero. +If Vref was non-zero, then the return value will be the voltage read. +A +.B -1 +will be returned if the packet does not contain sample data. +.sp +.SH EXAMPLE +To read sample data from previously made connection: +.in +4n +.nf +#include <xbee.h> +xbee_pkt *pkt; +double Vref = 3.3; +if ((pkt = xbee_getpacket(con)) != NULL) { + if (xbee_hasanalog(pkt,0,0)) { + printf("A0 read %fv\\n",xbee_getanalog(pkt,0,0,Vref)); + } else { + printf("No A0 data\\n"); + } + free(pkt); +} +.fi +.in +.SH AUTHOR +Attie Grande <attie@attie.co.uk> +.SH "SEE ALSO" +.BR libxbee (3), +.BR xbee_pkt (3), +.BR xbee_getpacket (3), +.BR xbee_hasdigital (3), +.BR xbee_getdigital (3) diff --git a/thirdParty/libxbee/man/man3/xbee_getdigital.3 b/thirdParty/libxbee/man/man3/xbee_getdigital.3 new file mode 100644 index 0000000000..4a0af65b50 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_getdigital.3 @@ -0,0 +1,91 @@ +.\" libxbee - a C library to aid the use of Digi's Series 1 XBee modules +.\" running in API mode (AP=2). +.\" +.\" Copyright (C) 2009 Attie Grande (attie@attie.co.uk) +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.TH XBEE_GETPACKET 3 2009-11-01 "GNU" "Linux Programmer's Manual" +.SH NAME +xbee_hasdigital, xbee_getdigital +.SH SYNOPSIS +.B #include <xbee.h> +.sp +.BI "int xbee_hasdigital(xbee_pkt *" pkt ", int " sample ", int " input ");" +.sp +.BI "int xbee_getdigital(xbee_pkt *" pkt ", int " sample ", int " input ");" +.ad b +.SH DESCRIPTION +The +.BR xbee_hasdigital () +function will check the packet for the presence of a given sample on the specified input. +.sp +The +.BR xbee_getdigital () +function will read the packet and return the sample value for the specified input. +.sp +They both take 3 arguments, with the same purposes. +.sp +The argument +.I pkt +points to a packet that was previously retrieved with +.BR xbee_getpacket () +.sp +The argument +.I sample +selects the sample within the packet to use. +.sp +The argument +.I input +specifies which input you are interested in testing. +.SH "RETURN VALUE" +The +.BR xbee_hasdigital () +function will return +.B 1 +if the provided packet has sample data for the specified input, otherwise +.BR 0 . +.sp +The +.BR xbee_getdigital () +function will return +.B 1 +if the provided packet has sample data for the specified input and the sample was HIGH. +A +.B 0 +will be returned if the sample was LOW, or the packet does not contain sample data. +.sp +.SH EXAMPLE +To read sample data from previously made connection: +.in +4n +.nf +#include <xbee.h> +xbee_pkt *pkt; +if ((pkt = xbee_getpacket(con)) != NULL) { + if (xbee_hasdigital(pkt,0,0)) { + printf("D0 read %d\n",xbee_getdigital(pkt,0)); + } else { + printf("No D0 data\n"); + } + free(pkt); +} +.fi +.in +.SH AUTHOR +Attie Grande <attie@attie.co.uk> +.SH "SEE ALSO" +.BR libxbee (3), +.BR xbee_pkt (3), +.BR xbee_getpacket (3), +.BR xbee_hasanalog (3), +.BR xbee_getanalog (3) diff --git a/thirdParty/libxbee/man/man3/xbee_getpacket.3 b/thirdParty/libxbee/man/man3/xbee_getpacket.3 new file mode 100644 index 0000000000..a458e49602 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_getpacket.3 @@ -0,0 +1,88 @@ +.\" libxbee - a C library to aid the use of Digi's Series 1 XBee modules +.\" running in API mode (AP=2). +.\" +.\" Copyright (C) 2009 Attie Grande (attie@attie.co.uk) +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.TH XBEE_GETPACKET 3 2009-11-01 "GNU" "Linux Programmer's Manual" +.SH NAME +xbee_getpacket, xbee_getpacketwait +.SH SYNOPSIS +.B #include <xbee.h> +.sp +.BI "xbee_pkt *xbee_getpacket(xbee_con *" con ");" +.sp +.BI "xbee_pkt *xbee_getpacketwait(xbee_con *" con ");" +.ad b +.SH DESCRIPTION +The +.BR xbee_getpacket () +function will return the next avaliable packet for the provided connection. +It takes 1 argument. +.sp +The argument +.I con +points to a connection made previously with +.BR xbee_newcon (). +.sp +The +.BR xbee_getpacketwait () +function behaves the same, but will wait for an internally specified time for a packet to arrive (currently around 1 second). +.SH "RETURN VALUE" +Upon successful return, this function returns the packet, having unlinked it from the internal list. +You must keep hold of the packet until you are finished with it, and then you must +.BR free () +it to prevent memory leaks. +.sp +If a packet was not avaliable for the provided connection, a +.B NULL +is returned. +.sp +If an error occured a +.B NULL +is also returned (though unlikely). +.sp +For more information on the structure of the packet, please see +.BR xbee_pkt (3) +.sp +For information on using callback functions with connections instead, please see +.BR xbee_con (3) +or +.B callback.c +in the SVN sample directory. +.SH EXAMPLE +To recieve a packet from a previously made connection: +.in +4n +.nf +#include <xbee.h> +xbee_pkt *pkt; +if ((pkt = xbee_getpacket(con)) != NULL) { + /* process packet... */ + free(pkt); +} +.fi +.in +.SH AUTHOR +Attie Grande <attie@attie.co.uk> +.SH "SEE ALSO" +.BR libxbee (3), +.BR xbee_setup (3), +.BR xbee_newcon (3), +.BR xbee_senddata (3), +.BR xbee_pkt (3), +.BR xbee_con (3), +.BR xbee_hasDigital (3), +.BR xbee_getDigital (3), +.BR xbee_hasAnalog (3), +.BR xbee_getAnalog (3) diff --git a/thirdParty/libxbee/man/man3/xbee_hasanalog.3 b/thirdParty/libxbee/man/man3/xbee_hasanalog.3 new file mode 100644 index 0000000000..402a3f266f --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_hasanalog.3 @@ -0,0 +1 @@ +.so man3/xbee_getanalog.3 diff --git a/thirdParty/libxbee/man/man3/xbee_hasdigital.3 b/thirdParty/libxbee/man/man3/xbee_hasdigital.3 new file mode 100644 index 0000000000..5557111123 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_hasdigital.3 @@ -0,0 +1 @@ +.so man3/xbee_getdigital.3 diff --git a/thirdParty/libxbee/man/man3/xbee_logit.3 b/thirdParty/libxbee/man/man3/xbee_logit.3 new file mode 100644 index 0000000000..5fd1de5127 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_logit.3 @@ -0,0 +1,23 @@ +.\" libxbee - a C library to aid the use of Digi's Series 1 XBee modules +.\" running in API mode (AP=2). +.\" +.\" Copyright (C) 2009 Attie Grande (attie@attie.co.uk) +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.TH LIBXBEE 3 2009-11-01 "GNU" "Linux Programmer's Manual" +.SH NAME +libxbee +.sp +This page has not been written yet... + diff --git a/thirdParty/libxbee/man/man3/xbee_newcon.3 b/thirdParty/libxbee/man/man3/xbee_newcon.3 new file mode 100644 index 0000000000..2ec511278d --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_newcon.3 @@ -0,0 +1,152 @@ +.\" libxbee - a C library to aid the use of Digi's Series 1 XBee modules +.\" running in API mode (AP=2). +.\" +.\" Copyright (C) 2009 Attie Grande (attie@attie.co.uk) +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.TH XBEE_NEWCON 3 2009-11-01 "GNU" "Linux Programmer's Manual" +.SH NAME +xbee_newcon, xbee_purgecon, xbee_endcon +.SH SYNOPSIS +.B #include <xbee.h> +.sp +.BI "xbee_con *xbee_newcon(unsigned char " frameID ", xbee_types " type ", ...);" +.sp +.BI "void xbee_purgecon(xbee_con *" con ");" +.sp +.BI "void xbee_endcon(xbee_con *" con ");" +.ad b +.SH DESCRIPTION +The +.BR xbee_newcon () +function will setup a new connection with the specified settings. +It takes at least 2 arguments, and potentially up to 4 depending on the +.I type. +.sp +.B NOTE: +Packets will only be collected when they match an active connection. +You must setup a connection in order to recieve packets. +.sp +The argument +.I frameID +allows similar functionality to that of TCP/IP port numbers. This is 1 +.I unsigned char +(or 8-bit integer) that identifies where the data is coming from or going to. +.s +The +.I type +specifies the type of connection you would like. The following types are avaliable: +.TP +.B xbee_localAT +communicates AT commands with the local XBee +.TP +.B xbee_txStatus +recieves transmit status information from the local XBee +.TP +.B xbee_modemStatus +recieves modem status information from the local XBee +.TP +.B xbee_16bitRemoteAT +communicates AT commands with a remote node (using 16-bit addressing) +.TP +.B xbee_64bitRemoteAT +communicates AT commands with a remote node (using 64-bit addressing) +.TP +.B xbee_16bitData +sends/recieves data through a remote node (using 16-bit addressing) +.TP +.B xbee_64bitData +sends/recieves data through a remote node (using 64-bit addressing) +.TP +.B xbee_16bitIO +sends/recieves I/O data through a remote node (using 16-bit addressing) +.TP +.B xbee_64bitIO +sends/recieves I/O data through a remote node (using 64-bit addressing) +.TP +.B xbee2_data +sends/recieves data using a Series 2 XBee (uses 64-bit addressing) +.TP +.B xbee2_txStatus +recieves transmit status information from the local Series 2 XBee +.PP +If you are using +.BR xbee_localAT ", " xbee_txStatus ", " xbee2_txStatus " or " xbee_modemStatus +then only the +.I frameID +and +.I type +arguments are required. +.sp +If you are using any 16-bit connection, you must also specify 1 right aligned integer, +containing the 16-bit address (e.g. 0x1234). +.sp +If you are using any 64-bit connection, you must also specify 2 integers containing the +64-bit address, first the high 32-bits, then the low 32-bits. +.sp +The +.BR xbee_purgecon () +function is very basic. It removes any packets that have been collected in the buffer for the specified connection. +.sp +The +.BR xbee_endcon () +function is used to end a connection. This will stop collecting packets for the given connection, and remove any packets from the buffer. +.SH "RETURN VALUE" +A pointer to the connection is returned. A connection can only be made once, using the same +.I type +, +.I frameID +and address (if needed). The second call using the same parameters will return the same +connection. +.sp +For information on using callback functions for packet handling please see +.BR xbee_con (3) +or +.B callback.c +in the SVN sample directory. +.SH EXAMPLE +To create a local AT connection: +.in +4n +.nf +#include <xbee.h> +xbee_con *con; +con = xbee_newcon('A', xbee_localAT); +.fi +.in +.sp +To create a 16-bit Data connection: +.in +4n +.nf +#include <xbee.h> +xbee_con *con; +con = xbee_newcon('A', xbee_16bitData, 0x1234); +.fi +.in +.sp +To create a 64-bit Data connection: +.in +4n +.nf +#include <xbee.h> +xbee_con *con; +con = xbee_newcon('A', xbee_64bitData, 0x0013A200, 0x40081826); +.fi +.in +.SH AUTHOR +Attie Grande <attie@attie.co.uk> +.SH "SEE ALSO" +.BR libxbee (3), +.BR xbee_setup (3), +.BR xbee_getpacket (3), +.BR xbee_con (3), +.BR xbee_senddata (3) diff --git a/thirdParty/libxbee/man/man3/xbee_nsenddata.3 b/thirdParty/libxbee/man/man3/xbee_nsenddata.3 new file mode 100644 index 0000000000..b36885d854 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_nsenddata.3 @@ -0,0 +1 @@ +.so man3/xbee_senddata.3 diff --git a/thirdParty/libxbee/man/man3/xbee_pkt.3 b/thirdParty/libxbee/man/man3/xbee_pkt.3 new file mode 100644 index 0000000000..d5e269c13c --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_pkt.3 @@ -0,0 +1,79 @@ +.\" libxbee - a C library to aid the use of Digi's Series 1 XBee modules +.\" running in API mode (AP=2). +.\" +.\" Copyright (C) 2009 Attie Grande (attie@attie.co.uk) +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.TH XBEE_PKT 3 2009-11-01 "GNU" "Linux Programmer's Manual" +.SH NAME +xbee_pkt +.SH SYNOPSIS +.B #include <xbee.h> +.ad b +.SH DESCRIPTION +This is the packet structure. If you want to get more advanced information from connections (such as RSSI) then this is where it lives. +.sp +.in +4n +.nf +struct xbee_pkt { + unsigned char frameID; /* AT Status */ + unsigned char atCmd[2]; /* AT */ + unsigned char status; /* AT Data Status */ /* status / options */ + unsigned char Addr64[8]; /* AT Data */ + unsigned char Addr16[2]; /* AT Data */ + unsigned char data[128]; /* AT Data */ + unsigned char RSSI; /* Data */ + unsigned int datalen; + + /* X A5 A4 A3 A2 A1 A0 D8 D7 D6 D5 D4 D3 D2 D1 D0 */ + unsigned short IOmask; /* IO */ + + /* X X X X X X X D8 D7 D6 D5 D4 D3 D2 D1 D0 */ + unsigned short IOdata; /* IO */ + + /* X X X X X D D D D D D D D D D D */ + unsigned short IOanalog[6]; /* IO */ +}; +typedef struct xbee_pkt xbee_pkt; +.fi +.in +.sp +Most of these fields are fairly self explanatory, however some need attention brought to them +and others need explaining. I will touch on the most important here: +.TP +.B atCmd +This is the 2 character identifier for the AT command response you just recieved. +Of course if you didnt setup an AT connection, you should never see, or try to see data here. +.TP +.BR Addr64 " and " Addr16 +These contain the address of the XBee that you recieved the packet from. You should really know this +because you setup the connection. However remote AT packets will contain both 16 and 64 bit +addresses. +.TP +.B data +This is the data you just recieved. Either the AT reponse, or the data from the remote XBee node. +.TP +.B datalen +Would you be suprised if I told you this is how much data there is?... Dont try and +.BR printf () +the +.B data +as it isn't null terminated. Use this for processing instead. +.fi +.in +.SH AUTHOR +Attie Grande <attie@attie.co.uk> +.SH "SEE ALSO" +.BR libxbee (3), +.BR xbee_getpacket (3) diff --git a/thirdParty/libxbee/man/man3/xbee_purgecon.3 b/thirdParty/libxbee/man/man3/xbee_purgecon.3 new file mode 100644 index 0000000000..e64ccedb26 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_purgecon.3 @@ -0,0 +1 @@ +.so man3/xbee_newcon.3 diff --git a/thirdParty/libxbee/man/man3/xbee_senddata.3 b/thirdParty/libxbee/man/man3/xbee_senddata.3 new file mode 100644 index 0000000000..10296bb8c1 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_senddata.3 @@ -0,0 +1,86 @@ +.\" libxbee - a C library to aid the use of Digi's Series 1 XBee modules +.\" running in API mode (AP=2). +.\" +.\" Copyright (C) 2009 Attie Grande (attie@attie.co.uk) +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.TH XBEE_SENDDATA 3 2009-11-01 "GNU" "Linux Programmer's Manual" +.SH NAME +xbee_senddata, xbee_nsenddata, xbee_vsenddata +.SH SYNOPSIS +.B #include <xbee.h> +.sp +.BI "int xbee_senddata(xbee_con *" con ", char *" format ", ...);" +.sp +.BI "int xbee_nsenddata(xbee_con *" con ", char *" data ", int " length ");" +.sp +.B #include <stdarg.h> +.sp +.BI "int xbee_vsenddata(xbee_con *" con ", char *" format ", va_list " ap "); +.ad b +.SH DESCRIPTION +The +.BR xbee_senddata () +function will send data via a provided connection. +It takes at least 2 arguments, and possibly more depending on the format string. +.sp +The argument +.I con +points to a connection made previously with +.BR xbee_newcon (). +.sp +The +.I format +string and any following parameters are passed to +.BR snprintf () +within these functions. +Please see the +.BR printf (3) +man page for more information. +.sp +If you are using +.BR xbee_nsenddata () +you must provide a character array of the data, and the data's length. +.sp +If you are using +.BR xbee_vsenddata () +you must provide a va_list. See +.BR stdarg (3). +.SH "RETURN VALUE" +Upon successful completion, these functions return 0. +.sp +If an invalid packet or connection was provided, -1 is returned. +.sp +If an unknown error occured, -2 is returned. +.sp +If +.I con +has +.I waitforACK +enabled, then these functions return 1 when an ACK was not recieved within 1 second. +.SH EXAMPLE +To send the string "Hello World!" through a previously made connection: +.in +4n +.nf +#include <xbee.h> +xbee_senddata(con,"Hello World!"); +.fi +.in +.SH AUTHOR +Attie Grande <attie@attie.co.uk> +.SH "SEE ALSO" +.BR libxbee (3), +.BR xbee_setup (3), +.BR xbee_newcon (3), +.BR xbee_getpacket (3) diff --git a/thirdParty/libxbee/man/man3/xbee_setup.3 b/thirdParty/libxbee/man/man3/xbee_setup.3 new file mode 100644 index 0000000000..2628c46f71 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_setup.3 @@ -0,0 +1,108 @@ +.\" libxbee - a C library to aid the use of Digi's Series 1 XBee modules +.\" running in API mode (AP=2). +.\" +.\" Copyright (C) 2009 Attie Grande (attie@attie.co.uk) +.\" +.\" This program is free software: you can redistribute it and/or modify +.\" it under the terms of the GNU General Public License as published by +.\" the Free Software Foundation, either version 3 of the License, or +.\" (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program. If not, see <http://www.gnu.org/licenses/>. +.TH XBEE_SETUP 3 2009-11-01 "GNU" "Linux Programmer's Manual" +.SH NAME +xbee_setup, xbee_setuplog, xbee_setupAPI, xbee_setuplogAPI +.SH SYNOPSIS +.B #include <xbee.h> +.sp +.BI "int xbee_setup(char *" path ", int " baudrate ");" +.sp +.BI "int xbee_setuplog(char *" path ", int " baudrate ", int " logfd ");" +.sp +.BI "int xbee_setupAPI(char *" path ", int " baudrate ", char " cmdSeq ", int " cmdTime ");" +.sp +.BI "int xbee_setuplogAPI(char *" path ", int " baudrate ", int " logfd ", char " cmdSeq ", int " cmdTime ");" +.ad b +.SH DESCRIPTION +.sp +.B A VERSION OF THIS FUNCTION MUST BE CALLED BEFORE ANY OTHER libxbee FUNCTION! +The +.BR xbee_setup () +function will setup libxbee so that it can handle an XBee. +It takes 2 arguments. +.sp +The argument +.I path +is the path to the serial port that the XBee is connected to (e.g. /dev/ttyUSB0). +.sp +The +.I baudrate +is the baud rate that the local XBee is configured to run at. The following are avaliable: +.in +2n +.nf +.B 1200 +.B 2400 +.B 4800 +.B 9600 +.B 19200 +.B 38400 +.B 57600 +.BR 115200 " - this is potentially unstable (read the XBee manual to find out why...)" +.fi +.in +.sp +Using +.BR xbee_setuplog () +is exactly the same, but instead you give an open file descriptor. All log messages will be written to this file (you can use stderr or stdout if you want!). NOTE: The file descriptor is +.BR dup ()'ed +before use, so you may close it immediately. Providing a value of +.B 0 +will disable the log output. +.sp +Using +.BR xbee_setupAPI () +is exactly the same, but instead you provide the 'Command Sequence' character and the 'Guard Time' that your local XBee has been configured with. +libxbee will then place your XBee in API mode 2, and when you call +.BR xbee_end () +it will return your XBee to its previous API mode. +.sp +Using +.BR xbee_setuplogAPI () +is simply a combination of +.BR xbee_setuplog () +and +.BR xbee_setupAPI () +.SH "RETURN VALUE" +If any error occures, +.B -1 +is returned. Otherwise +.B 0 +is returned. +.SH EXAMPLE +To setup libxbee to use /dev/ttyUSB0 at 57600 baud: +.in +4n +.nf +#include <xbee.h> +if (xbee_setup("/dev/ttyUSB0",57600) == -1) { + printf("Oh no...\n"); + exit(1); +} +.fi +.in +.SH NOTE +If libxbee is compiled with +.B DEBUG +defined, then the log output will ALWAYS be enabled. If no file descriptor is provided, then stderr will be used. +.SH AUTHOR +Attie Grande <attie@attie.co.uk> +.SH "SEE ALSO" +.BR libxbee (3), +.BR xbee_newcon (3), +.BR xbee_getpacket (3), +.BR xbee_senddata (3) diff --git a/thirdParty/libxbee/man/man3/xbee_setupAPI.3 b/thirdParty/libxbee/man/man3/xbee_setupAPI.3 new file mode 100644 index 0000000000..56a5fcac56 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_setupAPI.3 @@ -0,0 +1 @@ +.so man3/xbee_setup.3 diff --git a/thirdParty/libxbee/man/man3/xbee_setuplog.3 b/thirdParty/libxbee/man/man3/xbee_setuplog.3 new file mode 100644 index 0000000000..56a5fcac56 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_setuplog.3 @@ -0,0 +1 @@ +.so man3/xbee_setup.3 diff --git a/thirdParty/libxbee/man/man3/xbee_setuplogAPI.3 b/thirdParty/libxbee/man/man3/xbee_setuplogAPI.3 new file mode 100644 index 0000000000..56a5fcac56 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_setuplogAPI.3 @@ -0,0 +1 @@ +.so man3/xbee_setup.3 diff --git a/thirdParty/libxbee/man/man3/xbee_vsenddata.3 b/thirdParty/libxbee/man/man3/xbee_vsenddata.3 new file mode 100644 index 0000000000..b36885d854 --- /dev/null +++ b/thirdParty/libxbee/man/man3/xbee_vsenddata.3 @@ -0,0 +1 @@ +.so man3/xbee_senddata.3 diff --git a/thirdParty/libxbee/notes/Notepad++ Style.xml b/thirdParty/libxbee/notes/Notepad++ Style.xml new file mode 100644 index 0000000000..5e56ab9ce3 --- /dev/null +++ b/thirdParty/libxbee/notes/Notepad++ Style.xml @@ -0,0 +1,36 @@ +<NotepadPlus> + <UserLang name="libxbee" ext="xbl"> + <Settings> + <Global caseIgnored="no" /> + <TreatAsSymbol comment="no" commentLine="no" /> + <Prefix words1="no" words2="no" words3="no" words4="no" /> + </Settings> + <KeywordLists> + <Keywords name="Delimiters">000000</Keywords> + <Keywords name="Folder+"></Keywords> + <Keywords name="Folder-"></Keywords> + <Keywords name="Operators"></Keywords> + <Keywords name="Comment"></Keywords> + <Keywords name="Words1">_xbee_nsenddata(): xbee_send_pkt():</Keywords> + <Keywords name="Words2">xbee_listen():</Keywords> + <Keywords name="Words3">_xbee_logit():</Keywords> + <Keywords name="Words4">_xbee_getpacket():</Keywords> + </KeywordLists> + <Styles> + <WordsStyle name="DEFAULT" styleID="11" fgColor="000000" bgColor="FFFFFF" fontStyle="0" /> + <WordsStyle name="FOLDEROPEN" styleID="12" fgColor="000000" bgColor="FFFFFF" fontStyle="0" /> + <WordsStyle name="FOLDERCLOSE" styleID="13" fgColor="000000" bgColor="FFFFFF" fontStyle="0" /> + <WordsStyle name="KEYWORD1" styleID="5" fgColor="000000" bgColor="D1FFC8" fontStyle="0" /> + <WordsStyle name="KEYWORD2" styleID="6" fgColor="000000" bgColor="FFDBDB" fontStyle="0" /> + <WordsStyle name="KEYWORD3" styleID="7" fgColor="000000" bgColor="C7D0FE" fontStyle="0" /> + <WordsStyle name="KEYWORD4" styleID="8" fgColor="000000" bgColor="FFC1C1" fontStyle="0" /> + <WordsStyle name="COMMENT" styleID="1" fgColor="000000" bgColor="FFFFFF" fontStyle="0" /> + <WordsStyle name="COMMENT LINE" styleID="2" fgColor="000000" bgColor="FFFFFF" fontStyle="0" /> + <WordsStyle name="NUMBER" styleID="4" fgColor="000000" bgColor="FFFFFF" fontStyle="0" /> + <WordsStyle name="OPERATOR" styleID="10" fgColor="000000" bgColor="FFFFFF" fontStyle="0" /> + <WordsStyle name="DELIMINER1" styleID="14" fgColor="000000" bgColor="FFFFFF" fontStyle="0" /> + <WordsStyle name="DELIMINER2" styleID="15" fgColor="000000" bgColor="FFFFFF" fontStyle="0" /> + <WordsStyle name="DELIMINER3" styleID="16" fgColor="000000" bgColor="FFFFFF" fontStyle="0" /> + </Styles> + </UserLang> +</NotepadPlus> diff --git a/thirdParty/libxbee/notes/v1-v2.txt b/thirdParty/libxbee/notes/v1-v2.txt new file mode 100644 index 0000000000..cb2e1c923d --- /dev/null +++ b/thirdParty/libxbee/notes/v1-v2.txt @@ -0,0 +1,29 @@ +XBee +0x8A* Modem Status +0x08* AT Command +0x09* AT Command (Queue) +0x88* AT Command Response +0x17* Remote AT Command Request +0x97* Remote AT Command Response +0x00* Tx Request (64-bit) +0x01* Tx Request (16-bit) +0x89* Tx Status +0x80* Rx Data (64-bit) +0x81* Rx Data (16-bit) + +XBee 2.5 +0x8A* Modem Status +0x08* AT Command +0x09* AT Command (Queue) +0x88* AT Command Response +0x17* Remote AT Command Request +0x97* Remote AT Command Response +0x10* ZigBee Transmit Request +0x11 Explicit Addressing ZigBee Command Frame +0x8B* ZigBee Transmit Status +0x90* ZigBee Recieve Packet +0x91 ZigBee Explicit Rx +0x92 ZigBee IO Data Sample Rx +0x94 Xbee Sensor Read +0x95 Node Identification + diff --git a/thirdParty/libxbee/pdf/api.c.pdf b/thirdParty/libxbee/pdf/api.c.pdf new file mode 100644 index 0000000000000000000000000000000000000000..dc8c75af3cb7130fa8716de8a733fd3a3fe13ba3 GIT binary patch literal 75665 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�s>|Zu(J<VmIE1!%K#P%2}44m2#72cAtNIsBZrVhNXyFu?g&7X gll=c{m}0iu-O(0qXlxjO0DL7R*_ku)=M~8Q531BBCjbBd literal 0 HcmV?d00001 diff --git a/thirdParty/libxbee/pdf/api.h.pdf b/thirdParty/libxbee/pdf/api.h.pdf new file mode 100644 index 0000000000000000000000000000000000000000..43d99a493e1864ab981612be1960ae6e71117f56 GIT binary patch literal 11188 zcmcgyc|4Ts+qXrHEFoLeAX&o9SO;Se24!DE)|tUDjAcZ&ELlQ`?2^b9sjQK`B>PU5 zgou)CB};f8s&hK0^S<x-eBR&Zeg2tyuIJjn*L~mDb3YHSjxtIZCL#{vZTT3J1(E<m z!2}xz5CQ?wz&hIz?ZJ`&MGu0);fYu`Fa(9SCSsMbXaWX{M1tIjZdhw4kXL%=B`5dM zC(OHD4|_0npW?L0y(@3Kd5Wm3w>wXOFr!`XXx|1LsY`lgGA7<SE`OEx0-4QW*&F5q z#8eWuF8An@obM4O3H2m+Fv+a^jyuuVah<~@Z3w&p-hDH)d;jh?vdpVdpBj1<F3q&j zQO2ik$x*Pburu)lH0ODiZ`EEsK~g5ap}iQum0B4d>iR$n3}0h(Wn;LLsWji_2vw!& z>g3(^dzIW4BO5%L$By?Jc=nR94on$HElm*>X`Fm6mZDt!MqpT{=FU<?fZIesI%(1) z#I^R*Q6*MKoih|<+nY#y)xOzt%)oRbRvqb}t>(<Sd!JMV1*2$>BpSoiPGkgo7$jYZ z5x<Vdts?>+QOGyklFEM;aaYQxN!r*_k^R-%NfPNziFubC!V{9oORK7f1MN4nzFM0( zuDVr*A0D@R-bYClows#wGj}q5hMB|bJ|nG1_G9pv!6lN8rnHtcFbP!yRm-aRG@mv& zGVoNiq9jcNf<^&By7X*pd6?;Q@ady^q<gb!-}=lE8QnodYRQq%+HdFI=`x`z!BGm^ zC1)2YC#xswzVX#f5b!W<_qFLSxCdRdU$6Qdc@M9<dcJ84cc$p1<x(UmsoXMtBb?H* zZpV1H78Y@0ZO>wf5cp1-_<AHrCOK5#iT3o^^Lp~>+0)1T5?{oBY}5`?T4w5QREz35 z%^HSFye73KL}E>OO|}z$^ESO!Mupd;^MaYRok-JpH`-Eg)dk+j)y}ZBv&&rJLC^05 zwr_R{aRm0eFewMwSw1-{uby|s->GrE!urB3Mm9&w7Lb<BRMedi*U!upckQ(sD#7Z_ zJ_=Emqt`3JS`iHv<R`2sB43vDf-f*&>(7AelI(*V<h{wn<juH?Z{!&+2wq<}%wlhT zNT9D8LlB~R6oqAf6KQb=WJf_qH-)EkUe!qLup?A9KFnzsELI@7^E5by#hAPYxd%d4 z`qZv(PA<p>#%iK_*?p;*{JlKosY7J5)|%(LGL%mdf^){Kx@BtL#*pRt4ahCh)`7em z)ID7$-hXXuRiP_u#6FdpKWTZp!e?^zzUP(RCGmh{ehd}Gn9hjgfN(Z3jxUVW@GW@l znMrkm&h6a%<h;U*mMYx2S>$$T=$HCK++3=P8=AyBbSRtYjqT?n?;1=Ki@CQ;FLrpx zAp;+A7-sENGtxJYn8il;<26e^?mimv_42YGN3EgK$0hAR(oVY-65q-Z=2`VPk>SF6 z0l_Gz(slYXCAZP359L@z_@)}u<QHsizm}h*AG$iS_jS^<6wE*+_U?K@G!LC_)r@P0 z9BLqF!)Br4&@mQfWo?;|fgn~?_Q<8<haN`s@KEbpVNE;_^SwI$2}aB2kqBAkx4`d2 z^CR-6L^92AlC*DMe6EbsP!#Dr;_yh*;TB7RPPXPqCQ9jogL1h+>WO#Kf{|)mk@+h3 zlNXFs5@6UsL2}`O)%dYh1L=&ch~xRwk_B#7SOc8CWPV?du!*|LaUEXe!qgRxv~hlj z;1nvYr13_mvnEPc@~k$^vsCusGZJl)=kt4W@jBUe%@pI5XBQ|?*K=Q#s^3`6VsI!E zI5A*9Z^S-<@;`)AGAP#s4N5*XaS|&kTx^9W*T^7~ijuui$3tmP$B}o0^X*)_1r9}Y z4n}s4P4fpmJx9;BJf&k_^LA=^@GiLHgfCi1-d~CSSXp08r_`i^Z(xaF4A%qBaLvWc z+I)<b!cbXopmS%o&cMCdIf{9E=WtDDAOkKy1}0HTl`|GN*1Vk7yBUS8j|*nXSUh0z zVZ94gt#;~Y$6@_4R#r-Hc+CgTnbYQRCx-jSq5BcvSK~mpottKzAM%sbB&+{cgfh<u zqzlVgJgzY2U~p&+69K2AUWO@e?X5NOAjd@&-juf&8HXsV6OcKbLN(NFd9=f$sjmix zMkBqU7c8}Jyp1?FdU4c=>p`56(t?clreSqfu0|o=Mjz`45me{0)x@5dADV-*x6mCo zaJnVv#$To$4P?>{$m9%=$wQTo^1U}ymu=kZm3(xMK%S4jRv~|V-?p>SJ2+r;9Nc4J z&~&t-LeVOd<+$SJb|lk#IWh<L7zH0)x-8d=6{)BN9}3z0BdeySN-T~+tGuKJtBHMc zX-@}o5xg13gYSxASQSz>m%9O7qgRPq)p@tw@W-^N4IC&0N$T@yn3q?w<XJ5~Hws$H z`>)0#93Ou0x&1WF3PJnAhc}y8-j^+zkg<Nw{yM`Ns+cz_XArjWHdyDGrBWeG)PLvo zA=n<P+3*+6Iff>+A|1-QZ?_p}vCgUXt9(v$^toh8a!=1tW^9Y)BxQe|oWQYmo@#%` zJj@U~dMjWwQqV2(;n@cB*~HM|)0JhyW>q;;VRxR+eYn@Oz-{dk!Vqr~E}Q|{Deao< zzGb4(`dser)De+16N3e1TYWwUNZVpSfmgVZ@zFhvTLOUB#&cKGEq#%Y3+zMeAtM9) zqmgm!Du=Ea$aRChAWBWUl^&Lu1-?iOF$<*h?s@9%#~DL!apN3kxckQWl}7x8FE_oB zTEgw8+R}!gt$Ti>kY@>{N6Fr4RH+rYY=x7%gQRWOhNv#PVxO~_oqaxgqwnpv=C2<` zZiZBeef^@LAhh+GwYpf|Vu^f(^BZ|XOFW}F&c*J^w`*6<&aJ_3sk&VDK{B{IT*lXJ zs<U?MLnE^JSzDi3gMF&$`uftOZ07R^BgcfK%UA}Z5VmtB2<h_@pOdn+?7X~P$B~>B zRJ`Y>jt30{>Tk?fn>sc%W4fK3&CzXz=xFCxPbZGKvv0Av*LLMG$WmlnjA1!;<Xxt1 zv=Chu=o5Y@Dj7cLsw#>2R>AX0{Il36WJ1A1CeJh6t+y**nBQh;Lpzru60f#piVEH= zUwx%8XRt0~#}cenz$X4C*X((`c4kJYb!qfiQ4;Kav4vzskqecSi?IW($Ex7VYZRw$ zzKbs6V0ae-N*yc8ylHHH$O&(f*#~IJFt1rkr`Zl(pS*7w*QTPD6^$cg_W5Y#pw|SL zr(8V@WKNt!j~q*2m&tQm&JmB<jH(V-O}IA^$~O2|fRFy6mKLj-<de5&-GchFKUr<m z32$ucNz!PlWjzXX#PL5V72u~Y)Y94KLHja#*7l93#41lX&2;5vDwN46TH{A1ql*uN zo)@;uGRD1>ExRt8X6Hm-@Tus=V{EW2jrnA;@5E1uEu|+iU+e%0TAya=QXgHnZTzw5 zV#DRp^%S)JHrJ)w>tYo}P^w51V^a5JHurlCmtLFb`g^pPkKD1u*NB~$i=y6MgH-s_ zUD-@0Nl3pbyONV3+A$Km;I`D#!d2DZfJ^L99a&Isze8rC%(W-<)`k7X8zGBYeX05l zH>ys7dAZ@-3HQQypJIvfyqjUq`akJrL@u^}T1HpNDo58T&WsumwXmuz9FBY};;R`N z;V;T&^!YBelCV7N2oxFF;dq(;Ay=WoVr2<KIq)PwBj8LZKA)E9PAG2uW9OFmeBZO% zsPr||YeAbKzH3s~zSSc%s>kWwMy8KF@>S6prd64nflLVVC1{uLk(=80Yh#@;KYCJN zwBN_>cdz@uqLR{Z&<`5yC-KiF7bf*@y4+?{C&HK{{q84AMXOWqSj(SzsvlXuyI7K` zGL%ywOJNUEdOWLK$dgynCwX@LjVF`3dg82e`Ngv;JSqsz&2hOF*|@Fn<#2G(Zpy;v zVo$HByJ?1W+4>t-`?p{5RFQ}#z323nq~x-cW9|0Yk_)1sMx`?-PrWyPc=gnTa`?%p zy$>{prmj$ncX<1S_AXh2Y$!5fc|M+H6KqvGf0kjQCEM)F24>vn^|R~%s#_FLW^U-} z<L7E>PqI0(#XofVkoh?~d#{-vesYUP=+J7)ORn@h*Ekh1;!b#mtqI57esK+3-RSG? zaqYAM?O{jrEkm!PR9cU<-=ywP4OFGMzc$VtrcuseK@qMqxEbpvJ)M!SBwrKIxQS{y zHKmZnwQ{TDX&oenHk9El^4!Sjr<&O=mzf`mimPQoMphcPSK2KCUf9*HkYMC^wqu;< zw|9FRyIqb9G_xi{UqF+sPs5W_v!+{{-&dOUFIF6K*=3jAP~+C#s<JjV*@AYSr`n_H zFXAc^xpTwoF124(bXKdAsFGzl+E@H&Sqj;uWC51cmPq@!yFxxiBm7|0a^ANp7-%h@ zo-{MzH2Bg~k^yB9E*tN(b26I(6y8J1*lpKalcO0WXmFh~#)eL876CeT|HXA_9<nBZ zu*bEVX7CTUw|Pv7$dvRt?`>bv5jN0WJ=Yx4$ZJ+{42G;GIq!#t2wYs{b!-K%R$Kx? zmxC$8WP`2Gy(jk%K!VwYSxvB`F?8~+31Oe1ThPMAsFt+^LKOG$^J^oIqh%@Om~OUI zALU1_^{PY~4lv~PmRZt%(2+Dh0ZNo#Y|R%n(n3uLuzi7Y#P;&*VKma7@XLg#KjBG6 z-3;2SI+FX5=?rtU6}t+^wk(}MvPh-V-B2p(xqax9{4Syj?&Iz6zgp<+vnjAswB{?q zjAyw}{wg-6Z8XrTW+%k3AZb#>kxIZLD<aNhyyWtu`|F6|g0{xX=64oMH9ern(;;2@ z6#X83^c~ev%&lK$khL`Zi56n1J(I`|=a{dTgmlS{p~FZf%v5k3B0W2zow4lNK2)N% z94{AWnHI`-UMn&C1y1`vu4yF{9y9HVs;`C1Dw4+*Nc!B?BfTKSm}huTNM`_Z8A*Q2 z|8;<3DQRB&J!b_yGu6Pu><teO6-jqy#nERa#+#-~I@ayQI@#MUWP!;vc4HG#%UR!W zGZ#mCq`p7oe(U`MZtSD?t6Z(o3)E)k99rv$XID~h)CV!?K1Lqi%6aBs&?5^HOm3jj z)suiVFK{k|VcNI1Y!`Qg$Dvss{ypsSM!mNgDyEn143h~X#|4%O`?8Lx=czE+MMv-# z9?qd_eW9V?c!=q)e_rNbZX#n3>X@mBt#-F1o|1+}run*`s`MKNvVxJc`D{u-`*JVr zlMDGmhsU1`2<oY|te6A+Kg!{fZRZIg`8wvl20xn%ToP{)S)1H7Y=f8G*~l@6NG@Yi zZy?)lP8>EW<v5>ZUvX}P!CVy@Z1=%gt;gZWnq_|O@Jo$eTcmP7l(aVu&Q>l`n=C#? zam}Mz+v-K{UfHE<CN;18RH>Lrd5g-iT`{U;DrYE)7oTcgnooVIaMP|i-BCu8OmBn% ztbsqvn0!gQ$YHMrf#~5b4<_H~c^5JLz(kzx6!VC(oI-u3F`>Kb{;Hzkgsso^D&_(A z6kI+z;Lysh_8Hcp3q2oKkPhWE4~I&PM*O9jA7#BwoI4weW>%3*2{Ex3IU!Dd^?maf ze@+zn^hf^I4<%~#k{E-D_o1X;zOZj|nKVnOi#tjmG4(Ll2&z~z@`y!p3tI6%tPPe~ zueHuA+IY}EqaycifMDU-+P?l8dF41iv#wkGYe`-aks){Oj3<+i#o3z1u7+k_s&1z@ z8krEgw)jdtlwSuEU+S9Pk<_fIpSb+=B}0dM5^q#7gA+Pqo_JHeV99nCd;G4KJE!on z?P9*O!zn|0#i3x<3?0t;phbCqb%oc>4-G56Zj^J%UVlTTB6(%E<N3onT)1VUY`EpL znB9t_M}mFYv~l>Jy7Nd4pM}YG_*Rm!@<!+$r?1bU3sPa<q}tZIufCh17JYU#k~>Y~ zS@X0^x_@&1&aJICG`(O~mR<#N&t5B{lNA93Qcvx+{GiB%!&3R1FJ@Le1)IphPY*Y8 zHSY#Ln|txdnpt~{Z76?~fSFOmdGD4*jTMR2fI<~jVjK+Lb`t9Bz9=9HmsV-{AE)=d zR^?Nct}fgirP!f(FkL@5cl(2zM<zP4XElx1D)A%OUT!MN6lF*?ASx%Dnb<rTVTyV) zJ8+~ts)93r)<Z#9;I{6C%a2b=oZ5Sm_2V{{y?i$DId2b*^Wxx)!?A^?X@i#x3<G2) zqpYWIMYLHbeYBxg@ahVBp8o-?rqN9sgke;QWW77vBQl3$DnEQot0=c{*WXjBD&Wfa z^}rnd4p|*8-Fu)HjjLD*r^@i^4VzmFymUn*Z!up>2hwl(qG_IpC0JqY%2L=L&$b5W zQo1h=D*DGdU(lA@Mz)?Prj^v9MvUKeyg1n*flA;RW_8Ma;qab4yJ$M~z2xvrZOx}0 zYV7r+7QgNI2V436mJgE_7yY^Ai^6_8*Af-|H(Ne%utgX{G3*vwK7PsNSz^_`t<^_L zs}}S^ZR$+H!aB$xMB&1%2c^nYOoONQcGnY3RpO}KE63xlBe~y?T)CW)a{IRV2Rf3l z!wQ?|3BLA;O%Jk9Lvn{jnwQL%VovHwk*rCY1W8Fv=Ne=@N%``5kE=mV@*XRxP?w0$ zPRqAql9`!z^|fN5`PJMa8a{qxjdWLdot37KRtFT+P`QiGj8DYLcZGdj{p=}Kd&<Wp zx%X(c#(WSfg}@9wR3sW2k}2q2dXoGOo#obhlf(RTN-x>ej_A`P4cAIUawpf%dYKQe zkzF#nA}!2x=KRg-uSXekN)&edEF272&FO`fY+`9kDNY#NF^EYoL`v6pku;U8h-qxb zp804tKR0}?%HU1oGPDy8SGry^SBX5|)7;7y_Gm9A{tcn7^0hKU$Hg-mt-7K7aa756 zQ2`6>dBsL8K5F^NpI%)|W<8zqDFX*fOKKj{xZ21<-O_fxpUW9Tsv1?pFJVO0ts}y7 z<B4S<x22F#{7@TL5XZgj-K749*^DGbmxQ{;nVSo|PTUT!pPrsqULjM2Yc!hJ(uAPd z1!t#@Vlg42w~l>XC=wiX485jwQN4{xq5hVEb++za_n<F`GPt)@zMhplr)ez8@7k4@ zAqWAad8_v4=^4u*R5(2uc1}z%i;l9B4V#^9d<V@VGXtI~(7S3r_oYV8QlER#2_r4} zfh06H3}?FT>Eqrs1C1EcP&zEzrk=zJG4d>3XBT~EpC8<?QI}43oThrwQ{xgo-mt3J z>}^w&Y>CVZuFxIIW<QH^s+;Fno-3Go8w#&gqo2`7aJDcDC_5@&<26I1=^aJTaiZ_i zQ}VDii?g@#cQwUE^%27`rJGssK{l@Q*G4LN<i&X8;TvxKf%T`5(``}Qh09Vr=L>iW z&BU_A9ZlC=g^mt-;b20_-UC-YYmtp8HFxt5HKbp^RH-<{@^pmxxmAS#-xpuQ7e~gq zmg!-4G|iQ5!R)kQ+407L7WA;@2CbS&m>uY7Xqo`4N%11XQAV|U9#EbX117zo<mCRd z94!#}LlmF71vUDOPeEFikQRH(Te*I>vge@;O-HnH?sJHy;_1X=(Z+We-{!9izFv=f zV^IvT(7H+m8MZ;XyKzlemf7*%`o{e78b-b9^qJW*c58k+Oh{@vyX)n;Ni!AbG|F#w zCo?59nY)Rr;&OvnyvT`JizpP<$7ZTS;=O<jXUv=0`YmS!GnMg@{Cu#d{8cZXwcWQ= zU#60V-wqEa$=_(PHI2SftuLjH){CEX84xcyr`sQ1%CTDD;;LF(|L&cDZ=LQjjI4kw zbANt`&WW~slo5Y6yXy^IIS`ZEE79q)BWYR5em78~l7}Tjpw?+jlKlxI*+o9xs2c&L zSE+Nf%+oxepbu=+S)^I<;EdA&H+fedlGiGFHfcwsPUxUaoIgyrU+iwEf6w9plwll( zF2&R)0xP^?3l6y%UN(ngh*~!?0*{)x-VZw!dEd0WyV9c%!yCP|P(8}CtH@{NOq<d7 z;$v}v#&D#-AzSf;=Ux0+v5xwjwOdgWlWylb8TDZfOS?yI)>_R3oFRGDAo{^Gt@XY` zf#F<;21YK<So&*aiB^c;>_hI(e8@yw!lj@qgRF@;vb|1bQCGzGvRPL@9EtcC+x!JD zB4<{^_xd5TOK8vo=8GoBjHvPbNL~(#$NgN2%+v#`!3p`ksL$?(^}C<zY7-IhCtG91 zxTUBmD;NUQhLpJ)3kS^O&zBw+;yKOH{?g+909(68Kk3B^x~3%TbM?(373nVmhWQ4q z=c8)*6U0+Dj#CUq81%0Mw>ngHwBv@4D<+2o^1SHdgd6JCk91U{;+GYi6-DQ(Lr|ss zZMhY#){NbvUcCb6Ih&v~EKN~GtXv)9oZxGV!OJw(s4T{&+-B~*4^@va&8TQJ$D#MW z>Chxa&$OD<iH;=mXUFz>_@`J}STEz5&I;+jY-;Ge&}RnMZ4%XV0UPHDc$)h`g!Erj zTC-K*Y(shOrNo9s_PP*!OzmK!fDzPE@bZmbRF=r&nZat-ZsWRmwwH8N_OD+m(NM;~ z`oyz`axZl+wPo#yh@XqMza~00ShmPgz&O*ys_{kS_&Lw@JlmO8bHUdH19c3>%4B*; z4>$CZwB2`S*;Uev#eC_|GYwNNij%b?S&C&{NimV!pfl$fR2l1coZ>#cv2u7v&q{N9 zD&o^o<D%`U2wsy%Q*CV#&`Tq^<R1s*0<w0zaxQ-`z3#wYuvEx>Ct7~)%S>HuZi>)# zv#M-=xw`6<q|)Q8FY7fAMKk7+C9ND5GfHd-_&oaNNgrFS72JFA?s6^*k=b-^p_;$t zPT{we$IJW%ij^%f3>q^V?-Q-mj|Q!{I8qrI0lzwqR8$IOb4j*Bs&7`?OYb}Ke&QWd zwGS2Z?9f2>L`}JfqkYosWU^Cmqdqc$P*3liw~Kuadnrz1jxvF)h@;uH?fHY&XLWnG zi}MNfLyMjQR?6&wEkmPv9}#;ASQz43sF_7+iH%n{PUcpavZ4**8s)`l*vS&QXTwVT zBP+3jdmrac!(H#4bdQfBtQ|j!7Mg-GI3H<gi<mlddVryelzy=wXYKg3(3H?DVqxWO zMiC;8x%?Ws8EMGno8PJ0n|=vp?=TR4(+L!O*DU7+^jt#fT^B=#vllRg{+g~v@HJkK z&&uQFGr=Eh>qpsS^xiFcacUXX>g11#7<^OKb$IGBRzSMWAP%OCJ8zyuQguP*A%j&! zh0Zu91^%g=2^@JHM$&jXeePN9gVNhH3Qz@@Ii12b*p~`Ck0(v^IsC0D(ezG<D4j-% zM~|P)M^~w7Yc-zOXj>e#&&1@Inq3;L4kaQWOK!n{t>^pz$4i#TG2hkYQ%f?Lk!C}r zZ|bBCs5HhuhAv{H##^1e60N!d(G0^{st=KaEc5iQ^~@^~rvkR>F0wQry`NIX*HBbW zKX>3k*juzMOtx<=u)kED7`Afx1Ov4vGMbMxK~b=Qij&Vf<LsMt#>%eZ<w=^vDhM8F z!`v0dYraz^N6Q)B5?pC|m%MRL-hUnQ6??E+of3#X`kKuvN>5~V>U<SY7JM*GDwjAv z`Z}$q$7v+O5!bc1$T`dQsI>Ze@<zQH`t%!e7Zx^4HpDCg0udLTKD@9z?CxHPmn~@v zTZRT5JJpmuFc4tdpSAPMd^Bd>pSLiQVBC{|VLufEk^lDXGGbk5^JLTN*EzZB8OJf^ z>)k0{n|WeevOK)~HvUrCx=PQhTW!RgEKhf-@!TIH)W4jW;2!%-okGZfyqkU3?lQeu z&cfvGn3?>h)qY@}CDOxZ;q-fEotBC0;8@%!ynB6i3B~`|C}MM<OqVD8#NC}XZDVIl zs*$reyI)2U#rF0wjRzt28q_$6Eno@rvM?=W`;??E<8oReGc~u~<DR*EHRIJis)(L! z(ce1JgAVii;S*HiXD2HDXCrEG#RUt|v9`lPG_e?*^*MqU*bEBXmXMYJ!^K6-K@dFx z5qRASh5}q}SZ5+wY`<j%$XIuRhZ`E}4jf?VxDn9$SfUvOc#jK)7+}4KfSigKQC0sy z6!t>|MF7NM`^NP^z>8am67V0;=nme0;d?;(c{ujV8{q#J2jSmi`tG3gPjCKo@ZhxW zR}V$^bF`mUAo~9g4@G}Xq3A!P@ZjO%R}c3EzB>pY0)PxYK-nD(xq!pCgUvwSb-=!- z{vaGZkU1C#*<&B$eSCg`@rR-xdX%h*)_8*5PlZ1`)5H?3F~A+L=-<)YKi2#;Reux) z2%@c{35Fq&KP~;~Gel1cbZ{K{iyyyKtsWe702xFNCJKUme~8kP1|1*=(4ZjLK0bQD z5C($nKX&Q;qGw<7hd=*dWnah7yZ;9(2Y~(5^II$j2>!hLf3WgPDCex*vHSH4QN!Xd zV~IGl_4mTur-2~)9yY}NnZ92MK*ImPc0YAL{P;rwPy%i^tefyT0v_`(bo`RAKUDnT z!@pH>fY*QH$iML60OS8gTv*!%k8}0-9y{cJOvgd#{!nu;tA7^tp9#FEsqyop6quN_ zG!psas2?Hk<zkI?#1g?aSUa4v9N*H@dOk1?Bgbbfp$XM=QNr5e)V$rW`rcXwXm3Zf zG=@(e2|~zQ18)eh!d})c!nOxrx446`?r1q~B|Qxk_dbJ{jF*#(6EL^HUQT#tcNs4^ zz5@{%V7yO;@PQ9lh>mi67d3UjL;?Zth$DhUMWjVw!Z0x*u&tZ56V{X9<_Ly~Nb&(H z-7vN?dcZ>cT_NyKj?bP*bdiBTJUu-{JjFx^Zgvouw6rt?Dhd%56$Utj-LE(kt-XYu z-FX0e2aez_{vqb<E^^?L2%6vo!Ci#FM4*tLhLnMD+;A>L9Kjj9Z`j&~;6aq*lMsX1 z!qB4P!qTErSYa3pYa<K=E@5%FI938K3YCDtC4O3R`NhM(m;!D9w#0xG03#V-6T*0) zv2JpFsyZ5AReORv@w;g-Tto`S2l)~Cf50ICk$;XIfbmE02!KaMlYqh5UQq^iPoyXm z1`~#g35!7upfDLITm}j|yFY*;Ab;ZoAO}R1fNz?BZ=C*x=r5eVh!WfkfI>j3Y8isD z&Og!sz%L^H-QI!F4;}<$AD3U!@*hl;wTq_a|C}l(r~L}v=aW$;pgo*`en4IMU)INe z5K;{K4>w&r-0%le0E32L@z{Nj+yPW!fS(w&j4i><$r>nNYZn(hu*UA!H3X<WJ|qIT zNyHKHSmeP3Q^XU$5AeAC2_u8IcD9q_^Ag5jZLK}<L_Va-Pgt})h%O$)?<nAL$nS## zamb%4ff0JYBnWQbwd!MCf2v0+5{Wo0Sk=wi8H4?sngh0dHGc^I1K0;7U_k(Ihy1bJ zAVJ{&(Dk2F^yeB2Gz@Zlp8G2(F#7Au)?aqCpDP0YKP?CXK>xX)Q2@aGX~wTCvp+|n zVq#Dz3<^J(o_tU!AHW7o<Nt-jU>|q>zaa`pDtZv@32ywq0`$`?K>mGl3jEOudAVV2 zK~S)$BxrwG{C<HYB_zZoz_#EYG&ocmXqfgdu=5WZ;QxNB`WG4y%zk_KSDKWB*l&D5 z;6Us4S3XfG_}^_n;V=oH@AxYpTmt%=EL>6yXyN|GCk6e@E?i0y=pp{bC-Dz7U{Csu zPgL|b8ldhs8=`RNZ*hpj_mAoSW>*Xfw2ObIiTy^Cg8!Zaak$uTd6AO%J*RN--+h6L zi~Z&w9ANy@7owXr4v%#M9yq`deVjKIs0}diY(@Z{sP_9?Fht$imH<9zg+UN?Ww04S zT2dSad~$G3MOjKoSw&n71%*qgh@qrJfnRAAX$j>2&SAd)9N<p0b|W4XBn;S>fsb@~ JRkTr{{{nlBI;Q{t literal 0 HcmV?d00001 diff --git a/thirdParty/libxbee/pdf/main.c.pdf b/thirdParty/libxbee/pdf/main.c.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4410e6b8e4d9f3a95779694316ce6943da6202e7 GIT binary patch literal 8923 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 literal 0 HcmV?d00001 diff --git a/thirdParty/libxbee/pdf/xbee.h.pdf b/thirdParty/libxbee/pdf/xbee.h.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a4ee0d754dea35167f2c622db520a173d2fcd0e6 GIT binary patch literal 11925 zcmch71yq#X_BT?>NP~b<1JX4?4K;Lkw=lra&5$BUNQ0ChU4k?cf*=yok}8dYAfSXu zhah|d>U(`(@BjbZwZ6N)XR#J%_StpzZ=ZAad7i_pAtT2P;o$=?_pIN~2k-;IKo<*p zfT$=)1?g;qvIPpDDOw;oJ4Y1K9SD+hM4*r|NJ|$hBpeR#K)E9kP5__GE@LN;X$8{L zp{mdQx?e0(3DU2>m~O1-FlSvqa-?TTRb@6##>YgFka9-CD$9<)P86hF+Op7c=!=+) zlPCySUdaxijue-0ARajsKRR>ObJ*v4$i!bU|Cx}PP{qD;<gVrkKmQXh(~!xsSO;9u z1)%X;u8g+lj`0=q5mWB|8qYsj@Wl$rMD@v0vCwI9EZH7K?>ye9y&uUV&RpMYKJoZU z=#{`x1v%Wsz>e!Cy9x1w;-5c0SYV<WwS!UMbgm5B?}>OXT(YYvI1RLa99CrWX>+uA zzcFCxGTnfsxXO#y*NFkGO$@~3R@v9Fmum~OgFULLADw=0-?{O&VD7ke!GtS(YprW3 zDB}@0TJCf*RZ4gkoKfIm4d%fP@>F&JN8`O~$|!0%I9PYFq~fPAJBqg+o~OK-psh3z z7V9U@Jmngh6)V|TPt~!G+vS@{%1JFVba=Nv;ES2<H8P=emIe_^m78TDv(N9?eEjqv zMyYxtxm-|XG$f(qnQt>hC|?i-^Q?({&FibB_~BD19R}uEP;H2|Yu?~om-7j>9d@O7 zFlx1(aSM1ux+mvQoYnPfS4%4J#D&s_gyRm0PamCQJ<;vGC`!cVaI#Hl+xMQ0CPXcx z#@>MiW^p%ecdn)Rh_+OY#nu+&<Vf4g?>wH&QPEDGK6MY})b_wIdUv|X<JE!h?4ao{ zG>zqCJ>uy=WFNT7`s`VO;`$H<Q4eI5E3$i~fcm!0CONlxM8DX+TtH&?X$Rw8oBE~4 zZ(}T~^K<qG+GZacC)Y|CxmkCNM%&;uFb3{yEMqnANP)bto*9c`pAuJo&!f!GGR@>U zV@mV8=`$JrWxZpWO+Rz(#UenTM6Fx(JDcdG;hr6c|IPyT9G3P@ViGKfZ5G?>hR!82 zC$h90o!)m5CRGp_kGQZRuMXB2;uV0KgV<8xRn|(fCd9aCZ;_$?IQ16JK%+{5ko}#g zBuNp`Z;}{9X{@o7?S1e=ZtuR2jF|rG`*U*vpQYE9$^0Gn{3<d|AA86sJSNHBYw^XL z%NfMN54-!SXDkbz7kALUdTf5?JLS+SpE)jj&@^)vx*SyIe73xON>}N8dnEX|Ue%ma z;4|mF4;#{7H}+3!E>W>P!)(4&+zlTUD??=pU9K!mNNoy;U*|7IY1gbg_AOWc9D&CH zrfMJkzMLmbD0W6&I(&}-H;!Ips0Gi_*N$$AfHB7Joqxm=Bi-WG4XT%HVnNt@hhFJL zJGIt3TU*r-Jjz(MY(A`@OuoP=<-mS*{m(svx-BnnAk2dGYjigdxPH$SJ+p7aC)k@7 zOG@naTCJxHttG5AJ6yp}(>fW1huv8CX$N`?asBt#TksVGp}Do`vhV3F>!@2FCd4-S zvtM<Oe3zeIh?p7y7q_o*RphP2P#HW!ie`(yxZjHlqaXo%Yl!aeZ$AzWV+iBJFL?vD zpzy4VqW8lgxQWz7P~n+IA^3QcWLHWZSLh3}4DNYBX_SRWqWjW@v;Zf}Hu)1a=2HgP zoQ~CR<UmD|SGt}SJ-Smu?^8{(ev|yr{BB>77*%s-G-A;)8abjaPCLohIqosdWlybC z9%h>5#8%jNPvCI!1!8x}1i!{Qqa4&7r_JINbJ_2~R$G0oudf>yU@P^WQwrHriu$y^ z;=w_LeVB6vVQ6)>$T6#d)pcpf*1jmuvGD~2Ij%a`q_di`=!7kOuo~ohMO5>i>GAx6 z$k(<H1@zEwMFwqxT=Lcy1xnFThNCZBb%4FfQWnbL>D1Q;N)vMwt#CPYF4bffOH<yk z7*yJ9H-`~X;GJ>Xa)$sMrj9B~ma>!b)(8u!jkSlfzw_$N8*2mJ9ml=!HW=a3(z_NU zBh_lxDoQ~dyG)LGHi+3`$34ThOaEBu?6slYR#2osnBCe|knU7uu4T$NBZuKN6eGY7 z{A}Zv)fa`eO5-|aNQA8-RRyDr!sf2s#<hkRa@@;H?Ozy!T4e*~XQiWraa&l$ABGj| zaOoMaP_%OBJyCitJIKMQ_c@O3^}`kt&eHM+DC1G302n?+L8^=KhbE1D!i+kaSyuMX z4T{3<9~CXXDNAZk<*!>(Bk9X(*56jVc?D-KO{`H5qWpSP5-I6PnL5!*tw`0kQtgZX z_%Jx%c%Vs9_N;TAgEIZ0EIXvVJU{*#L{h3%wK+{BN3L35l#43g)k+PgD+Ci%=%ew{ zJX_6jn3ljgdh{5saP(q@>stQ-BP}&5EpDwz569aSl<=Iqei0t?G9j1eS@eNOaS}%{ zZ-LCJ)?}hzlOGd9K_z@vvL!0m@G&#RfD)CtL@$|H;xK%!JyW+m(|{S8`tn2R?K{5B zAxD!$&9tN96MG!q)}E>x1Gs(tNg7@~GK#{Eu|OqmJZ|OCu`<`{Hk!t%QvE53Uc+Qf zE;h|;<W~XTzQ~Ky$lh0+*9sEK4;dK*1czgSn0?p~BO9K_@4eRiTmz>zyj@%ZOgId5 zT^kf5-xY#w=Vnn&nY$n6DsDA+y4^Vn(aMXWwcTAIEm1~nws^jkY%&(IR4>tx^^Hl$ zmD$#stX<4uzZSz0WoeykK*Na`h6dK_fJ@(PTQ_OG6fjMB@}L-N0+6=tX=ziT(X3;h zzsqlXdW7hvClTE=Dzq2zgxvO3?D6SNNwfmLe45istvYZEULReib?u4!5zosi#4c5~ zm4nVI!|nKVm#^2CzkLASXp$@oWSj^LFr_yS?;AZ#9N~M))LkvIlRLxSe4|)eX5Q9d z&EL|6qL7Ys$f4(!eUBl%>cD03FD1$xuL++T98E)(EVGO1hbBhLK5;JV@t8?t(<YUF z^~^wpH;Oo~X6r2D>j*Y{-U%--{u0R4wb#aF=Uv~iagB`9<2Lhx4yt&$`wsit$!d(I z21b|_)&Omk7S?J}A!fK;)qUmGxyQ~;3hs#lQdiI511k7Nan;Epr(aDl3>G(!q8~DE zbh9Haw}zD6y^2J*UH0x{NDb2uH}>{e(`&)3<|vkkxV6xoPU_`zRp|p$EM-Ss8!caO zkzoySMXX51<y)r)2CoJ5=fY}s0pDm|u0vrqvMq^E<qVVWe=9Al)+5<`qB*yCpOkF1 zIQNWNqW^9RAvZ2JfE$yWKv+Osp7yFR3kv`9=Mlt6-U!3U>s(hO;KEFKF^<P$id%E5 zT37QiZiPmQv+vg3-q%Pc^)|TAoc{EUtyr3z+ohbr4N;IU%EiWcd(VHYkiO38+WnHU zK0d(>?oIuJ`a>nA8nfzhrSA#xnc~i8&Gq8;+fx|*m80}sd`dg=PREymLXHYLdAjJY z-QW1qn{!w~ovHu%zB{yP@jhYF)z>9&XleIj1ieOy7UKj10Bdb28QArDg}hOQ$xG4u z`wfyrOHrgv`06@bO%2YUabGXi9v%DY#@Vh_t%RqXOqZ#Si&(xknVQo7w&sN+mZE79 zjno-MTxS+AkZWm84^&OPJd^dnRMw_2b;4j}A9t*x=+*3d9a=UE=;MKizIu8Cm`<nF zYISsew6>dqQGur8DhE94l90G-?<1iH7QO!4q_$F26+L};r{BfRFuKK&&Q?FGP;~3O zay_qC&;LUOV0?g|G{`UFzsg#O;D1ur4w^c-%)m%bv&|$w+<neu^W2|=9U>dlU+*pJ zP5HjQFQAk%%%VS%r+(eYJ!5wM^mt3RXq{=2;JTYBUp2QKti#tD#!JI)hC#!Cu_V58 zyGhh<iydcTkA!9`)UvaEk0hU%nCq1H${W5Qb8VWz`)r3SYOjDQyx6m)Nl>;SgZfXP zI3A|!SMcP+VuVAWTZER<mzyY`hx3e1utDbX2TWY&8Z3a2m#H@&g<e{oK;Z>EBgaH; zM=QG(!mqF`-^{iEb~l>P(FXQbUA=1-pVS{nPr$A+3URab+C4fnTgt~+Q#Iu8TE_?C z2MloD#b)r5BQXG}hbe3(#*S>g*VT-1RttE3qPdyq&R8{(3fgYE)IV09nHtucVNvR{ zXp^kKXz_vR-pxc(u?@FbKI9hBo(G?4Y<<IaGG)%QW`irx&WKnj<g4@}H9^ZV5A63U zIZ5#(<o@`YrO3X?slIqgAN;!(J2|QH^!I{^8L$D7a(pB=dUC%nzn$rcbEeC7X}4M) z5>%EmP{Gr!eNnNx-Na#?XgnB%(PlYai)m<oWr4(@FNijaj!6<s%lu^$^O|}pW`SmX zl0}N(QTPn*!&HerWql|Mu#d_$)Rp=6=4Z>qJRWhX=e6G!$df%ZD%yxM&4NAQFSu{G zep~2!L(1`(+cNPPhQ*C*5$Un!5`2sK7_Vb!F(UM$mN)YIGMt>+*n)~rEV?^=q@6_- zDRhJEZs-JsnULe8S7Wh_C^1l^TQt6%#{w*BUhA#N1)$~GMq+3sg7l(Pt4;X3j+P22 zdJ#G}T6DilZEaB6Fb8S`u~lLs3~*jX07BczZ67^US@mpTXCW(-@Xu|tj2m9`Ug#K> zPkk(v!&C~#BP>;y=81w2PQK0X|Cpz-90i$M>|c1Fkt$NKE?6&D5}G<M*E!BuBmjD$ z(eFL`nx93uX<1Q+$zC9s;dOj;une!)6(%Fd_VS+l{`IqcC<iHlAT86ztyu+`NXFrn z?C2Qdz`KYwBCy5x_83~shk7waLX17qa+g>h@qp(RRq0;IlBNc<)+BV|#Kfx(^ZQ)V zTPrfrecI3kapvF@wMTY6A$irw)kwu+-9u<@Q9<R|VgiaX>Pe)D#B)drD&8Yc!Krv` z;I27p-A$M$z}fvcI@%i~a@7iZ*tU^mR=TCm2EW0oR)>-vrmwsYCXqIBWu$sK-exdj z6v9l2lV!b5{JG8|bJ&`?^IZfKSC~LB%TokjIFD41b@@uZvkbe=jce)TIQNPeC~?x! z%p-Lc3br+i9u$=6VHux-t%C{p`rv#8Me{M(svX>oY$HtVZ#MPt8{dDsKHodSv}l+Y zNrt7`L^N0&36qv2b5rI4@M#vy-PHp`4#;Z0PhyH-Fn-z>c3*Mlj_Ihxsej36F*%nS zSzqT|Oup|y)SeTTTG>M7Yf74%*fSm^tJ!6>*ETmOojBiUnLH6~O~_4-W-nr|lY8?n znZH*s<3!})^0j9icjF%wTX*4`+_^l{R9-1rIczVmw7c(E#emCfNIeeltrm0czP6m7 z;X=r1G2}pSEAlmE^cc$DB=wA4Z)dAIYi0}YP-ODhNWB2&&T;=UJ~95K8#%p!vvO+e z<7whjURVo(w0yZT_68?K+uknwl4N}}ujv$|P<jJ7Ty`mVyiYp6J@rtV4qCIW&H6U& z%Xts82c`Seg^=sk=a{TLj&i*lMGT#T5q!6#9az5vdM43&?I@E!wUyNz$$!91X(?1= zc?^=TAde+nh~05$sCj;sEXt@QA8dQ{Dls}=f~u6Z_yMB}+&S85o((Kl>@Y=Ac1YQ$ z#(i^k#lCT%%#fg7SDUBp$N{Lg(NugQOt4h?aC4wCN|QPZpFS_wuCMEE5$z0pdIkC5 z`;3~QDvGY7wH&%#ZkYWRq%W9)9*rVkK#E`ZsTQBNxTD^YBggT~$0LgVxJ_>T6xxJK z<!#|R2dCLgA>BzIiV2Lv?z>9FOgusM5MGkG*;P*bdUf?!w)&wwjzvakibr)kKUP8v z1&49-tH%us9Ywu1AB-Cf4C40i%1Swk+*y6Z5rbN+)NSg@246UH1iNsr+-kG03>!23 z&i|~hm4Y#ihvUg?d6BGXwEy&s<3m+tx6u|@hdj6zvGr|Xee%*kx6&3jDC5Y!AZ0GX zx?{Qp)~7*$tqjOb1a0kqKT^kS9%QLnMH)`L)Hz{Lio9n#s`O(1CY6j`v(gJ%5e%6M z^7nf0>dCx8a*tXIz@<@{F#9DD21(Aj6ccjYBy(=t3aWZ#eTRoa-(rn`O0FZA3CxtT z4lo0KZO*V#;>L_-&2i$6SOaMTXfp>jMtF%i4rJ%jQ57ZI(>2*q_tg21hij$&!sNQ1 z<64*>KWbAyic=qGxpzfL{j!(kN0k2?Z(E6kjy#PrE8=3XUrU9~ll3Z1+cFuL^8<w) z5~+ePQro>F4?{uF*OErENmFR*OwqFpKBt;|_}8jzY_Wg@nt?_QvyiW?%i9|tRB9S7 z8FF>`KBv<4_Zp77QAZ*d^NPY(n+Gt=-<}v<%`#d2J+&be5GqT0Ps--T_Y}cyQwY<h zii3YEA@TE9B!tA;fLrVyY-MXfuus>D8?@7^h&orQ76-q*#J-HtPq1o7xa`|Vg~14~ zXvkQ@5E9FabW61Y&8AS_Rx=Lz2sZFmH}X$f{bHNA*GjAU<ZJ`*k^A~(qSbgSy%$GV z{)I9YgT#Eds-`N%YFU+C{ohrQl(vl!ZrFrQr%tB9O+O6|=GvqtvdhzB@J84SHAeug zMP?RN87w%Sf^XJ4C^3k>j1!kUH5PfpGt$11{MeK#Sme1ud1X!|&dWz|g25Kmo04Bf zvdhR&k0LCoZVX+L2qBq@v>42{u>%(njy6B)6D}n&$Qmw>{TO=Rz+nk52C*~}c&2V7 zBs%$Wx6WPK)n@4v{p^uZW8U?SSBQw)qIC~uO5$vnE=d%Wzl$QBcqRQA*9OHpgc5qr z*0Rfm-<}piNI&*jMBCJkryoiEkhpHfUqypFb*WXm++@7nx}mB+I6Npab>huR8N*D& zME*9Rgvhg;IVIDlvRlT}Glw6$7w7bn4FZ&V$Qc&rX~&8`KXPf6RiJuE5|w2bxft5$ zzz<JX1bX|w3L;Z$d_I;o>0Y`mCO9@w5dfbmb88F_ZfwzZCe0_zqe(BM>dKpH$Aa-G zbEHex;vb6C=_QA7VB2h*N=RiB*<7FPNz=bIY^z-3l3SuxP5X|>_PPsRS5R7*{PLVt zDB0qGQr!dX3U7wRgn2hkRlzcK-cOMMY>L^#)><_#ytlTB>aI&e;|3owc-cQ1q>_R- zvFv^Ig9=#Qi*(>+KuHt3;Y5+;zvhc@SBRqFr^mL%Tj$E$J<7yT-Y|r{IJw)@HU8$y z3|TP&g~&5ARa{c}I9Q8>@e@RQKc&X<fHId^uHFlbH^lEWRg;^O8cVl49Ij9Ik#?0Z zPd>d-)tuA|sN#%W8@J-rG(NF>epw+x-R{iz0Jhay`(P_Y<%v=*bFrwqrZ3+x(D2QZ z#c%taY);|(_EK-3gDS`co`#OTKY7KdlL*0k^9|7#+Hs!&hKG?`S12%xL%$t67IJ)O zpX@qO#2#b*HsbiE+At&F8EcwQd5Imlvfhe^IF`qieWyto*-Ey~lt-1Hr_$gR8LAF* zRP|5tA^VZw;P!ZO*D^K_gN)F-iLY6jhkK6+z4P9M)HNUCd=-wa=be*G(M~3xoW8vX z&(C5kT$RF4a9qhY>D(H+tkcy{(jvAK*?p7qO^U_WYm|-QR+kT4c64JerI^eW-y9P4 z%OBFMd2wL-BoJ!~BSx-(mL@BUDqWQI5ZW;NDH=|2H|FH}N!S%lF4kF%&Jt)Dmt0Td zY}!-HW61;${g^o%*#T(7s?3T<FvN3B&FsZ%1>>lM>S85<6v{w8dznWNI&GGW#P!|) z9Kwgsq(o!7s*bEQ#|e5Tp1&tvc;s8B&6`VNj~jeXLNl+BoQtCld#rqja^_oie?IA` z7L5p<#EGpw4|dkO``rrdnxr3EWGmvB%qg;k%2lOSLWE7|4xe2nm&ua9Got1`#K`pN zO1RPxccJU_OEvdfI=qnR$yy7fV$=A|r*ChU$*-zBoS?&Ok23(8^|B88pFK579&@Um zX$|Y$n&gsOjdLv?eXj+G;1%>dz)eTJISd*V<5_)Hc4ba2QjdTLQ8~lg?kGNE_U^fl zVifz5)QzxbnXoNfUbRSyZ|wzv*!~=ga!uFm^#=M^R}MByd)^uuF?{GzR32*2{^}R% z$UFP~5c}CfI{Gu+J3@CqCWUk<tVVQ>l620au!*85ZV3k;wn_So>vJo9VZhbWPO2>3 zCCMwllO-f;kb-&{enmZC=%j)5dV@~zmwGC{rXsCq_6PR`4z@oVx|@yCGCTH4?P|u? zW$kJU3Eff72MAwk3*l|aAbrACy0%<o8pP%;<wWuE`b^1L4gv9U0-fk-->@kD3q|m8 zu1NlU8%a&ZY`!+Ka#Ti!t_*(C>jNol4042{Ap30=>4+UZo)kI!%MVwu(r$kjyHr!K zXwTUNz9+MarTvmQ70eL9Sb5LqaMM!j9c9GBYSyHNuYq^O(tMnG=58ty1!hS*$<^#v z8%u9(pE*!8Sp^%!U|u75!zhL29WgRgE9q}qQ|dLct4>l!+#g}n8|=*(^!CWUc7VE8 z*Ii>Ve%9fjxGH4ADp7E-sCimoJ17Y{KEBvFvnTh#0^Wv|f99(E$))@e2>``3@ctyv zW%*MU;SvUkz<l7#LrK|GCJFu6@`nbrG#2^^CqBD@es_X~{y2?Z95c_4qr3vVe;r4m zkUze%K%xK9an#t@g;9_^;FG?=Y6mGfON&_zNO#PuP?vt1YgM^q1REFnyzR+Ad>zsE zuTRDH%}ImnVmci2F<$cK+!;C=8qD^`0ZU?}n;pPS_nbGd4U)wkvXz3h%wJ36V+QZh zhf7=mv<s{a-o_VQiDn9wV%%)M#gx}#F=o=beg_IBCcQ@!^CH;oJDz1YR!2rhp8CFn z%=-p~ChE95Wvp*_{l749;=8)My>@8#2q$qlI-#YO4jaEr1`mH%v_QA&>~>QxMk9lM z!SD-)kkPo6Jj1V5r&UK#tPH1?%9<%|2`Yb;2@E@6KtJ(hd1aVFl`Ko~+3=kdW+MH- z`|#DLS7Zmi?|td7D{m`(xU};w=p<A1%Z)Mao47LSDmW?;z`f@0b*0<u^2g~a(N+gt zChi`O2L_Ge8RSG0jJ`@+fxJCt9QZ2BtMV8V{Ai__><!~38uX<J5%kR`X)3#pGbaK1 z$Rs?fgP!lc)ux3HPHnq#%#s|0TcE99E8+n$0c&<D{<rrk5BiG_!t41NLnSIQLp4?D z@Y7v3;F&kxw>S%PSBZjYRbj-5#vLoj>uGC!{IP0oZDn0pZewkCF*@<nx~7Tdp72PL zPGQ{eP@(I06w4^o_1h;UktJAshMPs<03HENw5Nk|J!52mv%3uMv$@GxEUFGA2df=6 zAF8D^?kA#nTWXvm7}VLQIEGE$gf$-CptI!pa<|b$4pA8r*<*4U7Aa>+kt@6nFSlv) zM=NzVyccHMg$$N@pJh?Yghx0zFx@qu>PSa`&*l9@eDcy`O-8V#Qd!hZBxBU+-NrY* zJ@&g}uU!!JZz?$qvQ%o3X;~E-46$}JS_)SywV|JY<`N3g`ts^{L4=RTDW<Qw@nUp@ z(1V`|<uH$2DfD!RPatlfEWAzY^={p%BQ7M8(u*cH_VSky!ujcbQR|88Nqn4kX&^V? zD7>3V(SlJTi!-6#jn<T}-HH<XCJfL{qaqqC)TYQ3mKHT28DOTUS}HN^rAUD51yd5F zEnLZVF1^}>Aid{I$U^s?#(V&`P11{YNCtT87`Kh{)V6Q;RQB@7gi`<|pEMs}5Ung- zsI7ObN&0&WW(I(Oq`>H)8z%cA*JNT;I>oQjA$dNaXC}2UCEUc#EQNvyI2Lx){Pt>q zAh*(Ha+OV&HXhv@Qb+HD1K%SIy{Xd4)2n(b!lqVbj;1RKNWE1m!qV_&Y+cPd9@|E8 zPf1S2%h@Y7fn3{DNAJVtL*%0tGNA_Pd+A34BCXU?R5({@4nU>Wp}t&V6Z3_dyXM+X zFCH^=zU(%5LnvavvkJc@|JFaC{z?7)T@6ZSMB#X0&NttyGqdxaEM>IWUq0r&_l^&k zYu5_cDZ~tE^S8N87CfnT^<bl}w^UX5dtz2j9Esq)n#*_ebok4eR_{Jo;9jz1>s=zj zCg+n7%j&20wR<wgv1F{IyhY*wFZ8_{RA_H*R?C_+Z(XC~!p^|Zvp%IJgXF!&FlV7n zHx34b@yAG|&K)gBbQKqhsni)wV~q=|_8YeJmZ7Euri4b_+92QER~D{+R7e+8H7@uD zHFZjv>hgx=_BlhWG#Th6TV~fwi?%-<r)baf0F0@YY~OZtdXV)JVR|zO2Av$cC0$8x za9+@zE6nJOm%ZmNI?u8Qe2Q`{er1&`txH5UXd{}d&fP?7MiH&|JczEwGQ9eE5M=aL zjx%5S*KQ>C+c5;W-8zr|&B45W@U?Nv@{o5gW!|?BM!o;Oed2^SGw)YUHDqzDNA#IY z#n=YHWq|D2&`Nq&QFyJLjc9#RH>{fJK9C@YZ$$YE4<$vI2F)-eLL$%Rq;YV0_89M; zkzMS;PDnDlutM59T2;!mZGWuk?`lMzh8<&)5%Mtes+oPcD9O;fVey_mbnthZ&$30W zXP}_*3NK;N&xPJ0UkF2Un#Y`<_(Jm&Ub^Th&}8nF@MN2t<IC?{*<WA}i}uBi-o(DU za|I+TbKksuW9~bT*$~T-->o{=D>rg)O*6*`HkHf>VJGL2&oYNzp<C7D=%u21NeIQw zOHg|!s#QlONMvh=jB~HudsH5!I<t^KBSz$cAG!iBw2UAmk_C6t(jg&>-_DM>9DI|P z@?M&=fXU;jv=G*(4OlGkq@D4lT|RdXlWB%o8`S1ma#V^kmMZxIzYtba)rH4*!%ri( z&j@q!yPov(DwJAeN*ZaFl&@*vPkGpT9c6+aY!-)J{r*k7w}AfEADiCAW_G^mK?Gp1 zU+-Y~{<Y`n__`uN8VDOCNEK;ihmdmd0UCqR-TXrQKo}p?6adn4L80#%0KsT3cce24 z$a}s!qRB`P7f*LfqzC#vu7<mdr8W{}3_@RE0D^RoJ}9)DtPe_F`$81*Q$)@MEe<(1 zt_48fSO7_*f1@>e0MBnaT#$afBmV8`!~YitVL!(7!$F~6-u%nKi<j2Fdk8&`(Ro<W zqyPWmA@uhULjO$&FY1`zJv<lq;UF3jG|0dUls$kTWjiYmpfTWw4#<ztUkpbJU<yPJ z+4CIZb9{b*@t2~XdZZC3grkeiFNHrnQ$?Z>R_Goe^q**+zuo^mRDUG~0Hm&=3WUJn zzbyUBXONa4;Nq*mZ+`riwOTO11!N#C2owPMQLkwU0WOe3)4%}8IX+tGCIkREukf^f z({nEQ)1QB1<y^<F-v0+H7l8fJ^T${&5d78q|6t{}p-3S-kmvaeQb0O-AyIagh#!f0 zP6L3nJuOh@GyOah&;kDo+w;)<^y4oD=oE0bL%MTIxj0(=2ReQW*k3CC^5H*Ka)H<X z;K+aA!v)6wgE+Ukg`=ID=Z~?2{?~9^r0!2O7qj|TQvWM}2C6E*Zeu}sVNf{y=NB(g zaUWNNr2`TLv_RU}Ig7D=ecs9nw6hXp)#q0QtGY@fZS55N+>zRTYC4vF4wgbztm1Hh zs5k=sp$y6GgK*`xzPQ%q0YrLOiZM!SsmL*&Gx!MmIJr8Z=N8b%$<f(E*hh@@LPQwd zJ|}}%ffp<&2QgLyRSh7@#l_LV4h4kr2=PF;A-r5bYj=bb(%Z$|0SMs{U`4BRx3U)2 zLNC-m6rz8LvD%_guEHRYx3@QsH!qKiyA22;BqRg^LqSj|H=2Xn!`B&w@Zom$xQVuR z;fS5VUt-Q4JQqIkSh_fY><mB<9x&*aAsO^=-0fUZb}r7qbHfM=7f+NJs}LWO4{0qR z$jvVxB*YDYAT7AT=!e_Fl9ykASIF7|0_Oc?$@Mo6|7Hr^fwskq4gtC)jNXK-JS~y# zVyyBSDnNN#7Z21A(?A%HAcPh4bL9U8htP=p`>~^8{5g10G>@>Vi<O<VuMB$kghRm) z2saoF2vi3G6Xu5q^TUipLH}Svqm7o5M&IK@-|PF|rG8`jP0Gbx2Ms@5UQHK>bpAPb zH0V5hKTKT+{p1k^oulzvF#e0-LAa`_{_g>Dayrl3b3S1i7fVkkbQPc|^B-o#e-TJ4 z%fH-o^>lZ<NPH_x5YiEO?vV!?O9<LeD@$Q(7k4KFI&BfIu8!!H^*ozF=$vDPi=sPG zb|^<A{9;;3I--6w9PQ4hiLfKW*+z`jhuaEijqr3tvBG74!J_Voa`i<0K*7-t{-bdr z4*Hi$bj$KQ8(iFfXw^o#{ZbE?M4{}E|B%1vKbQYY>ffMzK|;@eG~l4WRu?z`_+NVd zdy4+Gq@wEsF;?&M1ry!+`xS%VHn3j{0NcNt|Lo{;^E{Mj<j$uSn~d=JltlkQAuxUj zdNzW=tmr>98+z9MUpREm0cZOMlxRswPn4~TJKF^^zwDuZ|2ZAm|0;QW+>zD*Fc2yL zIA8vLJU{_{eqMf{HSi}52IEJUKIae6`6mtSxd6Jt`5O%k6NI5loqy1vLg+H;?=&#@ zyz2Wq4Js&r-pBt=g9$<Ypb0?*(Dyg~&L_kxgswyWLE{tn!>$lN?;k!3@%~AJ3H_U~ z2?_ln3*+Pe!v<6k_J_{`eCV^xKm7v>pfl$mK7)n+puq(GjDZ0E`ElUyvM_W2|49>q z2>cT_Fgm1v(geW2;f8WY*f}EI(FY44NZZa2iOvlm`V8iRJ~^G&u|SZbv$YHGJnhkk zFhv=lu_&J$A5@Z8PzEd{BqPfYmEjeT<bw&y!33oQ1mvJFS@{2*!}Pq~_dp@sQ5Ok` Qo)!EM05h|!x*XvD0H!RWi~s-t literal 0 HcmV?d00001 diff --git a/thirdParty/libxbee/sample/README b/thirdParty/libxbee/sample/README new file mode 100644 index 0000000000..3610d03469 --- /dev/null +++ b/thirdParty/libxbee/sample/README @@ -0,0 +1,12 @@ +To use these samples, you must first install libxbee. +To install, simply type `make install` and provide the root password. + +If you cannot install the library for any reason, follow these instructions: + http://code.google.com/p/libxbee/wiki/install_libxbee#But_I_can't_install_it! + +The compile line can be found at the top of the source files, surrounded by #ifdef +and #endif. These allow us to run the source file as a shell script. Simply type +`sh simple.c` to compile the simple sample. +If you do not have the library installed, you must edit the compile line, or type +it by hand. + gcc <sample_file>.c ../obj/api.o -o <sample_file> -lpthread -lrt diff --git a/thirdParty/libxbee/sample/analog.c b/thirdParty/libxbee/sample/analog.c new file mode 100644 index 0000000000..84069e39a2 --- /dev/null +++ b/thirdParty/libxbee/sample/analog.c @@ -0,0 +1,71 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample will output the voltage read from analog 0 */ + +#include <stdio.h> +#include <stdlib.h> +#include <xbee.h> + +/* set this to the voltage measured between GND and Vref - 3.3 is a good place to start */ +#define Vref 3.3 + +int main(int argc, char *argv[]) { + xbee_con *con; + xbee_pkt *pkt; + int i; + + /* setup libxbee */ + if (xbee_setup("/dev/ttyUSB0",57600) == -1) { + return 1; + } + + /* get a connection to the remote XBee */ + con = xbee_newcon('I',xbee_64bitIO, 0x13A200, 0x403CB26A); + /* do this forever! */ + while (1) { + /* get as many packets as we can */ + while ((pkt = xbee_getpacket(con)) != NULL) { + for (i = 0; i < pkt->samples; i++) { + /* did we get a value for A0? */ + if (!xbee_hasanalog(pkt,i,0)) { + /* there was no data for A0 in the packet */ + printf("A0: -- No Data --\n"); + continue; + } + /* print out the reading in raw, and adjusted */ + printf("A0: %.0f (~%.2fv)\n", + xbee_getanalog(pkt,i,0,0), + xbee_getanalog(pkt,i,0,Vref)); + fflush(stdout); + } + /* release the packet */ + free(pkt); + } + usleep(100); + } + + return 0; +} diff --git a/thirdParty/libxbee/sample/api.c b/thirdParty/libxbee/sample/api.c new file mode 100644 index 0000000000..cff70bf1ae --- /dev/null +++ b/thirdParty/libxbee/sample/api.c @@ -0,0 +1,42 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee -g +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample will show you how to seup the xbee and ensure that it is in API mode */ + +#include <stdio.h> +#include <stdlib.h> +#include <xbee.h> + +int main(int argc, char *argv[]) { + /* the extra arguments are the CC ('+' by default) and GT (1000) by default AT values */ + xbee_setuplogAPI("/dev/ttyUSB0",57600,2,'+',1000); + + /* now we can do our stuff! */ + sleep(10); + + /* calling xbee_end() will return the xbee to its previous API mode */ + xbee_end(); + return 0; +} diff --git a/thirdParty/libxbee/sample/atis.c b/thirdParty/libxbee/sample/atis.c new file mode 100644 index 0000000000..66946f1848 --- /dev/null +++ b/thirdParty/libxbee/sample/atis.c @@ -0,0 +1,81 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample will output the voltage read from analog 0 */ + +#include <stdio.h> +#include <stdlib.h> +#include <xbee.h> + +/* set this to the voltage measured between GND and Vref - 3.3 is a good place to start */ +#define Vref 3.3 + +int main(int argc, char *argv[]) { + xbee_con *con; + xbee_pkt *pkt; + + /* setup libxbee */ + if (xbee_setup("/dev/ttyUSB0",57600) == -1) { + printf("xbee_setup failed...\n"); + return 1; + } + + /* create an AT connection */ + con = xbee_newcon('I',xbee_64bitRemoteAT,0x13A200,0x403CB26A); + + /* do this forever! */ + for (;;) { + /* request samples now! */ + xbee_senddata(con,"IS"); + /* get as many packets as we can */ + while ((pkt = xbee_getpacketwait(con)) != NULL) { + if (pkt) { + if (pkt->status != 0x00) { + /* if the return status was not 0x00 (OK) then the request failed... */ + printf("Sample A0: -- Request Failed --\n"); + } else { + if (!xbee_hasanalog(pkt,0,0)) { + /* there was no data for A0 in the packet */ + printf("Sample A0: -- No Data --\n"); + } else { + /* it appears that there is sample data for A0! */ + printf("Sample A0: %.0f (~%.2fv)\n", + xbee_getanalog(pkt,0,0,0), + xbee_getanalog(pkt,0,0,Vref)); + } + } + /* dont forget to free the packet! */ + free(pkt); + } else { + /* couldnt get a packet */ + printf("Sample A0: -- No Packet Returned --\n"); + } + } + /* wait a second for the next sample */ + sleep(1); + } + + return 0; +} diff --git a/thirdParty/libxbee/sample/atsetup.c b/thirdParty/libxbee/sample/atsetup.c new file mode 100644 index 0000000000..13afbe4169 --- /dev/null +++ b/thirdParty/libxbee/sample/atsetup.c @@ -0,0 +1,157 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample will setup certain AT parameters of the local XBee unit */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <xbee.h> + +/* con = connection to use + cmd = 2 character command string, eg NI + parameter = NULL - no parameter + !NULL - command parameter, either NULL terminated string, or block of memory + length = 0 - use parameter as NULL terminated string + !0 - use 'length' bytes from parameter + ret = NULL - don't return anything + !NULL - pointer to pointer. doAT will allocate memory, you must free it! + str = return data pointer + + returns the length of the data in ret, or -ve for error */ +int doAT(xbee_con *con, char *cmd, char *parameter, int length, unsigned char **ret) { + xbee_pkt *pkt; + if (con->type != xbee_localAT && con->type != xbee_16bitRemoteAT && con->type != xbee_64bitRemoteAT) { + printf("Thats not an AT connection!...\n"); + return -1; + } + if (strlen(cmd) != 2) { + printf("Invalid command: \"%s\"\n",cmd); + return -2; + } + if (parameter == NULL) { + xbee_senddata(con,"%s",cmd); + } else if (length != 0) { + char *tmp; + if ((tmp = malloc(1024)) == NULL) { + printf("Failed to get memory!\n"); + return -3; + } + snprintf(tmp,1024,"%s",cmd); + memcpy(&(tmp[2]),parameter,(length>1022)?1022:length); + xbee_nsenddata(con,tmp,length+2); + free(tmp); + } else { + xbee_senddata(con,"%s%s",cmd,parameter); + } + pkt = xbee_getpacketwait(con); + if (pkt == NULL) { + printf("Failed to set %s!\n",cmd); + return -4; + } + if (pkt->status != 0) { + printf("An error occured while setting %s!\n",cmd); + return -5; + } + if (ret && pkt->datalen > 0) { + *ret = realloc(*ret,sizeof(char) * (pkt->datalen + 1)); + memcpy(*ret,pkt->data,pkt->datalen); + (*ret)[pkt->datalen] = '\0'; + free(pkt); + return pkt->datalen; + } + free(pkt); + return 0; +} + +int main(int argc, char *argv[]) { + xbee_con *con; + int ret,i; + unsigned char *str = NULL; + + if (argc != 2) { + printf("Usage: %s <newname>\n",argv[0]); + return 1; + } + + /* setup libxbee */ + if (xbee_setup("/dev/ttyUSB0",57600) == -1) { + printf("xbee_setup failed...\n"); + return 1; + } + + /* create an AT connection */ + con = xbee_newcon('I',xbee_localAT); + /*con = xbee_newcon('I',xbee_64bitRemoteAT,0x13A200,0x403CB26A);*/ + + + /* get the node's address! */ + if ((ret = doAT(con,"SH",NULL,0,&str)) < 0) return 1; + if (ret == 4) { + printf("SH: 0x%02X%02X%02X%02X\n", str[0], str[1], str[2], str[3]); + } + if ((ret = doAT(con,"SL",NULL,0,&str)) < 0) return 1; + if (ret == 4) { + printf("SL: 0x%02X%02X%02X%02X\n", str[0], str[1], str[2], str[3]); + } + + /* set the power level - 2 methods, i prefer the first but it generates compile warnings :( */ + /*if ((ret = doAT(con,"PL",&((unsigned char[]){4}),1,&str)) < 0) return 1;*/ + /*{ + char t[] = {0}; + if ((ret = doAT(con,"PL",t,1,&str)) < 0) return 1; + }*/ + + /* get the power level */ + if ((ret = doAT(con,"PL",NULL,0,&str)) < 0) return 1; + if (ret == 1) { + printf("PL: 0x%02X\n", str[0]); + } + + /* get NI */ + if ((ret = doAT(con,"NI",NULL,0,&str)) < 0) return 1; + if (ret > 0) { + printf("NI: "); + for (i = 0; i < ret; i++) { + printf("%c",(str[i]>=32 && str[i]<=126)?str[i]:'.'); + } + printf("\n"); + } + + printf("Setting NI to '%s': ",(argc!=2)?"MyNode":argv[1]); + if ((ret = doAT(con,"NI",(argc!=2)?"MyNode":argv[1],0,NULL)) < 0) return 1; + printf("OK\n"); + + if ((ret = doAT(con,"NI",NULL,0,&str)) < 0) return 1; + if (ret > 0) { + printf("NI: "); + for (i = 0; i < ret; i++) { + printf("%c",(str[i]>=32 && str[i]<=126)?str[i]:'.'); + } + printf("\n"); + } + + return 0; +} diff --git a/thirdParty/libxbee/sample/callback.c b/thirdParty/libxbee/sample/callback.c new file mode 100644 index 0000000000..9e48276b0f --- /dev/null +++ b/thirdParty/libxbee/sample/callback.c @@ -0,0 +1,88 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample will return any recieved data, using a callback function */ + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <xbee.h> + +void sighandler(int sig) { + xbee_pkt *pkt; + if (sig == SIGINT) { + xbee_end(); + exit(0); + } +} + +void callback(xbee_con *con, xbee_pkt *pkt) { + int ret; + /* print the recieved data */ + printf("Rx: %s\n",pkt->data); + /* say thank you */ + if ((ret = xbee_senddata(con,"%s",pkt->data)) != 0) { + printf("xbee_senddata: Error %d... Retrying!\n",ret); + if ((ret = xbee_senddata(con,"%s",pkt->data)) != 0) { + printf("xbee_senddata: Error %d... Data lost!\n",ret); + } else { + printf("xbee_senddata: Success after retry!\n",ret); + } + } +free(pkt); +} + +int main(int argc, char *argv[]) { + xbee_con *con; + xbee_pkt *pkt, *rpkt; + + /* setup the xbee */ + //if (xbee_setupAPI("/dev/ttyUSB0",57600,'+',250) == -1) { + //if (xbee_setuplogAPI("/dev/ttyUSB0",57600,2,'+',250) == -1) { + if (xbee_setuplog("/dev/ttyUSB0",57600,2) == -1) { + /* oh no... it failed */ + printf("xbee_setup() failed...\n"); + exit(1); + } + + /* handle ^C */ + signal(SIGINT, sighandler); + + /* setup a connection */ + con = xbee_newcon('I',xbee_64bitData, 0x0013A200, 0x40081826); + con->waitforACK = 1; + con->callback = callback; + + printf("Waiting...\n"); + + /* do nothing forever! */ + for (;;) { + sleep(86400); /* 24hrs */ + } + + /* shouldn't ever get here but... */ + return 0; +} + diff --git a/thirdParty/libxbee/sample/digital.c b/thirdParty/libxbee/sample/digital.c new file mode 100644 index 0000000000..4b0c9f6331 --- /dev/null +++ b/thirdParty/libxbee/sample/digital.c @@ -0,0 +1,146 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee -g +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample will control digital output pins of a chosen node */ + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <xbee.h> + +int mode; +char bitmask; +char outputs; + +void sighandler(int sig) { + if (sig == SIGINT) { + xbee_end(); + exit(0); + } +} + +void doneCB(xbee_con *con, xbee_pkt *pkt) { + /* this packet should be confirmation... */ + xbee_end(); + exit(0); +} +void doCB(xbee_con *con, xbee_pkt *pkt) { + int i,m; + outputs = pkt->IOdata[0].IOdigital; + printf("\n 7 6 5 4 3 2 1 0\n"); + printf("Current output state: "); + for (i = 0; i < 8; i++) { + if (xbee_hasdigital(pkt,0,7-i)) { + if (xbee_getdigital(pkt,0,7-i)) { + printf(" 1"); + } else { + printf(" 0"); + } + } else { + printf(" x"); + } + } + printf("\n"); + switch (mode) { + case 0: outputs |= bitmask; break; + case 1: outputs &= ~bitmask; break; + case 2: default: + xbee_end(); + exit(0); + } + m = outputs; + printf("New output state: "); + for (i = 0; i < 8; i++) { + if (xbee_hasdigital(pkt,0,7-i)) { + if (m & 0x80) { + printf(" 1"); + } else { + printf(" 0"); + } + } else { + printf(" x"); + } + m <<= 1; + } + printf("\n\n"); + con->callback = doneCB; + xbee_senddata(con,"IO%c",outputs); +} + +void usage(char *argv0) { + printf("Usage: %s <query>\n",argv0); + printf("Usage: %s <on|off> <port[0-7]>[port[0-7]]...\n",argv0); + exit(1); +} +int main(int argc, char *argv[]) { + xbee_con *con; + + if (argc < 2) usage(argv[0]); + + if (!strcasecmp(argv[1],"on")) { + mode = 0; + } else if (!strcasecmp(argv[1],"off")) { + mode = 1; + } else if (!strcasecmp(argv[1],"query")) { + mode = 2; + } else usage(argv[0]); + + if (mode != 2) { + int i; + char *c; + bitmask = 0; + c = argv[2]; + while (*c != '\0') { + *c -= '0'; + if ((*c >= 0) && (*c <= 7)) { + bitmask |= 0x01 << *c; + } else { + usage(argv[0]); + } + c++; + } + } + + /* setup libxbee */ + if (xbee_setupAPI("/dev/ttyUSB0",57600,'+',250) == -1) { + return 1; + } + + /* handle ^C */ + signal(SIGINT, sighandler); + + /* get a connection to the remote XBee */ + con = xbee_newcon('I',xbee_64bitRemoteAT, 0x0013A200, 0x403CB26B); + con->waitforACK = 1; + con->callback = doCB; + + xbee_senddata(con,"IS"); + + /* timeout after 1 second... */ + sleep(1); + + xbee_end(); + return 0; +} diff --git a/thirdParty/libxbee/sample/digitalout.c b/thirdParty/libxbee/sample/digitalout.c new file mode 100644 index 0000000000..46db084f13 --- /dev/null +++ b/thirdParty/libxbee/sample/digitalout.c @@ -0,0 +1,128 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample will control the digital 0 output from the keyboard. Type: + 0, <RETURN> - off + 1, <RETURN> - on + q, <RETURN> - quit */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <xbee.h> + +int main(int argc,char *argv[]) { + xbee_con *con; + xbee_pkt *pkt; + + printf("Hello\n"); + + if (xbee_setup("/dev/ttyUSB0",57600) == -1) { + printf("failed to setup xbee\n"); + return 1; + } + + con = xbee_newcon('R',xbee_64bitRemoteAT,0x0013a200,0x403af247); + if (!con) { + printf("no connection returned\n"); + return 1; + } + + for (;;) { + + xbee_senddata(con,"D0"); + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("no packet returned from state probe\n"); + return 1; + } + + if (pkt->status != 0) { + printf("state probe failed (ret=0x%02X - ",pkt->status); + switch (pkt->status) { + case 0x1: printf("Error"); break; + case 0x2: printf("Invalid Command"); break; + case 0x3: printf("Invalid Parameter"); break; + case 0x4: printf("No Response"); break; + default: printf("Unknown"); break; + } + printf(")\n"); + return 1; + } + + if (pkt->datalen != 1) { + printf("unexpected datalen from state probe\n"); + return 1; + } + + if (pkt->data[0] == 0x05) { + printf("this port is currently ON\n"); + } else if (pkt->data[0] == 0x04) { + printf("this port is currently OFF\n"); + } else { + printf("this port is currently in an unknown state\n"); + return 1; + } + free(pkt); + pkt = NULL; + + recharprompt: + printf("--> "); + rechar: + switch(getchar()) { + case 'q': case 'Q': + printf("byebye\n"); + return 0; + case '0': + printf("turning off...\n"); + xbee_senddata(con,"D0%c",0x04); + break; + case '1': + printf("turning on...\n"); + xbee_senddata(con,"D0%c",0x05); + break; + case '\n': goto rechar; + default: goto recharprompt; + } + + if ((pkt = xbee_getpacketwait(con)) != NULL) { + if (pkt->status != 0) { + printf("state set failed (ret=0x%02X - ",pkt->status); + switch (pkt->status) { + case 0x1: printf("Error"); break; + case 0x2: printf("Invalid Command"); break; + case 0x3: printf("Invalid Parameter"); break; + case 0x4: printf("No Response"); break; + default: printf("Unknown"); break; + } + printf(")\n"); + return 1; + } + } + + } + + return 0; +} diff --git a/thirdParty/libxbee/sample/multi.c b/thirdParty/libxbee/sample/multi.c new file mode 100644 index 0000000000..107f88f6e9 --- /dev/null +++ b/thirdParty/libxbee/sample/multi.c @@ -0,0 +1,100 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee -g +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample will make use of multiple instances of libxbee and send messages between the attached XBees */ + +#include <stdio.h> +#include <stdlib.h> +#include <signal.h> +#include <xbee.h> + +int mode; +char bitmask; +char outputs; + +xbee_hnd xbee1; +xbee_hnd xbee2; + +void sighandler(int sig) { + if (sig == SIGINT) { + _xbee_end(xbee1); + _xbee_end(xbee2); + exit(0); + } +} + +void xbee1CB(xbee_con *con, xbee_pkt *pkt) { + char data[128]; + snprintf(data,pkt->datalen+1,"%s",pkt->data); + printf("XBee1: Rx[%3d]: %s\n",pkt->datalen,data); +} + +void xbee2CB(xbee_con *con, xbee_pkt *pkt) { + char data[128]; + snprintf(data,pkt->datalen+1,"%s",pkt->data); + printf("XBee2: Rx[%3d]: %s\n",pkt->datalen,data); +} + +int main(int argc, char *argv[]) { + xbee_con *con1; + xbee_con *con2; + + if (!(xbee1 = _xbee_setuplogAPI("/dev/ttyUSB0",57600,3,'+',250))) { + //if (!(xbee1 = _xbee_setupAPI("/dev/ttyUSB0",57600,'+',250))) { + printf("xbee1: setup error...\n"); + return 1; + } + if (!(xbee2 = _xbee_setuplogAPI("/dev/ttyUSB1",57600,4,'+',250))) { + //if (!(xbee2 = _xbee_setupAPI("/dev/ttyUSB1",57600,'+',250))) { + printf("xbee2: setup error...\n"); + return 1; + } + + /* handle ^C */ + signal(SIGINT, sighandler); + + con1 = _xbee_newcon(xbee1,'1',xbee_64bitData, 0x0013A200, 0x40081826); + con1->waitforACK = 1; + con1->callback = xbee1CB; + + con2 = _xbee_newcon(xbee2,'2',xbee_64bitData, 0x0013A200, 0x404B75DE); + con2->waitforACK = 1; + con2->callback = xbee2CB; + + while (1) { + printf("xbee1: Tx\n"); + _xbee_logit(xbee1,"xbee1: Tx"); + _xbee_logit(xbee2,"xbee1: Tx"); + _xbee_senddata(xbee1,con1,"Hello"); + usleep(1000000); + printf("xbee2: Tx\n"); + _xbee_logit(xbee1,"xbee2: Tx"); + _xbee_logit(xbee2,"xbee2: Tx"); + _xbee_senddata(xbee2,con2,"Hi There!"); + usleep(1000000); + } + + return 0; +} diff --git a/thirdParty/libxbee/sample/scan.c b/thirdParty/libxbee/sample/scan.c new file mode 100644 index 0000000000..4546887f9e --- /dev/null +++ b/thirdParty/libxbee/sample/scan.c @@ -0,0 +1,144 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample will scan the currently configured channel for all nodes, + returning the values of a few useful settings */ + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <string.h> +#include <unistd.h> +#include <xbee.h> + +#define MAXNODES 100 + +int main(int argc, char *argv[]) { + int i; + int saidfull = 0; + int ATNT = 0x19; /* node discover timeout */ + int ATNTc; /* counter */ + + int nodes = 0; + char addrs[MAXNODES][8]; + + xbee_con *con; + xbee_pkt *pkt, *rpkt; + + time_t ttime; + char stime[32]; + + /* setup libxbee */ + if (xbee_setup("/dev/ttyUSB0",57600) == -1) { + return 1; + } + + /* grab a local AT connection */ + con = xbee_newcon('I',xbee_localAT); + + /* get the ND timeout */ + xbee_senddata(con,"NT"); + if ((rpkt = xbee_getpacketwait(con)) == NULL) { + printf("XBee didnt return a result for NT\n"); + return 1; + } + ATNT = rpkt->data[0]; + free(rpkt); + + while (1) { + /* send a ND - Node Discover request */ + xbee_senddata(con,"ND"); + /* only wait for a bit longer than the ND timeout */ + ATNTc = ATNT + 10; + /* loop until the end packet has been received or timeout reached */ + while (ATNTc--) { + /* get a packet */ + pkt = xbee_getpacketwait(con); + /* check a packet was returned, and that its one we are after... */ + if (pkt && !memcmp(pkt->atCmd,"ND",2)) { + /* is this the end packet? you can tell from the 0 datalen */ + if (pkt->datalen == 0) { + /* free the packet */ + free(pkt); + break; + } else { + /* check if we know this node already */ + for (i = 0; i < nodes; i++) { + /* the 64bit address will match one in the list */ + if (!memcmp(&(pkt->data[2]),&(addrs[i]),8)) break; + } + ttime = time(NULL); + strftime(stime,32,"%I:%M:%S %p",gmtime(&ttime)); + /* is there space for another? */ + if ((i == nodes) && + (nodes == MAXNODES) && + (!saidfull)) { + printf("MAXNODES reached... Can't add more...\r"); + /* flush so the change is seen! */ + fflush(stdout); + saidfull = 1; + } else { + /* is this a rewrite? */ + if (i != nodes) { + /* find the line to edit */ + printf("%c[%dA",27,nodes-i); + /* clear the line */ + printf("%c[2K",27); + } + /* write out the info */ + memcpy(&(addrs[nodes]),&(pkt->data[2]),8); + printf("MY: 0x%02X%02X ",pkt->data[0],pkt->data[1]); + printf("SH: 0x%02X%02X%02X%02X ",pkt->data[2],pkt->data[3],pkt->data[4],pkt->data[5]); + printf("SL: 0x%02X%02X%02X%02X ",pkt->data[6],pkt->data[7],pkt->data[8],pkt->data[9]); + printf("dB: -%2d ",pkt->data[10]); + printf("NI: %-20s ",&(pkt->data[11])); + printf("@: %s",stime); + /* is this a rewrite? */ + if (i != nodes) { + /* go back the the bottom */ + printf("%c[%dB\r",27,nodes-i); + } else { + /* new line is only wanted for new nodes */ + printf("\n"); + /* if not, then add 1 to the number of nodes! */ + nodes++; + } + } + /* flush so the change is seen! */ + fflush(stdout); + } + /* free the packet */ + free(pkt); + } + /* sleep for 100ms (same as NT steps) */ + usleep(100000); + } + /* try again! */ + usleep(100000); + } + + return 0; +} + diff --git a/thirdParty/libxbee/sample/scan_adv.c b/thirdParty/libxbee/sample/scan_adv.c new file mode 100644 index 0000000000..d3360222cc --- /dev/null +++ b/thirdParty/libxbee/sample/scan_adv.c @@ -0,0 +1,589 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample will scan all possible channels for remote nodes and return + the value of a few useful settings */ + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <xbee.h> + +#define MAXNODES 100 + +int ATCH = 0x0C; /* origional channel number */ +int ATNT = 0x19; /* node discover timeout */ +int ATNTc; /* node discover timeout counter */ +int BREAK = 0; +xbee_con *con; + +void sighandler(int sig) { + xbee_pkt *pkt; + if (sig == SIGINT) { + BREAK = 1; + /* wait for the rest of the timeout... */ + printf("\r%c[2KWaiting for node discover command to timeout...",27); + fflush(stdout); + for (; ATNTc; ATNTc--) { + usleep(100000); + } + /* Restore the XBee's channel setting */ + printf("\r%c[2KRestoring channel to 0x%02X...",27,ATCH); + fflush(stdout); + if (xbee_senddata(con,"CH%c",ATCH)) { + printf("xbee_senddata: Error\n"); + exit(1); + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("\r%c[2K*** XBee didnt return a result for CH... ***\nPlease manually reset your channel to 0x%02X\n",27,ATCH); + } + if (pkt->status) { + printf("\r%c[2K*** An error occured while restoring the channel setting... ***\nPlease manually reset your channel to 0x%02X\n",27,ATCH); + } else { + printf("\nDone!\n"); + } + free(pkt); + /* Restore the terminal */ + printf("%c[?25h%c[0m",27,27); + fflush(stdout); + exit(0); + } +} + +int main(int argc, char *argv[]) { + int i; + int saidfull = 0; + int ATCHc; /* current channel number */ + int XBeePro = 0; /* XBee pro? */ + + int nodes = 0; + unsigned char addrs[MAXNODES][19]; /* 0-7 : 64 bit address + 8 : channel + 9-10 : id + 11 : baud + 12 : API + 13-14: HV + 15-16: VR + 17 : CC + 18 : mask - not address */ + + xbee_pkt *pkt, *rpkt; + + time_t ttime; + char stime[32]; + + /* handle ^C */ + signal(SIGINT, sighandler); + + /* setup libxbee */ + if (xbee_setupAPI("/dev/ttyUSB0",57600,'+',250) == -1) { + return 1; + } + + /* grab a local AT connection */ + con = xbee_newcon('I',xbee_localAT); + + /* get the current channel */ + if (xbee_senddata(con,"CH")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("XBee didnt return a result for CH\n"); + return 1; + } + ATCH = pkt->data[0]; + free(pkt); + + /* XBee - 0x0B - 0x1A + XBee Pro - 0x0C - 0x17 */ + if (xbee_senddata(con,"CH%c",0x0B)) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("XBee didnt return a result for CH\n"); + return 1; + } + /* did that fail? */ + if (pkt->status == 0) { + /* nope.. its not a pro */ + printf("Using XBee (not Pro) channels (0x0B - 0x1A)...\n"); + XBeePro = 0; + ATCHc = 0x0B; + } else { + /* yup... its a pro */ + printf("Using XBee Pro channels (0x0C - 0x17)...\n"); + XBeePro = 1; + ATCHc = 0x0C; + } + free(pkt); + + /* find and print data for the local node */ + printf("\n%c[31mCH:%c[32m 0x%02X ",27,27,ATCH); + if (xbee_senddata(con,"ID")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("\nXBee didnt return a result for ID\n"); + return 1; + } + printf("%c[31mID:%c[32m 0x%02X%02X ",27,27,pkt->data[0],pkt->data[1]); + free(pkt); + /* ### */ + if (xbee_senddata(con,"MY")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("\nXBee didnt return a result for MY\n"); + return 1; + } + printf("%c[31mMY:%c[32m 0x%02X%02X ",27,27,pkt->data[0],pkt->data[1]); + free(pkt); + /* ### */ + if (xbee_senddata(con,"SH")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("\nXBee didnt return a result for SH\n"); + return 1; + } + printf("%c[31mSH:%c[32m 0x%02X%02X%02X%02X ",27,27,pkt->data[0],pkt->data[1],pkt->data[2],pkt->data[3]); + free(pkt); + /* ### */ + if (xbee_senddata(con,"SL")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("\nXBee didnt return a result for SL\n"); + return 1; + } + printf("%c[31mSL:%c[32m 0x%02X%02X%02X%02X ",27,27,pkt->data[0],pkt->data[1],pkt->data[2],pkt->data[3]); + free(pkt); + /* ### */ + if (xbee_senddata(con,"BD")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("\nXBee didnt return a result for BD\n"); + return 1; + } + printf("%c[31mBD:%c[32m ",27,27); + /* print the baud rate */ + switch (pkt->data[3]) { + case 0: printf(" 1200"); break; + case 1: printf(" 2400"); break; + case 2: printf(" 4800"); break; + case 3: printf(" 9600"); break; + case 4: printf(" 19200"); break; + case 5: printf(" 38400"); break; + case 6: printf(" 57600"); break; + case 7: printf("115200"); break; + default: printf(" other"); break; + } + printf(" "); + free(pkt); + /* ### */ + if (xbee_senddata(con,"AP")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("\nXBee didnt return a result for AP\n"); + return 1; + } + printf("%c[31mAP:%c[32m 0x%02X ",27,27,pkt->data[0]); + free(pkt); + /* ### */ + if (xbee_senddata(con,"HV")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("\nXBee didnt return a result for HV\n"); + return 1; + } + printf("%c[31mHV:%c[32m 0x%02X%02X ",27,27,pkt->data[0],pkt->data[1]); + free(pkt); + /* ### */ + if (xbee_senddata(con,"VR")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("\nXBee didnt return a result for VR\n"); + return 1; + } + printf("%c[31mVR:%c[32m 0x%02X%02X ",27,27,pkt->data[0],pkt->data[1]); + free(pkt); + /* ### */ + if (xbee_senddata(con,"CC")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("\nXBee didnt return a result for CC\n"); + return 1; + } + printf("%c[31mCC:%c[32m '%c' (0x%02X) ",27,27,pkt->data[0],pkt->data[0]); + free(pkt); + /* ### */ + if (xbee_senddata(con,"NI")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("\nXBee didnt return a result for NI\n"); + return 1; + } + printf("%c[31mNI:%c[32m %-20s ",27,27,pkt->data); + free(pkt); + /* ### */ + printf("%c[95m* This is the lobal XBee *",27); + + printf("%c[34m\n---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------%c[0m\n\n",27,27); + + /* get the ND timeout */ + if (xbee_senddata(con,"NT")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if ((pkt = xbee_getpacketwait(con)) == NULL) { + printf("XBee didnt return a result for NT\n"); + return 1; + } + ATNT = pkt->data[0]; + free(pkt); + + printf("%c[?25l",27); + fflush(stdout); + + usleep(100000); + + while (!BREAK) { + /* set the channel to scan */ + if (xbee_senddata(con,"CH%c",ATCHc)) { + printf("xbee_senddata: Error\n"); + return 1; + } + pkt = xbee_getpacketwait(con); + if (!pkt || pkt->status) { + printf("\nXBee didnt return a result for CH\n"); + return 1; + } + free(pkt); + printf("%c[2KScanning channel 0x%02X...\r",27,ATCHc); + fflush(stdout); + /* send a ND - Node Discover request */ + if (!xbee_senddata(con,"ND")) { + /* only wait for a bit longer than the ND timeout */ + ATNTc = ATNT + 10; + /* loop until the end packet has been received or timeout reached */ + while (!BREAK && ATNTc--) { + /* get a packet */ + pkt = xbee_getpacket(con); + /* check a packet was returned, and that its one we are after... */ + if (pkt && !memcmp(pkt->atCmd,"ND",2)) { + /* is this the end packet? you can tell from the 0 datalen */ + if (pkt->datalen == 0) { + /* free the packet */ + free(pkt); + break; + } else { + /* check if we know this node already */ + for (i = 0; i < nodes; i++) { + /* the 64bit address will match one in the list */ + if (!memcmp(&(pkt->data[2]),&(addrs[i][0]),8)) break; + } + ttime = time(NULL); + strftime(stime,32,"%I:%M:%S %p",gmtime(&ttime)); + /* is there space for another? */ + if ((i == nodes) && + (nodes == MAXNODES) && + (!saidfull)) { + printf("%c[2KMAXNODES reached... Can't add more...\r",27); + /* flush so the change is seen! */ + fflush(stdout); + saidfull = 1; + } else { + /* is this a rewrite? */ + if (i != nodes) { + /* find the line to edit */ + printf("%c[%dA",27,nodes-i+1); + /* clear the line */ + printf("%c[2K",27); + } else { + /* fill the blank line */ + printf("%c[%dA",27,1); + } + /* save the channel */ + addrs[i][8] = ATCHc; + /* write out the info */ + printf("%c[31mCH:%c[32m 0x%02X ",27,27,ATCHc); + printf("%c[31mID:%c[32m 0x",27,27); + if (i == nodes || !(addrs[i][18] & 0x80)) { + printf("...."); + } else { + printf("%02X%02X",addrs[i][9],addrs[i][10]); + } + printf(" "); + printf("%c[31mMY:%c[32m 0x%02X%02X ",27,27,pkt->data[0],pkt->data[1]); + printf("%c[31mSH:%c[32m 0x%02X%02X%02X%02X ",27,27,pkt->data[2],pkt->data[3],pkt->data[4],pkt->data[5]); + printf("%c[31mSL:%c[32m 0x%02X%02X%02X%02X ",27,27,pkt->data[6],pkt->data[7],pkt->data[8],pkt->data[9]); + printf("%c[31mBD:%c[32m ",27,27); + if (i == nodes || !(addrs[i][18] & 0x40)) { + printf("......"); + } else { + switch (addrs[i][11]) { + case 0: printf(" 1200"); break; + case 1: printf(" 2400"); break; + case 2: printf(" 4800"); break; + case 3: printf(" 9600"); break; + case 4: printf(" 19200"); break; + case 5: printf(" 38400"); break; + case 6: printf(" 57600"); break; + case 7: printf("115200"); break; + default: printf(" other"); break; + } + } + printf(" "); + printf("%c[31mAP:%c[32m 0x",27,27); + if (i == nodes || !(addrs[i][18] & 0x20)) { + printf(".."); + } else { + printf("%02X",addrs[i][12]); + } + printf(" "); + printf("%c[31mHV:%c[32m 0x",27,27); + if (i == nodes || !(addrs[i][18] & 0x10)) { + printf("...."); + } else { + printf("%02X%02X",addrs[i][13],addrs[i][14]); + } + printf(" "); + printf("%c[31mVR:%c[32m 0x",27,27); + if (i == nodes || !(addrs[i][18] & 0x08)) { + printf("...."); + } else { + printf("%02X%02X",addrs[i][15],addrs[i][16]); + } + printf(" "); + printf("%c[31mCC:%c[32m ",27,27); + if (i == nodes || !(addrs[i][18] & 0x04)) { + printf(" . (0x..)"); + } else { + printf("'%c' (0x%02X)",addrs[i][17],addrs[i][17]); + } + printf(" "); + printf("%c[31mNI:%c[32m %-20s ",27,27,&(pkt->data[11])); + printf("%c[31mdB:%c[32m -%2d ",27,27,pkt->data[10]); + printf("%c[31m@:%c[32m %s",27,27,stime); + /* is this a rewrite? */ + if (i != nodes) { + /* go back the the bottom */ + printf("%c[%dB\r",27,nodes-i+1); + } else { + /* if its new... save the address */ + memcpy(&(addrs[nodes][0]),&(pkt->data[2]),8); + /* turn off all the flags */ + addrs[nodes][18] = 0; + /* new line is only wanted for new nodes */ + printf("\n%c[2K\n%c[0m",27,27); + /* if not, then add 1 to the number of nodes! */ + nodes++; + } + printf("%c[0m%c[2KScanning channel 0x%02X...\r",27,27,ATCHc); + fflush(stdout); + } + /* flush so the change is seen! */ + fflush(stdout); + } + /* free the packet */ + free(pkt); + } + /* sleep for 100ms (same as NT steps */ + usleep(100000); + } + } + fflush(stdout); + /* check for all nodes on this channel, and get thier pan id */ + for (i = 0; i < nodes; i++) { + int first = 1; + if (addrs[i][8] == ATCHc) { + xbee_con *tcon; + unsigned int dh,dl; + if (first) { + printf("%c[2KGathering settings for nodes on channel 0x%02X...\r",27,ATCHc); + first = 0; + } + /* get the address, and turn it the right way up! */ + memcpy(&dh,&(addrs[i][0]),4); + dh = ((dh & 0xFF) << 24) | ((dh & 0xFF00) << 8) | ((dh & 0xFF0000) >> 8) | ((dh & 0xFF000000) >> 24); + memcpy(&dl,&(addrs[i][4]),4); + dl = ((dl & 0xFF) << 24) | ((dl & 0xFF00) << 8) | ((dl & 0xFF0000) >> 8) | ((dl & 0xFF000000) >> 24); + /* setup a connection the the remote node */ + if ((tcon = xbee_newcon('I',xbee_64bitRemoteAT,dh,dl)) != NULL) { + /* find the line to edit */ + printf("\r%c[%dA",27,nodes-i+1); + + /* in this case we dont care if we dont get a response packet... */ + if (xbee_senddata(tcon,"ID")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if (((rpkt = xbee_getpacketwait(tcon)) != NULL) && (rpkt->status == 0)) { + /* move over the ID column */ + printf("\r%c[18C",27); + /* print the ID */ + printf("%c[32m%02X%02X%c[0m",27,rpkt->data[0],rpkt->data[1],27); + addrs[i][9] = rpkt->data[0]; + addrs[i][10] = rpkt->data[1]; + /* turn on the flag */ + addrs[i][18] |= 0x80; + free(rpkt); + } + + /* in this case we dont care if we dont get a response packet... */ + if (xbee_senddata(tcon,"BD")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if (((rpkt = xbee_getpacketwait(tcon)) != NULL) && (rpkt->status == 0)) { + /* move over the BD column */ + printf("\r%c[80C",27); + if ((rpkt->data[0] != 0x00) || (rpkt->data[1] != 0x00) || (rpkt->data[2] != 0x00) || ((rpkt->data[3] & 0xF8) != 0x00)) { + addrs[i][11] = 8; + } else { + addrs[i][11] = rpkt->data[3]; + } + /* turn on the flag */ + addrs[i][18] |= 0x40; + /* print the baud rate */ + printf("%c[32m",27); + switch (addrs[i][11]) { + case 0: printf(" 1200"); break; + case 1: printf(" 2400"); break; + case 2: printf(" 4800"); break; + case 3: printf(" 9600"); break; + case 4: printf(" 19200"); break; + case 5: printf(" 38400"); break; + case 6: printf(" 57600"); break; + case 7: printf("115200"); break; + default: printf(" other"); break; + } + printf("%c[0m",27); + free(rpkt); + } + /* in this case we dont care if we dont get a response packet... */ + if (xbee_senddata(tcon,"AP")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if (((rpkt = xbee_getpacketwait(tcon)) != NULL) && (rpkt->status == 0)) { + /* move over the AP column */ + printf("\r%c[96C",27); + /* print the ID */ + printf("%c[32m%02X%c[0m",27,rpkt->data[0],27); + addrs[i][12] = rpkt->data[0]; + /* turn on the flag */ + addrs[i][18] |= 0x20; + free(rpkt); + } + /* in this case we dont care if we dont get a response packet... */ + if (xbee_senddata(tcon,"HV")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if (((rpkt = xbee_getpacketwait(tcon)) != NULL) && (rpkt->status == 0)) { + /* move over the HV column */ + printf("\r%c[108C",27); + /* print the ID */ + printf("%c[32m%02X%02X%c[0m",27,rpkt->data[0],rpkt->data[1],27); + addrs[i][13] = rpkt->data[0]; + addrs[i][14] = rpkt->data[1]; + /* turn on the flag */ + addrs[i][18] |= 0x10; + free(rpkt); + } + /* in this case we dont care if we dont get a response packet... */ + if (xbee_senddata(tcon,"VR")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if (((rpkt = xbee_getpacketwait(tcon)) != NULL) && (rpkt->status == 0)) { + /* move over the VR column */ + printf("\r%c[122C",27); + /* print the ID */ + printf("%c[32m%02X%02X%c[0m",27,rpkt->data[0],rpkt->data[1],27); + addrs[i][15] = rpkt->data[0]; + addrs[i][16] = rpkt->data[1]; + /* turn on the flag */ + addrs[i][18] |= 0x08; + free(rpkt); + } + /* in this case we dont care if we dont get a response packet... */ + if (xbee_senddata(tcon,"CC")) { + printf("xbee_senddata: Error\n"); + return 1; + } + if (((rpkt = xbee_getpacketwait(tcon)) != NULL) && (rpkt->status == 0)) { + /* move over the CC column */ + printf("\r%c[134C",27); + /* print the ID */ + printf("%c[32m'%c' (0x%02X)%c[0m",27,rpkt->data[0],rpkt->data[0],27); + addrs[i][17] = rpkt->data[0]; + /* turn on the flag */ + addrs[i][18] |= 0x04; + free(rpkt); + } + /* go back the the bottom */ + printf("%c[%dB\r",27,nodes-i+1); + fflush(stdout); + } + } + } + /* fall back to the first channel if that was the last */ + if (XBeePro && ATCHc == 0x17) { + ATCHc = 0x0C; + } else if (!XBeePro && ATCHc == 0x1A) { + ATCHc = 0x0B; + } else { + /* else move onto next channel */ + ATCHc++; + } + usleep(100000); + } + + return 0; +} + diff --git a/thirdParty/libxbee/sample/simple.c b/thirdParty/libxbee/sample/simple.c new file mode 100644 index 0000000000..8ab776f127 --- /dev/null +++ b/thirdParty/libxbee/sample/simple.c @@ -0,0 +1,68 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample will politely return any recieved data */ + +#include <stdio.h> +#include <stdlib.h> +#include <xbee.h> + +int main(int argc, char *argv[]) { + xbee_con *con; + xbee_pkt *pkt, *rpkt; + + /* setup the xbee */ + if (xbee_setup("/dev/ttyUSB0",57600) == -1) { + /* oh no... it failed */ + printf("xbee_setup() failed...\n"); + exit(1); + } + + /* setup a connection */ + con = xbee_newcon('I',xbee_64bitData, 0x0013A200, 0x40081826); + + printf("Waiting...\n"); + + /* just wait for data, and echo it back! */ + while (1) { + /* while there are packets avaliable... */ + while ((pkt = xbee_getpacket(con)) != NULL) { + /* print the recieved data */ + printf("Rx: %s\n",pkt->data); + /* say thank you */ + if (xbee_senddata(con,"thank you for saying '%s'\r\n",pkt->data)) { + printf("xbee_senddata: Error\n"); + return 1; + } + /* free the packet */ + free(pkt); + } + usleep(100000); + } + + /* shouldn't ever get here but... */ + return 0; +} + diff --git a/thirdParty/libxbee/sample/talk_to_me.c b/thirdParty/libxbee/sample/talk_to_me.c new file mode 100644 index 0000000000..26750988ab --- /dev/null +++ b/thirdParty/libxbee/sample/talk_to_me.c @@ -0,0 +1,82 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee -g +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample will make the remote XBee talk to us! */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <xbee.h> + +int main(int argc, char *argv[]) { + union { + unsigned char as8[8]; + unsigned int as32[2]; + } addr; + xbee_con *atCon, *rCon; + xbee_pkt *pkt; + + /* the extra arguments are the CC ('+' by default) and GT (1000) by default AT values */ + xbee_setuplogAPI("/dev/ttyUSB0",57600,2,'+',1000); + + atCon = xbee_newcon('@', xbee_localAT); + + xbee_senddata(atCon, "SH"); + pkt = xbee_getpacketwait(atCon); + if (!pkt || pkt->status || pkt->atCmd[0] != 'S' || pkt->atCmd[1] != 'H') { + printf("Missing SH Packet!\n"); + return 1; + } + addr.as8[3] = pkt->data[0]; + addr.as8[2] = pkt->data[1]; + addr.as8[1] = pkt->data[2]; + addr.as8[0] = pkt->data[3]; + free(pkt); + + xbee_senddata(atCon, "SL"); + pkt = xbee_getpacketwait(atCon); + if (!pkt || pkt->status || pkt->atCmd[0] != 'S' || pkt->atCmd[1] != 'L') { + printf("Missing SL Packet!\n"); + return 1; + } + addr.as8[7] = pkt->data[0]; + addr.as8[6] = pkt->data[1]; + addr.as8[5] = pkt->data[2]; + addr.as8[4] = pkt->data[3]; + free(pkt); + + printf("Local XBee address is: 0x%08X %08X\n", addr.as32[0], addr.as32[1]); + + rCon = xbee_newcon('#', xbee_64bitRemoteAT, 0x13A200, 0x403CB26A); + + xbee_senddata(rCon, "DH%c%c%c%c", addr.as8[3], addr.as8[2], addr.as8[1], addr.as8[0]); + usleep(250000); + xbee_senddata(rCon, "DL%c%c%c%c", addr.as8[7], addr.as8[6], addr.as8[5], addr.as8[4]); + usleep(250000); + + /* calling xbee_end() will return the xbee to its previous API mode */ + xbee_end(); + return 0; +} diff --git a/thirdParty/libxbee/sample/vb6/README.txt b/thirdParty/libxbee/sample/vb6/README.txt new file mode 100644 index 0000000000..fe13a7dfcb --- /dev/null +++ b/thirdParty/libxbee/sample/vb6/README.txt @@ -0,0 +1,8 @@ +These sample projects provide a quick demo of how to use various functions + +Running these assume that you have first compiled libxbee.dll successfully +You will also need to either copy libxbee.dll into this folder or into a + directory in your PATH + +If you want to use libxbee in your own projects, you must include libxbee.bas + which will provide you with access to the functions and type declarations diff --git a/thirdParty/libxbee/sample/vb6/demo/Form1.frm b/thirdParty/libxbee/sample/vb6/demo/Form1.frm new file mode 100644 index 0000000000..4c7c6655bc --- /dev/null +++ b/thirdParty/libxbee/sample/vb6/demo/Form1.frm @@ -0,0 +1,64 @@ +VERSION 5.00 +Begin VB.Form Form1 + Caption = "Form1" + ClientHeight = 2250 + ClientLeft = 120 + ClientTop = 450 + ClientWidth = 3855 + LinkTopic = "Form1" + ScaleHeight = 2250 + ScaleWidth = 3855 + StartUpPosition = 3 'Windows Default + Begin VB.TextBox tb + Height = 1995 + Left = 120 + MultiLine = -1 'True + TabIndex = 0 + Top = 120 + Width = 3615 + End +End +Attribute VB_Name = "Form1" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Option Explicit + +Dim myCon As Long +Dim myDataCon As Long + +Private Sub Form_Load() + Dim i As Long + Dim x As Byte + Dim ctype, addrH, addrL As Long + Me.Show + DoEvents + + ' Connect to the XBee on COM1 with a baud rate of 57600 + ' The XBee should be in API mode 2 (ATAP2) + If xbee_setupDebug("COM8", 57600, "xbee.log") <> 0 Then + MsgBox "Error while setting up the local XBee module", vbCritical, "xbee_setup()" + End + End If + xbee_logit "Hello!" + + ' Enable callbacks, this only needs to be done ONCE + ' The window handle provided must remain in memory (dont unload the form - callbacks will automatically be disabled) + xbee_enableCallbacks Me.hWnd + + ' Create a Remote AT connection to a node using 64-bit addressing + myCon = xbee_newcon_64bit(&H30, xbee_64bitRemoteAT, &H13A200, &H404B75DE) + xbee_enableACKwait myCon + + myDataCon = xbee_newcon_64bit(&H31, xbee_64bitData, &H13A200, &H404B75DE) + + ' Setup callbacks + xbee_attachCallback myCon, AddressOf Module1.callback1 + xbee_attachCallback myDataCon, AddressOf Module1.callback2 + + ' Send the AT command NI (Node Identifier) + tb.text = "Sending 'ATNI'..." + xbee_sendstring myCon, "NI" +End Sub + diff --git a/thirdParty/libxbee/sample/vb6/demo/demo.bas b/thirdParty/libxbee/sample/vb6/demo/demo.bas new file mode 100644 index 0000000000..b1e51fd907 --- /dev/null +++ b/thirdParty/libxbee/sample/vb6/demo/demo.bas @@ -0,0 +1,19 @@ +Attribute VB_Name = "Module1" +Public Function callback1(ByVal con As Long, ByRef pkt As xbee_pkt) As Long + ' Check the returned status, if it isnt 0 then an error occured + If pkt.status <> 0 Then + Form1.tb.Text = Form1.tb.Text & vbNewLine & "An error occured (" & pkt.status & ")" + Exit Function + End If + + ' Display the Node Identifier + Form1.tb.Text = Form1.tb.Text & vbNewLine & "Node Identifier:" & StrConv(pkt.data, vbUnicode) + Form1.tb.SelStart = Len(Form1.tb.Text) +End Function + +Public Function callback2(ByVal con As Long, ByRef pkt As xbee_pkt) As Long + ' Display the data + Form1.tb.Text = Form1.tb.Text & vbNewLine & "Rx:" & StrConv(pkt.data, vbUnicode) + Form1.tb.SelStart = Len(Form1.tb.Text) +End Function + diff --git a/thirdParty/libxbee/sample/vb6/demo/demo.vbp b/thirdParty/libxbee/sample/vb6/demo/demo.vbp new file mode 100644 index 0000000000..815e949e70 --- /dev/null +++ b/thirdParty/libxbee/sample/vb6/demo/demo.vbp @@ -0,0 +1,33 @@ +Type=Exe +Form=Form1.frm +Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation +Module=Module1; demo.bas +Module=libxbee; ..\libxbee.bas +IconForm="Form1" +Startup="Form1" +ExeName32="demo.exe" +Command32="" +Name="Project1" +HelpContextID="0" +CompatibleMode="0" +MajorVer=1 +MinorVer=0 +RevisionVer=0 +AutoIncrementVer=0 +ServerSupportFiles=0 +VersionCompanyName="Microsoft" +CompilationType=0 +OptimizationType=0 +FavorPentiumPro(tm)=0 +CodeViewDebugInfo=0 +NoAliasing=0 +BoundsCheck=0 +OverflowCheck=0 +FlPointCheck=0 +FDIVCheck=0 +UnroundedFP=0 +StartMode=0 +Unattended=0 +Retained=0 +ThreadPerObject=0 +MaxNumberOfThreads=1 diff --git a/thirdParty/libxbee/sample/vb6/libxbee.bas b/thirdParty/libxbee/sample/vb6/libxbee.bas new file mode 100644 index 0000000000..0875907f91 --- /dev/null +++ b/thirdParty/libxbee/sample/vb6/libxbee.bas @@ -0,0 +1,285 @@ +Attribute VB_Name = "libxbee" +Option Explicit + +Enum xbee_types + xbee_unknown + + xbee_localAT + xbee_remoteAT + xbee_modemStatus + xbee_txStatus + + ' XBee Series 1 stuff + xbee_16bitRemoteAT + xbee_64bitRemoteAT + + xbee_16bitData + xbee_64bitData + + xbee_16bitIO + xbee_64bitIO + + ' XBee Series 2 stuff + xbee2_data + xbee2_txStatus +End Enum + +Type xbee_sample + '# X A5 A4 A3 A2 A1 A0 D8 D7 D6 D5 D4 D3 D2 D1 D0 + IOmask As Integer + '# X X X X X X X D8 D7 D6 D5 D4 D3 D2 D1 D0 + IOdigital As Integer + '# X X X X X D D D D D D D D D D D + IOanalog(0 To 5) As Integer +End Type + +Type xbee_pkt + flags As Long '# bit 0 - is64 + '# bit 1 - dataPkt + '# bit 2 - txStatusPkt + '# bit 3 - modemStatusPkt + '# bit 4 - remoteATPkt + '# bit 5 - IOPkt + frameID As Byte + atCmd(0 To 1) As Byte + + status As Byte + samples As Byte + RSSI As Byte + + Addr16(0 To 1) As Byte + + Addr64(0 To 7) As Byte + + data(0 To 127) As Byte + + datalen As Long + + type As Long ' enum xbee_types + + SPARE As Long ' IGNORE THIS (is the pointer to the next packet in C... this will ALWAYS be 0 in VB) + + IOdata As xbee_sample +End Type + +Private OldhWndHandler As Long +Private ActivehWnd As Long +Private callbackMessageID As Long +Private Callbacks As New Collection + +Public Declare Sub xbee_free Lib "libxbee.dll" (ByVal ptr As Long) + +Public Declare Function xbee_setup Lib "libxbee.dll" (ByVal port As String, ByVal baudRate As Long) As Long +Public Declare Function xbee_setupDebug Lib "libxbee.dll" (ByVal port As String, ByVal baudRate As Long, ByVal logfile As String) As Long +Private Declare Function xbee_setupDebugAPIRaw Lib "libxbee.dll" Alias "xbee_setupDebugAPI" (ByVal port As String, ByVal baudRate As Long, ByVal logfile As String, ByVal cmdSeq As Byte, ByVal cmdTime As Long) As Long +Private Declare Function xbee_setupAPIRaw Lib "libxbee.dll" Alias "xbee_setupAPI" (ByVal port As String, ByVal baudRate As Long, ByVal cmdSeq As Byte, ByVal cmdTime As Long) As Long + +Public Declare Function xbee_end Lib "libxbee.dll" () As Long + +Public Declare Function xbee_newcon_simple Lib "libxbee.dll" (ByVal frameID As Byte, ByVal conType As Long) As Long 'xbee_con * +Public Declare Function xbee_newcon_16bit Lib "libxbee.dll" (ByVal frameID As Byte, ByVal conType As Long, ByVal addr16bit As Long) As Long 'xbee_con * +Public Declare Function xbee_newcon_64bit Lib "libxbee.dll" (ByVal frameID As Byte, ByVal conType As Long, ByVal addr64bitLow As Long, ByVal addr64bitHigh As Long) As Long 'xbee_con * +Public Declare Sub xbee_enableACKwait Lib "libxbee.dll" (ByVal con As Long) +Public Declare Sub xbee_disableACKwait Lib "libxbee.dll" (ByVal con As Long) +Public Declare Sub xbee_enableDestroySelf Lib "libxbee.dll" (ByVal con As Long) + +Private Declare Sub xbee_enableCallbacksRaw Lib "libxbee.dll" Alias "xbee_enableCallbacks" (ByVal hWnd As Long, ByVal uMsg As Long) +Private Declare Sub xbee_attachCallbackRaw Lib "libxbee.dll" Alias "xbee_attachCallback" (ByVal con As Long) +Private Declare Sub xbee_detachCallbackRaw Lib "libxbee.dll" Alias "xbee_detachCallback" (ByVal con As Long) +Private Declare Function xbee_runCallback Lib "libxbee.dll" (ByVal func As Long, ByVal con As Long, ByVal pkt As Long) As Long + +Public Declare Sub xbee_endcon2 Lib "libxbee.dll" (ByVal con As Long) +Public Declare Sub xbee_flushcon Lib "libxbee.dll" (ByVal con As Long) + +Public Declare Function xbee_senddata Lib "libxbee.dll" Alias "xbee_nsenddata" (ByVal con As Long, ByRef data As Byte, ByVal Length As Long) As Long +Private Declare Function xbee_senddata_str Lib "libxbee.dll" Alias "xbee_nsenddata" (ByVal con As Long, ByVal data As String, ByVal Length As Long) As Long + +Public Declare Function xbee_getpacketRaw Lib "libxbee.dll" Alias "xbee_getpacket" (ByVal con As Long) As Long 'xbee_pkt * + +Public Declare Function xbee_hasanalog Lib "libxbee.dll" (ByRef pkt As xbee_pkt, ByVal sample As Long, ByVal inputPin As Long) As Long +Public Declare Function xbee_getanalog Lib "libxbee.dll" (ByRef pkt As xbee_pkt, ByVal sample As Long, ByVal inputPin As Long, ByVal Vref As Double) As Double + +Public Declare Function xbee_hasdigital Lib "libxbee.dll" (ByRef pkt As xbee_pkt, ByVal sample As Long, ByVal inputPin As Long) As Long +Public Declare Function xbee_getdigital Lib "libxbee.dll" (ByRef pkt As xbee_pkt, ByVal sample As Long, ByVal inputPin As Long) As Long + +Private Declare Function xbee_svn_versionRaw Lib "libxbee.dll" Alias "xbee_svn_version" () As Long +Public Declare Sub xbee_logit Lib "libxbee.dll" (ByVal text As String) + +'########################################################################################################################################################################### + +Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long) +Private Declare Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long +Private Declare Function RegisterWindowMessage Lib "user32" Alias "RegisterWindowMessageA" (ByVal lpString As String) As Long +Private Declare Function SetWindowLong Lib "user32" Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long +Private Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long +Private Const WM_DESTROY = &H2 +Private Const GWL_WNDPROC = -4 + +Public Function PointerToString(lngPtr As Long) As String + Dim strTemp As String + Dim lngLen As Long + If lngPtr Then + lngLen = lstrlenW(lngPtr) * 2 + If lngLen Then + strTemp = Space(lngLen) + CopyMemory ByVal strTemp, ByVal lngPtr, lngLen + PointerToString = Replace(strTemp, Chr(0), "") + End If + End If +End Function + +Public Function ArrayToString(data() As Byte, Optional lb As Integer = -1, Optional ub As Integer = -1) As String + Dim tmp As String + Dim i + If lb = -1 Then lb = LBound(data) + If ub = -1 Then ub = UBound(data) + tmp = "" + For i = lb To ub + If (data(i) = 0) Then Exit For + tmp = tmp & Chr(data(i)) + Next + ArrayToString = tmp +End Function + +Public Function xbee_pointerToPacket(lngPtr As Long) As xbee_pkt + Dim p As xbee_pkt + CopyMemory p, ByVal lngPtr, Len(p) + xbee_pointerToPacket = p +End Function + +Public Sub libxbee_load() + ' this function is simply to get VB6 to call a libxbee function + ' if you are using any C DLLs that make use of libxbee, then you should call this function first so that VB6 will load libxbee + xbee_svn_versionRaw +End Sub + +Public Function xbee_svn_version() As String + xbee_svn_version = PointerToString(xbee_svn_versionRaw()) +End Function + +Public Function xbee_setupAPI(ByVal port As String, ByVal baudRate As Long, ByVal cmdSeq As String, ByVal cmdTime As Long) + xbee_setupAPI = xbee_setupAPIRaw(port, baudRate, Asc(cmdSeq), cmdTime) +End Function + +Public Function xbee_setupDebugAPI(ByVal port As String, ByVal baudRate As Long, ByVal logfile As String, ByVal cmdSeq As String, ByVal cmdTime As Long) + xbee_setupDebugAPI = xbee_setupDebugAPIRaw(port, baudRate, logfile, Asc(cmdSeq), cmdTime) +End Function + +Private Sub xbee_ensureMessageID() + If callbackMessageID = 0 Then + callbackMessageID = RegisterWindowMessage("libxbee") + End If + xbee_enableCallbacksRaw ActivehWnd, callbackMessageID +End Sub + +Public Sub xbee_attachCallback(ByVal con As Long, ByVal func As Long) + Dim t(0 To 1) As Long + Dim c As String + If ActivehWnd = 0 Then + Debug.Print "Callbacks not enabled!" + Exit Sub + End If + xbee_ensureMessageID + c = CStr(con) + t(0) = con + t(1) = func + On Error Resume Next + Callbacks.Remove c + Callbacks.Add t, c + On Error GoTo 0 + xbee_attachCallbackRaw con +End Sub + +Public Sub xbee_detachCallback(ByVal con As Long) + If ActivehWnd = 0 Then + Debug.Print "Callbacks not enabled!" + Exit Sub + End If + On Error Resume Next + xbee_detachCallbackRaw con + Callbacks.Remove CStr(con) +End Sub + +Public Sub xbee_enableCallbacks(ByVal hWnd As Long) + If ActivehWnd <> 0 Then + Debug.Print "Callbacks already enabled!" + Exit Sub + End If + ActivehWnd = hWnd + OldhWndHandler = SetWindowLong(hWnd, GWL_WNDPROC, AddressOf libxbee.xbee_messageHandler) + xbee_ensureMessageID +End Sub + +Public Sub xbee_disableCallbacks() + Dim id As Variant + If ActivehWnd = 0 Then + Debug.Print "Callbacks not enabled!" + Exit Sub + End If + For Each id In Callbacks + xbee_detachCallback id(0) + Next + SetWindowLong ActivehWnd, GWL_WNDPROC, OldhWndHandler + ActivehWnd = 0 + OldhWndHandler = 0 +End Sub + +Private Function xbee_messageHandler(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long + If uMsg = callbackMessageID Then + Dim t As Long + On Error Resume Next + Err.Clear + t = Callbacks.Item(CStr(wParam))(1) + If Err.Number = 0 Then + On Error GoTo 0 + xbee_messageHandler = xbee_runCallback(t, wParam, lParam) + Exit Function + End If + On Error GoTo 0 + xbee_logit "Unable to match Connection with active callback!" + End If + xbee_messageHandler = CallWindowProc(OldhWndHandler, hWnd, uMsg, wParam, lParam) + If uMsg = WM_DESTROY And ActivehWnd <> 0 Then + ' Disable the MessageHandler if the form "unload" event is detected + xbee_disableCallbacks + End If +End Function + +Public Sub xbee_endcon(ByRef con As Long) + xbee_endcon2 con + con = 0 +End Sub + +Public Function xbee_sendstring(ByVal con As Long, ByVal str As String) + xbee_sendstring = xbee_senddata_str(con, str, Len(str)) +End Function + +Public Function xbee_getpacketPtr(ByVal con As Long, ByRef pkt As Long) As Integer + Dim ptr As Long + + ptr = xbee_getpacketRaw(con) + If ptr = 0 Then + pkt = 0 + xbee_getpacketPtr = 0 + Exit Function + End If + + pkt = ptr + xbee_getpacketPtr = 1 +End Function + +Public Function xbee_getpacket(ByVal con As Long, ByRef pkt As xbee_pkt) As Integer + Dim ptr As Long + + ptr = xbee_getpacketRaw(con) + If ptr = 0 Then + xbee_getpacket = 0 + Exit Function + End If + + pkt = xbee_pointerToPacket(ptr) + xbee_free ptr + + xbee_getpacket = 1 +End Function + diff --git a/thirdParty/libxbee/sample/vb6/talk_to_me/Form1.frm b/thirdParty/libxbee/sample/vb6/talk_to_me/Form1.frm new file mode 100644 index 0000000000..426a9df939 --- /dev/null +++ b/thirdParty/libxbee/sample/vb6/talk_to_me/Form1.frm @@ -0,0 +1,1197 @@ +VERSION 5.00 +Begin VB.Form Form1 + BorderStyle = 1 'Fixed Single + Caption = "Talk to Me" + ClientHeight = 7875 + ClientLeft = 45 + ClientTop = 375 + ClientWidth = 7515 + LinkTopic = "Form1" + MaxButton = 0 'False + ScaleHeight = 7875 + ScaleWidth = 7515 + StartUpPosition = 1 'CenterOwner + Begin VB.Timer tmr_timeout + Enabled = 0 'False + Interval = 5000 + Left = 3720 + Top = 1380 + End + Begin VB.Frame Frame2 + Caption = " Actions " + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 1335 + Left = 180 + TabIndex = 1 + Top = 6420 + Width = 7215 + Begin VB.CommandButton write_settings + Caption = "Write Settings" + Enabled = 0 'False + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 375 + Left = 1920 + TabIndex = 50 + Top = 780 + Width = 1935 + End + Begin VB.CommandButton set_default + Caption = "Set Default" + Enabled = 0 'False + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 375 + Left = 180 + TabIndex = 49 + Top = 780 + Width = 1575 + End + Begin VB.CommandButton reset_node + Caption = "Reset Node" + Enabled = 0 'False + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 375 + Left = 4020 + TabIndex = 47 + Top = 780 + Width = 1575 + End + Begin VB.CommandButton set_dest + Caption = "Set destination" + Enabled = 0 'False + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 375 + Left = 1920 + TabIndex = 46 + Top = 300 + Width = 1935 + End + Begin VB.CommandButton talk_to_me + Caption = "Talk to Me" + Enabled = 0 'False + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 375 + Left = 180 + TabIndex = 45 + Top = 300 + Width = 1575 + End + Begin VB.CommandButton set_ni + Caption = "Set Node Identifier" + Enabled = 0 'False + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 375 + Left = 4020 + TabIndex = 51 + Top = 300 + Width = 2355 + End + End + Begin VB.Frame Frame1 + Caption = " Settings " + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 3315 + Left = 180 + TabIndex = 0 + Top = 3000 + Width = 7215 + Begin VB.Label ni + BackStyle = 0 'Transparent + Caption = "-" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3180 + TabIndex = 24 + Top = 300 + Width = 3915 + End + Begin VB.Label sl + BackStyle = 0 'Transparent + Caption = "-" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3180 + TabIndex = 22 + Top = 1020 + Width = 3915 + End + Begin VB.Label sh + BackStyle = 0 'Transparent + Caption = "-" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3180 + TabIndex = 20 + Top = 780 + Width = 3915 + End + Begin VB.Label my + BackStyle = 0 'Transparent + Caption = "-" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3180 + TabIndex = 18 + Top = 540 + Width = 3915 + End + Begin VB.Label ap + BackStyle = 0 'Transparent + Caption = "-" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3180 + TabIndex = 17 + Top = 1260 + Width = 3915 + End + Begin VB.Label bd + BackStyle = 0 'Transparent + Caption = "-" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3180 + TabIndex = 16 + Top = 1500 + Width = 3915 + End + Begin VB.Label ch + BackStyle = 0 'Transparent + Caption = "-" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3180 + TabIndex = 15 + Top = 1740 + Width = 3915 + End + Begin VB.Label dh + BackStyle = 0 'Transparent + Caption = "-" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3180 + TabIndex = 14 + Top = 1980 + Width = 3915 + End + Begin VB.Label dl + BackStyle = 0 'Transparent + Caption = "-" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3180 + TabIndex = 13 + Top = 2220 + Width = 3915 + End + Begin VB.Label ia + BackStyle = 0 'Transparent + Caption = "-" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3180 + TabIndex = 11 + Top = 2460 + Width = 3915 + End + Begin VB.Label vr + BackStyle = 0 'Transparent + Caption = "-" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3180 + TabIndex = 10 + Top = 2940 + Width = 3915 + End + Begin VB.Label hv + BackStyle = 0 'Transparent + Caption = "-" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Left = 3180 + TabIndex = 12 + Top = 2700 + Width = 3915 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "NI - Node Identifier" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Index = 17 + Left = 180 + TabIndex = 25 + Top = 300 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "MY - 16-bit Address" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Index = 13 + Left = 180 + TabIndex = 19 + Top = 540 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "VR - Firmware Version" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Index = 14 + Left = 180 + TabIndex = 9 + Top = 2940 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "IA - I/O Address" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Index = 12 + Left = 180 + TabIndex = 8 + Top = 2460 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "DL - Destination Low" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Index = 10 + Left = 180 + TabIndex = 6 + Top = 2220 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "DH - Destination High" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Index = 9 + Left = 180 + TabIndex = 5 + Top = 1980 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "CH - Channel" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Index = 8 + Left = 180 + TabIndex = 4 + Top = 1740 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "BD - Interface Rate" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Index = 7 + Left = 180 + TabIndex = 3 + Top = 1500 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "AP - API Enable" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Index = 6 + Left = 180 + TabIndex = 2 + Top = 1260 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "HV - Hardware Version" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Index = 11 + Left = 180 + TabIndex = 7 + Top = 2700 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = " .....:" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 255 + Index = 29 + Left = 180 + TabIndex = 44 + Top = 2700 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = " ...........:" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 255 + Index = 28 + Left = 180 + TabIndex = 43 + Top = 1260 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = " .......:" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 255 + Index = 27 + Left = 180 + TabIndex = 42 + Top = 1500 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = " ..............:" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 255 + Index = 26 + Left = 180 + TabIndex = 41 + Top = 1740 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = " .....:" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 255 + Index = 25 + Left = 180 + TabIndex = 40 + Top = 1980 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = " ......:" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 255 + Index = 24 + Left = 180 + TabIndex = 39 + Top = 2220 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = " ..........:" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 255 + Index = 23 + Left = 180 + TabIndex = 38 + Top = 2460 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = " .....:" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 255 + Index = 22 + Left = 180 + TabIndex = 37 + Top = 2940 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = " .......:" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 255 + Index = 21 + Left = 180 + TabIndex = 36 + Top = 540 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = " ......:" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 255 + Index = 18 + Left = 180 + TabIndex = 33 + Top = 300 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "SL - 64-bit Address (Lo)" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Index = 16 + Left = 180 + TabIndex = 23 + Top = 1020 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "SH - 64-bit Address (Hi)" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 255 + Index = 15 + Left = 180 + TabIndex = 21 + Top = 780 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = " ..:" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 255 + Index = 20 + Left = 180 + TabIndex = 35 + Top = 780 + Width = 2955 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = " ..:" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 255 + Index = 19 + Left = 180 + TabIndex = 34 + Top = 1020 + Width = 2955 + End + End + Begin VB.Timer tmr_refresh + Enabled = 0 'False + Interval = 500 + Left = 3240 + Top = 1380 + End + Begin VB.Frame Frame3 + Caption = " Node List " + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 2775 + Left = 180 + TabIndex = 26 + Top = 120 + Width = 7215 + Begin VB.ListBox nodelist + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 2085 + Left = 180 + TabIndex = 27 + Top = 540 + Width = 6855 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "16-bit" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 195 + Index = 0 + Left = 240 + TabIndex = 32 + Top = 300 + Width = 675 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "RSSI" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 195 + Index = 3 + Left = 3660 + TabIndex = 30 + Top = 300 + Width = 435 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "@" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 195 + Index = 4 + Left = 4440 + TabIndex = 29 + Top = 300 + Width = 135 + End + Begin VB.Label Label + BackStyle = 0 'Transparent + Caption = "Node Name" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 195 + Index = 5 + Left = 4740 + TabIndex = 28 + Top = 300 + Width = 915 + End + Begin VB.Label Label + Alignment = 2 'Center + BackStyle = 0 'Transparent + Caption = "- -" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + ForeColor = &H00C0C0C0& + Height = 195 + Index = 2 + Left = 1020 + TabIndex = 48 + Top = 300 + Width = 2355 + End + Begin VB.Label Label + Alignment = 2 'Center + BackStyle = 0 'Transparent + Caption = "(Hi) 64-bit (Lo)" + BeginProperty Font + Name = "Courier New" + Size = 9 + Charset = 0 + Weight = 400 + Underline = 0 'False + Italic = 0 'False + Strikethrough = 0 'False + EndProperty + Height = 195 + Index = 1 + Left = 1020 + TabIndex = 31 + Top = 300 + Width = 2355 + End + End +End +Attribute VB_Name = "Form1" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = True +Attribute VB_Exposed = False +Dim dieNow As Boolean + +Private Sub Form_Load() + Me.Show + DoEvents + dieNow = False + + ' setup libxbee + If (xbee_setupDebugAPI("COM8", 57600, "xbee.log", "+", 250) = -1) Then + MsgBox "libxbee setup failed...", vbCritical + Unload Me + End + End If + + ' enable callback functions + xbee_enableCallbacks Me.hWnd + + ' setup a local at connection + atcon = xbee_newcon_simple(Asc("A"), xbee_localAT) + xbee_enableACKwait atcon + xbee_attachCallback atcon, AddressOf localCB + + ' set off the chain reaction! + xbeesend atcon, "MY" +End Sub + +Private Sub Form_Unload(Cancel As Integer) + Static c As Integer + dieNow = 1 + Cancel = 1 + Me.Caption = "Waiting for command to complete..." + c = c + 1 + If (c >= 2) Then + Cancel = 0 + End If +End Sub + +Private Sub nodelist_Click() + Dim tmp() As String + If nodelist.ListCount = 0 Or nodelist.ListIndex = -1 Then Exit Sub + If set_dest.Tag = "yes" Then + nodelist.Enabled = False + Else + If nodelist.ListIndex = 0 Then + remoteCon = atcon + Else + str2 = Split(nodelist.text, " ") + remoteCon = xbee_newcon_64bit(Asc("2"), xbee_64bitRemoteAT, CLng("&H" & Right(str2(1), 8)), CLng("&H" & Right(str2(2), 8))) + End If + setButtons False + nodelist.Enabled = False + tmp = Split(nodelist.List(nodelist.ListIndex), " ") + ni = tmp(5) + my = tmp(0) + sh = tmp(1) + sl = tmp(2) + ap = "-" + bd = "-" + ch = "-" + dh = "-" + dl = "-" + ia = "-" + hv = "-" + vr = "-" + End If +End Sub + +Private Sub reset_node_Click() + If nodelist.ListCount = 0 Or nodelist.ListIndex = -1 Then Exit Sub + nodelist.Enabled = False + setButtons False + reset_node.Tag = "yes" +End Sub + +Private Sub set_default_Click() + If nodelist.ListCount = 0 Or nodelist.ListIndex = -1 Then Exit Sub + nodelist.Enabled = False + setButtons False + set_default.Tag = "yes" +End Sub + +Private Sub set_dest_Click() + If nodelist.ListCount = 0 Or nodelist.ListIndex = -1 Then Exit Sub + nodelist.Tag = nodelist.ListIndex + setButtons False + set_dest.Tag = "yes" +End Sub + +Private Sub set_ni_Click() + Dim newni As String + Dim oldni As String + oldni = Split(nodelist.text, " ")(5) + newni = InputBox("New node identifier:", "Set Node Identifier", oldni) + If newni = oldni Then Exit Sub + nodelist.Enabled = False + setButtons False + set_ni.Tag = newni +End Sub + +Private Sub talk_to_me_Click() + If nodelist.ListCount = 0 Or nodelist.ListIndex = -1 Then Exit Sub + nodelist.Enabled = False + setButtons False + talk_to_me.Tag = "yes" +End Sub + +Private Sub tmr_refresh_Timer() + Dim str As String + Dim str2() As String + tmr_refresh.Enabled = False + If atcon = 0 Then Exit Sub + + If (dieNow) Then + xbee_end + DoEvents + xbee_disableCallbacks + Unload Me + End + End If + + If nodelist.Enabled = False Then + xbee_attachCallback remoteCon, AddressOf remoteCB + If talk_to_me.Tag = "yes" Then + str2 = Split(Form1.nodelist.text, " ") + xbee_attachCallback remoteCon, AddressOf setupCB_TTM + str2 = Split(nodelist.List(0), " ") + str = Chr(CInt("&H" & Mid(str2(1), 9, 2))) + str = Chr(CInt("&H" & Mid(str2(1), 7, 2))) & str + str = Chr(CInt("&H" & Mid(str2(1), 5, 2))) & str + str = Chr(CInt("&H" & Mid(str2(1), 3, 2))) & str + str = "DH" & str + xbeesend remoteCon, str + ElseIf set_dest.Tag = "yes" Then + str2 = Split(Form1.nodelist.text, " ") + xbee_attachCallback remoteCon, AddressOf setupCB_SDEST + str2 = Split(nodelist.text, " ") + str = Chr(CInt("&H" & Mid(str2(1), 9, 2))) + str = Chr(CInt("&H" & Mid(str2(1), 7, 2))) & str + str = Chr(CInt("&H" & Mid(str2(1), 5, 2))) & str + str = Chr(CInt("&H" & Mid(str2(1), 3, 2))) & str + str = "DH" & str + xbeesend remoteCon, str + ElseIf reset_node.Tag = "yes" Then + xbee_sendstring remoteCon, "FR" + setButtons True + reset_node.Tag = "" + tmr_refresh.Enabled = True + ElseIf write_settings.Tag = "yes" Then + xbee_sendstring remoteCon, "WR" + setButtons True + write_settings.Tag = "" + tmr_refresh.Enabled = True + ElseIf set_default.Tag = "yes" Then + setupCB_Default_Start + ElseIf set_ni.Tag <> "" Then + xbeesend remoteCon, "NI" & set_ni.Tag + set_ni.Tag = "" + Else + xbeesend remoteCon, "AP" + End If + Exit Sub + End If + ' initiate network scan + xbee_attachCallback atcon, AddressOf localCB + xbeesend atcon, "MY" +End Sub + +Private Sub tmr_timeout_Timer() + Dim con As Long + Dim str As String + Dim str2() As String + tmr_timeout.Enabled = False + str2 = Split(tmr_timeout.Tag, Chr(1), 2) + con = CStr(str2(0)) + str = str2(1) + If MsgBox("Request timed out... Retry?", vbYesNo + vbQuestion, "Retry?") = vbNo Then + setButtons True + nodelist.Enabled = True + tmr_refresh.Enabled = True + Exit Sub + End If + xbeesend con, str +End Sub + +Private Sub write_settings_Click() + If nodelist.ListCount = 0 Or nodelist.ListIndex = -1 Then Exit Sub + nodelist.Enabled = False + setButtons False + write_settings.Tag = "yes" +End Sub diff --git a/thirdParty/libxbee/sample/vb6/talk_to_me/talk_to_me.bas b/thirdParty/libxbee/sample/vb6/talk_to_me/talk_to_me.bas new file mode 100644 index 0000000000..dc9f5f76d1 --- /dev/null +++ b/thirdParty/libxbee/sample/vb6/talk_to_me/talk_to_me.bas @@ -0,0 +1,431 @@ +Attribute VB_Name = "Module1" +Public atcon As Long +Public remoteCon As Long + +Public Sub setButtons(ByVal state As Boolean) + Form1.talk_to_me.Tag = "" + Form1.talk_to_me.Enabled = state + Form1.set_dest.Tag = "" + Form1.set_dest.Enabled = state + Form1.reset_node.Tag = "" + Form1.reset_node.Enabled = state + Form1.set_default.Tag = "" + Form1.set_default.Enabled = state + Form1.write_settings.Tag = "" + Form1.write_settings.Enabled = state + Form1.set_ni.Tag = "" + Form1.set_ni.Enabled = state +End Sub + +Public Function xbeesend(ByVal con As Long, ByVal str As String) As Long + Form1.tmr_timeout.Enabled = False + Form1.tmr_timeout.Tag = CStr(con) & Chr(1) & str + Form1.tmr_timeout.Enabled = True + xbee_sendstring con, str +End Function + +Public Sub setupCB_Default_Start() + xbee_attachCallback remoteCon, AddressOf setupCB_Default + xbee_attachCallback atcon, AddressOf setupCB_Default + xbeesend remoteCon, "CH" & Chr(16) +End Sub +Public Function setupCB_Default(ByVal con As Long, ByRef pkt As xbee_pkt) As Long + Dim str As String + Dim str2() As String + ' default values (in order of setting): + ' CH = 10 + ' local CH = 10 + ' MY = FF + ' T3 = 1 + ' BD = 6 + ' AP = 0 + ' RO = 1 + ' D0 = 5 (turn on rest of system) + ' D1 = 2 (battery reading) + ' D2 = 0 + ' D3 = 5 (reset) + ' D4 = 4 (battery reading power) + ' D5 = 0 + ' D6 = 0 + ' D7 = 0 + ' D8 = 0 + ' IA = 0xFFFF (accept inputs from anyone) + ' IU = 0 + Debug.Print ArrayToString(pkt.atCmd) + If con = atcon Then + xbee_attachCallback con, AddressOf localCB + xbeesend remoteCon, "MY" & Chr(255) & Chr(255) + Exit Function + End If + Select Case ArrayToString(pkt.atCmd) + Case "CH" + xbeesend atcon, "CH" & Chr(16) + Case "MY" + xbeesend con, "T3" & Chr(1) + Case "T3" + xbeesend con, "BD" & Chr(0) & Chr(0) & Chr(0) & Chr(6) + Case "BD" + xbeesend con, "AP" & Chr(0) + Case "AP" + xbeesend con, "RO" & Chr(1) + Case "RO" + xbeesend con, "D0" & Chr(5) + Case "D0" + xbeesend con, "D1" & Chr(2) + Case "D1" + xbeesend con, "D2" & Chr(0) + Case "D2" + xbeesend con, "D3" & Chr(4) + Case "D3" + xbeesend con, "D4" & Chr(4) + Case "D4" + xbeesend con, "D5" & Chr(0) + Case "D5" + xbeesend con, "D6" & Chr(0) + Case "D6" + xbeesend con, "D7" & Chr(0) + Case "D7" + xbeesend con, "D8" & Chr(0) + Case "D8" + xbeesend con, "IA" & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(0) & Chr(255) & Chr(255) + Case "IA" + xbeesend con, "IU" & Chr(0) + Case "IU" + Form1.set_default.Tag = "" + Form1.tmr_refresh.Enabled = True + Form1.tmr_timeout.Enabled = False + End Select +End Function + +Public Function setupCB_TTM(ByVal con As Long, ByRef pkt As xbee_pkt) As Long + Dim str As String + Dim str2() As String + Select Case ArrayToString(pkt.atCmd) + Case "DH" + str2 = Split(Form1.nodelist.List(0), " ") + str = Chr(CInt("&H" & Mid(str2(2), 9, 2))) + str = Chr(CInt("&H" & Mid(str2(2), 7, 2))) & str + str = Chr(CInt("&H" & Mid(str2(2), 5, 2))) & str + str = Chr(CInt("&H" & Mid(str2(2), 3, 2))) & str + str = "DL" & str + xbeesend con, str + Case "DL" + Form1.talk_to_me.Tag = "" + Form1.tmr_refresh.Enabled = True + End Select +End Function + +Public Function setupCB_SDEST(ByVal con As Long, ByRef pkt As xbee_pkt) As Long + Dim str As String + Dim str2() As String + Select Case ArrayToString(pkt.atCmd) + Case "DH" + str2 = Split(Form1.nodelist.text, " ") + str = Chr(CInt("&H" & Mid(str2(2), 9, 2))) + str = Chr(CInt("&H" & Mid(str2(2), 7, 2))) & str + str = Chr(CInt("&H" & Mid(str2(2), 5, 2))) & str + str = Chr(CInt("&H" & Mid(str2(2), 3, 2))) & str + str = "DL" & str + xbeesend con, str + Case "DL" + Form1.set_dest.Tag = "" + Form1.nodelist.ListIndex = Form1.nodelist.Tag + Form1.tmr_refresh.Enabled = True + End Select +End Function + +Public Function remoteCB(ByVal con As Long, ByRef pkt As xbee_pkt) As Long + Dim t As String + Dim i As Long + Debug.Print "<+>", ArrayToString(pkt.atCmd) + Form1.tmr_timeout.Enabled = False + Select Case ArrayToString(pkt.atCmd) + Case "AP" + Select Case pkt.data(0) + Case 0 + Form1.ap.Caption = "0 - API Disabled" + Case 1 + Form1.ap.Caption = "1 - API Enabled (no escapes)" + Case 2 + Form1.ap.Caption = "2 - API Enabled (with escapes)" + Case Default + Form1.ap.Caption = "0x" & Hex(pkt.data(0)) & " - Unknown..." + End Select + xbeesend con, "BD" + Case "BD" + t = Hex(pkt.data(3)) + If (Len(t) < 2) Then t = "0" & t + t = Hex(pkt.data(2)) & t + If (Len(t) < 4) Then t = "0" & t + t = Hex(pkt.data(1)) & t + If (Len(t) < 6) Then t = "0" & t + t = Hex(pkt.data(0)) & t + If (Len(t) < 8) Then t = "0" & t + i = CStr("&H" & t) + Select Case i + Case 0 + Form1.bd.Caption = "0 - 1200 bps" + Case 1 + Form1.bd.Caption = "1 - 2400 bps" + Case 2 + Form1.bd.Caption = "2 - 4800 bps" + Case 3 + Form1.bd.Caption = "3 - 9600 bps" + Case 4 + Form1.bd.Caption = "4 - 19200 bps" + Case 5 + Form1.bd.Caption = "5 - 38400 bps" + Case 6 + Form1.bd.Caption = "6 - 57600 bps" + Case 7 + Form1.bd.Caption = "7 - 115200 bps" + Case Default + Form1.bd.Caption = "0x" & Hex(i) & " - Unknwon..." + End Select + xbeesend con, "CH" + Case "CH" + t = Hex(pkt.data(0)) + If (Len(t) < 2) Then t = "0" & t + Form1.ch.Caption = "0x" & t + xbeesend con, "DH" + Case "DH" + t = Hex(pkt.data(3)) + If (Len(t) < 2) Then t = "0" & t + t = Hex(pkt.data(2)) & t + If (Len(t) < 4) Then t = "0" & t + t = Hex(pkt.data(1)) & t + If (Len(t) < 6) Then t = "0" & t + t = Hex(pkt.data(0)) & t + If (Len(t) < 8) Then t = "0" & t + Form1.dh.Caption = "0x" & t + xbeesend con, "DL" + Case "DL" + t = Hex(pkt.data(3)) + If (Len(t) < 2) Then t = "0" & t + t = Hex(pkt.data(2)) & t + If (Len(t) < 4) Then t = "0" & t + t = Hex(pkt.data(1)) & t + If (Len(t) < 6) Then t = "0" & t + t = Hex(pkt.data(0)) & t + If (Len(t) < 8) Then t = "0" & t + Form1.dl.Caption = "0x" & t + xbeesend con, "IA" + Case "IA" + t = Hex(pkt.data(7)) & t + If (Len(t) < 2) Then t = "0" & t + t = Hex(pkt.data(6)) & t + If (Len(t) < 4) Then t = "0" & t + t = Hex(pkt.data(5)) & t + If (Len(t) < 6) Then t = "0" & t + t = Hex(pkt.data(4)) & t + If (Len(t) < 8) Then t = "0" & t + t = Hex(pkt.data(3)) & t + If (Len(t) < 10) Then t = "0" & t + t = Hex(pkt.data(2)) & t + If (Len(t) < 12) Then t = "0" & t + t = Hex(pkt.data(1)) & t + If (Len(t) < 14) Then t = "0" & t + t = Hex(pkt.data(0)) & t + If (Len(t) < 16) Then t = "0" & t + Form1.ia.Caption = "0x" & t + xbeesend con, "HV" + Case "HV" + t = Hex(pkt.data(1)) + If (Len(t) < 2) Then t = "0" & t + t = Hex(pkt.data(0)) & t + If (Len(t) < 4) Then t = "0" & t + Form1.hv.Caption = "0x" & t + xbeesend con, "VR" + Case "VR" + t = Hex(pkt.data(1)) + If (Len(t) < 2) Then t = "0" & t + t = Hex(pkt.data(0)) & t + If (Len(t) < 4) Then t = "0" & t + Form1.vr.Caption = "0x" & t + If con = atcon Then + xbee_attachCallback con, AddressOf localCB + End If + setButtons True + Form1.nodelist.Enabled = True + Form1.tmr_refresh.Enabled = True + Form1.tmr_timeout.Enabled = False + Case Else + If con = atcon Then + xbee_attachCallback con, AddressOf localCB + End If + setButtons True + Form1.nodelist.Enabled = True + Form1.tmr_refresh.Enabled = True + Form1.tmr_timeout.Enabled = False + End Select +End Function + +Public Function localCB(ByVal con As Long, ByRef pkt As xbee_pkt) As Long + Dim nodeinfo As String + Dim nodename As String + Dim tmp As String + Dim tmp2() As String + Dim sh, sl As String + Dim i, m As Integer + Dim AT As String + Form1.tmr_timeout.Enabled = False + AT = ArrayToString(pkt.atCmd) + ' handle initial stuff + Select Case AT + Case "MY" + nodeinfo = "0x" + tmp = Hex(pkt.data(0)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + nodeinfo = nodeinfo & tmp + tmp = Hex(pkt.data(1)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + nodeinfo = nodeinfo & tmp + If Form1.nodelist.ListCount > 0 Then + Form1.nodelist.List(0) = nodeinfo + Else + Form1.nodelist.AddItem nodeinfo + End If + ' issue next command + xbeesend con, "SH" + Case "SH" + nodeinfo = Form1.nodelist.List(0) & " 0x" + tmp = Hex(pkt.data(0)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + nodeinfo = nodeinfo & tmp + tmp = Hex(pkt.data(1)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + nodeinfo = nodeinfo & tmp + tmp = Hex(pkt.data(2)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + nodeinfo = nodeinfo & tmp + tmp = Hex(pkt.data(3)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + nodeinfo = nodeinfo & tmp + Form1.nodelist.List(0) = nodeinfo + ' issue next command + xbeesend con, "SL" + Case "SL" + nodeinfo = Form1.nodelist.List(0) & " 0x" + tmp = Hex(pkt.data(0)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + nodeinfo = nodeinfo & tmp + tmp = Hex(pkt.data(1)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + nodeinfo = nodeinfo & tmp + tmp = Hex(pkt.data(2)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + nodeinfo = nodeinfo & tmp + tmp = Hex(pkt.data(3)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + nodeinfo = nodeinfo & tmp + Form1.nodelist.List(0) = nodeinfo + ' issue next command + xbeesend con, "NI" + Case "NI" + nodeinfo = Form1.nodelist.List(0) & " -***dB * " + tmp = ArrayToString(pkt.data) + nodeinfo = nodeinfo & tmp + Form1.nodelist.List(0) = nodeinfo + ' issue next command + xbeesend con, "ND" + End Select + + If (AT <> "ND") Then Exit Function + If (pkt.status <> 0) Then + MsgBox "An error occured when attempting to scan!", vbCritical + Exit Function + End If + + If (pkt.datalen = 0) Then + ' increment the counter for each node + For i = 0 To Form1.nodelist.ListCount - 1 + tmp2 = Split(Form1.nodelist.List(i), " ") + If tmp2(4) <> "+" And tmp2(4) <> "*" Then + tmp2(4) = CInt(tmp2(4)) + 1 + If (CInt(tmp2(4)) > 9) Then tmp2(4) = "+" + End If + tmp = "" + For m = LBound(tmp2) To UBound(tmp2) + If m > 0 Then tmp = tmp & " " + tmp = tmp & tmp2(m) + Next + Form1.nodelist.List(i) = tmp + Next + + ' restart the refresh timer + Form1.tmr_refresh.Enabled = True + Exit Function + End If + + ' extract the 16-bit address + nodeinfo = "" + tmp = Hex(pkt.data(1)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + tmp = Hex(pkt.data(0)) & tmp + If (Len(tmp) < 4) Then tmp = "0" & tmp + tmp = "0x" & tmp + nodeinfo = nodeinfo & tmp + + nodeinfo = nodeinfo & " " + + ' extract the high portion of the 64-bit address + nodeinfo = nodeinfo + tmp = Hex(pkt.data(5)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + tmp = Hex(pkt.data(4)) & tmp + If (Len(tmp) < 4) Then tmp = "0" & tmp + tmp = Hex(pkt.data(3)) & tmp + If (Len(tmp) < 6) Then tmp = "0" & tmp + tmp = Hex(pkt.data(2)) & tmp + If (Len(tmp) < 8) Then tmp = "0" & tmp + tmp = "0x" & tmp + nodeinfo = nodeinfo & tmp + sh = tmp + + nodeinfo = nodeinfo & " " + + ' extract the low portion of the 64-bit address + nodeinfo = nodeinfo + tmp = Hex(pkt.data(9)) + If (Len(tmp) < 2) Then tmp = "0" & tmp + tmp = Hex(pkt.data(8)) & tmp + If (Len(tmp) < 4) Then tmp = "0" & tmp + tmp = Hex(pkt.data(7)) & tmp + If (Len(tmp) < 6) Then tmp = "0" & tmp + tmp = Hex(pkt.data(6)) & tmp + If (Len(tmp) < 8) Then tmp = "0" & tmp + tmp = "0x" & tmp + nodeinfo = nodeinfo & tmp + sl = tmp + + nodeinfo = nodeinfo & " " + + ' extract the rssi (signal strength) + tmp = "-" & CStr(pkt.data(10)) + If Len(tmp) < 3 Then tmp = " " & tmp + If Len(tmp) < 4 Then tmp = " " & tmp + tmp = tmp & "dB" + nodeinfo = nodeinfo & tmp + + nodeinfo = nodeinfo & " " + ' add a number of scans + nodeinfo = nodeinfo & 0 + + nodeinfo = nodeinfo & " " + + ' extract the node name + nodename = ArrayToString(pkt.data, 11) + nodeinfo = nodeinfo & nodename + + ' see if we have already got this node + For i = 0 To Form1.nodelist.ListCount - 1 + tmp2 = Split(Form1.nodelist.List(i), " ") + If tmp2(1) = sh And tmp2(2) = sl Then + Form1.nodelist.List(i) = nodeinfo + Exit Function + End If + Next + + ' otherwise add the info to the list + Form1.nodelist.AddItem nodeinfo +End Function diff --git a/thirdParty/libxbee/sample/vb6/talk_to_me/talk_to_me.vbp b/thirdParty/libxbee/sample/vb6/talk_to_me/talk_to_me.vbp new file mode 100644 index 0000000000..a80cc9bf25 --- /dev/null +++ b/thirdParty/libxbee/sample/vb6/talk_to_me/talk_to_me.vbp @@ -0,0 +1,33 @@ +Type=Exe +Form=Form1.frm +Reference=*\G{00020430-0000-0000-C000-000000000046}#2.0#0#..\..\..\..\..\..\..\..\Windows\SysWOW64\stdole2.tlb#OLE Automation +Module=libxbee; ..\libxbee.bas +Module=Module1; talk_to_me.bas +IconForm="Form1" +Startup="Form1" +ExeName32="talk_to_me.exe" +Command32="" +Name="Project1" +HelpContextID="0" +CompatibleMode="0" +MajorVer=1 +MinorVer=0 +RevisionVer=0 +AutoIncrementVer=0 +ServerSupportFiles=0 +VersionCompanyName="Microsoft" +CompilationType=0 +OptimizationType=0 +FavorPentiumPro(tm)=0 +CodeViewDebugInfo=0 +NoAliasing=0 +BoundsCheck=0 +OverflowCheck=0 +FlPointCheck=0 +FDIVCheck=0 +UnroundedFP=0 +StartMode=0 +Unattended=0 +Retained=0 +ThreadPerObject=0 +MaxNumberOfThreads=1 diff --git a/thirdParty/libxbee/sample/xbee2_rx.c b/thirdParty/libxbee/sample/xbee2_rx.c new file mode 100644 index 0000000000..223ddcf637 --- /dev/null +++ b/thirdParty/libxbee/sample/xbee2_rx.c @@ -0,0 +1,60 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee -g +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample demonstrates how to communicate using series 2 radios */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <xbee.h> + +void callback(xbee_con *con, xbee_pkt *pkt) { + int ret; + /* print the recieved data */ + printf("Rx: %s\n",pkt->data); +} + +int main(int argc, char *argv[]) { + union { + unsigned char as8[8]; + unsigned int as32[2]; + } addr; + xbee_con *rCon; + xbee_pkt *pkt; + + xbee_setuplog("/dev/ttyUSB1",57600, 2); + + rCon = xbee_newcon('#', xbee2_data, 0x13A200, 0x403302B1); + rCon->waitforACK = 1; + rCon->callback = callback; + + for (;;) { + sleep(60); + } + + /* calling xbee_end() will return the xbee to its previous API mode */ + xbee_end(); + return 0; +} diff --git a/thirdParty/libxbee/sample/xbee2_tx.c b/thirdParty/libxbee/sample/xbee2_tx.c new file mode 100644 index 0000000000..db49fe6fa6 --- /dev/null +++ b/thirdParty/libxbee/sample/xbee2_tx.c @@ -0,0 +1,54 @@ +#ifdef shell +gcc -o ${0//.c/} $0 -lxbee -g +exit +} +#endif +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this sample demonstrates how to communicate using series 2 radios */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <xbee.h> + +int main(int argc, char *argv[]) { + union { + unsigned char as8[8]; + unsigned int as32[2]; + } addr; + xbee_con *rCon; + xbee_pkt *pkt; + + xbee_setuplog("/dev/ttyUSB0",57600, 2); + + rCon = xbee_newcon('#', xbee2_data, 0x13A200, 0x403302BF); + + for (;;) { + xbee_senddata(rCon, "Hello!"); + printf("Sent!\n"); + sleep(1); + } + + /* calling xbee_end() will return the xbee to its previous API mode */ + xbee_end(); + return 0; +} diff --git a/thirdParty/libxbee/win32.README.txt b/thirdParty/libxbee/win32.README.txt new file mode 100644 index 0000000000..f16dc0d94e --- /dev/null +++ b/thirdParty/libxbee/win32.README.txt @@ -0,0 +1,31 @@ +Welcome to libxbee! + +I have proveded sample code in the ./sample directory. Hopefully this will help +get you up and running with libxbee. If you would like samples showing a different +aspect of libxbee, then please do not hesitate to file an 'issue' on the project +site, and I will get to it ASAP: + http://code.google.com/p/libxbee/issues/list + + +Documentation is avaliable as HTML in the 'doc' folder. + + +Please note that this project is still in development, so should not be used for +any purpose other than learning/playing/testing etc... Basically don't use it to +make money, and then hold me responsible if it breaks! + +Feel free to contact me directly with any queries: + attie@attie.co.uk + + +=== Compiling & Using === + +To compile you must: + 1) Have Visual C++ 2008 (v9.0) installed (Express or otherwise) + 2) Have make installed - see GnuWin + 3) Modify win32.makefile so that the paths at the top are correct + +Compile using `make -f win32.makefile` from the command prompt + +For C/C++ (and probrably others) just include xbee.h and link with libxbee.dll +For VB6 see ./sample/vb6/ for more info & examples diff --git a/thirdParty/libxbee/xbee.h b/thirdParty/libxbee/xbee.h new file mode 100644 index 0000000000..61331d8443 --- /dev/null +++ b/thirdParty/libxbee/xbee.h @@ -0,0 +1,218 @@ +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#ifndef XBEE_H +#define XBEE_H + +#if !defined(__GNUC__) && !defined(_WIN32) +#error "This library is only currently compatible with Linux and Win32" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __LIBXBEE_API_H +typedef void* xbee_hnd; +#endif + +#include <stdarg.h> + +#ifdef __GNUC__ /* ---- */ +#include <semaphore.h> +typedef pthread_mutex_t xbee_mutex_t; +typedef pthread_cond_t xbee_cond_t; +typedef pthread_t xbee_thread_t; +typedef sem_t xbee_sem_t; +typedef FILE* xbee_file_t; +#elif (defined(WIN32) || defined(_WIN32)) /* -------------- */ +#include <Windows.h> +#define CALLTYPE __stdcall +#define CALLTYPEVA __cdecl +typedef HANDLE xbee_mutex_t; +typedef CONDITION_VARIABLE xbee_cond_t; +typedef HANDLE xbee_thread_t; +typedef HANDLE xbee_sem_t; +typedef HANDLE xbee_file_t; +#else +#error "Unknown operating system or compiler" +#endif /* ------------- */ + +#ifndef CALLTYPE +#define CALLTYPE +#endif + +#ifndef CALLTYPEVA +#define CALLTYPEVA +#endif + +enum xbee_types { + xbee_unknown, + + xbee_localAT, /* frame ID */ + xbee_remoteAT, + xbee_modemStatus, + xbee_txStatus, + + /* XBee Series 1 stuff */ + xbee_16bitRemoteAT, /* frame ID */ + xbee_64bitRemoteAT, /* frame ID */ + + xbee_16bitData, /* frame ID for ACKs */ + xbee_64bitData, /* frame ID for ACKs */ + + xbee_16bitIO, + xbee_64bitIO, + + /* XBee Series 2 stuff */ + xbee2_data, + xbee2_txStatus +}; +typedef enum xbee_types xbee_types; + +typedef struct xbee_sample xbee_sample; +struct xbee_sample { + /* X A5 A4 A3 A2 A1 A0 D8 D7 D6 D5 D4 D3 D2 D1 D0 */ + unsigned short IOmask; /* IO */ + /* X X X X X X X D8 D7 D6 D5 D4 D3 D2 D1 D0 */ + unsigned short IOdigital; /* IO */ + /* X X X X X D D D D D D D D D D D */ + unsigned short IOanalog[6]; /* IO */ +}; + +typedef struct xbee_pkt xbee_pkt; +struct xbee_pkt { + unsigned int sAddr64 : 1; /* yes / no */ + unsigned int dataPkt : 1; /* if no - AT packet */ + unsigned int txStatusPkt : 1; + unsigned int modemStatusPkt : 1; + unsigned int remoteATPkt : 1; + unsigned int IOPkt : 1; + unsigned int isBroadcastADR : 1; + unsigned int isBroadcastPAN : 1; + + unsigned char frameID; /* AT Status */ + unsigned char atCmd[2]; /* AT */ + + unsigned char status; /* AT Data Status */ /* status / options */ + unsigned char samples; + unsigned char RSSI; /* Data */ + + unsigned char Addr16[2]; /* AT Data */ + + unsigned char Addr64[8]; /* AT Data */ + + unsigned char data[128]; /* AT Data */ + + unsigned int datalen; + xbee_types type; + + xbee_pkt *next; + + xbee_sample IOdata[1]; /* this array can be extended by using a this trick: + p = calloc(sizeof(xbee_pkt) + (sizeof(xbee_sample) * (samples - 1))) */ +}; + +typedef struct xbee_con xbee_con; +struct xbee_con { + unsigned int tAddr64 : 1; + unsigned int atQueue : 1; /* queues AT commands until AC is sent */ + unsigned int txDisableACK : 1; + unsigned int txBroadcastPAN: 1; /* broadcasts to PAN */ + unsigned int destroySelf : 1; /* if set, the callback thread will destroy the connection + after all of the packets have been processed */ + unsigned int waitforACK : 1; /* waits for the ACK or NAK after transmission */ + unsigned int noFreeAfterCB : 1; /* prevents libxbee from free'ing the packet after the callback has completed */ + unsigned int __spare__ : 1; + xbee_types type; + unsigned char frameID; + unsigned char tAddr[8]; /* 64-bit 0-7 16-bit 0-1 */ + void *customData; /* can be used to store data related to this connection */ + void (CALLTYPE *callback)(xbee_con*,xbee_pkt*); /* call back function */ + void *callbackList; + xbee_mutex_t callbackmutex; + xbee_mutex_t callbackListmutex; + xbee_mutex_t Txmutex; + xbee_sem_t waitforACKsem; + volatile unsigned char ACKstatus; /* 255 = waiting, 0 = success, 1 = no ack, 2 = cca fail, 3 = purged */ + xbee_con *next; +}; + +int CALLTYPE xbee_setup(char *path, int baudrate); +int CALLTYPE xbee_setuplog(char *path, int baudrate, int logfd); +int CALLTYPE xbee_setupAPI(char *path, int baudrate, char cmdSeq, int cmdTime); +int CALLTYPE xbee_setuplogAPI(char *path, int baudrate, int logfd, char cmdSeq, int cmdTime); +xbee_hnd CALLTYPE _xbee_setup(char *path, int baudrate); +xbee_hnd CALLTYPE _xbee_setuplog(char *path, int baudrate, int logfd); +xbee_hnd CALLTYPE _xbee_setupAPI(char *path, int baudrate, char cmdSeq, int cmdTime); +xbee_hnd CALLTYPE _xbee_setuplogAPI(char *path, int baudrate, int logfd, char cmdSeq, int cmdTime); + +int CALLTYPE xbee_end(void); +int CALLTYPE _xbee_end(xbee_hnd xbee); + +void CALLTYPE xbee_logitf(char *format, ...); +void CALLTYPE _xbee_logitf(xbee_hnd xbee, char *format, ...); +void CALLTYPE xbee_logit(char *str); +void CALLTYPE _xbee_logit(xbee_hnd xbee, char *str); + +xbee_con * CALLTYPEVA xbee_newcon(unsigned char frameID, xbee_types type, ...); +xbee_con * CALLTYPEVA _xbee_newcon(xbee_hnd xbee, unsigned char frameID, xbee_types type, ...); +xbee_con * CALLTYPE _xbee_vnewcon(xbee_hnd xbee, unsigned char frameID, xbee_types type, va_list ap); + +void CALLTYPE xbee_purgecon(xbee_con *con); +void CALLTYPE _xbee_purgecon(xbee_hnd xbee, xbee_con *con); + +void CALLTYPE xbee_endcon2(xbee_con **con, int alreadyUnlinked); +void CALLTYPE _xbee_endcon2(xbee_hnd xbee, xbee_con **con, int alreadyUnlinked); +#define xbee_endcon(x) xbee_endcon2(&(x),0) +#define _xbee_endcon(xbee,x) _xbee_endcon2((xbee),&(x),0) + +int CALLTYPE xbee_nsenddata(xbee_con *con, char *data, int length); +int CALLTYPE _xbee_nsenddata(xbee_hnd xbee, xbee_con *con, char *data, int length); +int CALLTYPEVA xbee_senddata(xbee_con *con, char *format, ...); +int CALLTYPEVA _xbee_senddata(xbee_hnd xbee, xbee_con *con, char *format, ...); +int CALLTYPE xbee_vsenddata(xbee_con *con, char *format, va_list ap); +int CALLTYPE _xbee_vsenddata(xbee_hnd xbee, xbee_con *con, char *format, va_list ap); + +#if defined(WIN32) +/* oh and just 'cos windows has rubbish memory management rules... this too */ +void CALLTYPE xbee_free(void *ptr); +#endif /* ------------- */ + +xbee_pkt * CALLTYPE xbee_getpacket(xbee_con *con); +xbee_pkt * CALLTYPE _xbee_getpacket(xbee_hnd xbee, xbee_con *con); +xbee_pkt * CALLTYPE xbee_getpacketwait(xbee_con *con); +xbee_pkt * CALLTYPE _xbee_getpacketwait(xbee_hnd xbee, xbee_con *con); + +int CALLTYPE xbee_hasdigital(xbee_pkt *pkt, int sample, int input); +int CALLTYPE xbee_getdigital(xbee_pkt *pkt, int sample, int input); + +int CALLTYPE xbee_hasanalog(xbee_pkt *pkt, int sample, int input); +double CALLTYPE xbee_getanalog(xbee_pkt *pkt, int sample, int input, double Vref); + +const char * CALLTYPE xbee_svn_version(void); +const char * CALLTYPE xbee_build_info(void); + +void CALLTYPE xbee_listen_stop(xbee_hnd xbee); + +#ifdef __cplusplus +} /* cplusplus */ +#endif + +#endif diff --git a/thirdParty/libxbee/xsys/README b/thirdParty/libxbee/xsys/README new file mode 100644 index 0000000000..48d3928505 --- /dev/null +++ b/thirdParty/libxbee/xsys/README @@ -0,0 +1 @@ +This directory contains cross-system support files. \ No newline at end of file diff --git a/thirdParty/libxbee/xsys/linux.c b/thirdParty/libxbee/xsys/linux.c new file mode 100644 index 0000000000..768d5b3d4e --- /dev/null +++ b/thirdParty/libxbee/xsys/linux.c @@ -0,0 +1,148 @@ +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* ################################################################# */ +/* ### Linux Code ################################################## */ +/* ################################################################# */ + +/* this file contains code that is used by Linux ONLY */ +#ifndef __GNUC__ +#error "This file should only be used on a Linux system" +#endif + +#include "linux.h" + +int init_serial(xbee_hnd xbee, int baudrate) { + struct flock fl; + struct termios tc; + speed_t chosenbaud; + + /* select the baud rate */ + switch (baudrate) { + case 1200: chosenbaud = B1200; break; + case 2400: chosenbaud = B2400; break; + case 4800: chosenbaud = B4800; break; + case 9600: chosenbaud = B9600; break; + case 19200: chosenbaud = B19200; break; + case 38400: chosenbaud = B38400; break; + case 57600: chosenbaud = B57600; break; + case 115200:chosenbaud = B115200; break; + default: + fprintf(stderr,"%s(): Unknown or incompatiable baud rate specified... (%d)\n",__FUNCTION__,baudrate); + return -1; + }; + + /* open the serial port as a file descriptor */ + if ((xbee->ttyfd = open(xbee->path,O_RDWR | O_NOCTTY | O_NONBLOCK)) == -1) { + xbee_perror("xbee_setup():open()"); + xbee_mutex_destroy(xbee->conmutex); + xbee_mutex_destroy(xbee->pktmutex); + xbee_mutex_destroy(xbee->sendmutex); + Xfree(xbee->path); + return -1; + } + + /* lock the file */ + fl.l_type = F_WRLCK | F_RDLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + fl.l_pid = getpid(); + if (fcntl(xbee->ttyfd, F_SETLK, &fl) == -1) { + xbee_perror("xbee_setup():fcntl()"); + xbee_mutex_destroy(xbee->conmutex); + xbee_mutex_destroy(xbee->pktmutex); + xbee_mutex_destroy(xbee->sendmutex); + Xfree(xbee->path); + close(xbee->ttyfd); + return -1; + } + + /* open the serial port as a FILE* */ + if ((xbee->tty = fdopen(xbee->ttyfd,"r+")) == NULL) { + xbee_perror("xbee_setup():fdopen()"); + xbee_mutex_destroy(xbee->conmutex); + xbee_mutex_destroy(xbee->pktmutex); + xbee_mutex_destroy(xbee->sendmutex); + Xfree(xbee->path); + close(xbee->ttyfd); + return -1; + } + + /* flush the serial port */ + fflush(xbee->tty); + + /* disable buffering */ + setvbuf(xbee->tty,NULL,_IONBF,BUFSIZ); + + /* setup the baud rate and other io attributes */ + tcgetattr(xbee->ttyfd, &tc); + /* input flags */ + tc.c_iflag &= ~ IGNBRK; /* enable ignoring break */ + tc.c_iflag &= ~(IGNPAR | PARMRK); /* disable parity checks */ + tc.c_iflag &= ~ INPCK; /* disable parity checking */ + tc.c_iflag &= ~ ISTRIP; /* disable stripping 8th bit */ + tc.c_iflag &= ~(INLCR | ICRNL); /* disable translating NL <-> CR */ + tc.c_iflag &= ~ IGNCR; /* disable ignoring CR */ + tc.c_iflag &= ~(IXON | IXOFF); /* disable XON/XOFF flow control */ + /* output flags */ + tc.c_oflag &= ~ OPOST; /* disable output processing */ + tc.c_oflag &= ~(ONLCR | OCRNL); /* disable translating NL <-> CR */ + tc.c_oflag &= ~ OFILL; /* disable fill characters */ + /* control flags */ + tc.c_cflag |= CREAD; /* enable reciever */ + tc.c_cflag &= ~ PARENB; /* disable parity */ + tc.c_cflag &= ~ CSTOPB; /* disable 2 stop bits */ + tc.c_cflag &= ~ CSIZE; /* remove size flag... */ + tc.c_cflag |= CS8; /* ...enable 8 bit characters */ + tc.c_cflag |= HUPCL; /* enable lower control lines on close - hang up */ + /* local flags */ + tc.c_lflag &= ~ ISIG; /* disable generating signals */ + tc.c_lflag &= ~ ICANON; /* disable canonical mode - line by line */ + tc.c_lflag &= ~ ECHO; /* disable echoing characters */ + tc.c_lflag &= ~ ECHONL; /* ??? */ + tc.c_lflag &= ~ NOFLSH; /* disable flushing on SIGINT */ + tc.c_lflag &= ~ IEXTEN; /* disable input processing */ + /* control characters */ + memset(tc.c_cc,0,sizeof(tc.c_cc)); + /* i/o rates */ + cfsetspeed(&tc, chosenbaud); /* set i/o baud rate */ + tcsetattr(xbee->ttyfd, TCSANOW, &tc); + tcflow(xbee->ttyfd, TCOON|TCION); /* enable input & output transmission */ + + return 0; +} + +static int xbee_select(xbee_hnd xbee, struct timeval *timeout) { + fd_set fds; + + FD_ZERO(&fds); + FD_SET(xbee->ttyfd, &fds); + + return select(xbee->ttyfd+1, &fds, NULL, NULL, timeout); +} + +#define xbee_sem_wait1sec(a) xbee_sem_wait1sec2(&(a)) +static inline int xbee_sem_wait1sec2(xbee_sem_t *sem) { + struct timespec to; + clock_gettime(CLOCK_REALTIME,&to); + to.tv_sec++; + return sem_timedwait(sem,&to); +} diff --git a/thirdParty/libxbee/xsys/linux.h b/thirdParty/libxbee/xsys/linux.h new file mode 100644 index 0000000000..886bbf5bf1 --- /dev/null +++ b/thirdParty/libxbee/xsys/linux.h @@ -0,0 +1,57 @@ +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this file contains code that is used by Linux ONLY */ +#ifndef __GNUC__ +#error "This file should only be used on a Linux system" +#endif + +/* ################################################################# */ +/* ### Linux Code ################################################## */ +/* ################################################################# */ + +#define xbee_thread_create(a,b,c) pthread_create(&(a),NULL,(void *(*)(void *))(b),(void *)(c)) +#define xbee_thread_cancel(a,b) pthread_cancel((a)) +#define xbee_thread_join(a) pthread_join((a),NULL) +#define xbee_thread_tryjoin(a) pthread_tryjoin_np((a),NULL) + +#define xbee_mutex_init(a) pthread_mutex_init(&(a),NULL) +#define xbee_mutex_destroy(a) pthread_mutex_destroy(&(a)) +#define xbee_mutex_lock(a) pthread_mutex_lock(&(a)) +#define xbee_mutex_trylock(a) pthread_mutex_trylock(&(a)) +#define xbee_mutex_unlock(a) pthread_mutex_unlock(&(a)) + +#define xbee_sem_init(a) sem_init(&(a),0,0) +#define xbee_sem_destroy(a) sem_destroy(&(a)) +#define xbee_sem_wait(a) sem_wait(&(a)) +#define xbee_sem_post(a) sem_post(&(a)) + +#define xbee_cond_init(a) pthread_cond_init(&(a),NULL) +#define xbee_cond_destroy(a) pthread_cond_destroy(&(a)) +#define xbee_cond_wait(a,b) pthread_cond_wait(&(a),&(b)) +#define xbee_cond_signal(a) pthread_cond_signal(&(a)) +#define xbee_cond_broadcast(a) pthread_cond_broadcast(&(a)) + +#define xbee_write(xbee,a,b) fwrite((a),1,(b),(xbee)->tty) +#define xbee_read(xbee,a,b) fread((a),1,(b),(xbee)->tty) +#define xbee_ferror(xbee) ferror((xbee)->tty) +#define xbee_feof(xbee) feof((xbee)->tty) +#define xbee_close(a) fclose((a)) + diff --git a/thirdParty/libxbee/xsys/pdf/linux.c.pdf b/thirdParty/libxbee/xsys/pdf/linux.c.pdf new file mode 100644 index 0000000000000000000000000000000000000000..75a9a38b29af858ad4bb773704982d44fa400b32 GIT binary patch literal 8394 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 literal 0 HcmV?d00001 diff --git a/thirdParty/libxbee/xsys/pdf/linux.h.pdf b/thirdParty/libxbee/xsys/pdf/linux.h.pdf new file mode 100644 index 0000000000000000000000000000000000000000..a4c65ae408966bc912ed72e08fc49c4edee516ff GIT binary patch literal 5205 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 QB+Z0MA?WK{JJ}Ha3mo~kxBvhE literal 0 HcmV?d00001 diff --git a/thirdParty/libxbee/xsys/pdf/win32.c.pdf b/thirdParty/libxbee/xsys/pdf/win32.c.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ec776c30b824ae659ab2cb2f31907df2f608dff8 GIT binary patch literal 14179 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 literal 0 HcmV?d00001 diff --git a/thirdParty/libxbee/xsys/pdf/win32.def.pdf b/thirdParty/libxbee/xsys/pdf/win32.def.pdf new file mode 100644 index 0000000000000000000000000000000000000000..99b0548e4d2703b57cf69ec0fde18166639f570e GIT binary patch literal 3538 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 Bi5~y} literal 0 HcmV?d00001 diff --git a/thirdParty/libxbee/xsys/pdf/win32.dll.c.pdf b/thirdParty/libxbee/xsys/pdf/win32.dll.c.pdf new file mode 100644 index 0000000000000000000000000000000000000000..97d7acb34cfe49904b5c08b6c227512fc8bc6048 GIT binary patch literal 7893 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 I7;1w42PsX5#{d8T literal 0 HcmV?d00001 diff --git a/thirdParty/libxbee/xsys/pdf/win32.h.pdf b/thirdParty/libxbee/xsys/pdf/win32.h.pdf new file mode 100644 index 0000000000000000000000000000000000000000..b844726f1a19607952831452b160be3896a412b1 GIT binary patch literal 5959 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 JFtam9{2yx~BG~`{ literal 0 HcmV?d00001 diff --git a/thirdParty/libxbee/xsys/pdf/win32.rc.pdf b/thirdParty/libxbee/xsys/pdf/win32.rc.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8ff8a7956bff9e4e4ff4b5cb33683835c635a36c GIT binary patch literal 4744 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 DyZfM7 literal 0 HcmV?d00001 diff --git a/thirdParty/libxbee/xsys/win32.c b/thirdParty/libxbee/xsys/win32.c new file mode 100644 index 0000000000..a05950a94b --- /dev/null +++ b/thirdParty/libxbee/xsys/win32.c @@ -0,0 +1,279 @@ +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* ################################################################# */ +/* ### Win32 Code ################################################## */ +/* ################################################################# */ + +/* this file contains code that is used by Win32 ONLY */ +#ifndef _WIN32 +#error "This file should only be used on a Win32 system" +#endif + +#include "win32.h" +#include "win32.dll.c" + +static int init_serial(xbee_hnd xbee, int baudrate) { + int chosenbaud; + DCB tc; + int evtMask; + COMMTIMEOUTS timeouts; + + /* open the serial port */ + xbee->tty = CreateFile(TEXT(xbee->path), + GENERIC_READ | GENERIC_WRITE, + 0, /* exclusive access */ + NULL, /* default security attributes */ + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + if (xbee->tty == INVALID_HANDLE_VALUE) { + xbee_logS("Invalid file handle..."); + xbee_logE("Is the XBee plugged in and avaliable on the correct port?"); + xbee_mutex_destroy(xbee->conmutex); + xbee_mutex_destroy(xbee->pktmutex); + xbee_mutex_destroy(xbee->sendmutex); + Xfree(xbee->path); + return -1; + } + + GetCommState(xbee->tty, &tc); + tc.BaudRate = baudrate; + tc.fBinary = TRUE; + tc.fParity = FALSE; + tc.fOutxCtsFlow = FALSE; + tc.fOutxDsrFlow = FALSE; + tc.fDtrControl = DTR_CONTROL_DISABLE; + tc.fDsrSensitivity = FALSE; + tc.fTXContinueOnXoff = FALSE; + tc.fOutX = FALSE; + tc.fInX = FALSE; + tc.fErrorChar = FALSE; + tc.fNull = FALSE; + tc.fRtsControl = RTS_CONTROL_DISABLE; + tc.fAbortOnError = FALSE; + tc.ByteSize = 8; + tc.Parity = NOPARITY; + tc.StopBits = ONESTOPBIT; + SetCommState(xbee->tty, &tc); + + timeouts.ReadIntervalTimeout = MAXDWORD; + timeouts.ReadTotalTimeoutMultiplier = 0; + timeouts.ReadTotalTimeoutConstant = 0; + timeouts.WriteTotalTimeoutMultiplier = 0; + timeouts.WriteTotalTimeoutConstant = 0; + SetCommTimeouts(xbee->tty, &timeouts); + + SetCommMask(xbee->tty, EV_RXCHAR); + + return 0; +} + +/* a replacement for the linux select() function... for a serial port */ +static int xbee_select(xbee_hnd xbee, struct timeval *timeout) { + int evtMask = 0; + COMSTAT status; + int ret; + + for (;;) { + /* find out how many bytes are in the Rx buffer... */ + if (ClearCommError(xbee->tty,NULL,&status) && (status.cbInQue > 0)) { + /* if there is data... return! */ + return 1; /*status.cbInQue;*/ + } else if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) { + /* if the timeout was 0 (return immediately) then return! */ + return 0; + } + + /* otherwise wait for an Rx event... */ + memset(&(xbee->ttyovrs),0,sizeof(OVERLAPPED)); + xbee->ttyovrs.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); + if (!WaitCommEvent(xbee->tty,&evtMask,&(xbee->ttyovrs))) { + if (GetLastError() == ERROR_IO_PENDING) { + DWORD timeoutval; + if (!timeout) { + /* behave like the linux function... if the timeout pointer was NULL + then wait indefinately */ + timeoutval = INFINITE; + } else { + /* Win32 doesn't give the luxury of microseconds and seconds... just miliseconds! */ + timeoutval = (timeout->tv_sec * 1000) + (timeout->tv_usec / 1000); + } + ret = WaitForSingleObject(xbee->ttyovrs.hEvent,timeoutval); + if (ret == WAIT_TIMEOUT) { + /* cause the WaitCommEvent() call to stop */ + SetCommMask(xbee->tty, EV_RXCHAR); + /* if a timeout occured, then return 0 */ + CloseHandle(xbee->ttyovrs.hEvent); + return 0; + } + } else { + return -1; + } + } + CloseHandle(xbee->ttyovrs.hEvent); + } + + /* always return -1 (error) for now... */ + return -1; +} + +/* this offers the same behavior as non-blocking I/O under linux */ +int xbee_write(xbee_hnd xbee, const void *ptr, size_t size) { + xbee->ttyeof = FALSE; + if (!WriteFile(xbee->tty, ptr, size, NULL, &(xbee->ttyovrw)) && + (GetLastError() != ERROR_IO_PENDING)) return 0; + if (!GetOverlappedResult(xbee->tty, &(xbee->ttyovrw), &(xbee->ttyw), TRUE)) { + if (GetLastError() == ERROR_HANDLE_EOF) xbee->ttyeof = TRUE; + return 0; + } + return xbee->ttyw; +} + +/* this offers the same behavior as non-blocking I/O under linux */ +int xbee_read(xbee_hnd xbee, void *ptr, size_t size) { + xbee->ttyeof = FALSE; + if (!ReadFile(xbee->tty, ptr, size, NULL, &(xbee->ttyovrr)) && + (GetLastError() != ERROR_IO_PENDING)) return 0; + if (!GetOverlappedResult(xbee->tty, &(xbee->ttyovrr), &(xbee->ttyr), TRUE)) { + if (GetLastError() == ERROR_HANDLE_EOF) xbee->ttyeof = TRUE; + return 0; + } + return xbee->ttyr; +} + +/* this is because Win32 has some weird memory management rules... + - the thread that allocated the memory, MUST free it... */ +void xbee_free(void *ptr) { + if (!ptr) return; + free(ptr); +} + +/* win32 equivalent of unix gettimeofday() */ +int gettimeofday(struct timeval *tv, struct timezone *tz) { + if (tv) { + struct _timeb timeb; + _ftime(&timeb); + tv->tv_sec = timeb.time; + tv->tv_usec = timeb.millitm * 1000; + } + /* ignore tz for now */ + return 0; +} + +/* ################################################################# */ +/* ### Helper Functions (Mainly for VB6 use) ####################### */ +/* ################################################################# */ + +/* enable the debug output to a custom file or fallback to stderr */ +int xbee_setupDebugAPI(char *path, int baudrate, char *logfile, char cmdSeq, int cmdTime) { + xbee_hnd xbee = NULL; + int fd, ret; + if ((fd = _open(logfile,_O_WRONLY | _O_CREAT | _O_TRUNC)) == -1) { + fd = 2; + } + ret = xbee_setuplogAPI(path,baudrate,fd,cmdSeq,cmdTime); + if (fd > 2) { /* close fd, as libxbee dup'ed it */ + //_close(fd); + } + if (!ret) { /* libxbee started correctly */ + xbee = default_xbee; + if (fd == -1) { + xbee_log("Error opening logfile '%s' (errno=%d)... using stderr instead!",logfile,errno); + } + } + return ret; +} +int xbee_setupDebug(char *path, int baudrate, char *logfile) { + return xbee_setupDebugAPI(path,baudrate,logfile,0,0); +} + +/* These silly little functions are required for VB6 + - it freaks out when you call a function that uses va_args... */ +xbee_con *xbee_newcon_simple(unsigned char frameID, xbee_types type) { + return xbee_newcon(frameID, type); +} +xbee_con *xbee_newcon_16bit(unsigned char frameID, xbee_types type, int addr) { + return xbee_newcon(frameID, type, addr); +} +xbee_con *xbee_newcon_64bit(unsigned char frameID, xbee_types type, int addrL, int addrH) { + return xbee_newcon(frameID, type, addrL, addrH); +} + +void xbee_enableACKwait(xbee_con *con) { + con->waitforACK = 1; +} +void xbee_disableACKwait(xbee_con *con) { + con->waitforACK = 0; +} + +void xbee_enableDestroySelf(xbee_con *con) { + con->destroySelf = 1; +} + +/* for vb6... it will send a message to the given hWnd which can in turn check for a packet */ +void xbee_callback(xbee_con *con, xbee_pkt *pkt) { + xbee_hnd xbee = default_xbee; + + if (!win32_hWnd) { + xbee_log("*** Cannot do callback! No hWnd set... ***"); + return; + } + if (!win32_MessageID) { + xbee_log("*** Cannot do callback! No MessageID set... ***"); + return; + } + + xbee_log("Callback message sent!"); + SendMessage(win32_hWnd, win32_MessageID, (int)con, (int)pkt); +} + +/* very simple C function to provide more functionality to VB6 */ +int xbee_runCallback(int(*func)(xbee_con*,xbee_pkt*), xbee_con *con, xbee_pkt *pkt) { + return func(con,pkt); +} + +void xbee_enableCallbacks(HWND hWnd, UINT uMsg) { + xbee_hnd xbee = default_xbee; + if (!win32_MessageID || win32_MessageID != uMsg) { + xbee_log("Configuring libxbee to use MessageID = 0x%08X", uMsg); + win32_MessageID = uMsg; + } + if (!win32_hWnd || win32_hWnd != hWnd) { + xbee_log("Configuring libxbee to use hWnd = 0x%08X", hWnd); + win32_hWnd = hWnd; + } +} + +void xbee_attachCallback(xbee_con *con) { + xbee_hnd xbee = default_xbee; + + /* setup the callback function */ + xbee_log("Setting callback for connection @ 0x%08X",con); + con->callback = xbee_callback; +} + +void xbee_detachCallback(xbee_con *con) { + xbee_hnd xbee = default_xbee; + + /* un-setup the callback function */ + xbee_log("Unsetting callback for connection @ 0x%08X",con); + con->callback = NULL; +} diff --git a/thirdParty/libxbee/xsys/win32.def b/thirdParty/libxbee/xsys/win32.def new file mode 100644 index 0000000000..888040ee38 --- /dev/null +++ b/thirdParty/libxbee/xsys/win32.def @@ -0,0 +1,71 @@ +LIBRARY libxbee + +EXPORTS + ver + DllMain + DllCanUnloadNow PRIVATE + DllRegisterServer PRIVATE + DllUnregisterServer PRIVATE + + xbee_free + + xbee_setup + _xbee_setup + xbee_setuplog + _xbee_setuplog + xbee_setupAPI + _xbee_setupAPI + xbee_setuplogAPI + _xbee_setuplogAPI + xbee_setupDebug + xbee_setupDebugAPI + + xbee_end + _xbee_end + xbee_listen_stop + + xbee_newcon + _xbee_newcon + xbee_newcon_simple + xbee_newcon_16bit + xbee_newcon_64bit + + xbee_enableACKwait + xbee_disableACKwait + xbee_enableDestroySelf + + xbee_enableCallbacks + xbee_attachCallback + xbee_detachCallback + xbee_runCallback + + xbee_endcon2 + _xbee_endcon2 + xbee_purgecon + _xbee_purgecon + + xbee_senddata + _xbee_senddata + xbee_nsenddata + _xbee_nsenddata + xbee_vsenddata + _xbee_vsenddata + + xbee_getpacket + _xbee_getpacket + xbee_getpacketwait + _xbee_getpacketwait + + xbee_hasanalog + xbee_getanalog + + xbee_hasdigital + xbee_getdigital + + xbee_svn_version + xbee_build_info + + xbee_logit + _xbee_logit + xbee_logitf + _xbee_logitf diff --git a/thirdParty/libxbee/xsys/win32.dll.c b/thirdParty/libxbee/xsys/win32.dll.c new file mode 100644 index 0000000000..1a9ebcaa85 --- /dev/null +++ b/thirdParty/libxbee/xsys/win32.dll.c @@ -0,0 +1,131 @@ +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* ################################################################# */ +/* ### Win32 DLL Code ############################################## */ +/* ################################################################# */ + +/* this file contains code that is used by Win32 ONLY */ +#ifndef _WIN32 +#error "This file should only be used on a Win32 system" +#endif + +int ver(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow) { + char t[256]; + sprintf(t,"libxbee.dll\n%s\n%s",xbee_svn_version(),xbee_build_info()); + MessageBox(NULL, t, "libxbee Win32 DLL", MB_OK); + return 0; +} + +void xbee_UNLOADALL(void) { + while (default_xbee) { + _xbee_end(default_xbee); + } +} + +/* this gets called when the dll is loaded and unloaded... */ +BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved) { + if (dwReason == DLL_PROCESS_DETACH) { + /* ensure that libxbee has been shut down nicely */ + xbee_UNLOADALL(); + } else if (dwReason == DLL_PROCESS_ATTACH || dwReason == DLL_THREAD_ATTACH) { + if (!glob_hModule) { + /* keep a handle on the module */ + glob_hModule = (HMODULE)hModule; + } + } + return TRUE; +} + +HRESULT DllCanUnloadNow(void) { + if (default_xbee) return 0; + return 1; +} + +/* ################################################################# */ +/* ### Win32 DLL COM Code ########################################## */ +/* ################################################################# */ + +/* this function is from this tutorial: + http://www.codeguru.com/Cpp/COM-Tech/activex/tutorials/article.php/c5567 */ +BOOL RegWriteKey(HKEY roothk, const char *lpSubKey, LPCTSTR val_name, + DWORD dwType, void *lpvData, DWORD dwDataSize) { + /* roothk: HKEY_CLASSES_ROOT, HKEY_LOCAL_MACHINE, etc + lpSubKey: the key relative to 'roothk' + val_name: the key value name where the data will be written + dwType: REG_SZ,REG_BINARY, etc. + lpvData: a pointer to the data buffer + dwDataSize: the size of the data pointed to by lpvData */ + HKEY hk; + if (ERROR_SUCCESS != RegCreateKey(roothk,lpSubKey,&hk) ) return FALSE; + if (ERROR_SUCCESS != RegSetValueEx(hk,val_name,0,dwType,(CONST BYTE *)lpvData,dwDataSize)) return FALSE; + if (ERROR_SUCCESS != RegCloseKey(hk)) return FALSE; + return TRUE; +} + +/* this is used by the regsrv32 application */ +STDAPI DllRegisterServer(void) { + char key[MAX_PATH]; + char value[MAX_PATH]; + + wsprintf(key,"CLSID\\%s",dllGUID); + wsprintf(value,"%s",dlldesc); + RegWriteKey(HKEY_CLASSES_ROOT, key, NULL, REG_SZ, (void *)value, lstrlen(value)); + + wsprintf(key,"CLSID\\%s\\InprocServer32",dllGUID); + GetModuleFileName(glob_hModule,value,MAX_PATH); + RegWriteKey(HKEY_CLASSES_ROOT, key, NULL, REG_SZ, (void *)value, lstrlen(value)); + + wsprintf(key,"CLSID\\%s\\ProgId",dllGUID); + lstrcpy(value,dllid); + RegWriteKey(HKEY_CLASSES_ROOT, key, NULL, REG_SZ, (void *)value, lstrlen(value)); + + lstrcpy(key,dllid); + lstrcpy(value,dlldesc); + RegWriteKey(HKEY_CLASSES_ROOT, key, NULL, REG_SZ, (void *)value, lstrlen(value)); + + wsprintf(key,"%s\\CLSID",dllid); + RegWriteKey(HKEY_CLASSES_ROOT, key, NULL, REG_SZ, (void *)dllGUID, lstrlen(dllGUID)); + + return S_OK; +} + +/* this is used by the regsrv32 application */ +STDAPI DllUnregisterServer(void) { + char key[MAX_PATH]; + char value[MAX_PATH]; + + wsprintf(key,"%s\\CLSID",dllid); + RegDeleteKey(HKEY_CLASSES_ROOT,key); + + wsprintf(key,"%s",dllid); + RegDeleteKey(HKEY_CLASSES_ROOT,key); + + wsprintf(key,"CLSID\\%s\\InprocServer32",dllGUID); + RegDeleteKey(HKEY_CLASSES_ROOT,key); + + wsprintf(key,"CLSID\\%s\\ProgId",dllGUID); + RegDeleteKey(HKEY_CLASSES_ROOT,key); + + wsprintf(key,"CLSID\\%s",dllGUID); + RegDeleteKey(HKEY_CLASSES_ROOT,key); + + return S_OK; +} diff --git a/thirdParty/libxbee/xsys/win32.h b/thirdParty/libxbee/xsys/win32.h new file mode 100644 index 0000000000..65f19f805c --- /dev/null +++ b/thirdParty/libxbee/xsys/win32.h @@ -0,0 +1,73 @@ +/* + libxbee - a C library to aid the use of Digi's Series 1 XBee modules + running in API mode (AP=2). + + Copyright (C) 2009 Attie Grande (attie@attie.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* this file contains code that is used by Win32 ONLY */ +#ifndef _WIN32 +#error "This file should only be used on a Win32 system" +#endif + +/* ################################################################# */ +/* ### Win32 Code ################################################## */ +/* ################################################################# */ + +#pragma comment(lib, "Advapi32.lib") +#pragma comment(lib, "User32.lib") + +#define dllid "attie-co-uk.libxbee" +#define dlldesc "libxbee - XBee API Library" +/* libxbee's GUID is {7A6E25AA-ECB5-4370-87B5-A1D31840FE23} */ +#define dllGUID "{7A6E25AA-ECB5-4370-87B5-A1D31840FE23}" + +#define Win32Message() MessageBox(0,"Run xbee_setup() first!...","libxbee",MB_OK); + +HMODULE glob_hModule = NULL; + +/* this uses miliseconds not microseconds... */ +#define usleep(a) Sleep((a)/1000) + +#define xbee_thread_create(a,b,c) (((a) = CreateThread(NULL,0,(void *)(b),(void *)(c),0,NULL)) == NULL) +#define xbee_thread_cancel(a,b) TerminateThread((a),(b)) +#define xbee_thread_join(a) WaitForSingleObject((a),INFINITE) +#define xbee_thread_tryjoin(a) WaitForSingleObject((a),0) + +#define xbee_mutex_init(a) (((a) = CreateEvent(NULL,FALSE,TRUE,NULL)) == NULL) +#define xbee_mutex_destroy(a) CloseHandle((a)) +#define xbee_mutex_lock(a) WaitForSingleObject((a),INFINITE) +#define xbee_mutex_trylock(a) WaitForSingleObject((a),0) +#define xbee_mutex_unlock(a) SetEvent((a)) + +#define xbee_sem_init(a) (((a) = CreateEvent(NULL,FALSE,FALSE,NULL)) == NULL) +#define xbee_sem_destroy(a) CloseHandle((a)) +#define xbee_sem_wait(a) WaitForSingleObject((a),INFINITE) +#define xbee_sem_wait1sec(a) WaitForSingleObject((a),1000) +#define xbee_sem_post(a) SetEvent((a)) + +#define xbee_cond_init(a) InitializeConditionVariable(&(a)) +#define xbee_cond_destroy(a) +#define xbee_cond_wait(a,b) SleepConditionVariableCS(&(a),&(b),INFINITE) +#define xbee_cond_signal(a) WakeConditionVariable(&(a)) +#define xbee_cond_broadcast(a) WakeAllConditionVariable(&(a)) + +#define xbee_feof(a) (xbee->ttyeof) +#define xbee_ferror(a) (0) +#define xbee_close(a) (((a)==xbee->log)?fclose((a)):CloseHandle((a))) + +HWND win32_hWnd = 0; +UINT win32_MessageID = 0; diff --git a/thirdParty/libxbee/xsys/win32.rc b/thirdParty/libxbee/xsys/win32.rc new file mode 100644 index 0000000000..80f7d33bc4 --- /dev/null +++ b/thirdParty/libxbee/xsys/win32.rc @@ -0,0 +1,47 @@ +/* more info: http://msdn.microsoft.com/en-us/library/aa381058(v=vs.85).aspx */ + +#define APSTUDIO_READONLY_SYMBOLS +#include "winresrc.h" +#undef APSTUDIO_READONLY_SYMBOLS + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG) + +#ifdef _WIN32 +/* Englush (UK) */ +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK +#pragma code_page(1252) +#endif //_WIN32 + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,4,1,0 + FILEFLAGSMASK 0x00L + FILEFLAGS 0x00L + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "Provides a simple interface for XBee radios" + VALUE "CompanyName", "attie.co.uk" + VALUE "FileDescription", "Provides a simple interface for XBee radios" + VALUE "InternalName", "libxbee" + VALUE "LegalCopyright", "Copyright (C) 2009 onwards Attie Grande" + VALUE "LegalTrademarks", "" + VALUE "OriginalFilename", "libxbee.dll" + VALUE "PrivateBuild", "" + VALUE "ProductName", "libxbee - http://code.google.com/p/libxbee/" + VALUE "ProductVersion", "v1.4.1" + VALUE "SpecialBuild", "" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x809, 1200 + END +END + + +#endif -- GitLab