├── .gitignore ├── AUTHORS ├── COPYING ├── ChangeLog ├── Makefile.am ├── NEWS ├── README ├── config.h.in ├── config └── pkg.m4 ├── configure.ac ├── debian ├── changelog ├── compat ├── control ├── copyright ├── dirs ├── docs └── rules ├── reconf └── src ├── Makefile.am ├── artnet-discover.c ├── artnet-dmxconsole.c ├── artnet-dmxmonitor.c ├── artnet-firmware-node.c ├── artnet-firmware-server.c ├── artnet-flood-rx.c ├── artnet-flood-tx.c ├── artnet-multiport.c ├── artnet-profile-rx.c ├── artnet-profile-tx.c ├── artnet-rdm-output.c ├── artnet-setdmx.c ├── artnet-test-defaults.h ├── artnet-test-defns.c ├── artnet-test-defns.h ├── artnet-test-master.c ├── artnet-test-slave.c ├── artnet-test-tx.c └── artnet-usb.c /.gitignore: -------------------------------------------------------------------------------- 1 | INSTALL 2 | Makefile 3 | Makefile.in 4 | aclocal.m4 5 | autom4te.cache/ 6 | config.h 7 | config.h.in 8 | config.log 9 | config.status 10 | configure 11 | libtool 12 | stamp-h1 13 | .deps 14 | .libs 15 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Author: 2 | 3 | Simon Newton 4 | 5 | Bug Reports & Patches: 6 | 7 | Massimo Callegari 8 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 28/8/2006 Simon Newton 2 | 3 | * added artnet_dmxmonitor 4 | 5 | 23/8/2006 Simon Newton 6 | 7 | * fixed off by one error in artnet-usb 8 | 9 | 10 | 9/05/2006 Simon Newton 11 | 12 | * removed compat mode 13 | * changed to single sd 14 | 15 | 25/04/2006 Simon Newton 16 | 17 | * added artnet_setdmx 18 | * examples now support compatability mode (libartnet >= 1.0.2) 19 | 20 | 21 | 30/01/2006 Simon Newton 22 | 23 | * Build scripts now detect ncurses 24 | 25 | 30/01/2006 Simon Newton 26 | 27 | * More OSX fixes 28 | 29 | 13/04/2005 Simon Newton 30 | 31 | * Mac OSX portability fixes 32 | 33 | 12/03/2005 Simon Newton 34 | 35 | * Split from libartnet 36 | * Added node joining support, two nodes can now be joined to get 8 ports - 37 | new example program artnet_multiport (you'll need to edit the second ip) 38 | 39 | 12/02/2005 Simon Newton 40 | 41 | * Fixed compiler warnings 42 | 43 | 11/02/2005 Simon Newton 44 | 45 | * Added firmware receive support - new example program artnet_firmware_node 46 | * Added firmware send support - new example program artnet_firmware_server 47 | 48 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | CLOCAL = aclocal -I $(auxdir) 2 | ACLOCAL_AMFLAGS = -I config 3 | 4 | SUBDIRS = src 5 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | 13/04/2005 artnet-examples-0.3.2 2 | 3 | Addition of artnet_setdmx 4 | Upgraded examples to support compatability mode (libartnet >= 1.0.2) 5 | 6 | 13/04/2005 artnet-examples-0.3.2 7 | 8 | Mac OS X fixes 9 | 10 | 12/03/2005 artnet-examples-0.3.1 11 | 12 | Split from libartnet package 13 | Added artnet-multiport 14 | 15 | 12/2/2005 libartnet-0.1.3 16 | 17 | Fixed compiler warnings 18 | 19 | 11/02/2005 libartnet-0.1.2 20 | 21 | Now includes support for Firmware send/receive. 22 | 23 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | 2 | This package provides example programs for use with libartnet. 3 | 4 | For installation notes, see the INSTALL file. 5 | 6 | Examples provided: 7 | 8 | A. artnet-usb 9 | B. artnet-dmxconsole 10 | C. artnet-discover 11 | 12 | A. artnet-usb 13 | ------------- 14 | 15 | Usage: artnet-usb [OPTIONS] 16 | Acts as an ArtNet to DMX node using the Enttec Open Usb Interface 17 | 18 | -a IP address to listen on (defaults to the address 19 | of the first non loopback interface) 20 | -d device for dmx output (default /dev/dmx0) 21 | -p port address for output universe (default 0) 22 | -s subnet address for output universe (default 0) 23 | -v be verbose (prints data for first four channels) 24 | 25 | The universe address of the port is made up from the subnet address and the 26 | port address. The four least significat bits are the port address, the four 27 | most significat are the subnet address. 28 | 29 | For example : 30 | 31 | artnet-usb -p 3 -s 2 32 | 33 | sets the universe address to 0x23 34 | 35 | 36 | B. artnet-dmxconsole 37 | -------------------- 38 | Usage: artnet-dmxconsole [OPTIONS] 39 | A console based controller which outputs DMX data over ArtNet. 40 | Modified from the original dmxconsole in dmx4linux. 41 | 42 | -a IP address to send from (defaults to the address 43 | of the first non loopback interface) 44 | -p port address for universe (default 0) 45 | -s subnet address for universe (default 0) 46 | 47 | 48 | C. artnet-discover 49 | ------------------ 50 | 51 | Usage: artnet-discover [OPTIONS] 52 | Prints information about ArtNet nodes 53 | 54 | -a IP address to use (defaults to the address 55 | of the first non loopback interface) 56 | -t The number of seconds to wait for replies 57 | (defaults to 2 seconds) 58 | -------------------------------------------------------------------------------- /config.h.in: -------------------------------------------------------------------------------- 1 | /* config.h.in. Generated from configure.in by autoheader. */ 2 | 3 | /* Define to 1 if you have the `atexit' function. */ 4 | #undef HAVE_ATEXIT 5 | 6 | /* Define to 1 if you have the header file. */ 7 | #undef HAVE_FCNTL_H 8 | 9 | /* Define to 1 if you have the `ftime' function. */ 10 | #undef HAVE_FTIME 11 | 12 | /* Define to 1 if you have the `gettimeofday' function. */ 13 | #undef HAVE_GETTIMEOFDAY 14 | 15 | /* Define to 1 if you have the header file. */ 16 | #undef HAVE_INTTYPES_H 17 | 18 | /* Define to 1 if your system has a GNU libc compatible `malloc' function, and 19 | to 0 otherwise. */ 20 | #undef HAVE_MALLOC 21 | 22 | /* Define to 1 if you have the header file. */ 23 | #undef HAVE_MALLOC_H 24 | 25 | /* Define to 1 if you have the header file. */ 26 | #undef HAVE_MEMORY_H 27 | 28 | /* Define to 1 if you have the `memset' function. */ 29 | #undef HAVE_MEMSET 30 | 31 | /* Define to 1 if your system has a GNU libc compatible `realloc' function, 32 | and to 0 otherwise. */ 33 | #undef HAVE_REALLOC 34 | 35 | /* Define to 1 if you have the `select' function. */ 36 | #undef HAVE_SELECT 37 | 38 | /* Define to 1 if you have the header file. */ 39 | #undef HAVE_STDINT_H 40 | 41 | /* Define to 1 if you have the header file. */ 42 | #undef HAVE_STDLIB_H 43 | 44 | /* Define to 1 if you have the `strdup' function. */ 45 | #undef HAVE_STRDUP 46 | 47 | /* Define to 1 if you have the `strerror' function. */ 48 | #undef HAVE_STRERROR 49 | 50 | /* Define to 1 if you have the header file. */ 51 | #undef HAVE_STRINGS_H 52 | 53 | /* Define to 1 if you have the header file. */ 54 | #undef HAVE_STRING_H 55 | 56 | /* Define to 1 if you have the header file. */ 57 | #undef HAVE_SYS_IOCTL_H 58 | 59 | /* Define to 1 if you have the header file. */ 60 | #undef HAVE_SYS_SELECT_H 61 | 62 | /* Define to 1 if you have the header file. */ 63 | #undef HAVE_SYS_SOCKET_H 64 | 65 | /* Define to 1 if you have the header file. */ 66 | #undef HAVE_SYS_STAT_H 67 | 68 | /* Define to 1 if you have the header file. */ 69 | #undef HAVE_SYS_TIMEB_H 70 | 71 | /* Define to 1 if you have the header file. */ 72 | #undef HAVE_SYS_TIME_H 73 | 74 | /* Define to 1 if you have the header file. */ 75 | #undef HAVE_SYS_TYPES_H 76 | 77 | /* Define to 1 if you have the header file. */ 78 | #undef HAVE_TERMIOS_H 79 | 80 | /* Define to 1 if you have the header file. */ 81 | #undef HAVE_UNISTD_H 82 | 83 | /* Name of package */ 84 | #undef PACKAGE 85 | 86 | /* Define to the address where bug reports for this package should be sent. */ 87 | #undef PACKAGE_BUGREPORT 88 | 89 | /* Define to the full name of this package. */ 90 | #undef PACKAGE_NAME 91 | 92 | /* Define to the full name and version of this package. */ 93 | #undef PACKAGE_STRING 94 | 95 | /* Define to the one symbol short name of this package. */ 96 | #undef PACKAGE_TARNAME 97 | 98 | /* Define to the home page for this package. */ 99 | #undef PACKAGE_URL 100 | 101 | /* Define to the version of this package. */ 102 | #undef PACKAGE_VERSION 103 | 104 | /* Define as the return type of signal handlers (`int' or `void'). */ 105 | #undef RETSIGTYPE 106 | 107 | /* Define to the type of arg 1 for `select'. */ 108 | #undef SELECT_TYPE_ARG1 109 | 110 | /* Define to the type of args 2, 3 and 4 for `select'. */ 111 | #undef SELECT_TYPE_ARG234 112 | 113 | /* Define to the type of arg 5 for `select'. */ 114 | #undef SELECT_TYPE_ARG5 115 | 116 | /* Define to 1 if you have the ANSI C header files. */ 117 | #undef STDC_HEADERS 118 | 119 | /* Define to 1 if you can safely include both and . */ 120 | #undef TIME_WITH_SYS_TIME 121 | 122 | /* Define to 1 if your declares `struct tm'. */ 123 | #undef TM_IN_SYS_TIME 124 | 125 | /* Version number of package */ 126 | #undef VERSION 127 | 128 | /* Define to empty if `const' does not conform to ANSI C. */ 129 | #undef const 130 | 131 | /* Define to rpl_malloc if the replacement function should be used. */ 132 | #undef malloc 133 | 134 | /* Define to rpl_realloc if the replacement function should be used. */ 135 | #undef realloc 136 | -------------------------------------------------------------------------------- /config/pkg.m4: -------------------------------------------------------------------------------- 1 | # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- 2 | # 3 | # Copyright © 2004 Scott James Remnant . 4 | # 5 | # This program is free software; you can redistribute it and/or modify 6 | # it under the terms of the GNU General Public License as published by 7 | # the Free Software Foundation; either version 2 of the License, or 8 | # (at your option) any later version. 9 | # 10 | # This program is distributed in the hope that it will be useful, but 11 | # WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU General Public License 16 | # along with this program; if not, write to the Free Software 17 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 | # 19 | # As a special exception to the GNU General Public License, if you 20 | # distribute this file as part of a program that contains a 21 | # configuration script generated by Autoconf, you may include it under 22 | # the same distribution terms that you use for the rest of that program. 23 | 24 | # PKG_PROG_PKG_CONFIG([MIN-VERSION]) 25 | # ---------------------------------- 26 | AC_DEFUN([PKG_PROG_PKG_CONFIG], 27 | [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) 28 | m4_pattern_allow([^PKG_CONFIG(_PATH)?$]) 29 | AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl 30 | if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then 31 | AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) 32 | fi 33 | if test -n "$PKG_CONFIG"; then 34 | _pkg_min_version=m4_default([$1], [0.9.0]) 35 | AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version]) 36 | if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then 37 | AC_MSG_RESULT([yes]) 38 | else 39 | AC_MSG_RESULT([no]) 40 | PKG_CONFIG="" 41 | fi 42 | 43 | fi[]dnl 44 | ])# PKG_PROG_PKG_CONFIG 45 | 46 | # PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) 47 | # 48 | # Check to see whether a particular set of modules exists. Similar 49 | # to PKG_CHECK_MODULES(), but does not set variables or print errors. 50 | # 51 | # 52 | # Similar to PKG_CHECK_MODULES, make sure that the first instance of 53 | # this or PKG_CHECK_MODULES is called, or make sure to call 54 | # PKG_CHECK_EXISTS manually 55 | # -------------------------------------------------------------- 56 | AC_DEFUN([PKG_CHECK_EXISTS], 57 | [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl 58 | if test -n "$PKG_CONFIG" && \ 59 | AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then 60 | m4_ifval([$2], [$2], [:]) 61 | m4_ifvaln([$3], [else 62 | $3])dnl 63 | fi]) 64 | 65 | 66 | # _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES]) 67 | # --------------------------------------------- 68 | m4_define([_PKG_CONFIG], 69 | [if test -n "$$1"; then 70 | pkg_cv_[]$1="$$1" 71 | elif test -n "$PKG_CONFIG"; then 72 | PKG_CHECK_EXISTS([$3], 73 | [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`], 74 | [pkg_failed=yes]) 75 | else 76 | pkg_failed=untried 77 | fi[]dnl 78 | ])# _PKG_CONFIG 79 | 80 | # _PKG_SHORT_ERRORS_SUPPORTED 81 | # ----------------------------- 82 | AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED], 83 | [AC_REQUIRE([PKG_PROG_PKG_CONFIG]) 84 | if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then 85 | _pkg_short_errors_supported=yes 86 | else 87 | _pkg_short_errors_supported=no 88 | fi[]dnl 89 | ])# _PKG_SHORT_ERRORS_SUPPORTED 90 | 91 | 92 | # PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND], 93 | # [ACTION-IF-NOT-FOUND]) 94 | # 95 | # 96 | # Note that if there is a possibility the first call to 97 | # PKG_CHECK_MODULES might not happen, you should be sure to include an 98 | # explicit call to PKG_PROG_PKG_CONFIG in your configure.ac 99 | # 100 | # 101 | # -------------------------------------------------------------- 102 | AC_DEFUN([PKG_CHECK_MODULES], 103 | [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl 104 | AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl 105 | AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl 106 | 107 | pkg_failed=no 108 | AC_MSG_CHECKING([for $1]) 109 | 110 | _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) 111 | _PKG_CONFIG([$1][_LIBS], [libs], [$2]) 112 | 113 | m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS 114 | and $1[]_LIBS to avoid the need to call pkg-config. 115 | See the pkg-config man page for more details.]) 116 | 117 | if test $pkg_failed = yes; then 118 | _PKG_SHORT_ERRORS_SUPPORTED 119 | if test $_pkg_short_errors_supported = yes; then 120 | $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1` 121 | else 122 | $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1` 123 | fi 124 | # Put the nasty error message in config.log where it belongs 125 | echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD 126 | 127 | ifelse([$4], , [AC_MSG_ERROR(dnl 128 | [Package requirements ($2) were not met: 129 | 130 | $$1_PKG_ERRORS 131 | 132 | Consider adjusting the PKG_CONFIG_PATH environment variable if you 133 | installed software in a non-standard prefix. 134 | 135 | _PKG_TEXT 136 | ])], 137 | [AC_MSG_RESULT([no]) 138 | $4]) 139 | elif test $pkg_failed = untried; then 140 | ifelse([$4], , [AC_MSG_FAILURE(dnl 141 | [The pkg-config script could not be found or is too old. Make sure it 142 | is in your PATH or set the PKG_CONFIG environment variable to the full 143 | path to pkg-config. 144 | 145 | _PKG_TEXT 146 | 147 | To get pkg-config, see .])], 148 | [$4]) 149 | else 150 | $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS 151 | $1[]_LIBS=$pkg_cv_[]$1[]_LIBS 152 | AC_MSG_RESULT([yes]) 153 | ifelse([$3], , :, [$3]) 154 | fi[]dnl 155 | ])# PKG_CHECK_MODULES 156 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # -*- Autoconf -*- 2 | # Process this file with autoconf to produce a configure script. 3 | 4 | AC_PREREQ(2.57) 5 | AC_INIT(artnet-examples, [0.3.13]) 6 | AC_CONFIG_SRCDIR([configure.ac]) 7 | AC_CONFIG_AUX_DIR(config) 8 | AC_CONFIG_HEADERS(config.h) 9 | AC_CONFIG_MACRO_DIR([config]) 10 | AM_INIT_AUTOMAKE 11 | 12 | # Checks for programs. 13 | AC_PROG_CC 14 | AC_PROG_INSTALL 15 | AC_PROG_LN_S 16 | AC_PROG_MAKE_SET 17 | AC_PROG_LIBTOOL 18 | 19 | # Checks for libraries. 20 | # FIXME: Replace `main' with a function in `-lncurses': 21 | AC_CHECK_LIB([ncurses], [initscr], [have_ncurses="yes"]) 22 | AM_CONDITIONAL(HAVE_NCURSES, test "${have_ncurses}" = "yes") 23 | 24 | # Checks for header files. 25 | AC_HEADER_STDC 26 | AC_CHECK_HEADERS([fcntl.h malloc.h stdlib.h string.h sys/ioctl.h sys/time.h sys/timeb.h termios.h unistd.h]) 27 | 28 | # check for libartnet 29 | PKG_CHECK_MODULES(libartnet, [libartnet >= 1.1.0]) 30 | 31 | # Checks for typedefs, structures, and compiler characteristics. 32 | AC_C_CONST 33 | AC_HEADER_TIME 34 | AC_STRUCT_TM 35 | 36 | # Checks for library functions. 37 | AC_PROG_GCC_TRADITIONAL 38 | AC_FUNC_MALLOC 39 | AC_FUNC_REALLOC 40 | AC_FUNC_SELECT_ARGTYPES 41 | AC_TYPE_SIGNAL 42 | AC_CHECK_FUNCS([gettimeofday atexit ftime memset select strdup strerror]) 43 | 44 | AC_MSG_CHECKING([operating system]) 45 | case $host in 46 | *-linux*) 47 | AC_DEFINE(OS_LINUX, [], [Linux backend]) 48 | AC_SUBST(OS_LINUX) 49 | AC_MSG_RESULT([Linux]) 50 | backend="linux" 51 | ;; 52 | *-darwin*) 53 | AC_DEFINE(OS_DARWIN, [], [Darwin backend]) 54 | AC_SUBST(OS_DARWIN) 55 | AC_MSG_RESULT([Darwin/MacOS X]) 56 | backend="darwin" 57 | ;; 58 | *-mingw*) 59 | AC_DEFINE(OS_WINDOWS, [], [Windows backend]) 60 | AC_SUBST(OS_WINDOWS) 61 | AC_MSG_RESULT([Windows]) 62 | backend="windows" 63 | ;; 64 | *-cygwin*) 65 | AC_DEFINE(OS_WINDOWS, [], [Windows backend]) 66 | AC_SUBST(OS_WINDOWS) 67 | AC_MSG_RESULT([Windows]) 68 | backend="windows" 69 | ;; 70 | *) 71 | AC_MSG_ERROR([unsupported operating system]) 72 | esac 73 | 74 | AM_CONDITIONAL([OS_LINUX], [test "x$backend" = "xlinux"]) 75 | AM_CONDITIONAL([OS_DARWIN], [test "x$backend" = "xdarwin"]) 76 | AM_CONDITIONAL([OS_WINDOWS], [test "x$backend" = "xwindows"]) 77 | 78 | AC_OUTPUT(Makefile src/Makefile) 79 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | artnet-examples (0.3.11-1em1) unstable; urgency=low 2 | 3 | * New emdebian release. 4 | 5 | -- Simon Newton Sat, 15 May 2010 23:13:25 +0000 6 | 7 | artnet-examples (0.3.11-1) unstable; urgency=low 8 | 9 | * Release 0.3.11 10 | 11 | -- Simon Newton Sat, 15 May 2010 23:01:21 +0000 12 | 13 | artnet-examples (0.3.9.200610290613-1) unstable; urgency=low 14 | 15 | * New upstream release 16 | 17 | -- Simon Sun, 29 Oct 2006 06:13:38 +0800 18 | 19 | artnet-examples (0.3.9.200609191253-1) unstable; urgency=low 20 | 21 | * New upstream release 22 | 23 | -- Simon Tue, 19 Sep 2006 12:53:39 +0800 24 | 25 | artnet-examples (0.3.9.200609191117-1) unstable; urgency=low 26 | 27 | * New upstream release 28 | 29 | -- Simon Tue, 19 Sep 2006 11:17:55 +0800 30 | 31 | artnet-examples (0.3.9.200609181329-1) unstable; urgency=low 32 | 33 | * New upstream release 34 | 35 | -- Simon Mon, 18 Sep 2006 13:29:44 +0800 36 | 37 | artnet-examples (0.3.9.200607292000-1) unstable; urgency=low 38 | 39 | * New upstream release 40 | 41 | -- simon Tue, 29 Aug 2006 20:00:45 +0800 42 | 43 | artnet-examples (0.3.9.200607282008-1) unstable; urgency=low 44 | 45 | * New upstream release 46 | 47 | -- simon Mon, 28 Aug 2006 20:08:45 +0800 48 | 49 | artnet-examples (0.3.8.200607281749-1) unstable; urgency=low 50 | 51 | * New upstream release 52 | 53 | -- simon Mon, 28 Aug 2006 17:49:42 +0800 54 | 55 | artnet-examples (0.3.8.200607281743-1) unstable; urgency=low 56 | 57 | * New upstream release 58 | 59 | -- simon Mon, 28 Aug 2006 17:43:13 +0800 60 | 61 | artnet-examples (0.3.6-3) unstable; urgency=low 62 | 63 | * Now build on stable 64 | 65 | -- simon Mon, 17 Apr 2006 19:48:22 +0800 66 | 67 | artnet-examples (0.3.6-2) unstable; urgency=low 68 | 69 | * Cleaned up control files to be lintian clean 70 | 71 | -- Simon Newton Fri, 31 Mar 2006 13:10:31 +0800 72 | 73 | artnet-examples (0.3.6-1) unstable; urgency=low 74 | 75 | * New upstream release 76 | 77 | -- simon Sat, 1 Apr 2006 20:01:23 +0800 78 | 79 | artnet-examples (0.3.5-1) unstable; urgency=low 80 | 81 | * Initial release 82 | 83 | -- simon Thu, 30 Mar 2006 22:36:16 +0800 84 | 85 | -------------------------------------------------------------------------------- /debian/compat: -------------------------------------------------------------------------------- 1 | 7 2 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: artnet-examples 2 | Section: electronics 3 | Priority: optional 4 | Maintainer: Simon Newton 5 | Build-Depends: debhelper (>= 7), autotools-dev 6 | Standards-Version: 3.8.0 7 | Homepage: http://code.google.com/p/linux-lighting/ 8 | 9 | Package: artnet-examples 10 | Architecture: any 11 | Depends: ${shlibs:Depends}, ${misc:Depends} 12 | Description: Art-Net DMX over IP example programs 13 | This package provides sample programs that use libartnet 14 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | This package was debianized by simon on 2 | Thu, 30 Mar 2006 22:36:16 +0800. 3 | 4 | It was downloaded from http://code.google.com/p/linux-lighting/ 5 | 6 | Upstream Author: 7 | 8 | Simon Newton 9 | 10 | Copyright: 11 | 12 | Copyright (C) 2004 Simon Newton 13 | 14 | License: 15 | 16 | You are free to distribute this software under the terms of 17 | the GNU General Public License either version of the License, 18 | or (at your option) any later version. 19 | 20 | This package is distributed in the hope that it will be useful, 21 | but WITHOUT ANY WARRANTY; without even the implied warranty of 22 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 23 | GNU General Public License for more details. 24 | 25 | You should have received a copy of the GNU General Public License 26 | along with this package; if not, write to the Free Software 27 | Foundation, Inc., Franklin St, Fifth Floor, Boston, MA - USA 28 | 29 | The Debian packaging is (C) 2010, Simon Newton and 30 | is licensed under the GPL, see `/usr/share/common-licenses/GPL'. 31 | -------------------------------------------------------------------------------- /debian/dirs: -------------------------------------------------------------------------------- 1 | usr/bin 2 | -------------------------------------------------------------------------------- /debian/docs: -------------------------------------------------------------------------------- 1 | NEWS 2 | README 3 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # -*- makefile -*- 3 | # Sample debian/rules that uses debhelper. 4 | # This file was originally written by Joey Hess and Craig Small. 5 | # As a special exception, when this file is copied by dh-make into a 6 | # dh-make output file, you may use that output file without restriction. 7 | # This special exception was added by Craig Small in version 0.37 of dh-make. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | #export DH_VERBOSE=1 11 | 12 | 13 | # These are used for cross-compiling and for saving the configure script 14 | # from having to guess our platform (since we know it already) 15 | DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) 16 | DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) 17 | ifneq ($(DEB_HOST_GNU_TYPE),$(DEB_BUILD_GNU_TYPE)) 18 | CROSS= --build $(DEB_BUILD_GNU_TYPE) --host $(DEB_HOST_GNU_TYPE) 19 | else 20 | CROSS= --build $(DEB_BUILD_GNU_TYPE) 21 | endif 22 | 23 | 24 | 25 | config.status: configure 26 | dh_testdir 27 | # Add here commands to configure the package. 28 | ifneq "$(wildcard /usr/share/misc/config.sub)" "" 29 | cp -f /usr/share/misc/config.sub config.sub 30 | endif 31 | ifneq "$(wildcard /usr/share/misc/config.guess)" "" 32 | cp -f /usr/share/misc/config.guess config.guess 33 | endif 34 | ./configure $(CROSS) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info CFLAGS="$(CFLAGS)" LDFLAGS="-Wl,-z,defs" 35 | 36 | 37 | build: build-stamp 38 | 39 | build-stamp: config.status 40 | dh_testdir 41 | 42 | # Add here commands to compile the package. 43 | $(MAKE) 44 | #docbook-to-man debian/artnet-examples.sgml > artnet-examples.1 45 | 46 | touch $@ 47 | 48 | clean: 49 | dh_testdir 50 | dh_testroot 51 | rm -f build-stamp 52 | 53 | # Add here commands to clean up after the build process. 54 | [ ! -f Makefile ] || $(MAKE) distclean 55 | rm -f config.sub config.guess 56 | 57 | dh_clean 58 | 59 | install: build 60 | dh_testdir 61 | dh_testroot 62 | dh_clean -k 63 | dh_installdirs 64 | 65 | # Add here commands to install the package into debian/artnet-examples. 66 | $(MAKE) DESTDIR=$(CURDIR)/debian/artnet-examples install 67 | 68 | 69 | # Build architecture-independent files here. 70 | binary-indep: build install 71 | # We have nothing to do by default. 72 | 73 | # Build architecture-dependent files here. 74 | binary-arch: build install 75 | dh_testdir 76 | dh_testroot 77 | # dh_install 78 | # dh_installmenu 79 | # dh_installdebconf 80 | # dh_installlogrotate 81 | # dh_installemacsen 82 | # dh_installpam 83 | # dh_installmime 84 | # dh_python 85 | # dh_installinit 86 | # dh_installcron 87 | dh_link 88 | dh_strip 89 | dh_compress 90 | dh_fixperms 91 | # dh_perl 92 | # dh_makeshlibs 93 | dh_installdeb 94 | dh_shlibdeps 95 | dh_gencontrol 96 | dh_md5sums 97 | dh_builddeb 98 | 99 | binary: binary-indep binary-arch 100 | .PHONY: build clean binary-indep binary-arch binary install 101 | -------------------------------------------------------------------------------- /reconf: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | rm -f config.cache 4 | aclocal 5 | autoconf 6 | autoheader 7 | automake -a 8 | exit 9 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | 2 | AM_CFLAGS = -Wall -Werror 3 | LDADD = $(libartnet_LIBS) 4 | 5 | if HAVE_NCURSES 6 | NCURSES_PROGS = artnet_dmxconsole artnet_dmxmonitor 7 | artnet_dmxconsole_SOURCES = artnet-dmxconsole.c 8 | artnet_dmxconsole_LDADD = $(libartnet_LIBS) -lcurses 9 | 10 | artnet_dmxmonitor_SOURCES = artnet-dmxmonitor.c 11 | artnet_dmxmonitor_LDADD = $(libartnet_LIBS) -lcurses 12 | endif 13 | 14 | if OS_LINUX 15 | ARTNET_USB = artnet_usb 16 | endif 17 | 18 | bin_PROGRAMS = artnet_discover artnet_flood_rx artnet_flood_tx \ 19 | artnet_firmware_node artnet_firmware_server artnet_multiport \ 20 | artnet_profile_tx artnet_profile_rx artnet_rdm_output \ 21 | artnet_setdmx $(NCURSES_PROGS) $(ARTNET_USB) 22 | 23 | artnet_usb_SOURCES = artnet-usb.c 24 | artnet_usb_LDADD = $(libartnet_LIBS) -lpthread 25 | artnet_discover_SOURCES = artnet-discover.c 26 | artnet_flood_rx_SOURCES = artnet-flood-rx.c 27 | artnet_flood_tx_SOURCES = artnet-flood-tx.c 28 | artnet_profile_tx_SOURCES = artnet-profile-tx.c 29 | artnet_profile_rx_SOURCES = artnet-profile-rx.c 30 | artnet_firmware_node_SOURCES = artnet-firmware-node.c 31 | artnet_firmware_server_SOURCES = artnet-firmware-server.c 32 | artnet_multiport_SOURCES = artnet-multiport.c 33 | artnet_rdm_output_SOURCES = artnet-rdm-output.c 34 | artnet_setdmx_SOURCES = artnet-setdmx.c 35 | 36 | #artnet_test_master_SOURCES = artnet-test-master.c artnet-test-defaults.h 37 | #artnet_test_slave_SOURCES = artnet-test-slave.c artnet-test-defaults.h artnet-test-defns.h artnet-test-defns.c 38 | -------------------------------------------------------------------------------- /src/artnet-discover.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | */ 16 | 17 | 18 | #ifdef HAVE_CONFIG_H 19 | #include 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | int verbose = 0; 31 | int nodes_found = 0; 32 | 33 | 34 | void print_node_config(artnet_node_entry ne) { 35 | printf("--------- %d.%d.%d.%d -------------\n", ne->ip[0], ne->ip[1], ne->ip[2], ne->ip[3]); 36 | printf("Short Name: %s\n", ne->shortname); 37 | printf("Long Name: %s\n", ne->longname); 38 | printf("Node Report: %s\n", ne->nodereport); 39 | printf("Subnet: 0x%02x\n", ne->sub); 40 | printf("Numb Ports: %d\n", ne->numbports); 41 | printf("Input Addrs: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", ne->swin[0], ne->swin[1], ne->swin[2], ne->swin[3] ); 42 | printf("Output Addrs: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", ne->swout[0], ne->swout[1], ne->swout[2], ne->swout[3] ); 43 | printf("----------------------------------\n"); 44 | } 45 | 46 | int reply_handler(artnet_node n, void *pp, void *d) { 47 | artnet_node_list nl = artnet_get_nl(n); 48 | 49 | if (nodes_found == artnet_nl_get_length(nl)) { 50 | // this is not a new node, just a previously discovered one sending 51 | // another reply 52 | return 0; 53 | } else if(nodes_found == 0) { 54 | // first node found 55 | nodes_found++; 56 | print_node_config( artnet_nl_first(nl)); 57 | } else { 58 | // new node 59 | nodes_found++; 60 | print_node_config( artnet_nl_next(nl)); 61 | } 62 | 63 | return 0; 64 | } 65 | 66 | int main(int argc, char *argv[]) { 67 | artnet_node node; 68 | char *ip_addr = NULL; 69 | int optc, sd, maxsd, timeout = 2; 70 | fd_set rset; 71 | struct timeval tv; 72 | time_t start; 73 | 74 | // parse options 75 | while ((optc = getopt (argc, argv, "va:t:")) != EOF) { 76 | switch (optc) { 77 | case 'a': 78 | ip_addr = (char *) strdup(optarg); 79 | break; 80 | case 't': 81 | timeout = atoi(optarg); 82 | break; 83 | case 'v': 84 | verbose = 1; 85 | break; 86 | default: 87 | break; 88 | } 89 | } 90 | 91 | if ((node = artnet_new(ip_addr, verbose)) == NULL) { 92 | printf("new failed %s\n" , artnet_strerror()); 93 | goto error; 94 | } 95 | 96 | artnet_set_short_name(node, "artnet-discovery"); 97 | artnet_set_long_name(node, "ArtNet Discovery Node"); 98 | artnet_set_node_type(node, ARTNET_SRV); 99 | 100 | // set poll reply handler 101 | artnet_set_handler(node, ARTNET_REPLY_HANDLER, reply_handler, NULL); 102 | 103 | if( artnet_start(node) != ARTNET_EOK) { 104 | printf("Failed to start: %s\n", artnet_strerror()); 105 | goto error_destroy; 106 | } 107 | 108 | sd = artnet_get_sd(node); 109 | 110 | if (artnet_send_poll(node, NULL, ARTNET_TTM_DEFAULT) != ARTNET_EOK) { 111 | printf("send poll failed\n"); 112 | exit(1); 113 | } 114 | 115 | start = time(NULL); 116 | // wait for timeout seconds before quitting 117 | while (time(NULL) - start < timeout) { 118 | FD_ZERO(&rset); 119 | FD_SET(sd, &rset); 120 | 121 | tv.tv_usec = 0; 122 | tv.tv_sec = 1; 123 | maxsd = sd; 124 | 125 | switch (select(maxsd+1, &rset, NULL, NULL, &tv)) { 126 | case 0: 127 | // timeout 128 | break; 129 | case -1: 130 | printf("select error\n"); 131 | break; 132 | default: 133 | artnet_read(node,0); 134 | break; 135 | } 136 | } 137 | 138 | error_destroy : 139 | artnet_destroy(node); 140 | 141 | error: 142 | free(ip_addr); 143 | exit(1); 144 | } 145 | -------------------------------------------------------------------------------- /src/artnet-dmxconsole.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2001 Dirk Jagdmann 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | /* 20 | * Edited by Simon Newton (nomis52westnet.com.au) 21 | * to use libartnet 22 | * 23 | */ 24 | 25 | #ifdef HAVE_CONFIG_H 26 | #include 27 | #endif 28 | 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #ifdef HAVE_MALLOC_H 35 | #include 36 | #endif 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | #include 49 | 50 | /* color names used */ 51 | enum { 52 | CHANNEL = 1, 53 | ZERO, 54 | NORM, 55 | FULL, 56 | HEADLINE, 57 | HEADEMPH, 58 | HEADERROR, 59 | 60 | MAXCOLOR 61 | }; 62 | 63 | /* display modes */ 64 | enum { 65 | DISP_MODE_DMX = 0, 66 | DISP_MODE_HEX, 67 | DISP_MODE_DEC, 68 | DISP_MODE_MAX, 69 | }; 70 | 71 | int MAXCHANNELS=512; 72 | int MAXFKEY=12; 73 | 74 | int verbose = 0; 75 | 76 | typedef unsigned char dmx_t; 77 | 78 | static dmx_t *dmx; 79 | static dmx_t *dmxsave; 80 | static dmx_t *dmxundo; 81 | 82 | static int display_mode = DISP_MODE_DMX; 83 | static int current_channel = 0; /* channel cursor is positioned on */ 84 | static int first_channel = 0; /* channel in upper left corner */ 85 | static int channels_per_line=80/4; 86 | static int channels_per_screen=80/4*24/2; 87 | static int undo_possible=0; 88 | static int current_cue=0; /* select with F keys */ 89 | static float fadetime=1.0f; 90 | static int fading=0; /* percentage counter of fade process */ 91 | static int palette_number=0; 92 | static int palette[MAXCOLOR]; 93 | static char *errorstr=NULL; 94 | static int channels_offset=1; 95 | 96 | static artnet_node node; 97 | 98 | void DMXsleep(int usec) 99 | { 100 | struct timeval tv; 101 | tv.tv_sec = usec/1000000; 102 | tv.tv_usec = usec%1000000; 103 | if(select(1, NULL, NULL, NULL, &tv) < 0) 104 | perror("could not select"); 105 | } 106 | 107 | // returns the time in milliseconds 108 | unsigned long timeGetTime() 109 | { 110 | #ifdef HAVE_GETTIMEOFDAY 111 | struct timeval tv; 112 | gettimeofday(&tv, NULL); 113 | return (unsigned long)tv.tv_sec*1000UL+ (unsigned long)tv.tv_usec/1000; 114 | 115 | #else 116 | # ifdef HAVE_FTIME 117 | struct timeb t; 118 | ftime(&t); 119 | return (unsigned long)t.time*1000UL+(unsigned long)t.millitm; 120 | # else 121 | 122 | # endif 123 | #endif 124 | } 125 | 126 | 127 | 128 | /* set all DMX channels */ 129 | void setall() 130 | { 131 | artnet_send_dmx(node,0,MAXCHANNELS, dmx); 132 | } 133 | 134 | /* set current DMX channel */ 135 | void set() 136 | { 137 | setall(); 138 | } 139 | 140 | 141 | /* display the channels numbers */ 142 | void mask() 143 | { 144 | int i=0,x,y,z=first_channel; 145 | 146 | erase(); 147 | 148 | /* clear headline */ 149 | attrset(palette[HEADLINE]); 150 | move(0,0); 151 | for(x=0; x24) 181 | { 182 | time_t t=time(NULL); 183 | struct tm *tt=localtime(&t); 184 | char *s=asctime(tt); 185 | s[strlen(s)-1]=0; /* strip newline at end of string */ 186 | 187 | attrset(palette[HEADLINE]); 188 | mvprintw(0,1,"%s", s); 189 | } 190 | if(COLS>31) 191 | { 192 | attrset(palette[HEADLINE]); 193 | printw(" cue:"); 194 | attrset(palette[HEADEMPH]); 195 | printw("%02i", current_cue+1); 196 | } 197 | if(COLS>44) 198 | { 199 | attrset(palette[HEADLINE]); 200 | printw(" fadetime:"); 201 | 202 | attrset(palette[HEADEMPH]); 203 | printw("%1.1f", fadetime); 204 | } 205 | if(COLS>55) 206 | { 207 | if(fading) 208 | { 209 | attrset(palette[HEADLINE]); 210 | printw(" fading:"); 211 | 212 | attrset(palette[HEADEMPH]); 213 | printw("%02i%%", (fading<100)?fading:99); 214 | } 215 | else 216 | { 217 | attrset(palette[HEADLINE]); 218 | printw(" "); 219 | } 220 | } 221 | 222 | if(COLS>80) 223 | if(errorstr) 224 | { 225 | attrset(palette[HEADERROR]); 226 | printw("ERROR:%s", errorstr); 227 | } 228 | 229 | /* values */ 230 | for(y=2; yMAXFKEY || new_cue<0) 295 | return; 296 | 297 | undo_possible=0; 298 | 299 | /* don't crossfade for small fadetimes */ 300 | if(fadetime<0.1f) 301 | { 302 | savecue(); 303 | current_cue=new_cue; 304 | loadcue(); 305 | setall(); 306 | return; 307 | } 308 | 309 | savecue(); 310 | dmxold=&dmxsave[current_cue*MAXCHANNELS]; 311 | dmxnew=&dmxsave[new_cue*MAXCHANNELS]; 312 | 313 | /* try to find the last channel value > 0, so we don't have to 314 | crossfade large blocks of 0s */ 315 | for(i=MAXCHANNELS-1; i>=0; max=i, i--) 316 | if(dmxold[i]||dmxnew[i]) 317 | break; 318 | 319 | { 320 | const unsigned long tstart=timeGetTime(); 321 | const unsigned long tend=tstart+(int)(fadetime*1000.0); 322 | unsigned long t=tstart; 323 | while(t<=tend) 324 | { 325 | /* calculate new cue */ 326 | t=timeGetTime(); 327 | { 328 | const float p=(float)(t-tstart)/1000.0f/fadetime; 329 | const float q=1.0f-p; 330 | for(i=1; i 15) { 636 | printf("Subnet address must be between 0 and 15\n"); 637 | exit(1); 638 | } 639 | break; 640 | case 'p': 641 | port_addr = atoi(optarg); 642 | 643 | if(port_addr < 0 && port_addr > 15) { 644 | printf("Port address must be between 0 and 15\n"); 645 | exit(1); 646 | } 647 | break; 648 | case 'v': 649 | verbose = 1; 650 | break; 651 | default: 652 | break; 653 | } 654 | } 655 | 656 | /* check for file to load */ 657 | if (optind < argc) { 658 | f=argv[optind]; 659 | load(f); 660 | loadcue(); 661 | setall(); 662 | } 663 | else { 664 | f="default.chn"; 665 | } 666 | 667 | /* set up artnet node */ 668 | node = artnet_new(ip_addr, verbose);; 669 | 670 | if(node == NULL) { 671 | printf ("Unable to set up artnet node: %s\n", artnet_strerror() ); 672 | return 1; 673 | } 674 | 675 | // set names and node type 676 | artnet_set_short_name(node, "DMX Console "); 677 | artnet_set_long_name(node, "ArtNet DMX Console for Linux"); 678 | artnet_set_node_type(node, ARTNET_SRV); 679 | 680 | artnet_set_subnet_addr(node, subnet_addr); 681 | 682 | // enable the first input port (1 universe only) 683 | artnet_set_port_type(node, 0, ARTNET_ENABLE_INPUT, ARTNET_PORT_DMX); 684 | artnet_set_port_addr(node, 0, ARTNET_INPUT_PORT, port_addr); 685 | artnet_set_bcast_limit(node, bcast_limit); 686 | 687 | //start the node 688 | artnet_start(node); 689 | 690 | // store the sds 691 | an_sd = artnet_get_sd(node); 692 | 693 | /* init curses */ 694 | w = initscr(); 695 | if (!w) 696 | { 697 | printf ("unable to open main-screen\n"); 698 | return 1; 699 | } 700 | 701 | savetty(); 702 | start_color(); 703 | noecho(); 704 | raw(); 705 | keypad(w, TRUE); 706 | 707 | calcscreengeometry(); 708 | changepalette(palette_number); 709 | 710 | /* main loop */ 711 | c=0; 712 | while (c!='q') 713 | { 714 | int n; 715 | fd_set rd_fds; 716 | struct timeval tv; 717 | 718 | FD_ZERO(&rd_fds); 719 | FD_SET(0, &rd_fds); 720 | FD_SET(an_sd, &rd_fds); 721 | 722 | tv.tv_sec = 1; 723 | tv.tv_usec = 0; 724 | 725 | n = select(an_sd+1, &rd_fds, NULL, NULL, &tv); 726 | if(n>0) 727 | { 728 | if(FD_ISSET(0, &rd_fds)) 729 | { 730 | c=wgetch(w); 731 | switch (c) 732 | { 733 | case KEY_PPAGE: 734 | undoprep(); 735 | if(dmx[current_channel] < 255-0x10) 736 | dmx[current_channel]+=0x10; 737 | else 738 | dmx[current_channel]=255; 739 | set(); 740 | break; 741 | 742 | case '+': 743 | if(dmx[current_channel] < 255) 744 | { 745 | undoprep(); 746 | dmx[current_channel]++; 747 | } 748 | set(); 749 | break; 750 | 751 | case KEY_NPAGE: 752 | undoprep(); 753 | if(dmx[current_channel]==255) 754 | dmx[current_channel]=0xe0; 755 | else if(dmx[current_channel] > 0x10) 756 | dmx[current_channel]-=0x10; 757 | else 758 | dmx[current_channel]=0; 759 | set(); 760 | break; 761 | 762 | case '-': 763 | if(dmx[current_channel] > 0) 764 | { 765 | undoprep(); 766 | dmx[current_channel]--; 767 | } 768 | set(); 769 | break; 770 | 771 | case ' ': 772 | undoprep(); 773 | if(dmx[current_channel]<128) 774 | dmx[current_channel]=255; 775 | else 776 | dmx[current_channel]=0; 777 | set(); 778 | break; 779 | 780 | case '0' ... '9': 781 | fadetime=c-'0'; 782 | break; 783 | 784 | case KEY_HOME: 785 | current_channel=0; 786 | first_channel=0; 787 | mask(); 788 | break; 789 | 790 | case KEY_RIGHT: 791 | if(current_channel < MAXCHANNELS-1) 792 | { 793 | current_channel++; 794 | if(current_channel >= first_channel+channels_per_screen) 795 | { 796 | first_channel+=channels_per_line; 797 | mask(); 798 | } 799 | } 800 | break; 801 | 802 | case KEY_LEFT: 803 | if(current_channel > 0) 804 | { 805 | current_channel--; 806 | if(current_channel < first_channel) 807 | { 808 | first_channel-=channels_per_line; 809 | if(first_channel<0) 810 | first_channel=0; 811 | mask(); 812 | } 813 | } 814 | break; 815 | 816 | case KEY_DOWN: 817 | current_channel+=channels_per_line; 818 | if(current_channel>=MAXCHANNELS) 819 | current_channel=MAXCHANNELS-1; 820 | if(current_channel >= first_channel+channels_per_screen) 821 | { 822 | first_channel+=channels_per_line; 823 | mask(); 824 | } 825 | break; 826 | 827 | case KEY_UP: 828 | current_channel-=channels_per_line; 829 | if(current_channel<0) 830 | current_channel=0; 831 | if(current_channel < first_channel) 832 | { 833 | first_channel-=channels_per_line; 834 | if(first_channel<0) 835 | first_channel=0; 836 | mask(); 837 | } 838 | break; 839 | 840 | case KEY_IC: 841 | undoprep(); 842 | for(n=MAXCHANNELS-1; n>current_channel && n>0; n--) 843 | dmx[n]=dmx[n-1]; 844 | setall(); 845 | break; 846 | 847 | case KEY_DC: 848 | undoprep(); 849 | for(n=current_channel; n=DISP_MODE_MAX) 871 | display_mode=0; 872 | mask(); 873 | break; 874 | 875 | case 'N': 876 | case 'n': 877 | if(++channels_offset>1) 878 | channels_offset=0; 879 | mask(); 880 | break; 881 | 882 | case 'P': 883 | case 'p': 884 | changepalette(++palette_number); 885 | break; 886 | 887 | case 'S': 888 | case 's': 889 | savecue(); 890 | save(f); 891 | break; 892 | 893 | case 'U': 894 | case 'u': 895 | undo(); 896 | break; 897 | 898 | default: 899 | if(c>=KEY_F(1) && c<=KEY_F(MAXFKEY)) 900 | crossfade(c-KEY_F(1)); 901 | break; 902 | 903 | } 904 | } 905 | 906 | if (FD_ISSET(an_sd, &rd_fds)) 907 | artnet_read(node,0); 908 | 909 | 910 | values(); 911 | refresh(); 912 | } 913 | } 914 | 915 | return 0; 916 | } 917 | -------------------------------------------------------------------------------- /src/artnet-dmxmonitor.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2001 Dirk Jagdmann 3 | * 4 | * This program is free software; you can redistribute it and/or 5 | * modify it under the terms of the GNU General Public License 6 | * as published by the Free Software Foundation; either version 2 7 | * of the License, or (at your option) any later version. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with this program; if not, write to the Free Software 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 | */ 18 | 19 | /* 20 | * Modified by Simon Newton (nomis52westnet.com.au) 21 | * to use artnet 22 | * 23 | */ 24 | 25 | #ifdef HAVE_CONFIG_H 26 | #include 27 | #endif 28 | 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #ifdef HAVE_MALLOC_H 35 | #include 36 | #endif 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | #include 46 | #include 47 | 48 | #include 49 | 50 | /* color names used */ 51 | enum { 52 | CHANNEL = 1, 53 | ZERO, 54 | NORM, 55 | FULL, 56 | HEADLINE, 57 | HEADEMPH, 58 | HEADERROR, 59 | 60 | MAXCOLOR 61 | }; 62 | 63 | /* display modes */ 64 | enum { 65 | DISP_MODE_DMX = 0, 66 | DISP_MODE_HEX, 67 | DISP_MODE_DEC, 68 | DISP_MODE_MAX, 69 | }; 70 | 71 | int MAXCHANNELS=512; 72 | 73 | typedef unsigned char dmx_t ; 74 | 75 | static dmx_t *dmx; 76 | 77 | static int display_mode = DISP_MODE_DMX; 78 | static int current_channel = 0; /* channel cursor is positioned on */ 79 | static int first_channel = 0; /* channel in upper left corner */ 80 | static int channels_per_line=80/4; 81 | static int channels_per_screen=80/4*24/2; 82 | static int palette_number=0; 83 | static int palette[MAXCOLOR]; 84 | static char *errorstr=NULL; 85 | static int channels_offset=1; 86 | 87 | WINDOW *w=NULL; 88 | static artnet_node node ; 89 | 90 | 91 | /* display the channels numbers */ 92 | void mask() { 93 | int i=0,x,y,z=first_channel; 94 | 95 | erase(); 96 | 97 | /* clear headline */ 98 | attrset(palette[HEADLINE]); 99 | move(0,0); 100 | for(x=0; x24) 127 | { 128 | time_t t=time(NULL); 129 | struct tm *tt=localtime(&t); 130 | char *s=asctime(tt); 131 | s[strlen(s)-1]=0; /* strip newline at end of string */ 132 | 133 | attrset(palette[HEADLINE]); 134 | mvprintw(0,1,"%s", s); 135 | } 136 | 137 | /* values */ 138 | for(y=2; y 15) { 356 | printf("Subnet address must be between 0 and 15\n") ; 357 | exit(1) ; 358 | } 359 | break ; 360 | case 'p': 361 | port_addr = atoi(optarg) ; 362 | 363 | if(port_addr < 0 && port_addr > 15) { 364 | printf("Port address must be between 0 and 15\n") ; 365 | exit(1) ; 366 | } 367 | break ; 368 | 369 | default: 370 | break; 371 | } 372 | } 373 | 374 | /* set up artnet connection */ 375 | node = artnet_new(ip_addr, 0 ) ; ; 376 | 377 | if(node == NULL) { 378 | printf("Unable to connect\n") ; 379 | return 1 ; 380 | } 381 | 382 | if(artnet_set_dmx_handler(node, dmx_handler, NULL) ) { 383 | printf("Failed to install handler\n") ; 384 | return 1 ; 385 | } 386 | 387 | artnet_set_subnet_addr(node, subnet_addr) ; 388 | 389 | artnet_set_port_type(node, 0, ARTNET_ENABLE_OUTPUT, ARTNET_PORT_DMX) ; 390 | artnet_set_port_addr(node, 0, ARTNET_OUTPUT_PORT, port_addr); 391 | 392 | artnet_start(node) ; 393 | 394 | // store the sds 395 | artnet_sd = artnet_get_sd(node) ; 396 | 397 | /* init curses */ 398 | w = initscr(); 399 | if (!w) { 400 | printf ("unable to open main-screen\n"); 401 | return 1; 402 | } 403 | 404 | savetty(); 405 | start_color(); 406 | noecho(); 407 | raw(); 408 | keypad(w, TRUE); 409 | 410 | calcscreengeometry(); 411 | changepalette(palette_number); 412 | 413 | /* main loop */ 414 | c=0; 415 | while (c!='q') { 416 | int n, max; 417 | fd_set rd_fds; 418 | struct timeval tv; 419 | 420 | FD_ZERO(&rd_fds); 421 | FD_SET(0, &rd_fds); 422 | FD_SET(artnet_sd, &rd_fds) ; 423 | 424 | max = artnet_sd ; 425 | 426 | tv.tv_sec = 1; 427 | tv.tv_usec = 0; 428 | 429 | n = select(max+1, &rd_fds, NULL, NULL, &tv); 430 | if(n>0) { 431 | if(FD_ISSET(0, &rd_fds)) { 432 | c=wgetch(w); 433 | switch (c) { 434 | case KEY_HOME: 435 | current_channel=0; 436 | first_channel=0; 437 | mask(); 438 | break; 439 | case KEY_RIGHT: 440 | if(current_channel < MAXCHANNELS-1) { 441 | current_channel++; 442 | if(current_channel >= first_channel+channels_per_screen) { 443 | first_channel+=channels_per_line; 444 | mask(); 445 | } 446 | } 447 | break; 448 | case KEY_LEFT: 449 | if(current_channel > 0) { 450 | current_channel--; 451 | if(current_channel < first_channel) { 452 | first_channel-=channels_per_line; 453 | if(first_channel<0) 454 | first_channel=0; 455 | mask(); 456 | } 457 | } 458 | break; 459 | 460 | case KEY_DOWN: 461 | current_channel+=channels_per_line; 462 | if(current_channel>=MAXCHANNELS) 463 | current_channel=MAXCHANNELS-1; 464 | if(current_channel >= first_channel+channels_per_screen) 465 | { 466 | first_channel+=channels_per_line; 467 | mask(); 468 | } 469 | break; 470 | 471 | case KEY_UP: 472 | current_channel-=channels_per_line; 473 | if(current_channel<0) 474 | current_channel=0; 475 | if(current_channel < first_channel) 476 | { 477 | first_channel-=channels_per_line; 478 | if(first_channel<0) 479 | first_channel=0; 480 | mask(); 481 | } 482 | break; 483 | 484 | case KEY_IC: 485 | for(n=MAXCHANNELS-1; n>current_channel && n>0; n--) 486 | dmx[n]=dmx[n-1]; 487 | break; 488 | 489 | case KEY_DC: 490 | for(n=current_channel; n=DISP_MODE_MAX) 498 | display_mode=0; 499 | mask(); 500 | break; 501 | 502 | case 'N': 503 | case 'n': 504 | if(++channels_offset>1) 505 | channels_offset=0; 506 | mask(); 507 | break; 508 | 509 | case 'P': 510 | case 'p': 511 | changepalette(++palette_number); 512 | break; 513 | 514 | default: 515 | break; 516 | 517 | } 518 | } 519 | 520 | if (FD_ISSET(artnet_sd , &rd_fds) ) 521 | artnet_read(node,0); 522 | } 523 | 524 | values(); 525 | refresh(); 526 | } 527 | 528 | return 0; 529 | } 530 | -------------------------------------------------------------------------------- /src/artnet-firmware-node.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | */ 16 | 17 | 18 | #ifdef HAVE_CONFIG_H 19 | #include 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | 30 | int verbose = 0 ; 31 | int nodes_found = 0; 32 | 33 | 34 | int firmware_handler(artnet_node n, int ubea, uint16_t *data, int length, void *d) { 35 | 36 | FILE *file=fopen("test", "wb"); 37 | printf("in firmware hanlder got %d words\n", length) ; 38 | if(file==NULL) 39 | printf("could not open savefile\n"); 40 | else { 41 | if(fwrite(data, sizeof(uint16_t), length, file) != length) 42 | printf("could not write complete savefile\n"); 43 | if(fclose(file) < 0) 44 | printf("could not close savefile"); 45 | } 46 | 47 | return 0; 48 | } 49 | 50 | int main(int argc, char *argv[]) { 51 | artnet_node node ; 52 | char *ip_addr = NULL ; 53 | int optc, timeout = 2; 54 | time_t start ; 55 | 56 | // parse options 57 | while ((optc = getopt (argc, argv, "va:t:")) != EOF) { 58 | switch (optc) { 59 | case 'a': 60 | ip_addr = (char *) strdup(optarg) ; 61 | break; 62 | case 't': 63 | timeout = atoi(optarg) ; 64 | break; 65 | case 'v': 66 | verbose = 1 ; 67 | break; 68 | default: 69 | break; 70 | } 71 | } 72 | 73 | node = artnet_new(ip_addr, verbose) ; ; 74 | 75 | 76 | artnet_set_short_name(node, "artnet-firmware") ; 77 | artnet_set_long_name(node, "ArtNet Firmware Test Node") ; 78 | artnet_set_node_type(node, ARTNET_NODE) ; 79 | 80 | // set poll reply handler 81 | artnet_set_firmware_handler(node, firmware_handler, NULL) ; 82 | 83 | artnet_start(node) ; 84 | 85 | start = time(NULL) ; 86 | 87 | // wait for timeout seconds before quitting 88 | // got an issue here if the upload starts towards the end of the time 89 | // we'll exit while the upload is in progress 90 | while(time(NULL) - start < timeout) { 91 | artnet_read(node,1) ; 92 | } 93 | 94 | return 0 ; 95 | } 96 | -------------------------------------------------------------------------------- /src/artnet-firmware-server.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | */ 16 | 17 | 18 | #ifdef HAVE_CONFIG_H 19 | #include 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | #define START_SIZE 1048576 34 | #define GROW_SIZE 1048576 35 | #define LINE 80 36 | 37 | //#define START_SIZE 1024 38 | //#define GROW_SIZE 1024 39 | 40 | typedef struct { 41 | char *ip_addr; 42 | char *firmware; 43 | int timeout; 44 | int verbose; 45 | int ubea; 46 | int size; 47 | uint16_t *buffer; 48 | int uploading; 49 | } options_t; 50 | 51 | void *Malloc(int len) { 52 | void *ptr = malloc(len); 53 | 54 | if(ptr == NULL) { 55 | fprintf(stderr,"malloc failed\n"); 56 | exit(1); 57 | } 58 | return ptr; 59 | } 60 | 61 | void *Realloc(void *ptr, int len) { 62 | ptr = realloc(ptr, len); 63 | 64 | if(ptr == NULL) { 65 | fprintf(stderr,"realloc failed\n"); 66 | exit(1); 67 | } 68 | return ptr; 69 | } 70 | 71 | /* 72 | * Parse command lines opts 73 | */ 74 | void parse_options(int argc, char *argv[], options_t *options ) { 75 | int optc; 76 | 77 | options->ip_addr = NULL; 78 | options->firmware = NULL; 79 | options->timeout = 2; 80 | options->verbose = 0; 81 | options->ubea = 0; 82 | options->uploading = 0; 83 | 84 | // parse options 85 | while ((optc = getopt (argc, argv, "uva:t:f:")) != EOF) { 86 | switch (optc) { 87 | case 'a': 88 | options->ip_addr = (char *) strdup(optarg); 89 | break; 90 | case 'f': 91 | options->firmware = (char *) strdup(optarg); 92 | break; 93 | case 't': 94 | options->timeout = atoi(optarg); 95 | break; 96 | case 'v': 97 | options->verbose = 1; 98 | break; 99 | case 'u': 100 | options->ubea = 1; 101 | break; 102 | default: 103 | break; 104 | } 105 | } 106 | } 107 | 108 | /* 109 | * Print the node list 110 | */ 111 | void print_node_list(artnet_node n) { 112 | artnet_node_list nl = artnet_get_nl(n); 113 | artnet_node_entry ent = artnet_nl_first(nl); 114 | int i = 1; 115 | 116 | printf("------------------------------\n"); 117 | for( ent = artnet_nl_first(nl); ent != NULL; ent = artnet_nl_next(nl)) { 118 | printf("%i : %s\n", i++, ent->shortname); 119 | } 120 | printf("------------------------------\n"); 121 | 122 | printf("Select a number, r to re-scan or q to quit\n"); 123 | } 124 | 125 | /* 126 | * Reads the firmware file into memory and returns a point 127 | * this must be freed once you're done 128 | */ 129 | void read_firmware(char *firmware, options_t *options ) { 130 | int fd, len, size; 131 | uint16_t *buf; 132 | char *buf2; 133 | 134 | struct stat f_stat; 135 | 136 | // check if filename is specified 137 | // should fix this up 138 | if(firmware == NULL) { 139 | printf("Use -f to specify firmware file\n"); 140 | exit(1); 141 | } 142 | 143 | // open file 144 | fd = open(firmware, O_RDONLY); 145 | 146 | if ( fstat(fd, &f_stat) ) { 147 | printf("Firmware file %s does not exist\n", firmware); 148 | exit(1); 149 | } 150 | 151 | if( ! fd) { 152 | printf("Could not open firmware file %s\n", firmware); 153 | exit(1); 154 | } 155 | 156 | len = START_SIZE; 157 | 158 | // read file 159 | for (;;) { 160 | buf = Malloc(len); 161 | size = read(fd, (void*) buf, len); 162 | 163 | if( size < len) { 164 | break; 165 | } else { 166 | len += GROW_SIZE; 167 | free(buf); 168 | lseek(fd,0,SEEK_SET); 169 | } 170 | } 171 | 172 | options->buffer = buf; 173 | options->size = size; 174 | 175 | buf2 = (char *) buf; 176 | 177 | if(buf2[size-1] == '\n') { 178 | printf("got char\n"); 179 | } 180 | } 181 | 182 | /* 183 | * Scan for nodes on the network 184 | * 185 | */ 186 | void scan_for_nodes(artnet_node n) { 187 | #define WAIT_TIME 2 188 | time_t start; 189 | 190 | start = time(NULL); 191 | 192 | printf("Searching for nodes... (wait %i seconds)\n", WAIT_TIME); 193 | // wait for WAIT_TIME seconds before quitting 194 | while(time(NULL) - start < WAIT_TIME) { 195 | artnet_read(n,1); 196 | } 197 | 198 | print_node_list(n); 199 | 200 | } 201 | 202 | /* 203 | * This is called when a upload completes 204 | */ 205 | int firmware_complete_callback( artnet_node n, artnet_firmware_status_code code, void *data) { 206 | options_t *options = (options_t*) data; 207 | 208 | printf("Upload Complete\n"); 209 | options->uploading = 0; 210 | return 0; 211 | } 212 | 213 | /* 214 | * Read 215 | */ 216 | int server_handle_input(artnet_node n, options_t *options) { 217 | char line[LINE]; 218 | artnet_node_entry ent; 219 | artnet_node_list nl = artnet_get_nl(n); 220 | int i = 0; 221 | int index; 222 | 223 | if (fgets(line, LINE, stdin) == NULL) { 224 | printf("Unable to read from stdin\n"); 225 | return 0; 226 | } 227 | index = atoi(line); 228 | 229 | if(0 == strcmp( line ,"q\n") ) { 230 | return 1; 231 | } else if ( 0 == strcmp(line, "r\n") ) { 232 | scan_for_nodes( n); 233 | } else if ( index > 0 && index <= artnet_nl_get_length(artnet_get_nl(n)) ) { 234 | // do upload 235 | printf("Starting upload...\n"); 236 | 237 | for(ent = artnet_nl_first(nl); ent != NULL; ent = artnet_nl_next(nl) ) { 238 | if(++i == index) 239 | break; 240 | } 241 | 242 | if(ent != NULL) 243 | artnet_send_firmware(n, ent, options->ubea, options->buffer, options->size / sizeof(uint16_t), firmware_complete_callback, (void *) options); 244 | 245 | } else { 246 | printf("Invalid Command\n"); 247 | } 248 | 249 | return 0; 250 | } 251 | 252 | /* 253 | * 254 | * 255 | */ 256 | void wait_for_input(artnet_node n, options_t *options) { 257 | int sd, maxsd; 258 | fd_set rset; 259 | struct timeval tv; 260 | 261 | sd = artnet_get_sd(n); 262 | maxsd = sd; 263 | 264 | while(1) { 265 | FD_ZERO(&rset); 266 | FD_SET(STDIN_FILENO, &rset); 267 | FD_SET(sd, &rset); 268 | 269 | tv.tv_usec = 0; 270 | tv.tv_sec = 1; 271 | 272 | switch (select( maxsd, &rset, NULL, NULL, &tv ) ) { 273 | case 0: 274 | // timeout 275 | break; 276 | case -1: 277 | printf("select error\n"); 278 | break; 279 | default: 280 | if(FD_ISSET(STDIN_FILENO, &rset) && ! options->uploading) { 281 | if ( server_handle_input(n,options) ) 282 | return; 283 | 284 | } else { 285 | artnet_read(n,0); 286 | break; 287 | } 288 | 289 | } 290 | } 291 | } 292 | 293 | int main(int argc, char *argv[]) { 294 | artnet_node node; 295 | options_t options; 296 | 297 | parse_options(argc, argv, &options); 298 | 299 | read_firmware(options.firmware, &options); 300 | 301 | node = artnet_new(options.ip_addr, options.verbose); ; 302 | 303 | artnet_set_short_name(node, "artnet-firmware"); 304 | artnet_set_long_name(node, "ArtNet Firmware Test Server"); 305 | artnet_set_node_type(node, ARTNET_SRV); 306 | artnet_start(node); 307 | artnet_send_poll(node, NULL, ARTNET_TTM_DEFAULT); 308 | 309 | scan_for_nodes(node); 310 | 311 | wait_for_input(node, &options); 312 | 313 | return 0; 314 | } 315 | -------------------------------------------------------------------------------- /src/artnet-flood-rx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | */ 16 | 17 | 18 | #ifdef HAVE_CONFIG_H 19 | #include 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | int length ; 32 | int verbose = 0; 33 | 34 | int dmx_callback(artnet_node n, void *p, void *d) { 35 | static time_t last = 0 ; 36 | static int counter = 0 ; 37 | time_t now ; 38 | static int last_seq = 0; 39 | 40 | artnet_packet pack = (artnet_packet) p ; 41 | 42 | // printf("seq %d\n", pack->data.admx.sequence ) ; 43 | 44 | // first time 45 | if(last ==0) { 46 | time(&last) ; 47 | last_seq = pack->data.admx.sequence ; 48 | } 49 | 50 | time(&now) ; 51 | 52 | if(pack->data.admx.sequence - last_seq > 1) { 53 | printf("lost %d packets %d %d \n", pack->data.admx.sequence - last_seq, pack->data.admx.sequence , last_seq ) ; 54 | } 55 | 56 | if(last == now) 57 | counter++ ; 58 | else { 59 | printf("Got %d packets last second\n", counter) ; 60 | counter = 0; 61 | last = now ; 62 | } 63 | last_seq = pack->data.admx.sequence ; 64 | 65 | 66 | return 0; 67 | } 68 | 69 | 70 | 71 | int main(int argc, char *argv[]) { 72 | artnet_node node ; 73 | char *ip_addr = NULL ; 74 | int optc, subnet_addr = 0, port_addr = 0 ; 75 | 76 | // parse options 77 | while ((optc = getopt (argc, argv, "s:p:d:a:v")) != EOF) { 78 | switch (optc) { 79 | case 'a': 80 | ip_addr = (char *) strdup(optarg) ; 81 | break; 82 | case 'v': 83 | verbose = 1 ; 84 | break; 85 | case 's': 86 | subnet_addr = atoi(optarg) ; 87 | 88 | if(subnet_addr < 0 && subnet_addr > 15) { 89 | printf("Subnet address must be between 0 and 15\n") ; 90 | exit(1) ; 91 | } 92 | break ; 93 | case 'p': 94 | port_addr = atoi(optarg) ; 95 | 96 | if(port_addr < 0 && port_addr > 15) { 97 | printf("Port address must be between 0 and 15\n") ; 98 | exit(1) ; 99 | } 100 | break ; 101 | default: 102 | break; 103 | } 104 | } 105 | 106 | node = artnet_new(ip_addr, verbose) ; 107 | 108 | artnet_set_short_name(node, "Artnet -> DMX ") ; 109 | artnet_set_long_name(node, "ArtNet Flood RX") ; 110 | artnet_set_node_type(node, ARTNET_NODE) ; 111 | 112 | artnet_set_handler(node, ARTNET_DMX_HANDLER, dmx_callback, NULL) ; 113 | 114 | // set the first port to output dmx data 115 | artnet_set_port_type(node, 0, ARTNET_ENABLE_OUTPUT, ARTNET_PORT_DMX) ; 116 | artnet_set_subnet_addr(node, subnet_addr) ; 117 | 118 | // set the universe address of the first port 119 | artnet_set_port_addr(node, 0, ARTNET_OUTPUT_PORT, port_addr) ; 120 | artnet_start(node) ; 121 | 122 | while(1) { 123 | artnet_read(node, 1) ; 124 | } 125 | 126 | return 0 ; 127 | } 128 | -------------------------------------------------------------------------------- /src/artnet-flood-tx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | */ 16 | 17 | #ifdef HAVE_CONFIG_H 18 | #include 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | int verbose = 0; 32 | int use_select = 0 ; 33 | 34 | int delay = 25000; 35 | 36 | #ifndef WIN32 37 | #include 38 | #else 39 | #include 40 | #endif 41 | 42 | int main(int argc, char *argv[]) { 43 | artnet_node node ; 44 | char *ip_addr = NULL ; 45 | int optc, subnet_addr = 0, port_addr = 0 ; 46 | uint8_t data[ARTNET_DMX_LENGTH] ; 47 | struct timeval tv; 48 | int sd, maxsd ; 49 | fd_set rset; 50 | #ifndef WIN32 51 | struct timespec ts; 52 | #endif 53 | 54 | // parse options 55 | while ((optc = getopt (argc, argv, "s:p:d:a:ve")) != EOF) { 56 | switch (optc) { 57 | case 'a': 58 | ip_addr = (char *) strdup(optarg) ; 59 | break; 60 | case 'v': 61 | verbose = 1 ; 62 | break; 63 | case 'e': 64 | use_select = 1 ; 65 | break; 66 | case 's': 67 | subnet_addr = atoi(optarg) ; 68 | 69 | if(subnet_addr < 0 && subnet_addr > 15) { 70 | printf("Subnet address must be between 0 and 15\n") ; 71 | exit(1) ; 72 | } 73 | break ; 74 | case 'd': 75 | delay = atoi(optarg) ; 76 | break ; 77 | case 'p': 78 | port_addr = atoi(optarg) ; 79 | 80 | if(port_addr < 0 && port_addr > 15) { 81 | printf("Port address must be between 0 and 15\n") ; 82 | exit(1) ; 83 | } 84 | break ; 85 | default: 86 | break; 87 | } 88 | } 89 | 90 | node = artnet_new(ip_addr, verbose) ; ; 91 | 92 | artnet_set_short_name(node, "Artnet -> DMX ") ; 93 | artnet_set_long_name(node, "ArtNet Flood RX") ; 94 | artnet_set_node_type(node, ARTNET_NODE) ; 95 | 96 | // set the first port to input dmx data 97 | artnet_set_port_type(node, 0, ARTNET_ENABLE_INPUT, ARTNET_PORT_DMX) ; 98 | artnet_set_subnet_addr(node, subnet_addr) ; 99 | 100 | // set the universe address of the first port 101 | artnet_set_port_addr(node, 0, ARTNET_INPUT_PORT, port_addr) ; 102 | artnet_start(node) ; 103 | 104 | sd = artnet_get_sd(node) ; 105 | 106 | if(use_select) { 107 | while(1) { 108 | FD_ZERO(&rset) ; 109 | FD_SET(sd, &rset) ; 110 | 111 | tv.tv_usec = delay ; 112 | tv.tv_sec = 0 ; 113 | 114 | maxsd = sd ; 115 | 116 | switch ( select( maxsd+1, &rset, NULL, NULL, &tv ) ) { 117 | case 0: 118 | artnet_send_dmx(node,0, ARTNET_DMX_LENGTH, data) ; 119 | artnet_send_dmx(node,0, ARTNET_DMX_LENGTH, data) ; 120 | artnet_send_dmx(node,0, ARTNET_DMX_LENGTH, data) ; 121 | artnet_send_dmx(node,0, ARTNET_DMX_LENGTH, data) ; 122 | 123 | break ; 124 | case -1: 125 | printf("select error\n") ; 126 | break ; 127 | default: 128 | artnet_read(node,0) ; 129 | break; 130 | } 131 | } 132 | } else { 133 | while(1) { 134 | #ifndef WIN32 135 | ts.tv_nsec = delay ; 136 | ts.tv_sec = 0 ; 137 | #endif 138 | artnet_send_dmx(node,0, ARTNET_DMX_LENGTH, data) ; 139 | 140 | artnet_read(node,0) ; 141 | artnet_send_dmx(node,0, ARTNET_DMX_LENGTH, data) ; 142 | #ifndef WIN32 143 | nanosleep(&ts, NULL) ; 144 | #else 145 | Sleep(delay); 146 | #endif 147 | artnet_send_dmx(node,0, ARTNET_DMX_LENGTH, data) ; 148 | artnet_send_dmx(node,0, ARTNET_DMX_LENGTH, data) ; 149 | } 150 | } 151 | return 0 ; 152 | } 153 | -------------------------------------------------------------------------------- /src/artnet-multiport.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | */ 16 | 17 | #ifdef HAVE_CONFIG_H 18 | #include 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | 31 | int8_t buff[ARTNET_DMX_LENGTH +1]; 32 | int length; 33 | int verbose = 0; 34 | 35 | 36 | int dmx_callback(artnet_node n, int port, void *d) { 37 | uint8_t *data; 38 | 39 | data = artnet_read_dmx(n, port, &length); 40 | memset(buff, 0x00, ARTNET_DMX_LENGTH+1); 41 | memcpy(&buff[1], data, length); 42 | 43 | printf("got dmx on port %i\n", artnet_get_universe_addr(n, port, ARTNET_OUTPUT_PORT) ); 44 | return 0; 45 | } 46 | 47 | 48 | 49 | int main(int argc, char *argv[]) { 50 | artnet_node node1, node2; 51 | char *ip_addr = NULL; 52 | int i, optc, subnet_addr = 0, port_addr = 0; 53 | int sd, maxsd; 54 | fd_set rset; 55 | struct timeval tv; 56 | 57 | // parse options 58 | while ((optc = getopt (argc, argv, "s:p:a:v")) != EOF) { 59 | switch (optc) { 60 | case 'a': 61 | ip_addr = (char *) strdup(optarg); 62 | break; 63 | case 'v': 64 | verbose = 1; 65 | break; 66 | case 's': 67 | subnet_addr = atoi(optarg); 68 | 69 | if(subnet_addr < 0 && subnet_addr > 15) { 70 | printf("Subnet address must be between 0 and 15\n"); 71 | exit(1); 72 | } 73 | break; 74 | case 'p': 75 | port_addr = atoi(optarg); 76 | 77 | if(port_addr < 0 && port_addr > 15) { 78 | printf("Port address must be between 0 and 15\n"); 79 | exit(1); 80 | } 81 | break; 82 | default: 83 | break; 84 | } 85 | } 86 | 87 | node1 = artnet_new(ip_addr, verbose);; 88 | node2 = artnet_new("192.168.0.100", verbose);; 89 | // node2 = artnet_new("192.168.0.101", verbose);; 90 | 91 | artnet_join(node1, node2); 92 | 93 | artnet_set_short_name(node1, "Artnet -> DMX (1)"); 94 | artnet_set_long_name(node1, "ArtNet to DMX convertor"); 95 | artnet_set_node_type(node1, ARTNET_NODE); 96 | artnet_set_dmx_handler(node1, dmx_callback, NULL); 97 | 98 | artnet_set_short_name(node2, "Artnet -> DMX (2)"); 99 | artnet_set_long_name(node2, "ArtNet to DMX convertor"); 100 | artnet_set_node_type(node2, ARTNET_NODE); 101 | artnet_set_dmx_handler(node2, dmx_callback, NULL); 102 | 103 | // set the first port to output dmx data 104 | for(i=0; i< 9; i++) { 105 | if(i < 5) { 106 | artnet_set_port_addr(node1, i%4, ARTNET_OUTPUT_PORT, i); 107 | artnet_set_subnet_addr(node1, subnet_addr); 108 | } else { 109 | artnet_set_subnet_addr(node2, subnet_addr); 110 | artnet_set_port_addr(node2, i%4, ARTNET_OUTPUT_PORT, i); 111 | } 112 | } 113 | 114 | // we need to share sd[1] to node2 here 115 | artnet_start(node1); 116 | artnet_start(node2); 117 | 118 | sd = artnet_get_sd(node1); 119 | maxsd = sd; 120 | 121 | while(1) { 122 | FD_ZERO(&rset); 123 | FD_SET(sd, &rset); 124 | 125 | tv.tv_usec = 0; 126 | tv.tv_sec = 1; 127 | 128 | switch (select( maxsd+1, &rset, NULL, NULL, &tv ) ) { 129 | case 0: 130 | // timeout 131 | break; 132 | case -1: 133 | printf("select error\n"); 134 | break; 135 | default: 136 | 137 | // these are the same descriptors anyway 138 | if(FD_ISSET(sd, &rset) ) { 139 | artnet_read(node1, 0); 140 | } else { 141 | printf("random!!!\n"); 142 | } 143 | break; 144 | } 145 | 146 | } 147 | return 0; 148 | } 149 | -------------------------------------------------------------------------------- /src/artnet-profile-rx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | */ 16 | 17 | #ifdef HAVE_CONFIG_H 18 | #include 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | 30 | int verbose = 0; 31 | 32 | int dmx_callback(artnet_node n, int port, void *d) { 33 | 34 | if(verbose) 35 | printf("got data\n") ; 36 | return 0; 37 | } 38 | 39 | 40 | 41 | int main(int argc, char *argv[]) { 42 | artnet_node node ; 43 | char *ip_addr = NULL ; 44 | int optc, subnet_addr = 0, port_addr = 0 ; 45 | 46 | // parse options 47 | while ((optc = getopt (argc, argv, "s:p:a:v")) != EOF) { 48 | switch (optc) { 49 | case 'a': 50 | ip_addr = (char *) strdup(optarg) ; 51 | break; 52 | case 'v': 53 | verbose = 1 ; 54 | break; 55 | case 's': 56 | subnet_addr = atoi(optarg) ; 57 | 58 | if(subnet_addr < 0 && subnet_addr > 15) { 59 | printf("Subnet address must be between 0 and 15\n") ; 60 | exit(1) ; 61 | } 62 | break ; 63 | case 'p': 64 | port_addr = atoi(optarg) ; 65 | 66 | if(port_addr < 0 && port_addr > 15) { 67 | printf("Port address must be between 0 and 15\n") ; 68 | exit(1) ; 69 | } 70 | break ; 71 | default: 72 | break; 73 | } 74 | } 75 | 76 | node = artnet_new(ip_addr, verbose) ; ; 77 | 78 | artnet_set_short_name(node, "Artnet -> DMX ") ; 79 | artnet_set_long_name(node, "ArtNet to DMX convertor") ; 80 | artnet_set_node_type(node, ARTNET_NODE) ; 81 | artnet_set_dmx_handler(node, dmx_callback, NULL) ; 82 | 83 | // set the first port to output dmx data 84 | artnet_set_port_type(node, 0, ARTNET_ENABLE_OUTPUT, ARTNET_PORT_DMX) ; 85 | artnet_set_subnet_addr(node, subnet_addr) ; 86 | 87 | // set the universe address of the first port 88 | artnet_set_port_addr(node, 0, ARTNET_OUTPUT_PORT, port_addr) ; 89 | artnet_start(node) ; 90 | 91 | while(1) { 92 | artnet_read(node, 1) ; 93 | } 94 | 95 | return 0 ; 96 | } 97 | -------------------------------------------------------------------------------- /src/artnet-profile-tx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | */ 16 | 17 | #ifdef HAVE_CONFIG_H 18 | #include 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | int verbose = 0; 32 | 33 | int delay = 25000; 34 | 35 | #ifndef WIN32 36 | #include 37 | #else 38 | #include 39 | #endif 40 | 41 | int main(int argc, char *argv[]) { 42 | artnet_node node ; 43 | char *ip_addr = NULL ; 44 | int optc, subnet_addr = 0, port_numb= 0, i ; 45 | uint8_t data[ARTNET_DMX_LENGTH] ; 46 | struct timeval tv; 47 | int sd, maxsd ; 48 | fd_set rset; 49 | 50 | // parse options 51 | while ((optc = getopt (argc, argv, "s:p:d:a:ve")) != EOF) { 52 | switch (optc) { 53 | case 'a': 54 | ip_addr = (char *) strdup(optarg) ; 55 | break; 56 | case 'v': 57 | verbose = 1 ; 58 | break; 59 | case 's': 60 | subnet_addr = atoi(optarg) ; 61 | 62 | if(subnet_addr < 0 && subnet_addr > 15) { 63 | printf("Subnet address must be between 0 and 15\n") ; 64 | exit(1) ; 65 | } 66 | break ; 67 | case 'd': 68 | delay = atoi(optarg) ; 69 | break ; 70 | case 'p': 71 | port_numb = atoi(optarg) ; 72 | 73 | if(port_numb < 0 && port_numb > 255) { 74 | printf("Port address must be between 0 and 255\n") ; 75 | exit(1) ; 76 | } 77 | break ; 78 | default: 79 | break; 80 | } 81 | } 82 | 83 | node = artnet_new(ip_addr, verbose) ; ; 84 | 85 | artnet_set_short_name(node, "Artnet Tester") ; 86 | artnet_set_long_name(node, "ArtNet Test TX") ; 87 | artnet_set_node_type(node, ARTNET_RAW) ; 88 | 89 | // set the first port to input dmx data 90 | artnet_set_port_type(node, 0, ARTNET_ENABLE_INPUT, ARTNET_PORT_DMX) ; 91 | artnet_set_subnet_addr(node, subnet_addr) ; 92 | 93 | // set the universe address of the first port 94 | artnet_start(node) ; 95 | 96 | artnet_send_poll(node, NULL, ARTNET_TTM_DEFAULT) ; 97 | 98 | sd = artnet_get_sd(node) ; 99 | 100 | while(1) { 101 | FD_ZERO(&rset) ; 102 | FD_SET(sd, &rset) ; 103 | 104 | tv.tv_usec = delay ; 105 | tv.tv_sec = 0 ; 106 | 107 | maxsd = sd ; 108 | 109 | switch ( select( maxsd+1, &rset, NULL, NULL, &tv ) ) { 110 | case 0: 111 | for(i=0 ; i < port_numb; i++) { 112 | // printf("sending dmx %i\n", i) ; 113 | artnet_raw_send_dmx(node,i, ARTNET_DMX_LENGTH, data); 114 | } 115 | break ; 116 | case -1: 117 | printf("select error\n") ; 118 | break ; 119 | default: 120 | artnet_read(node,0) ; 121 | break; 122 | } 123 | } 124 | return 0 ; 125 | } 126 | -------------------------------------------------------------------------------- /src/artnet-rdm-output.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | */ 16 | 17 | 18 | #ifdef HAVE_CONFIG_H 19 | #include 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | #define UID_WIDTH 6 32 | 33 | #define UID_COUNT 198 34 | int verbose = 0 ; 35 | 36 | 37 | uint8_t *generate_rdm_tod(int count, int iteration) { 38 | uint8_t *ptr = malloc(count * UID_WIDTH) ; 39 | int i ; 40 | 41 | if(ptr == NULL) { 42 | printf("malloc failed\n") ; 43 | exit(1) ; 44 | } 45 | 46 | memset(ptr, 0x00, UID_WIDTH * count ) ; 47 | for(i = 0 ; i < count; i++) { 48 | ptr[i * UID_WIDTH +5] = i ; 49 | ptr[i * UID_WIDTH +4] = iteration ; 50 | } 51 | 52 | return ptr; 53 | 54 | } 55 | 56 | /* 57 | * this is hell dodgy, i can't find the rdm spec so I don't know much about the packet structure 58 | * looking at AL's header files it looks like a RDM packet it 278 bytes. 512 bytes have been allocated 59 | * 60 | * In summary: it's up to you to decode the rdm packet and deal with it. 61 | * 62 | * TODO: helper library for rdm (grab the spec from ...?) 63 | * 64 | */ 65 | int rdm_handler(artnet_node n, int address, uint8_t *rdm, int length, void *d) { 66 | 67 | printf("got rdm data for address %d, of length %d\n", address, length) ; 68 | 69 | return 0; 70 | } 71 | 72 | int rdm_initiate(artnet_node n, int port, void *d) { 73 | uint8_t *tod ; 74 | int *count = (int*) d ; 75 | uint8_t uid[UID_WIDTH] ; 76 | 77 | memset(uid, 0x00, UID_WIDTH) ; 78 | 79 | tod = generate_rdm_tod(UID_COUNT, *count) ; 80 | artnet_add_rdm_devices(n, 0, tod, UID_COUNT) ; 81 | free(tod) ; 82 | 83 | uid[5] = 0xFF ; 84 | uid[4] = *count ; 85 | artnet_add_rdm_device(n,0, uid) ; 86 | 87 | uid[5] = 0x03 ; 88 | artnet_remove_rdm_device(n,0, uid) ; 89 | 90 | uid[5] = 0x06 ; 91 | artnet_remove_rdm_device(n,0, uid) ; 92 | 93 | (*count)++ ; 94 | 95 | return 0; 96 | } 97 | 98 | int main(int argc, char *argv[]) { 99 | artnet_node node ; 100 | char *ip_addr = NULL ; 101 | int optc ; 102 | uint8_t *tod ; 103 | int tod_refreshes = 0 ; 104 | 105 | // parse options 106 | while ((optc = getopt (argc, argv, "va:")) != EOF) { 107 | switch (optc) { 108 | case 'a': 109 | ip_addr = (char *) strdup(optarg) ; 110 | break; 111 | case 'v': 112 | verbose = 1 ; 113 | break; 114 | default: 115 | break; 116 | } 117 | } 118 | 119 | node = artnet_new(ip_addr, verbose) ; ; 120 | 121 | artnet_set_short_name(node, "artnet-rdm") ; 122 | artnet_set_long_name(node, "ArtNet RDM Test, Output Node") ; 123 | artnet_set_node_type(node, ARTNET_NODE) ; 124 | 125 | // set the first port to output dmx data 126 | artnet_set_port_type(node, 0, ARTNET_ENABLE_OUTPUT, ARTNET_PORT_DMX) ; 127 | artnet_set_subnet_addr(node, 0x00) ; 128 | 129 | // set the universe address of the first port 130 | artnet_set_port_addr(node, 0, ARTNET_OUTPUT_PORT, 0x00) ; 131 | 132 | // set poll reply handler 133 | // artnet_set_handler(node, ARTNET_REPLY_HANDLER, reply_handler, NULL) 134 | artnet_set_rdm_initiate_handler(node, rdm_initiate , &tod_refreshes ) ; 135 | artnet_set_rdm_handler(node, rdm_handler, NULL ) ; 136 | 137 | 138 | tod = generate_rdm_tod(UID_COUNT, tod_refreshes++) ; 139 | artnet_add_rdm_devices(node, 0, tod, UID_COUNT) ; 140 | 141 | 142 | artnet_start(node) ; 143 | 144 | artnet_send_tod_control(node, 0x10, ARTNET_TOD_FLUSH) ; 145 | artnet_send_rdm(node, 0x00 , tod, UID_COUNT* UID_WIDTH) ; 146 | free(tod) ; 147 | // loop until control C 148 | while(1) { 149 | artnet_read(node, 1) ; 150 | } 151 | // never reached 152 | artnet_destroy(node) ; 153 | 154 | return 0 ; 155 | } 156 | -------------------------------------------------------------------------------- /src/artnet-setdmx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | * 16 | * Copyright 2004-2006 Simon Newton 17 | * nomis52@westnet.com.au 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include 22 | #endif 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #ifndef WIN32 30 | #include 31 | #include 32 | #else 33 | #include 34 | #endif 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | char SHORT_NAME[] = "ArtNet Node"; 41 | char LONG_NAME[] = "libartnet setdmx example"; 42 | 43 | 44 | typedef struct { 45 | int verbose; 46 | int help; 47 | char *ip_addr; 48 | int port_addr; 49 | int channel; 50 | int value; 51 | float fade_time; 52 | } opts_t; 53 | 54 | 55 | /* 56 | * Set our default options, command line args will overide this 57 | */ 58 | void init_ops(opts_t *ops) { 59 | ops->verbose = 0; 60 | ops->help = 0; 61 | ops->ip_addr = NULL; 62 | ops->port_addr = 0; 63 | ops->channel = 1; 64 | ops->value = 0; 65 | ops->fade_time = 0.0; 66 | } 67 | 68 | 69 | /* 70 | * Parse command lines options and save in opts_s struct 71 | * 72 | */ 73 | void parse_args(opts_t *ops, int argc, char *argv[]) { 74 | 75 | static struct option long_options[] = { 76 | {"address", required_argument, 0, 'a'}, 77 | {"port", required_argument, 0, 'p'}, 78 | {"channel", required_argument, 0, 'c'}, 79 | {"dmx", required_argument, 0, 'd'}, 80 | {"fade", required_argument, 0, 'f'}, 81 | {"help", no_argument, 0, 'h'}, 82 | {"verbose", no_argument, 0, 'v'}, 83 | 84 | {0, 0, 0, 0} 85 | }; 86 | 87 | int c; 88 | int option_index = 0; 89 | 90 | while (1) { 91 | 92 | c = getopt_long(argc, argv, "a:p:c:d:f:vh", long_options, &option_index); 93 | 94 | if (c == -1) 95 | break; 96 | 97 | switch (c) { 98 | case 0: 99 | break; 100 | case 'a': 101 | ops->ip_addr = (char *) strdup(optarg); 102 | break; 103 | case 'd': 104 | ops->value = atoi(optarg); 105 | break; 106 | case 'c': 107 | ops->channel = atoi(optarg); 108 | break; 109 | case 'p': 110 | ops->port_addr = atoi(optarg); 111 | break; 112 | case 'f': 113 | ops->fade_time = atof(optarg); 114 | break; 115 | case 'h': 116 | ops->help = 1; 117 | break; 118 | case 'v': 119 | ops->verbose = 1; 120 | break; 121 | 122 | case '?': 123 | break; 124 | 125 | default: 126 | ; 127 | } 128 | } 129 | } 130 | 131 | /* 132 | * 133 | * 134 | */ 135 | void display_help_and_exit(opts_t *ops, char *argv[]) { 136 | printf( 137 | "Usage: %s --address --port --channel --dmx --fade \n" 138 | "\n" 139 | "Control lla port <-> universe mappings.\n" 140 | "\n" 141 | " -a, --address Address to send from.\n" 142 | " -c, --channel Channel to set (starts from 0).\n" 143 | " -d, --dmx Value to set the channel to.\n" 144 | " -h, --help Display this help message and exit.\n" 145 | " -f, --fade Total time of fade.\n" 146 | " -p, --port Universe (port) address.\n" 147 | " -v, --verbose Be verbose.\n" 148 | "\n", 149 | argv[0] ); 150 | exit(0); 151 | } 152 | 153 | void msleep(long time) { 154 | #ifndef WIN32 155 | struct timespec ts; 156 | ts.tv_sec = 0; 157 | ts.tv_nsec = 1000000*time; 158 | nanosleep(&ts, NULL); 159 | #else 160 | Sleep(time); 161 | #endif 162 | } 163 | 164 | // returns the time in milliseconds 165 | unsigned long timeGetTime() { 166 | #ifndef WIN32 167 | struct timeval tv; 168 | gettimeofday(&tv, NULL); 169 | return (unsigned long)tv.tv_sec*1000UL + (unsigned long)tv.tv_usec/1000; 170 | #else 171 | SYSTEMTIME st; 172 | GetSystemTime(&st); 173 | return (unsigned long)st.wSecond*1000UL + (unsigned long)st.wMilliseconds; 174 | #endif 175 | } 176 | 177 | /* 178 | * 179 | * 180 | */ 181 | int do_fade(artnet_node node, opts_t *ops) { 182 | int chan = ops->channel; 183 | float fadetime = ops->fade_time; 184 | int val = ops->value; 185 | uint8_t dmx[chan]; 186 | float p; 187 | 188 | memset(dmx, 0x00, chan); 189 | 190 | chan--; 191 | 192 | artnet_send_dmx(node, 0, chan, dmx); 193 | msleep(40); 194 | 195 | const unsigned long tstart=timeGetTime(); 196 | const unsigned long tend=tstart+(int)(fadetime*1000.0); 197 | unsigned long t=tstart; 198 | 199 | while (t<=tend) { 200 | t=timeGetTime(); 201 | 202 | if (fadetime) 203 | p = (float)(t-tstart)/1000.0f/fadetime; 204 | else 205 | p = 1.0; 206 | 207 | dmx[chan]=(int)(float)val*p; 208 | 209 | msleep(40); 210 | // printf("%f %i %i %f %li\n", p, chan, dmx[chan] , fadetime, t-tstart); 211 | 212 | // we have to call raw_send here as it sends a sequence number of 0 213 | // otherwise each execution of artnet_setdmx starts the sequence from 0 214 | // which confuses some devices 215 | if (artnet_raw_send_dmx(node, ops->port_addr , chan+1, dmx)) { 216 | printf("failed to send: %s\n", artnet_strerror() ); 217 | } 218 | 219 | t=timeGetTime(); // get current time, because the last time is too old (due to the sleep) 220 | } 221 | 222 | return 0; 223 | } 224 | 225 | 226 | 227 | 228 | int main(int argc, char *argv[]) { 229 | opts_t ops; 230 | artnet_node node; 231 | 232 | // init and parse the args 233 | init_ops(&ops); 234 | parse_args(&ops, argc, argv); 235 | 236 | // do some checks 237 | if (ops.help) 238 | display_help_and_exit(&ops, argv); 239 | 240 | if (ops.channel < 1 || ops.channel > 512) 241 | display_help_and_exit(&ops, argv); 242 | 243 | if (ops.value < 0 || ops.value > 255) 244 | display_help_and_exit(&ops, argv); 245 | 246 | if (ops.port_addr < 0 || ops.port_addr > 4) 247 | display_help_and_exit(&ops, argv); 248 | 249 | // create new artnet node, and set config values 250 | node = artnet_new(ops.ip_addr, ops.verbose);; 251 | 252 | artnet_set_short_name(node, SHORT_NAME); 253 | artnet_set_long_name(node, LONG_NAME); 254 | artnet_set_node_type(node, ARTNET_RAW); 255 | 256 | artnet_set_port_type(node, 0, ARTNET_ENABLE_INPUT, ARTNET_PORT_DMX); 257 | artnet_set_port_addr(node, 0, ARTNET_INPUT_PORT, ops.port_addr); 258 | 259 | if (artnet_start(node) != ARTNET_EOK) { 260 | printf("Failed to start: %s\n", artnet_strerror() ); 261 | goto error_destroy; 262 | } 263 | 264 | printf("channel is %i\n", ops.channel); 265 | do_fade(node, &ops); 266 | 267 | return 0; 268 | 269 | error_destroy : 270 | artnet_destroy(node); 271 | 272 | free(ops.ip_addr); 273 | exit(1); 274 | 275 | } 276 | 277 | -------------------------------------------------------------------------------- /src/artnet-test-defaults.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | #define LONG_NAME "ArtNet Test Slave" 4 | #define SHORT_NAME "artnet-test" 5 | 6 | #define DEFAULT_SUBNET 0x00 7 | #define DEFAULT_PORT_IN_1 0x01 8 | #define DEFAULT_PORT_IN_2 0x02 9 | #define DEFAULT_PORT_IN_3 0x03 10 | #define DEFAULT_PORT_IN_4 0x04 11 | 12 | #define DEFAULT_PORT_OUT_1 0x05 13 | #define DEFAULT_PORT_OUT_2 0x06 14 | #define DEFAULT_PORT_OUT_3 0x07 15 | #define DEFAULT_PORT_OUT_4 0x08 16 | -------------------------------------------------------------------------------- /src/artnet-test-defns.c: -------------------------------------------------------------------------------- 1 | 2 | #include "artnet-test-defns.h" 3 | 4 | address_test_t address_tests[] = { 5 | { 6 | // try programming first 7 | {"New Short Name","New Long Name", {0x81, 0x82, 0x83, 0x84}, {0x85, 0x86, 0x87, 0x88}, 0x80, ARTNET_PC_NONE }, 8 | {"New Short Name","New Long Name", {0x01, 0x02, 0x03, 0x04}, {0x05, 0x06, 0x07, 0x08}, 0x00, ARTNET_PC_NONE } 9 | }, 10 | { 11 | // now try programming without bit 7 of the port (& subnet) addresses set 12 | // should be no change 13 | {SHORT_NAME , LONG_NAME, {0x0F, 0x0E, 0x0D, 0x0C}, {0x0B, 0x0A, 0x09, 0x03}, 0x0F, ARTNET_PC_NONE }, 14 | {SHORT_NAME, LONG_NAME, {0x01, 0x02, 0x03, 0x04}, {0x05, 0x06, 0x07, 0x08}, 0x00, ARTNET_PC_NONE } 15 | 16 | }, 17 | { 18 | {"New Short Name","New Long Name", {0x01, 0x02, 0x03, 0x04}, {0x05, 0x06, 0x07, 0x08}, 0x00, ARTNET_PC_NONE }, 19 | {"New Short Name","New Long Name", {0x01, 0x02, 0x03, 0x04}, {0x05, 0x06, 0x07, 0x08}, 0x00, ARTNET_PC_NONE } 20 | }, 21 | 22 | { 23 | // 24 | {SHORT_NAME , LONG_NAME , {0x0F, 0x0E, 0x0D, 0x0C}, {0x0B, 0x0A, 0x09, 0x03}, 0x0F, ARTNET_PC_NONE }, 25 | {SHORT_NAME , LONG_NAME , {0x0F, 0x0E, 0x0D, 0x0C}, {0x0B, 0x0A, 0x09, 0x03}, 0x0F, ARTNET_PC_NONE } 26 | }, 27 | { 28 | // try a no change for the adddresses 29 | {"New Short Name","New Long Name", {0x7f, 0x7f, 0x7f, 0x7f}, {0x7f, 0x7f, 0x7f, 0x7f}, 0x7f, ARTNET_PC_NONE }, 30 | {SHORT_NAME , LONG_NAME , {0x0F, 0x0E, 0x0D, 0x0C}, {0x0B, 0x0A, 0x09, 0x03}, 0x0F, ARTNET_PC_NONE } 31 | 32 | 33 | 34 | }, 35 | // reset back to defaults 36 | { 37 | {"" , "" , {0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}, 0x00, ARTNET_PC_NONE }, 38 | {SHORT_NAME , LONG_NAME , {DEFAULT_PORT_IN_1 , DEFAULT_PORT_IN_2, DEFAULT_PORT_IN_3, DEFAULT_PORT_IN_4}, {DEFAULT_PORT_OUT_1, DEFAULT_PORT_OUT_2, DEFAULT_PORT_OUT_3, DEFAULT_PORT_OUT_4}, DEFAULT_SUBNET, ARTNET_PC_NONE } 39 | 40 | } 41 | 42 | 43 | } ; 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/artnet-test-defns.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "artnet-test-defaults.h" 4 | 5 | typedef struct { 6 | char shortName[ARTNET_SHORT_NAME_LENGTH] ; 7 | char longName[ARTNET_LONG_NAME_LENGTH] ; 8 | uint8_t inAddr[ARTNET_MAX_PORTS] ; 9 | uint8_t outAddr[ARTNET_MAX_PORTS] ; 10 | uint8_t subAddr ; 11 | artnet_port_command_t cmd ; 12 | } address_test_params_t ; 13 | 14 | 15 | typedef struct { 16 | address_test_params_t send; 17 | address_test_params_t check; 18 | } address_test_t ; 19 | 20 | /* 21 | typedef struct { 22 | int a; 23 | int b; 24 | } address_test_t ; 25 | */ 26 | 27 | extern address_test_t address_tests[] ; 28 | -------------------------------------------------------------------------------- /src/artnet-test-master.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | */ 16 | 17 | 18 | #ifdef HAVE_CONFIG_H 19 | #include 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | 34 | 35 | #include "artnet-test-defaults.h" 36 | #include "artnet-test-defns.h" 37 | 38 | #define START_SIZE 1048576 39 | #define GROW_SIZE 1048576 40 | #define LINE 80 41 | 42 | #define NEW_SHORT_NAME "New short name" 43 | #define NEW_LONG_NAME "New long name" 44 | 45 | typedef enum { 46 | PRE_TEST, 47 | TEST_ADDRESS_1, 48 | TEST_ADDRESS_2, 49 | TEST_ADDRESS_3, 50 | TEST_ADDRESS_4, 51 | 52 | TEST_ERROR, 53 | 54 | 55 | } test_state_e; 56 | 57 | typedef struct { 58 | char *ip_addr; 59 | int verbose ; 60 | artnet_node_entry peer ; 61 | test_state_e state; 62 | } options_t ; 63 | 64 | 65 | /* 66 | * Parse command lines opts 67 | */ 68 | void parse_options(int argc, char *argv[], options_t *options ) { 69 | int optc ; 70 | 71 | options->ip_addr = NULL ; 72 | options->verbose = 0 ; 73 | options->peer = NULL ; 74 | options->state = PRE_TEST ; 75 | 76 | // parse options 77 | while ((optc = getopt (argc, argv, "va:")) != EOF) { 78 | switch (optc) { 79 | case 'a': 80 | options->ip_addr = (char *) strdup(optarg) ; 81 | break; 82 | case 'v': 83 | options->verbose = 1 ; 84 | break; 85 | default: 86 | break; 87 | } 88 | } 89 | } 90 | 91 | 92 | 93 | 94 | /* 95 | * Scan for nodes on the network 96 | * 97 | */ 98 | void scan_for_nodes(artnet_node n, options_t *options ) { 99 | artnet_node_list nl = artnet_get_nl(n) ; 100 | artnet_node_entry ent = artnet_nl_first(nl) ; 101 | 102 | #define WAIT_TIME 2 103 | int i, sd[2] ; 104 | time_t start ; 105 | 106 | sd[0] = artnet_get_sd(n,0) ; 107 | sd[1] = artnet_get_sd(n,1) ; 108 | 109 | start = time(NULL) ; 110 | 111 | printf("Searching for nodes... (waiting %i seconds)\n", WAIT_TIME) ; 112 | // wait for WAIT_TIME seconds before quitting 113 | while(time(NULL) - start < WAIT_TIME) { 114 | artnet_read(n,1) ; 115 | } 116 | 117 | i = 1 ; 118 | 119 | for( ent = artnet_nl_first(nl) ; ent != NULL; ent = artnet_nl_next(nl)) { 120 | if(0 == strncmp(ent->longname , LONG_NAME, ARTNET_LONG_NAME_LENGTH) && 121 | 0 == strncmp(ent->shortname , SHORT_NAME, ARTNET_SHORT_NAME_LENGTH) ) 122 | 123 | options->peer = ent; 124 | } 125 | 126 | } 127 | 128 | 129 | int poll_reply_handler(artnet_node n, void *pp, void *d) { 130 | options_t *options = (options_t* ) d; 131 | // uint8_t in_addr[ARTNET_MAX_PORTS] ; 132 | uint8_t out_addr[ARTNET_MAX_PORTS] ; 133 | int i ; 134 | 135 | if(options->state == TEST_ADDRESS_1 ) { 136 | 137 | if( strncmp(options->peer->longname, NEW_LONG_NAME, ARTNET_LONG_NAME_LENGTH) || 138 | strncmp(options->peer->shortname, NEW_SHORT_NAME, ARTNET_SHORT_NAME_LENGTH) ) { 139 | 140 | printf(" node names incorrectly set\n") ; 141 | options->state = TEST_ERROR ; 142 | } 143 | 144 | for(i=0; i < ARTNET_MAX_PORTS; i++) { 145 | if(options->peer->swin[i] == i && options->peer->swout[i] == i) { 146 | 147 | out_addr[i] = 0x0F - i ; 148 | } 149 | } 150 | 151 | 152 | options->state = TEST_ADDRESS_2 ; 153 | 154 | } else if (options->state == TEST_ADDRESS_3 ) { 155 | if( strncmp(options->peer->longname, LONG_NAME, ARTNET_LONG_NAME_LENGTH) || 156 | strncmp(options->peer->shortname, SHORT_NAME, ARTNET_SHORT_NAME_LENGTH) ) { 157 | 158 | printf(" node names incorrectly set\n") ; 159 | options->state = TEST_ERROR ; 160 | } 161 | 162 | options->state = TEST_ADDRESS_4 ; 163 | 164 | } 165 | 166 | 167 | 168 | return 0; 169 | } 170 | 171 | 172 | 173 | 174 | int wait_for_test(artnet_node n, options_t *options) { 175 | test_state_e current_state = options->state ; 176 | 177 | #define WAIT_TIME 2 178 | int sd[2] ; 179 | time_t start ; 180 | 181 | sd[0] = artnet_get_sd(n,0) ; 182 | sd[1] = artnet_get_sd(n,1) ; 183 | 184 | start = time(NULL) ; 185 | 186 | // wait for WAIT_TIME seconds before quitting 187 | while(time(NULL) - start < WAIT_TIME && options->state == current_state) { 188 | artnet_read(n,1) ; 189 | } 190 | 191 | if(options->state == current_state) 192 | // got no response 193 | return -1 ; 194 | 195 | if(options->state == TEST_ERROR) 196 | // tests returned an error 197 | return -1 ; 198 | 199 | return 0; 200 | } 201 | 202 | 203 | int run_address_tests(artnet_node n, options_t *options) { 204 | int numTests ; 205 | // uint8_t in_addr[ARTNET_MAX_PORTS] ; 206 | // uint8_t out_addr[ARTNET_MAX_PORTS] ; 207 | 208 | numTests = sizeof(address_test_t) ; 209 | numTests = sizeof(address_tests) ; 210 | 211 | printf("%i tests\n", numTests) ; 212 | 213 | /* 214 | // send an ArtAddress first 215 | for(i=0; i < ARTNET_MAX_PORTS; i++) { 216 | in_addr[i] = i ; 217 | out_addr[i] = i ; 218 | } 219 | 220 | printf("Sending an ArtAddress packet...") ; 221 | fflush(stdout) ; 222 | 223 | artnet_send_address(n, options->peer, NEW_SHORT_NAME , NEW_LONG_NAME, 224 | in_addr , out_addr, 0x01, ARTNET_PC_NONE ) ; 225 | 226 | options->state = TEST_ADDRESS_1 ; 227 | if( wait_for_test(n, options) ) 228 | return -1 ; 229 | 230 | printf("\tok\n") ; 231 | 232 | // change port and addresses 233 | for(i=0; i < ARTNET_MAX_PORTS; i++) { 234 | in_addr[i] = 0x0F - i ; 235 | out_addr[i] = 0x0F - i ; 236 | } 237 | 238 | printf("Sending a second ArtAddress packet...") ; 239 | fflush(stdout) ; 240 | 241 | artnet_send_address(n, options->peer, SHORT_NAME , LONG_NAME, 242 | in_addr , out_addr, 0x01, ARTNET_PC_NONE ) ; 243 | 244 | options->state = TEST_ADDRESS_3 ; 245 | if( wait_for_test(n, options) ) 246 | return -1 ; 247 | 248 | printf("\tok\n") ; 249 | 250 | // 251 | 252 | 253 | */ 254 | return 0; 255 | 256 | 257 | 258 | 259 | 260 | } 261 | int run_tests(artnet_node n, options_t *options) { 262 | 263 | // art poll reply 264 | run_address_tests(n, options) ; 265 | 266 | // run_dmx_tests(n,options) ; 267 | 268 | // art poll reply 269 | // run_input_tests(n, options) ; 270 | 271 | // 272 | // run_firmware_tests(n,options) ; 273 | 274 | return 0; 275 | } 276 | 277 | int main(int argc, char *argv[]) { 278 | artnet_node node ; 279 | options_t options ; 280 | 281 | parse_options(argc, argv, &options) ; 282 | 283 | node = artnet_new(options.ip_addr, options.verbose) ; ; 284 | 285 | artnet_set_short_name(node, "artnet-test") ; 286 | artnet_set_long_name(node, "ArtNet Test Master") ; 287 | artnet_set_node_type(node, ARTNET_SRV) ; 288 | 289 | artnet_set_handler(node, ARTNET_REPLY_HANDLER, poll_reply_handler, (void*) &options) ; 290 | 291 | artnet_start(node) ; 292 | artnet_send_poll(node, NULL, ARTNET_TTM_DEFAULT) ; 293 | 294 | 295 | scan_for_nodes(node, &options) ; 296 | 297 | if(options.peer == NULL) { 298 | printf("Could not locale peer node, exiting...\n") ; 299 | exit(1) ; 300 | } 301 | 302 | printf("Good, found a test peer at \n") ; 303 | 304 | if( run_tests(node, &options) ) { 305 | printf("\nERROR: Timeout, aborting tests\n") ; 306 | } 307 | return 0 ; 308 | } 309 | -------------------------------------------------------------------------------- /src/artnet-test-slave.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | */ 16 | 17 | 18 | #ifdef HAVE_CONFIG_H 19 | #include 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "artnet-test-defaults.h" 29 | 30 | #include 31 | 32 | int verbose = 0 ; 33 | int nodes_found = 0; 34 | 35 | 36 | int firmware_handler(artnet_node n, int ubea, uint16_t *data, int length, void *d) { 37 | 38 | FILE *file=fopen("test", "wb"); 39 | printf("in firmware hanlder got %d words\n", length) ; 40 | if(file==NULL) 41 | printf("could not open savefile\n"); 42 | else { 43 | if(fwrite(data, sizeof(uint16_t), length, file) != length) 44 | printf("could not write complete savefile\n"); 45 | if(fclose(file) < 0) 46 | printf("could not close savefile"); 47 | } 48 | 49 | return 0; 50 | } 51 | 52 | int main(int argc, char *argv[]) { 53 | artnet_node node ; 54 | char *ip_addr = NULL ; 55 | int i, optc, sd[2], timeout = 2; 56 | time_t start ; 57 | 58 | // parse options 59 | while ((optc = getopt (argc, argv, "va:t:")) != EOF) { 60 | switch (optc) { 61 | case 'a': 62 | ip_addr = (char *) strdup(optarg) ; 63 | break; 64 | case 't': 65 | timeout = atoi(optarg) ; 66 | break; 67 | case 'v': 68 | verbose = 1 ; 69 | break; 70 | default: 71 | break; 72 | } 73 | } 74 | 75 | node = artnet_new(ip_addr, verbose) ; ; 76 | 77 | // set default params 78 | artnet_set_short_name(node, SHORT_NAME) ; 79 | artnet_set_long_name(node, LONG_NAME) ; 80 | artnet_set_node_type(node, ARTNET_NODE) ; 81 | artnet_set_subnet_addr(node, DEFAULT_SUBNET ) ; 82 | 83 | for(i=0; i< ARTNET_MAX_PORTS; i++) 84 | artnet_set_port_type(node, i, ARTNET_ENABLE_OUTPUT & ARTNET_ENABLE_INPUT, ARTNET_PORT_DMX ) ; 85 | 86 | // set default port addresses 87 | artnet_set_port_addr(node, 0, ARTNET_INPUT_PORT, DEFAULT_PORT_IN_1 ) ; 88 | artnet_set_port_addr(node, 1, ARTNET_INPUT_PORT, DEFAULT_PORT_IN_2 ) ; 89 | artnet_set_port_addr(node, 2, ARTNET_INPUT_PORT, DEFAULT_PORT_IN_3 ) ; 90 | artnet_set_port_addr(node, 3, ARTNET_INPUT_PORT, DEFAULT_PORT_IN_4 ) ; 91 | 92 | artnet_set_port_addr(node, 0, ARTNET_OUTPUT_PORT, DEFAULT_PORT_OUT_1 ) ; 93 | artnet_set_port_addr(node, 1, ARTNET_OUTPUT_PORT, DEFAULT_PORT_OUT_2 ) ; 94 | artnet_set_port_addr(node, 2, ARTNET_OUTPUT_PORT, DEFAULT_PORT_OUT_3 ) ; 95 | artnet_set_port_addr(node, 3, ARTNET_OUTPUT_PORT, DEFAULT_PORT_OUT_4 ) ; 96 | 97 | 98 | 99 | // set poll reply handler 100 | artnet_set_firmware_handler(node, firmware_handler, NULL) ; 101 | 102 | artnet_start(node) ; 103 | 104 | sd[0] = artnet_get_sd(node,0) ; 105 | sd[1] = artnet_get_sd(node,1) ; 106 | 107 | start = time(NULL) ; 108 | 109 | // wait for timeout seconds before quitting 110 | // got an issue here if the upload starts towards the end of the time 111 | // we'll exit while the upload is in progress 112 | while(time(NULL) - start < timeout) { 113 | artnet_read(node,1) ; 114 | } 115 | 116 | return 0 ; 117 | } 118 | -------------------------------------------------------------------------------- /src/artnet-test-tx.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | */ 16 | 17 | #ifdef HAVE_CONFIG_H 18 | #include 19 | #endif 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | 31 | int verbose = 0; 32 | 33 | int delay = 25000; 34 | 35 | 36 | #include 37 | 38 | int main(int argc, char *argv[]) { 39 | artnet_node node ; 40 | char *ip_addr = NULL ; 41 | int optc, subnet_addr = 0, port_numb= 0, i ; 42 | uint8_t data[ARTNET_DMX_LENGTH] ; 43 | struct timeval tv; 44 | int sd[2], maxsd ; 45 | fd_set rset; 46 | 47 | // parse options 48 | while ((optc = getopt (argc, argv, "s:p:d:a:ve")) != EOF) { 49 | switch (optc) { 50 | case 'a': 51 | ip_addr = (char *) strdup(optarg) ; 52 | break; 53 | case 'v': 54 | verbose = 1 ; 55 | break; 56 | case 's': 57 | subnet_addr = atoi(optarg) ; 58 | 59 | if(subnet_addr < 0 && subnet_addr > 15) { 60 | printf("Subnet address must be between 0 and 15\n") ; 61 | exit(1) ; 62 | } 63 | break ; 64 | case 'd': 65 | delay = atoi(optarg) ; 66 | break ; 67 | case 'p': 68 | port_numb = atoi(optarg) ; 69 | 70 | if(port_numb < 0 && port_numb > 255) { 71 | printf("Port address must be between 0 and 255\n") ; 72 | exit(1) ; 73 | } 74 | break ; 75 | default: 76 | break; 77 | } 78 | } 79 | 80 | node = artnet_new(ip_addr, verbose) ; ; 81 | 82 | artnet_set_short_name(node, "Artnet Tester") ; 83 | artnet_set_long_name(node, "ArtNet Test TX") ; 84 | artnet_set_node_type(node, ARTNET_RAW) ; 85 | 86 | // set the first port to input dmx data 87 | artnet_set_port_type(node, 0, ARTNET_ENABLE_INPUT, ARTNET_PORT_DMX) ; 88 | artnet_set_subnet_addr(node, subnet_addr) ; 89 | 90 | // set the universe address of the first port 91 | artnet_start(node) ; 92 | 93 | 94 | sd[0] = artnet_get_sd(node,0) ; 95 | sd[1] = artnet_get_sd(node,1) ; 96 | 97 | while(1) { 98 | FD_ZERO(&rset) ; 99 | FD_SET(sd[0], &rset) ; 100 | FD_SET(sd[1], &rset) ; 101 | 102 | tv.tv_usec = delay ; 103 | tv.tv_sec = 0 ; 104 | 105 | maxsd = sd[0] > sd[1] ? sd[0] : sd[1] ; 106 | 107 | switch ( select( maxsd+1, &rset, NULL, NULL, &tv ) ) { 108 | case 0: 109 | for(i=0 ; i < port_numb; i++) { 110 | printf("sending dmx %i\n", i) ; 111 | artnet_raw_send_dmx(node,i, ARTNET_DMX_LENGTH, data) ; 112 | } 113 | break ; 114 | case -1: 115 | printf("select error\n") ; 116 | break ; 117 | default: 118 | artnet_read(node,0) ; 119 | break; 120 | } 121 | } 122 | return 0 ; 123 | } 124 | -------------------------------------------------------------------------------- /src/artnet-usb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * This program is free software; you can redistribute it and/or modify 3 | * it under the terms of the GNU General Public License as published by 4 | * the Free Software Foundation; either version 2 of the License, or 5 | * (at your option) any later version. 6 | * 7 | * This program is distributed in the hope that it will be useful, 8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 | * GNU Library General Public License for more details. 11 | * 12 | * You should have received a copy of the GNU General Public License 13 | * along with this program; if not, write to the Free Software 14 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 15 | * 16 | * Copyright 2004-2005 Simon Newton 17 | * nomis52@westnet.com.au 18 | */ 19 | 20 | #ifdef HAVE_CONFIG_H 21 | #include 22 | #endif 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #define DEFAULT_DEVICE "/dev/dmx0" 37 | #define DEFAULT_DEVICE2 "/dev/dmx1" 38 | #define DEFAULT_DEVICE3 "/dev/dmx2" 39 | #define DEFAULT_DEVICE4 "/dev/dmx3" 40 | 41 | #define UNCONNECTED -1 42 | #define SHORT_NAME "NWAN" 43 | #define LONG_NAME "Netgear Wireless Artnet Node" 44 | 45 | 46 | typedef struct { 47 | int verbose ; 48 | char *dev[ARTNET_MAX_PORTS]; 49 | char *ip_addr ; 50 | int subnet_addr ; 51 | int port_addr ; 52 | int persist ; 53 | int num_ports; 54 | int fd[ARTNET_MAX_PORTS] ; 55 | uint8_t dmx[ARTNET_MAX_PORTS][ARTNET_DMX_LENGTH +1] ; 56 | char *short_name ; 57 | char *long_name ; 58 | char *config_file ; 59 | } opts_t; 60 | 61 | typedef struct { 62 | opts_t *ops ; 63 | int port_id ; 64 | } thread_args_t ; 65 | 66 | 67 | pthread_mutex_t mem_mutex = PTHREAD_MUTEX_INITIALIZER ; 68 | 69 | int do_write(opts_t *ops, int pid, uint8_t *buf, int length) { 70 | int res ; 71 | 72 | res = write(ops->fd[pid], buf, length); 73 | 74 | if (res < 0){ 75 | /* if you unplug devices from the dongle 76 | */ 77 | if(ops->verbose) 78 | perror("Error writing to device"); 79 | 80 | res = close(ops->fd[pid]) ; 81 | if(res < 0) 82 | perror("close ") ; 83 | else 84 | ops->fd[pid] = UNCONNECTED ; 85 | 86 | return -1 ; 87 | } 88 | 89 | if(res > 0 && ops->verbose) 90 | printf("p%d: 0x%02hhx, 0x%02hhx, 0x%02hhx, 0x%02hhx length %d\n", pid, buf[1], buf[2], buf[3], buf[4] , length) ; 91 | 92 | return 0; 93 | } 94 | 95 | 96 | void *thread_run(void *arg) { 97 | thread_args_t *args = (thread_args_t*) arg ; 98 | uint8_t buf[ARTNET_DMX_LENGTH+1] ; 99 | int *pid = &args->port_id ; 100 | 101 | // int len ; 102 | 103 | args->ops->fd[*pid] = open(args->ops->dev[*pid],O_WRONLY) ; 104 | 105 | while(1) { 106 | 107 | if(args->ops->fd[*pid] == UNCONNECTED) { 108 | sleep(1) ; 109 | 110 | args->ops->fd[*pid] = open(args->ops->dev[*pid],O_WRONLY) ; 111 | 112 | if(args->ops->fd[*pid] == -1 && args->ops->verbose) 113 | printf("open %s: %s\n",args->ops->dev[*pid], strerror(errno) ) ; 114 | 115 | } else { 116 | pthread_mutex_lock(&mem_mutex) ; 117 | memcpy(buf, args->ops->dmx[*pid], ARTNET_DMX_LENGTH+1) ; 118 | pthread_mutex_unlock(&mem_mutex) ; 119 | 120 | do_write(args->ops, *pid, buf, ARTNET_DMX_LENGTH+1) ; 121 | // sleep(1) ; 122 | } 123 | } 124 | 125 | /* for(i = 513; i >=0; i--) { 126 | if(buff[i] != buf[i]) 127 | break ; 128 | } 129 | 130 | if(i>0) { 131 | */ 132 | return NULL ; 133 | 134 | } 135 | 136 | /* 137 | * Called when we have dmx data pending 138 | */ 139 | int dmx_handler(artnet_node n, int port, void *d) { 140 | uint8_t *data ; 141 | opts_t *ops = (opts_t *) d ; 142 | int len ; 143 | 144 | if(port < ops->num_ports) { 145 | data = artnet_read_dmx(n, port, &len) ; 146 | pthread_mutex_lock(&mem_mutex) ; 147 | memcpy(&ops->dmx[port][1], data, len) ; 148 | pthread_mutex_unlock(&mem_mutex) ; 149 | } 150 | return 0; 151 | } 152 | 153 | 154 | 155 | /* 156 | * saves the settings to the config file 157 | */ 158 | int save_config(opts_t *ops) { 159 | FILE *fh ; 160 | printf("in save config\n") ; 161 | if ((fh = fopen(ops->config_file, "w")) == NULL ) { 162 | perror("fopen") ; 163 | return -1 ; 164 | } 165 | 166 | fprintf(fh, "# artnet_usb config file\n") ; 167 | fprintf(fh, "Shortname=%s\n", ops->short_name) ; 168 | fprintf(fh, "Longname=%s\n", ops->long_name) ; 169 | fprintf(fh, "Subnet=%i\n", ops->subnet_addr) ; 170 | fprintf(fh, "Port=%i\n", ops->port_addr); 171 | 172 | fclose(fh) ; 173 | 174 | return 0 ; 175 | } 176 | 177 | /* 178 | * Load the settings from config file 179 | */ 180 | int load_config(opts_t *ops) { 181 | #define BUF_SIZE 1024 182 | FILE *fh ; 183 | char buf[1024], *c ; 184 | char *key, *data ; 185 | 186 | if(ops->config_file == NULL) 187 | return -1; 188 | 189 | if ((fh = fopen(ops->config_file, "r")) == NULL ) { 190 | perror("fopen") ; 191 | return -1 ; 192 | } 193 | 194 | while ( fgets(buf, 1024, fh) != NULL) { 195 | if(*buf == '#') 196 | continue ; 197 | 198 | // strip \n 199 | for(c = buf ; *c != '\n' ; c++) ; 200 | *c = '\0' ; 201 | 202 | key = strtok(buf, "=") ; 203 | data = strtok(NULL, "=") ; 204 | 205 | if(key == NULL || data == NULL) 206 | continue ; 207 | 208 | if(strcmp(key, "Shortname") == 0) { 209 | free(ops->short_name) ; 210 | ops->short_name = strdup(data) ; 211 | } else if(strcmp(key, "Longname") == 0) { 212 | free(ops->long_name) ; 213 | ops->long_name = strdup(data) ; 214 | } else if(strcmp(key, "Subnet") == 0) { 215 | ops->subnet_addr = atoi(data) ; 216 | } else if(strcmp(key, "Port") == 0 ) { 217 | ops->port_addr = atoi(data) ; 218 | } 219 | 220 | } 221 | 222 | fclose(fh) ; 223 | return 0 ; 224 | } 225 | 226 | /* 227 | * called when to node configuration changes, 228 | * we need to save the configuration to a file 229 | */ 230 | int program_handler(artnet_node n, void *d) { 231 | opts_t *ops = (opts_t*) d ; 232 | artnet_node_config_t config ; 233 | 234 | artnet_get_config(n, &config) ; 235 | 236 | free(ops->short_name) ; 237 | free(ops->long_name) ; 238 | 239 | ops->short_name = strdup(config.short_name) ; 240 | ops->long_name = strdup(config.long_name) ; 241 | ops->subnet_addr = config.subnet ; 242 | ops->port_addr = config.out_ports[0] ; 243 | 244 | save_config(ops) ; 245 | return 0 ; 246 | } 247 | 248 | 249 | /* 250 | * Main function 251 | * 252 | */ 253 | int run(opts_t *ops) { 254 | artnet_node node ; 255 | pthread_t tid[ARTNET_MAX_PORTS] ; 256 | thread_args_t targ[ARTNET_MAX_PORTS] ; 257 | int i ; 258 | 259 | load_config(ops) ; 260 | 261 | // create new artnet node, and set config values 262 | node = artnet_new(ops->ip_addr, ops->verbose) ; ; 263 | 264 | artnet_set_short_name(node, ops->short_name) ; 265 | artnet_set_long_name(node, ops->long_name) ; 266 | artnet_set_node_type(node, ARTNET_NODE) ; 267 | 268 | artnet_set_subnet_addr(node, ops->subnet_addr) ; 269 | 270 | // we want to be notified when the node config changes 271 | artnet_set_program_handler(node, program_handler, (void*) ops) ; 272 | artnet_set_dmx_handler(node, dmx_handler, (void*) ops) ; 273 | 274 | for(i=0; i < ops->num_ports ; i++) { 275 | // set the first port to output dmx data 276 | artnet_set_port_type(node, i, ARTNET_ENABLE_OUTPUT, ARTNET_PORT_DMX) ; 277 | 278 | // set the universe address of the first port 279 | artnet_set_port_addr(node, i, ARTNET_OUTPUT_PORT, ops->port_addr+i) ; 280 | 281 | targ[i].ops = ops ; 282 | targ[i].port_id = i ; 283 | 284 | if( pthread_create(&tid[i], NULL, &thread_run, (void*) &targ[i]) ) { 285 | printf("pthread failed\n") ; 286 | } 287 | } 288 | 289 | artnet_start(node) ; 290 | 291 | while(1) { 292 | // set a 1 second timeout on the read 293 | // this way we send a DMX frame every second 294 | // even if we don't get any ArtNet packets 295 | artnet_read(node, 1) ; 296 | 297 | } 298 | 299 | return 0 ; 300 | } 301 | 302 | 303 | /* 304 | * Set our default options, command line args will overide this 305 | */ 306 | void init_ops(opts_t *ops) { 307 | int i ; 308 | 309 | ops->verbose = 0; 310 | 311 | ops->ip_addr = NULL ; 312 | ops->subnet_addr = 0 ; 313 | ops->port_addr = 0 ; 314 | ops->persist = 0; 315 | ops->num_ports = 1; 316 | 317 | for(i=0; i < ARTNET_MAX_PORTS; i++) { 318 | ops->fd[i] = UNCONNECTED ; 319 | memset(ops->dmx[i], 0x00, ARTNET_DMX_LENGTH+1) ; 320 | } 321 | // dodgy but saves using vasprintf 322 | ops->dev[0] = strdup(DEFAULT_DEVICE) ; 323 | ops->dev[1] = strdup(DEFAULT_DEVICE2) ; 324 | ops->dev[2] = strdup(DEFAULT_DEVICE3) ; 325 | ops->dev[3] = strdup(DEFAULT_DEVICE4) ; 326 | 327 | ops->short_name = strdup(SHORT_NAME) ; 328 | ops->long_name = strdup(LONG_NAME) ; 329 | ops->config_file = NULL ; 330 | } 331 | 332 | /* 333 | * Parse command lines options and save in opts_s struct 334 | * 335 | */ 336 | void parse_args(opts_t *ops, int argc, char *argv[]) { 337 | // parse args 338 | int optc, port_addr, subnet_addr, num_ports ; 339 | 340 | // parse options 341 | while ((optc = getopt (argc, argv, "c:s:p:d:a:vn:z")) != EOF) { 342 | switch (optc) { 343 | case 'a': 344 | free(ops->ip_addr) ; 345 | ops->ip_addr = (char *) strdup(optarg) ; 346 | break; 347 | case 'c': 348 | free(ops->config_file) ; 349 | ops->config_file = (char *) strdup(optarg) ; 350 | break; 351 | case 'v': 352 | ops->verbose = 1 ; 353 | break; 354 | case 'd': 355 | free(ops->dev) ; 356 | ops->dev[0] = (char *) strdup(optarg) ; 357 | break; 358 | case 's': 359 | subnet_addr = atoi(optarg) ; 360 | 361 | if(subnet_addr < 0 && subnet_addr > 15) 362 | printf("Subnet address must be between 0 and 15\n") ; 363 | else 364 | ops->subnet_addr = subnet_addr ; 365 | break ; 366 | case 'n': 367 | num_ports = atoi(optarg) ; 368 | 369 | if(num_ports < 1 || num_ports > ARTNET_MAX_PORTS) { 370 | printf("number of ports must be between 1 and %d\n", ARTNET_MAX_PORTS) ; 371 | } else 372 | ops->num_ports = num_ports ; 373 | break ; 374 | case 'p': 375 | port_addr = atoi(optarg) ; 376 | 377 | if(port_addr < 0 && port_addr > 15) 378 | printf("Port address must be between 0 and 15\n") ; 379 | else 380 | ops->port_addr = port_addr ; 381 | break ; 382 | case 'z': 383 | ops->persist = 1 ; 384 | default: 385 | break; 386 | } 387 | } 388 | } 389 | 390 | 391 | int main(int argc, char *argv[]) { 392 | int statloc, pid ; 393 | opts_t ops ; 394 | 395 | init_ops(&ops) ; 396 | parse_args(&ops, argc, argv) ; 397 | 398 | // we don't load ops here 399 | // else if we restart and the options have been remote 400 | // programed we'll have to old ones 401 | 402 | if(ops.persist) { 403 | while(1) { 404 | if( (pid = fork() ) == 0) { 405 | // child ; 406 | run(&ops) ; 407 | exit(1) ; 408 | } else { 409 | // parent 410 | pid = wait(&statloc) ; 411 | printf("Child %i terminated, restarting\n", pid) ; 412 | } 413 | } 414 | } else 415 | run(&ops) ; 416 | 417 | return 0; 418 | } 419 | 420 | --------------------------------------------------------------------------------