diff options
author | fishsoupisgood <github@madingley.org> | 2019-04-27 22:20:21 +0100 |
---|---|---|
committer | fishsoupisgood <github@madingley.org> | 2019-04-27 22:20:21 +0100 |
commit | fd6bb20116127f6ac903d4b03abac72a49baa1ae (patch) | |
tree | 22e1e44fad2f844096f2d79bef9262112b45158c | |
download | datalink-fd6bb20116127f6ac903d4b03abac72a49baa1ae.tar.gz datalink-fd6bb20116127f6ac903d4b03abac72a49baa1ae.tar.bz2 datalink-fd6bb20116127f6ac903d4b03abac72a49baa1ae.zip |
fish
-rw-r--r-- | 70.txt | 177 | ||||
-rw-r--r-- | COPYING | 340 | ||||
-rw-r--r-- | Makefile | 147 | ||||
-rw-r--r-- | README | 112 | ||||
-rw-r--r-- | TODO | 23 | ||||
-rw-r--r-- | changelog | 88 | ||||
-rw-r--r-- | datafile | 41 | ||||
-rw-r--r-- | datalink.h | 266 | ||||
-rw-r--r-- | datalink_macros.h | 100 | ||||
-rw-r--r-- | datalink_private.h | 63 | ||||
-rw-r--r-- | dataread.l | 57 | ||||
-rw-r--r-- | dataread.y | 619 | ||||
-rw-r--r-- | dl_add_to_list.c | 37 | ||||
-rw-r--r-- | dl_anniv_by_date.c | 34 | ||||
-rw-r--r-- | dl_anniv_by_label.c | 28 | ||||
-rw-r--r-- | dl_app_by_datetime.c | 39 | ||||
-rw-r--r-- | dl_app_by_label.c | 28 | ||||
-rw-r--r-- | dl_docrc.c | 52 | ||||
-rw-r--r-- | dl_fill_pack_ascii.c | 40 | ||||
-rw-r--r-- | dl_free_download.c | 65 | ||||
-rw-r--r-- | dl_init_download.c | 607 | ||||
-rw-r--r-- | dl_init_watch.c | 150 | ||||
-rw-r--r-- | dl_item_ok.c | 306 | ||||
-rw-r--r-- | dl_new_item.c | 48 | ||||
-rw-r--r-- | dl_new_list.c | 38 | ||||
-rw-r--r-- | dl_pack_ascii.c | 59 | ||||
-rw-r--r-- | dl_pack_char.c | 42 | ||||
-rw-r--r-- | dl_pack_digit.c | 42 | ||||
-rw-r--r-- | dl_pack_phone.c | 55 | ||||
-rw-r--r-- | dl_pack_size.c | 34 | ||||
-rw-r--r-- | dl_phone_by_label.c | 28 | ||||
-rw-r--r-- | dl_send_data.c | 897 | ||||
-rw-r--r-- | dl_set_error.c | 27 | ||||
-rw-r--r-- | dl_set_warn.c | 27 | ||||
-rw-r--r-- | dl_sizeof_item.c | 103 | ||||
-rw-r--r-- | dl_sizeof_list.c | 34 | ||||
-rw-r--r-- | dl_sort.c | 83 | ||||
-rw-r--r-- | dl_string_ok.c | 44 | ||||
-rw-r--r-- | dl_todo_by_label.c | 28 | ||||
-rw-r--r-- | dl_todo_by_prio.c | 27 | ||||
-rw-r--r-- | dl_write_save.c | 153 | ||||
-rw-r--r-- | doc/datalink.ps | 228 | ||||
-rw-r--r-- | doc/usage | 115 | ||||
-rw-r--r-- | send_data.c | 93 | ||||
-rw-r--r-- | serblink.1 | 51 | ||||
-rw-r--r-- | serblink.c | 208 | ||||
-rw-r--r-- | settime.1 | 77 | ||||
-rw-r--r-- | settime.c | 156 | ||||
-rw-r--r-- | setwatch.1 | 77 | ||||
-rw-r--r-- | setwatch.c | 444 | ||||
-rw-r--r-- | sgiglblink.c | 264 | ||||
-rw-r--r-- | svgablink.1 | 51 | ||||
-rw-r--r-- | svgablink.c | 171 | ||||
-rw-r--r-- | vt.c | 196 |
54 files changed, 7319 insertions, 0 deletions
@@ -0,0 +1,177 @@ +The latest version of the document, and other info including my test +data and decoding program, can be found at +http://csgrad.cs.vt.edu/~tjohnson/timex/ + +This version is incomplete (not because I cut out information, but because +I don't know). + +Disclaimer: +I am not associated with Timex in any way, OTHER than wanting to use their +datalink watch on a civilized OS (read: Unix). All this info has been +discovered by watching the behavior of the FREELY AVAILABLE software +found on the Timex WWW server. (http://www.timex.com) + +Timex and DataLink are trademarks of Timex. + +If you buy, or would buy, a DataLink watch because of the availabilty of +this information, please email me. I would like to give Timex a count of +the number of customers this information has generated. Perhaps that +will inspire them to be more open in the future. + +-Tommy Johnson +tjohnson@bobdbob.com +http://csgrad.cs.vt.edu/~tjohnson/ + +Physical level: +The serial data is drawn on the display as a series of 9 horizontal +lines. It is convered to serial by the raster scanning the image, one +word per frame. The top line is always on, it functions as a start +bit. This is why LCD's don't work: they are not scanned in the same +order. + +The words are transfered least significant bit first, bright lines are +zero, dark lines are one. + +The sync signal is the word 0x55 a great many times. After the 0x55's, +there are 40 0xAA's, followed by data in packets. + +The packets are seperated by 6 empty frames (no start bit either). + +Logical level: + +The data is sent in packets from 4 to 32 bytes long. +byte 1 - length +byte 2 - type + 0x20 - START1 (one) + 0x30 - TIME (several) + 0x60 - START2 counts? (one) + 0x61 - DATA1 (several) + 0x62 - END1 (one) + 0x50 - ALARM (several) + 0x70 - ???? (several, alternating with ALARM) + 0x31 - ???? + 0x21 - END2 (one) + In DATA1 and ALARM packets, byte 3 is the packet number + (starting at 1) + +byte len-1 - check 0 +byte len - check 1 checksum of come kind + +I havn't the foggiest idea what the function for the checksum is. 16 bit CRC? + +Next Logical level: +The packets are sent in this order: +(from here on, byte 1 is byte 3 in the above list) + +one packet type START1 0x20 +byte 1 - 0 +byte 2 - 0 +byte 3 - 1 +Unknown, may be a protocol version, or magic number. I have never seen +these numbers change in all my test data. + +zero or more packet type TIME 0x30 +byte 1 - timezone (the watch has two timezones, 1 or 2) +byte 2 - hour +byte 3 - minute +byte 4 - month +byte 5 - day +byte 6 - +byte 7 - +byte 8 - +byte 9 - +byte 10 - +To indicate the timezone, the computer converts, and just sends a time. + +one packet type START2 0x60 +byte 1 - number of DATA1 packets to follow + +number from packet START2 packets type DATA1 0x20 +In the first DATA1 packet, the first 15 bytes are: +byte 1 - sequence number (1) +byte 2,3 - start address of appointments +byte 4,5 - start address of todos +byte 6,7 - start address of phone numbers +byte 8,9 - start address of aniversaries +byte 10 - number of appointments +byte 11 - number of todos +byte 12 - number of phone numbers +byte 13 - number of aniversaries +byte 14 - 0x60 ? +byte 15 - how long to beep early, in 5 minute units + +In the rest of the DATA1 packets, there are variable length records of the +following formats, there is no padding to fill the DATA1 packets evenly. +byte 10 appointments +byte 11 todos +byte 12 phone numbers +byte 14 aniversaries + +one packet type END1 +No data, just a checksum + +zero or five ALARM packets, one per alarm. If an alarm is inaudable, its +ALARM packet is followed by a 0x70 packet. +Alarms are in ALARM packets. +byte 1 - count, 1 to 5 +byte 2 - hour +byte 3 - minute +byte 4 - month Set to 0 for every month +byte 5 - day Set to 0 for every day +byte 6-13 - label, in watch char set, 1 char per byte (NOT packed) +byte 14 - 1 if audible, 0 otherwise + +type 0x70 packet: +byte 1 - 0 ? +byte 2 - number of the preceding alarm + 0x61 ????? +byte 3 - 0 ? + +zero or one packet type 0x31 +No idea. but it only shows up when the time is set. + +one packet type END2 0x21 + +Thats it. + +char set for labels is: (6 bits per char) +0-9 : digits +10-36: letters +37-63: symbols: +space !"#$%&'()*+,-./;\ +divide = +bell (image, not sound) +? + +These 4 record types are found in DATA1 packets: + +An appointment: +byte 1 - length +byte 2 - month +byte 3 - day +byte 4 - time + bits are: 16 8 4 2 1 0.5 0.25 hours +byte 5-len-1- label + 6 bits per char, packed 4 chars to 3 bytes + 11000000 + 22221111 + 33333322 +byte len - 0xFC ? + +A ToDo: +byte 1 - length +byte 2 - priority +byte 3-len-1 - label same as appointment +byte len - 0xFD ? + +A Phone number: +byte 1 - length +byte 2-6 - phone number, 4 bits per digit, LSnibble first +byte 7-len-1 - label same as appointment +byte len - 0xF ? + +An anniversary: +byte 1 - length +byte 2 - month +byte 3 - day +byte 4-len-1 - label same as appointment +byte len - 0xFC ? @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..22a7c9e --- /dev/null +++ b/Makefile @@ -0,0 +1,147 @@ +# Do not modify this - modify PREFIX (below) instead. This is used by +# package manages such as that for Debian. +DESTDIR = + + +# Edit the parameters below for your needs. + +PREFIX=$(DESTDIR)/usr/local +BINDIR=$(PREFIX)/bin +LIBDIR=$(PREFIX)/lib +MANDIR=$(PREFIX)/man +INCDIR=$(PREFIX)/include + +CC = gcc +#CFLAGS = -Wall -g -DBINDIR=\"$(BINDIR)\" +CFLAGS = -O2 -DBINDIR=\"$(BINDIR)\" + +PORT = /dev/ttyS0 + +ENGINES = svgablink serblink + +RANLIB = echo +#RANLIB = ranlib + +# Do not edit below here, no user serviceable parts. + +SRC = dl_add_to_list.c dl_anniv_by_date.c dl_anniv_by_label.c \ + dl_app_by_datetime.c dl_app_by_label.c dl_docrc.c dl_fill_pack_ascii.c \ + dl_free_download.c dl_init_download.c dl_init_watch.c dl_item_ok.c \ + dl_new_item.c dl_new_list.c dl_pack_ascii.c dl_pack_char.c \ + dl_pack_digit.c dl_pack_phone.c dl_pack_size.c dl_phone_by_label.c \ + dl_send_data.c dl_set_error.c dl_set_warn.c dl_sizeof_item.c \ + dl_sizeof_list.c dl_sort.c dl_string_ok.c dl_todo_by_label.c \ + dl_todo_by_prio.c dl_write_save.c + +OBJ = dl_add_to_list.o dl_anniv_by_date.o dl_anniv_by_label.o \ + dl_app_by_datetime.o dl_app_by_label.o dl_docrc.o dl_fill_pack_ascii.o \ + dl_free_download.o dl_init_download.o dl_init_watch.o dl_item_ok.o \ + dl_new_item.o dl_new_list.o dl_pack_ascii.o dl_pack_char.o \ + dl_pack_digit.o dl_pack_phone.o dl_pack_size.o dl_phone_by_label.o \ + dl_send_data.o dl_set_error.o dl_set_warn.o dl_sizeof_item.o \ + dl_sizeof_list.o dl_sort.o dl_string_ok.o dl_todo_by_label.o \ + dl_todo_by_prio.o dl_write_save.o \ + parse.o dl_read_save.o + +SVGASRC = svgablink.c vt.c send_data.c +SERSRC = serblink.c + +SVGAOBJ = svgablink.o vt.o send_data.o +SEROBJ = serblink.o + +YACC = bison -y -p dl_ -oy.tab.c +LEX = flex -Pdl_ -olex.yy.c + +.PHONY: all clean + +all: depend libdatalink.so.1 settime setwatch $(ENGINES) + +libdatalink.a: $(OBJ) + rm -f $@ + ar qv $@ $(OBJ) + +libdatalink.so.1: $(OBJ) + rm -f $@ + $(CC) -shared -o $@ $(OBJ) $(CFLAGS) + $(RANLIB) $@ + +dl_read_save.c: dataread.y + $(YACC) -d dataread.y + mv y.tab.c $@ + +parse.c: dataread.l dl_read_save.c y.tab.h + $(LEX) dataread.l + mv lex.yy.c $@ + +depend: parse.c dl_read_save.c + makedepend -f- -o.o $(CFLAGS) $(SRC) $(SVGASRC) $(SERSRC) > depend + @echo "Dependencies have been made, re-run make to build" + @false + +serblink.o: $(SERSRC) + $(CC) -c $(CFLAGS) -DPORT=\"$(PORT)\" $(SERSRC) + +serblink: $(SEROBJ) + rm -f $@ + $(CC) $(CFLAGS) -o $@ $(SEROBJ) + +svgablink: $(SVGAOBJ) + rm -f $@ + $(CC) $(CFLAGS) -o $@ $(SVGAOBJ) -lvga + +settime.o: settime.c + $(CC) $(CFLAGS) -I. -c settime.c + +setwatch.o: setwatch.c + $(CC) $(CFLAGS) -I. -c setwatch.c + +settime: settime.o libdatalink.a + $(CC) $(CFLAGS) -o $@ settime.o -L. -ldatalink + +setwatch: setwatch.o libdatalink.a + $(CC) $(CFLAGS) -o $@ setwatch.o -L. -ldatalink + +cvt: cvt.o + $(CC) $(CFLAGS) -o $@ + +install: all + mkdir -p $(BINDIR) $(MANDIR)/man1 + install -o root -g video -m 4750 svgablink $(BINDIR) + install -o root -g root -m 755 serblink $(BINDIR) + install -o root -g root -m 755 setwatch $(BINDIR) + install -o root -g root -m 755 settime $(BINDIR) + install -o root -g root -m 644 setwatch.1 $(MANDIR)/man1 + install -o root -g root -m 644 settime.1 $(MANDIR)/man1 + install -o root -g root -m 644 svgablink.1 $(MANDIR)/man1 + install -o root -g root -m 644 serblink.1 $(MANDIR)/man1 + +install-devel: install + mkdir -p $(LIBDIR) $(INCDIR) + install -o root -g root -m 555 libdatalink.so.1 $(LIBDIR) + install -o root -g bin -m 555 libdatalink.a $(LIBDIR) + install -o root -g bin -m 444 datalink.h $(INCDIR) + +uninstall: + rm -f $(BINDIR)/svgablink + rm -f $(BINDIR)/serblink + rm -f $(BINDIR)/setwatch + rm -f $(BINDIR)/settime + rm -f $(MANDIR)/man1/setwatch.1 + rm -f $(MANDIR)/man1/settime.1 + rm -f $(MANDIR)/man1/svgablink.1 + rm -f $(MANDIR)/man1/serblink.1 + rm -f $(LIBDIR)/libdatalink.so.1 + rm -f $(LIBDIR)/libdatalink.a + rm -f $(INCDIR)/datalink.h + +clean: + rm -f $(OBJ) libdatalink.a libdatalink.so.1 Makefile.bak + rm -f $(SVGAOBJ) $(SEROBJ) + rm -f parse.c dl_read_save.c y.tab.h + rm -f settime.o setwatch.o cvt.o + rm -f settime setwatch cvt $(ENGINES) + rm -f depend + +# The next line was used for makedepend +include depend +# DO NOT DELETE @@ -0,0 +1,112 @@ +Copyright 1996-2002 - Karl R. Hakimian <hakimian@aha.com> + and David Fries <dfries@mail.win.org> + +This is the README file for the datalink library. + +This software is in no way associated with or supported by Timex. Do +not contact them for help with this software. + +Datalink is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +Datalink is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with datalink (see COPYING); if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +========================================================================== + +This is the datalink library for Linux. It uses the SVGAlib to send data +to the Timex DataLink watches. You will need SVGAlib installed and the +development headers and libraries for SVGAlib to compile against. + +The original author is Karl R. Hakimian <hakimian@eecs.wsu.edu>, I have +extended the program to work with the Timex DataLink Ironman Triathlon +watch. I do not have the ability to test the original model 70 or model 150 +watches and I have only tested the SVGA output program. The original +watches and serblink (serial blink) program may have been broken with +my code changes, I have no way to test them. + +The watch has a Motorola 6805 microprocessor in it with the ability of the +model 150 or 150s version to write and run programs on the watch. + +Compiling: +Type make depend to make the dependences. + $ make depend +Then just type `make` on the command line. + $ make + +Installing: +Type `make install` on the command line. + % make install +The default locations of the installed programs are: + +/usr/local/lib/libdatalink.so.1 +/usr/local/lib/libdatalink.a +/usr/local/include/datalink.h +/usr/local/bin/svgablink +/usr/local/bin/serblink +/usr/local/bin/setwatch + +Please note that the svgablink must be installed setuid root to use +the SVGAlib and change to graphics mode. If you install as root +the default is to install setuid root. If you are concerned about +security I suggest you have it setuid root and executable by +the group and not executable by the world. Include only those +in the group who has a reason to run the program and you trust. +I do not know how much the original author has put into making +it secure, I know I haven't done anything along those lines. +If you have patches to fix any problems please email me (David). + +Running: +The short version: + Copy datafile from the source directory, make any changes. +Hit mode on your watch until you get to the "COMM READY V4.0" screen. +Run setwatch with the following arguements `setwatch -all datafile`. +If you have the model 70 or model 150 you have to add the option +-model150 or -150, or -model70 or -70 to the setwatch program. +The long version: + Make a directory called .datalink in your home directory, +copy the datalink file from the source directory to that directory, +follow above directions adding any of the options to send specific +data to the watch. Find all bugs, fix all bugs, send all patches +to me (David). + +Suggestions: + I have found my 15" monitor seems to send the data without +any problems, but my 19" monitor tends to corrupt some of the phone +data. All of the packets have crc data in them, but the watch does not +indicate the data is bad, so check to make sure everything was transfered +correctly. I may need to add code to adjust the spacing of the lines +on the monitor, I'm not sure what the problem is here. + Running anything in the background can cause the program to not +function correctly. SVGAlib appears to be polling the video card to +determine when the verticle sync occurs and if it misses it because +something else is running the watch may not get the data correctly. +I don't know how much of a problem this is, I just noticed it on +development of my additions. + Improvements, suggestions, patches, comments e-mail me. I am +also interested in how many people find this useful, please e-mail +if you just plan to use it, I would like to hear from you. + If you work for Timex or have any influence, I would like +some documentation on these watches. I have none. I am aware +there is a software development kit that Timex put out, but I am +also told it contains only information on how to use their equivalent +of the datalink library. I do not need this. I need documentation +of the protocol and watch capabilities, that is what I need. The +protocol was decoded by taking a light sensitive circuit, placing it +in from of a CRT screen that was flashing data from the Timex software, +recording it with a sound card, and useing software I wrote to +turn it back into data. Then figuring out by hand what it means. + When doing any transfers the chronograph and timer is stopped. +This is just so you know. + +David Fries +dfries@mail.win.org +August 25, 1999 @@ -0,0 +1,23 @@ +Document the Ironman protocol +add options in the datafile parser to + -set the watch model + -set the order of phone entries + -set the spacing of the lines + -set all other options that can be specified on the commandline +being able to abort a transfer while the screen is flashing would be nice + +figure out why just sending alarms will corrupt the phone entries +(later entries like 17 or so) + +Mon Jan 22 22:38:50 CST 2001 +question from a user, +I can't seem to move fast enough for me to put my watch in front of the +screen before your program starts sending data to the watch... + +How about showing the initializing sequence (the many bars on the screen +that makes DataLink go beeping while in COMM mode), then wait for a key +to be pressed before actually sending the data? + +probably not a bad idea to show the sync signal until the user initiates +the data mode, also possibly have an option for the time to wait while +displaying the sync signal diff --git a/changelog b/changelog new file mode 100644 index 0000000..0c1eef9 --- /dev/null +++ b/changelog @@ -0,0 +1,88 @@ +07-21-2002: + -Fixed the setwatch options of -app and +app to say appointments + instead of wristapp. + -setwatch was trying to run svgablink with -150S instead of -150s + -The -file (for creating a DEBUGOUTPUT) was broken, fixed. +07-17-2002: aka 1.0.0 + -Added header files for libc functions we are already using, + but weren't including the proper header files. + -Switched to using tmpfile instead of tmpnam for the temporary + file, this will fix the compiler warnings. + -The newer bison required a semicolon and would not compile + until it was added. + -Replaced tmpnam() with mkstemp() because the compiler gave + warnings about tmpnam being a possible security hole. + -Dependency information now goes in the file depend and will be + calculated if the file doesn't exist. +-- David Fries <dfries@mail.win.org> + +12-16-2001: + -Changed license to GPL (with permission from all 4 authors). + -Added info to readme about GPL and about lack of support from Timex. + -Created manpages for svgablink, serblink, setwatch, and settime + They still need work - I'll get to it when I can. + -Changed settime default to ironman for consistency w/ setwatch. + -Fixed apparent missing semicolon in dataread.y. + -Added DESTDIR to Makefile to be more friendly with Debian packaging. + -Split Makefile "install" rule into "install" (for basic datalink + user requirements) and "install-devel" for items needed only for + development. + -Added Makefile "uninstall" rule. +-- Steaphan Greene <stea@cs.binghamton.edu> + +02-14-2001: +The changes listed below from Frank Denis were incorporated with exception +of the time of the week information, I'll have to look into that later. +More important user visible changes are as follows, + It will now only search in the users path for serblink and svgablink + not any hard-coded paths. Previous behavior was to try + the user path and if it wasn't found, try executing + the program in the current working directory. + settime is now installed by default and will accept a command line for + the different types of watches + For me, svgablink no longer hangs on exit +-- David Fries <dfries@mail.win.org> + +02-04-2001: +I don't see the problem with the day of week. I'm reverting back to +the previous code. Will have to investigate sometime. On my watch +the code is correct as it used to be (and is now again). +-- David Fries + +04-22-2000: +Fixed a bug with the day of the week that was shifted by one. Please report +if it broke something. +-- Frank Denis + +04-20-2000: +Fixed the path to svgablink. +The datalink 150 S protocol was implemented but the "-150s" option was +rejected in setwatch. Fixed. +-- Frank Denis + +04-17-2000: +Add support for Datalink 150 S watches +-- Frank Denis + + +04-14-2000: +Lots, lots, lots of cleanups to the source code in order to make it compile +on modern compilers. +-- Frank Denis + + +01-05-2000: +Added a patch from Scottie Shore <sshore@escape.ca> for a Y2K problem. +As localtime(3) reads, + tm_year + The number of years since 1900. +The watch is expecting the last two digits and displays A0 for the year instead of 00. Fix is to take the year % 100. +-- David Fries + + +12-11-1999: +Added a patch from Danilo Fiorenzano <danilo@telusplanet.net> to +Added new function "maxPriority()" to switch to SCHED_RR kernel scheduling +policy at maximum priority and lock all pages into real memory, in order +to improve timing accuracy. +-- David Fries diff --git a/datafile b/datafile new file mode 100644 index 0000000..f270d3a --- /dev/null +++ b/datafile @@ -0,0 +1,41 @@ +#time_adjust = 5 + +# valid characters 0-9, A-Z, space, !"#$%&'()*+,-./:\ (division sign) = (bell symbol) ? +# alarm #, Month/Day, 24 hour time, "label", on/off +# 1-10, 0/0 anytime; 0/day a day per month; mon/day that day, hh:mm, "up to 16 characters and special values", on/off 1/0 +alarm = 1, 0/0, 20:55, "DS9", 1 +alarm = 2, 0/0, 19:55, "Voyager", 1 +alarm = 3, 0/0, 12:53, "no idea", 0 + +# timer #, "hh:mm:ss", "8 char label" repeat, chron ; only one of repeat or chron can be true +# the time is treated as a string to get the seconds, so it must have quotes +timer = 1, "12:34:11", "test 123", 0, 0 +timer = 2, "00:15", "15 mins.", 1, 0 +timer = 3, "00:30", "30 mins.", 0, 1 + +phone = "111111111111", "000000000000000" +phone = "9119119111 W", "call me" +phone = "5093363720 C", "Garren" + +# appointment (model 70 and 150) +# appointment = MM/DD/YY, hh:mm:ss, "15 char message" +#appointment = 10/29/99, 14:30, "this is a test" +# do appointments not take a year? +appointment = 10/29, 14:30, "this is a test" + +# chrono label and number of laps, "8 char label", laps range from 2 to 50 +# default entry +#chron = " Chrono", 8 +chron = " Chrono 8", 8 + +# hourly chime, button beep +system = 0, 0 + +# timezone, timezone #, 3 characters label, offset from system clock in minutes, hour format 1=12hour, 2=24hour, date format US=0 +timezone = 1, "ABC", 0, 1, 0 +timezone = 2, "CBS", 0, 2, 0 + +#wristapp = "~/.datalink/timer13.app" +#wristapp = "~/.datalink/melody17.app" +#melody = "~/.datalink/mainline.spc" +#melody = "~/src/watch/xx" diff --git a/datalink.h b/datalink.h new file mode 100644 index 0000000..ab6f2d7 --- /dev/null +++ b/datalink.h @@ -0,0 +1,266 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __DATALINK_H__ +#define __DATALINK_H__ + +typedef struct time_s +{ + unsigned char tz_num; + unsigned char hours; + unsigned char minutes; + unsigned char seconds; + unsigned char month; + unsigned char day; + unsigned char year; + unsigned char dow; /* Day Of the Week */ + unsigned char hour_fmt; + unsigned char date_fmt; + unsigned char download; + int offset; + char *label; +} Time, *TimePtr; + +typedef struct alarm_s +{ + unsigned char alarm_num; + unsigned char hours; + unsigned char minutes; + unsigned char month; + unsigned char day; + char *label; + unsigned char audible; +} Alarm, *AlarmPtr; + +typedef struct chron_s +{ + unsigned char chron_laps; + int memused; + char *label; +} Chron, *ChronPtr; + +typedef struct timer_s +{ + unsigned char timer_num; + unsigned char hours; + unsigned char minutes; + unsigned char second; + unsigned char repeat; + unsigned char chron; + char *label; +} Timer, *TimerPtr; + +typedef struct system_s +{ + unsigned char chime; + unsigned char beep; +} System, *SystemPtr; + +typedef struct appointment_s +{ + unsigned char month; + unsigned char day; + unsigned char time; + char *label; +} Appointment, *AppointmentPtr; + +typedef struct phone_s +{ + char *number; + char *label; +} Phone, *PhonePtr; + +typedef struct todo_s +{ + unsigned char priority; + char *label; +} ToDo, *ToDoPtr; + +typedef struct anniversary_s +{ + unsigned char month; + unsigned char day; + char *label; +} Anniversary, *AnniversaryPtr; + +typedef struct wristapp_s +{ + int len; + unsigned char *data; +} WristApp, *WristAppPtr; + +typedef struct melody_s +{ + int len; + unsigned char *data; +} Melody, *MelodyPtr; + +typedef struct item_s +{ + struct item_s *next; + int type; + union + { + Time time; + Alarm alarm; + Chron chron; + Timer timer; + System sys; + Appointment app; + Phone phone; + ToDo todo; + Anniversary anniv; + System system; + WristApp wristapp; + Melody melody; + } + data; +} +Item, *ItemPtr; + +typedef struct list_s +{ + ItemPtr first; + ItemPtr last; + int download; + int count; +} List, *ListPtr; + +typedef struct watch_info_s +{ + int dl_device; /* Device to download to. */ + int max_tz; + int max_alarms; + int max_apps; + int max_chrons; + int max_phones; + int max_timers; + int max_todos; + int max_annivs; + int max_system; + int max_wristapp; + int max_melody; + int max_tzlen; + int max_mem; /* Memory available. */ + int mem_size; /* Memory used. */ + int max_str; /* Max string length for this device. */ + int max_alarm_str; /* Max string length for an alarm on this device. */ + int max_chron_str; /* Max string length for the cron on this device. */ + int max_phone_str; /* Max string length for a phone on this device. */ + int max_timer_str; /* Max string length for the timer on this device. */ + int max_wristapp_len; + int max_mel_len; + int pre_notification_time; + int time_adjust; + List times; + List alarms; + List chron; + List timers; + List system; + List apps; + List phones; + List todos; + List annivs; + List wristapp; + List melody; +} WatchInfo, *WatchInfoPtr; + +/* defines */ + +#ifndef NULL +#define NULL 0l +#endif + +/* Item types */ +#define DL_NO_TYPE 0 +#define DL_TIME_TYPE 1 +#define DL_ALARM_TYPE 2 +#define DL_APP_TYPE 3 +#define DL_PHONE_TYPE 4 +#define DL_TODO_TYPE 5 +#define DL_ANNIV_TYPE 6 +#define DL_SYSTEM_TYPE 7 +#define DL_WRISTAPP_TYPE 8 +#define DL_MELODY_TYPE 9 +#define DL_TIMER_TYPE 10 +#define DL_CHRON_TYPE 11 +#define DL_MAX_TYPE 12 + +/* Output types */ +#define NO_OUTPUT 0 +#define SVGA_BLINK 1 +#define SER_BLINK 2 +#define BLINK_FILE 3 + +/* Watch types */ +#define NO_WATCH 0 +#define DATALINK_70 1 +#define DATALINK_150 2 +#define DATALINK_150S 3 +#define DATALINK_IRONMAN 4 + +#define DEF_LPTRANSINFO 1 + +extern int (*dl_error_proc) (char *); +extern int (*dl_warn_proc) (char *); + +/* Function definitions. */ + +void dl_add_to_list(ListPtr, ItemPtr); +int dl_anniv_by_date(ItemPtr, ItemPtr); +int dl_anniv_by_label(ItemPtr, ItemPtr); +int dl_app_by_datetime(ItemPtr, ItemPtr); +int dl_app_by_label(ItemPtr, ItemPtr); +unsigned short int dl_docrc(unsigned char *); +void dl_fill_pack_ascii(unsigned char *, unsigned char *, int, char); +void dl_free_download(void); +int dl_init_download(WatchInfoPtr, ListPtr, ListPtr, ListPtr, ListPtr, + ListPtr, ListPtr, ListPtr, ListPtr, ListPtr, ListPtr, + ListPtr); +WatchInfoPtr dl_init_watch(int); +int dl_item_ok(WatchInfoPtr, ItemPtr); +ItemPtr dl_new_item(WatchInfoPtr, int); +ListPtr dl_new_list(void); +int dl_pack_ascii(unsigned char *, unsigned char *); +int dl_pack_char(char); +int dl_pack_digit(char); +void dl_pack_phone(unsigned char *, unsigned char *, int); +int dl_pack_size(char *); +int dl_phone_by_label(ItemPtr, ItemPtr); +WatchInfoPtr dl_read_save(char *, int, ListPtr *, ListPtr *, ListPtr *, + ListPtr *, ListPtr *, ListPtr *, ListPtr *, + ListPtr *, ListPtr *, ListPtr *, ListPtr *); +int dl_send_data(WatchInfoPtr, int); +void dl_set_error(int (*)()); +void dl_set_warn(int (*)()); +int dl_sizeof_item(WatchInfoPtr, ItemPtr); +int dl_sizeof_list(WatchInfoPtr, ListPtr); +int dl_sort(ListPtr, int (*)()); +int dl_string_ok(char *, int); +int dl_todo_by_label(ItemPtr, ItemPtr); +int dl_todo_by_prio(ItemPtr, ItemPtr); +int dl_write_save(char *, char *, char *); + +int open_vt(); +void close_vt(int oldvt); +int send_data(int type, unsigned char **packets, int npckts); + +#endif /* __DATALINK_H__ */ diff --git a/datalink_macros.h b/datalink_macros.h new file mode 100644 index 0000000..8dbc9b4 --- /dev/null +++ b/datalink_macros.h @@ -0,0 +1,100 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * SVGA Macros for sending data to the datalink watch. + * + * Modified by David Fries <dfries@mail.win.org> 7/11/99 + * - Added support for the Timex Datalink Ironman Triathlon + * - Modified the screen position and only send half the initial sync signals + * + */ + +// This defines which line to start field 1 at +#define START1 70 +// The line to start field 2 at +#define START2 255 +// the distance between lines in each field +#define SPACE 15 + +#define WRITE_BYTE1(sb, byte) { \ + int pos = START1; \ + register int mask = 0x1; \ + if (sb) \ + vga_drawscanline(pos, white); \ + else \ + vga_drawscanline(pos, black); \ + pos += SPACE; \ + while (mask < 0xff) { \ + if (mask&byte) \ + vga_drawscanline(pos, black); \ + else \ + vga_drawscanline(pos, white); \ + pos += SPACE; \ + mask = mask << 1; \ + } \ +} + +#define WRITE_BYTE2(sb, byte) { \ + int pos = START2; \ + register int mask = 1; \ + if (sb) \ + vga_drawscanline(pos, white); \ + else \ + vga_drawscanline(pos, black); \ + pos += SPACE; \ + while (mask < 0xff) { \ + if (mask&byte) \ + vga_drawscanline(pos, black); \ + else \ + vga_drawscanline(pos, white); \ + pos += SPACE; \ + mask = mask << 1; \ + } \ +} + +#define END_PACKET { \ + vga_waitretrace(); \ + WRITE_BYTE1(0, 0xff) \ + WRITE_BYTE2(0, 0xff) \ + {int i; for (i = 0; i < (10+((type==DATALINK_IRONMAN)?2:0)); i++) \ + vga_waitretrace();} \ +} + +/* how many syncs to give to begin with, was 400 */ +#define SYNC { \ + register int i; \ + for (i = 0; i < 200; i++) { \ + vga_waitretrace(); \ + WRITE_BYTE1(1, 0x55) \ + WRITE_BYTE2(1, 0x55) \ + } \ + END_PACKET \ +} + +#define DATASTART { \ + register int i; \ + for (i = 0; i < 50; i++) { \ + vga_waitretrace(); \ + WRITE_BYTE1(1, 0xAA) \ + } \ + END_PACKET \ +} diff --git a/datalink_private.h b/datalink_private.h new file mode 100644 index 0000000..2c95692 --- /dev/null +++ b/datalink_private.h @@ -0,0 +1,63 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#ifndef __DATALINK_PRIVATE_H__ +#define __DATALINK_PRIVATE_H__ + +typedef struct download_s +{ + int num_times; + TimePtr times; + int num_alarms; + AlarmPtr alarms; + int num_chron; + int max_chron_str; + ChronPtr chron; + int num_timers; + TimerPtr timers; + int memory; + int num_apps; + int app_size; + int pre_notification_time; + AppointmentPtr apps; + int num_todos; + int todo_size; + ToDoPtr todos; + int max_alarm_str; + int max_phone_str; + int max_timer_str; + int num_phones; + int phone_size; + PhonePtr phones; + int num_annivs; + int anniv_size; + AnniversaryPtr annivs; + int num_system; + SystemPtr system; + int num_wristapp; + WristAppPtr wristapp; + int num_melody; + MelodyPtr melody; +} Download, *DownloadPtr; + +extern Download dl_download_data; + +#endif /* __DATALINK_PRIVATE_H__ */ diff --git a/dataread.l b/dataread.l new file mode 100644 index 0000000..b452ef7 --- /dev/null +++ b/dataread.l @@ -0,0 +1,57 @@ +%{ +#include <string.h> +#include "y.tab.h" +int line_num = 1; +%} +%option noyywrap +%% + +\"[^"\n]* { + if (dl_text[yyleng - 1] == '\\') + yymore(); + else { + strcpy(dl_lval.string,&yytext[1]); + + if (input() != '"') { + fprintf(stderr,"EOL found inside \" on line %d\n",line_num); + return(-1); + } + return(STRING); + } + }; +[a-zA-Z][a-zA-Z0-9.-_]* { + strcpy(dl_lval.string, yytext); + return(NAME); + }; +[0-9]{1,2}[:][0-9]{1,2}[:][0-9]{1,2} { + return(TIME); + }; +[0-9]{1,2}[:][0-9]{1,2} { + sprintf(dl_lval.string, "%s:00", yytext); + return(TIME); + }; +[0-9]{1,2}[/][0-9]{1,2}[/][0-9]{1,4} { + return(DATE); + }; +[0-9]{1,2}[/][0-9]{1,2} { + sprintf(dl_lval.string, "%s/00", yytext); + return(DATE); + }; +[0-9]+ { + dl_lval.integer = atoi(yytext); + return(INTEGER); + }; +-[0-9]+ { + dl_lval.integer = atoi(yytext); + return(INTEGER); + }; +[\[\]{}(),:=] {return(yytext[0]);}; +\n {line_num++; return(yytext[0]);}; +\\\n ; +[ \t]* ; +#.* ; +. { + fprintf(stderr,"Bad datalink save file (%s).\n", yytext); + return(BAD); +}; +%% diff --git a/dataread.y b/dataread.y new file mode 100644 index 0000000..218f51f --- /dev/null +++ b/dataread.y @@ -0,0 +1,619 @@ +%{ + /* + * + * Modified by David Fries <dfries@mail.win.org> 7/11/99 + * - Added support for the Timex Datalink Ironman Triathlon + */ +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <sys/stat.h> +#include <fcntl.h> +#include "datalink.h" + +extern int line_num; + +#define ALARM 0 +#define APP 1 +#define PHONE 2 +#define TODO 3 +#define ANNIV 4 +#define SYSTEM 5 +#define WRISTAPP 6 +#define MELODY 7 +#define TIMEZONE 8 +#define DATA 9 +#define INTVAL 10 +#define TIMER 11 +#define CHRON 12 +#define NUMLISTS 13 + +int dl_error(char *s); + +static ListPtr *lists = NULL; +static ItemPtr ip = NULL; +static char buf[1024]; +static int hour, minute, second, month, day, year; +static int repeat, chron; +static int prio, audible, chime, beep, pos; +static int val, tfmt, dfmt; +static char msg[64]; +static char phnum[64]; +static WatchInfoPtr wi; +static int watch_type; + +%} +%token NAME INTEGER STRING TIME DATE BAD + +%union { + char string[1024]; + int integer; +} + +%left <string> NAME +%left <string> STRING +%left <integer> INTEGER +%left <string> TIME +%left <string> DATE + +%type <integer> value + +%% + +data : item + | data item + ; + +item : NAME '=' value '\n' +{ + int fd; + char file[1024]; + unsigned char mask; + int min; + struct stat sbuf; + int l; + int i; + + if (!lists) { + wi = dl_init_watch(watch_type); + + if ((lists = (ListPtr *)calloc(NUMLISTS, sizeof(ListPtr))) == NULL) { + dl_error("Could not allocate List list."); + return(-1); + } + + for (i = 0; i < NUMLISTS; i++) { + + if (!(lists[i] = dl_new_list())) { + dl_error("Could not allocate item list."); + return(-1); + } + + } + + } + + switch ($3) { + case ALARM: + + if (strcmp($1, "alarm")) { + sprintf(buf, "Bad entry, %s = alarm.", $1); + dl_error(buf); + return(-1); + } + + if (!(ip = dl_new_item(wi, DL_ALARM_TYPE))) { + dl_error("Could not allocate alarm item."); + return(-1); + } + + ip->data.alarm.alarm_num = pos; + ip->data.alarm.hours = hour; + ip->data.alarm.minutes = minute; + ip->data.alarm.month = month; + ip->data.alarm.day = day; + ip->data.alarm.audible = audible; + l = strlen(msg); + + if (l > wi->max_alarm_str) + l = wi->max_alarm_str; + + if ((ip->data.alarm.label = (char *)malloc(l + 1)) == NULL) { + dl_error("Could not allocate alarm label."); + return(-1); + } + + strncpy(ip->data.alarm.label, msg, l); + ip->data.alarm.label[l] = '\0'; + dl_add_to_list(lists[ALARM], ip); + break; + + case CHRON: + if (strcmp($1, "chron")) { + sprintf(buf, "Bad entry, %s = chron.", $1); + dl_error(buf); + return(-1); + } + + if (!(ip = dl_new_item(wi, DL_CHRON_TYPE))) { + dl_error("Could not allocate chron item."); + return(-1); + } + + ip->data.chron.chron_laps = pos; + l = strlen(msg); + + if (l > wi->max_chron_str) + l = wi->max_chron_str; + + if ((ip->data.chron.label = (char *)malloc(l + 1)) == NULL) { + dl_error("Could not allocate chron label."); + return(-1); + } + + strncpy(ip->data.chron.label, msg, l); + ip->data.chron.label[l] = '\0'; + dl_add_to_list(lists[CHRON], ip); + break; + + case TIMER: + if (strcmp($1, "timer")) { + sprintf(buf, "Bad entry, %s = timer.", $1); + dl_error(buf); + return(-1); + } + + if (!(ip = dl_new_item(wi, DL_TIMER_TYPE))) { + dl_error("Could not allocate timer item."); + return(-1); + } + + ip->data.timer.timer_num = pos; + ip->data.timer.hours = hour; + ip->data.timer.minutes = minute; + ip->data.timer.second = second; + ip->data.timer.repeat = repeat; + ip->data.timer.chron = chron; + l = strlen(msg); + + if (l > wi->max_timer_str) + l = wi->max_timer_str; + + if ((ip->data.timer.label = (char *)malloc(l + 1)) == NULL) { + dl_error("Could not allocate timer label."); + return(-1); + } + + strncpy(ip->data.timer.label, msg, l); + ip->data.timer.label[l] = '\0'; + dl_add_to_list(lists[TIMER], ip); + break; + case APP: + + if (strcmp($1, "appointment")) { + sprintf(buf, "Bad entry, %s = appointment.", $1); + dl_error(buf); + return(-1); + } + + if (!(ip = dl_new_item(wi, DL_APP_TYPE))) { + dl_error("Could not allocate appointment item."); + return(-1); + } + + ip->data.app.month = month; + ip->data.app.day = day; + minute = hour*60+minute; + ip->data.app.time = 0; + + for (min = 960, mask = 0x40; mask; mask >>= 1, min /= 2) { + + if (minute >= min) { + ip->data.app.time |= mask; + minute -= min; + } + + } + + l = strlen(msg); + + if (l > wi->max_str) + l = wi->max_str; + + if ((ip->data.app.label = (char *)malloc(l + 1)) == NULL) { + dl_error("Could not allocate appointment label."); + return(-1); + } + + strncpy(ip->data.app.label, msg, l); + ip->data.app.label[l] = '\0'; + dl_add_to_list(lists[APP], ip); + break; + case PHONE: + + if (strcmp($1, "phone")) { + sprintf(buf, "Bad entry, %s = phone.", $1); + dl_error(buf); + return(-1); + } + + if (!(ip = dl_new_item(wi, DL_PHONE_TYPE))) { + dl_error("Could not allocate phone item."); + return(-1); + } + + l = strlen(phnum); + + if (l > wi->max_phone_str) + l = wi->max_phone_str; + + if ((ip->data.phone.number = (char *)malloc(l + 1)) == NULL) { + dl_error("Could not allocate phone number."); + return(-1); + } + + strncpy(ip->data.phone.number, phnum, l); + ip->data.phone.number[l] = '\0'; + + l = strlen(msg); + + if (l > wi->max_str) + l = wi->max_str; + + if ((ip->data.phone.label = (char *)malloc(l + 1)) == NULL) { + dl_error("Could not allocate phone label."); + return(-1); + } + + strncpy(ip->data.phone.label, msg, l); + ip->data.phone.label[l] = '\0'; + dl_add_to_list(lists[PHONE], ip); + break; + case TODO: + + if (strcmp($1, "todo")) { + sprintf(buf, "Bad entry, %s = todo.", $1); + dl_error(buf); + return(-1); + } + + if (!(ip = dl_new_item(wi, DL_TODO_TYPE))) { + dl_error("Could not allocate todo item."); + return(-1); + } + + ip->data.todo.priority = prio; + l = strlen(msg); + + if (l > wi->max_str) + l = wi->max_str; + + if ((ip->data.todo.label = (char *)malloc(l + 1)) == NULL) { + dl_error("Could not allocate todo label."); + return(-1); + } + + strncpy(ip->data.todo.label, msg, l); + ip->data.todo.label[l] = '\0'; + dl_add_to_list(lists[TODO], ip); + break; + case ANNIV: + + if (strcmp($1, "anniversary")) { + sprintf(buf, "Bad entry, %s = anniversary.", $1); + dl_error(buf); + return(-1); + } + + if (!(ip = dl_new_item(wi, DL_ANNIV_TYPE))) { + dl_error("Could not allocate anniversary item."); + return(-1); + } + + ip->data.anniv.month = month; + ip->data.anniv.day = day; + + l = strlen(msg); + + if (l > wi->max_str) + l = wi->max_str; + + if ((ip->data.anniv.label = (char *)malloc(l + 1)) == NULL) { + dl_error("Could not allocate anniversary label."); + return(-1); + } + + strncpy(ip->data.anniv.label, msg, l); + ip->data.anniv.label[l] = '\0'; + dl_add_to_list(lists[ANNIV], ip); + break; + case SYSTEM: + + if (strcmp($1, "system")) { + sprintf(buf, "Bad entry, %s = system.", $1); + dl_error(buf); + return(-1); + } + + if (!(ip = dl_new_item(wi, DL_SYSTEM_TYPE))) { + dl_error("Could not allocate system item."); + return(-1); + } + + ip->data.system.chime = chime; + ip->data.system.beep = beep; + dl_add_to_list(lists[SYSTEM], ip); + break; + case DATA: + + if (*msg == '~') + sprintf(file, "%s%s", getenv("HOME"), &msg[1]); + else + strcpy(file, msg); + + if ((fd = open(file, O_RDONLY)) < 0) { + sprintf(buf, "Could not open %s for reading %s.", file, $1); + dl_error(buf); + return(-1); + } + + if (fstat(fd, &sbuf) < 0) { + sprintf(buf, "Could not stat %s for %s.", file, $1); + dl_error(buf); + return(-1); + } + + if (strcmp($1, "wristapp") == 0) { + + if (!(ip = dl_new_item(wi, DL_WRISTAPP_TYPE))) { + dl_error("Could not allocate system item."); + return(-1); + } + + } + else if (strcmp($1, "melody") == 0) { + + if (!(ip = dl_new_item(wi, DL_MELODY_TYPE))) { + dl_error("Could not allocate system item."); + return(-1); + } + + } + else { + sprintf(buf, "Bad entry, %s = string.", $1); + dl_error(buf); + return(-1); + } + + ip->data.wristapp.len = sbuf.st_size; + + if ((ip->data.wristapp.data = (char *)malloc(sbuf.st_size)) == NULL) { + sprintf(buf, "Could not allocate data for %s.", $1); + dl_error(buf); + return(-1); + } + + if (read(fd, ip->data.wristapp.data, sbuf.st_size) != sbuf.st_size) { + sprintf(buf, "Could not read data for %s from %s.", $1, file); + dl_error(buf); + return(-1); + } + + if (strcmp($1, "wristapp") == 0) + dl_add_to_list(lists[WRISTAPP], ip); + else + dl_add_to_list(lists[MELODY], ip); + + break; + case INTVAL: + + if (strcmp($1, "time_adjust") == 0) { + wi->time_adjust = val; + } + else if (strcmp($1, "pre_notification_time") == 0) { + wi->pre_notification_time = val; + } + else { + sprintf(buf, "Bad entry, %s = intval.", $1); + dl_error(buf); + return(-1); + } + + break; + case TIMEZONE: + + if (strcmp($1, "timezone")) { + sprintf(buf, "Bad entry, %s = timezone.", $1); + dl_error(buf); + return(-1); + } + + if (!(ip = dl_new_item(wi, DL_TIME_TYPE))) { + dl_error("Could not allocate timezone item."); + return(-1); + } + + l = strlen(msg); + + if (l > wi->max_tzlen) + l = wi->max_tzlen; + + if ((ip->data.time.label = (char *)malloc(l + 1)) == NULL) { + dl_error("Could not allocate timezone label."); + return(-1); + } + + strncpy(ip->data.time.label, msg, l); + ip->data.time.label[l] = '\0'; + ip->data.time.offset = minute; + ip->data.time.tz_num = pos; + ip->data.time.month = 1; + ip->data.time.day = 1; + ip->data.time.hour_fmt = tfmt; + ip->data.time.date_fmt = dfmt; + dl_add_to_list(lists[TIMEZONE], ip); + break; + default: + dl_error("Internal Error, unknown type."); + return(-1); + } + +} + | '\n' + ; + +value : INTEGER ',' DATE ',' TIME ',' STRING ',' INTEGER + /* Alarm */ + { + pos = $1; + sscanf($3, "%d/%d/%d", &month, &day, &year); + sscanf($5, "%d:%d:%d", &hour, &minute, &second); + strcpy(msg, $7); + audible = $9; + $$ = ALARM; + } + + | INTEGER ',' STRING ',' STRING ',' INTEGER ',' INTEGER + /* Timer */ + { + pos = $1; + sscanf($3, "%d:%d:%d", &hour, &minute, &second); + strcpy(msg, $5); + repeat = $7; + chron = $9; + $$ = TIMER; + } + + | STRING ',' INTEGER + /* Chron */ + { + strcpy(msg, $1); + pos = $3; + $$ = CHRON; + } + + | DATE ',' TIME ',' STRING + /* Appointment */ + { + sscanf($1, "%d/%d/%d", &month, &day, &year); + sscanf($3, "%d:%d:%d", &hour, &minute, &second); + strcpy(msg, $5); + $$ = APP; + } + | INTEGER ',' STRING + /* To do */ + { + prio = $1; + strcpy(msg, $3); + $$ = TODO; + } + | STRING ',' STRING + /* Phone */ + { + strcpy(phnum, $1); + strcpy(msg, $3); + $$ = PHONE; + } + | DATE ',' STRING + /* Anniversary */ + { + sscanf($1, "%d/%d/%d", &month, &day, &year); + strcpy(msg, $3); + $$ = ANNIV; + } + | INTEGER ',' INTEGER + /* System */ + { + chime = $1; + beep = $3; + $$ = SYSTEM; + } + | INTEGER ',' STRING ',' INTEGER ',' INTEGER ',' INTEGER + /* Timezone */ + { + pos = $1; + strcpy(msg, $3); + minute = $5; + tfmt = $7; + dfmt = $9; + $$ = TIMEZONE; + } + | STRING + { + strcpy(msg, $1); + $$ = DATA; + } + | INTEGER + { + val = $1; + $$ = INTVAL; + } + ; + +%% +int dl_error(char *s) +{ + char buf[1024]; + + snprintf(buf, sizeof buf,"%s on line %d.",s,line_num); + (*dl_error_proc)(buf); + return 0; +} + +extern FILE *dl_in; + +WatchInfoPtr +dl_read_save(datafile, type, times, alarms, chron, timers, apps, todos, + phones, annivs, system, wristapp, melody) +char *datafile; +int type; +ListPtr *times; +ListPtr *alarms; +ListPtr *chron; +ListPtr *timers; +ListPtr *apps; +ListPtr *todos; +ListPtr *phones; +ListPtr *annivs; +ListPtr *system; +ListPtr *wristapp; +ListPtr *melody; +{ + char file[1024]; + char buf[1024]; + int r; + + if (*datafile == '~') + sprintf(file, "%s%s", getenv("HOME"), &datafile[1]); + else + strcpy(file, datafile); + + watch_type = type; + + if ((dl_in = fopen(file,"r")) == NULL) { + sprintf(buf,"Could not open %s for reading.", file); + (*dl_error_proc)(buf); + return(NULL); + } + + r = dl_parse(); + fclose(dl_in); + + if (r) + return(NULL); + + *alarms = lists[ALARM]; + *chron = lists[CHRON]; + *timers = lists[TIMER]; + *apps = lists[APP]; + *phones = lists[PHONE]; + *todos = lists[TODO]; + *annivs = lists[ANNIV]; + *system = lists[SYSTEM]; + *wristapp = lists[WRISTAPP]; + *melody = lists[MELODY]; + *times = lists[TIMEZONE]; + free(lists); + return(wi); +} diff --git a/dl_add_to_list.c b/dl_add_to_list.c new file mode 100644 index 0000000..e129653 --- /dev/null +++ b/dl_add_to_list.c @@ -0,0 +1,37 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "datalink.h" + +void dl_add_to_list(ListPtr list, ItemPtr item) +{ + + if (list->last) + { + list->last = list->last->next = item; + list->count++; + } else + { + list->first = list->last = item; + list->count = 1; + } + +} diff --git a/dl_anniv_by_date.c b/dl_anniv_by_date.c new file mode 100644 index 0000000..1764d80 --- /dev/null +++ b/dl_anniv_by_date.c @@ -0,0 +1,34 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "datalink.h" + +int dl_anniv_by_date(ItemPtr a, ItemPtr b) +{ + int r; + + r = a->data.anniv.month - b->data.anniv.month; + + if (r) + return (r); + + return (a->data.anniv.day - b->data.anniv.day); +} diff --git a/dl_anniv_by_label.c b/dl_anniv_by_label.c new file mode 100644 index 0000000..c2ae29e --- /dev/null +++ b/dl_anniv_by_label.c @@ -0,0 +1,28 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <string.h> +#include "datalink.h" + +int dl_anniv_by_label(ItemPtr a, ItemPtr b) +{ + return (strcmp(a->data.anniv.label, b->data.anniv.label)); +} diff --git a/dl_app_by_datetime.c b/dl_app_by_datetime.c new file mode 100644 index 0000000..07bffa9 --- /dev/null +++ b/dl_app_by_datetime.c @@ -0,0 +1,39 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "datalink.h" + +int dl_app_by_datetime(ItemPtr a, ItemPtr b) +{ + int r; + + r = a->data.app.month - b->data.app.month; + + if (r) + return (r); + + r = a->data.app.day - b->data.app.day; + + if (r) + return (r); + + return (a->data.app.time - b->data.app.time); +} diff --git a/dl_app_by_label.c b/dl_app_by_label.c new file mode 100644 index 0000000..e4f2ee9 --- /dev/null +++ b/dl_app_by_label.c @@ -0,0 +1,28 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <string.h> +#include "datalink.h" + +int dl_app_by_label(ItemPtr a, ItemPtr b) +{ + return (strcmp(a->data.app.label, b->data.app.label)); +} diff --git a/dl_docrc.c b/dl_docrc.c new file mode 100644 index 0000000..18a6cca --- /dev/null +++ b/dl_docrc.c @@ -0,0 +1,52 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* crc lookup table */ +static unsigned short int crc16_table[16] = { + 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, + 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400 +}; + +unsigned short int dl_docrc(unsigned char *data) +{ + int i; + unsigned short int t; + unsigned short int crc = 0; + int l; + + l = data[0] - 2; + + for (i = 0; i < l; i++) + { + t = crc16_table[crc & 0xF]; + crc = (crc >> 4) & 0x0FFF; + crc = crc ^ t ^ crc16_table[data[i] & 0xF]; + + /* upper 4 bits */ + t = crc16_table[crc & 0xF]; + crc = (crc >> 4) & 0x0FFF; + crc = crc ^ t ^ crc16_table[(data[i] >> 4) & 0xF]; + } + + data[l++] = crc >> 8; + data[l] = crc & 0xff; + return (crc); +} diff --git a/dl_fill_pack_ascii.c b/dl_fill_pack_ascii.c new file mode 100644 index 0000000..cc73634 --- /dev/null +++ b/dl_fill_pack_ascii.c @@ -0,0 +1,40 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <string.h> +#include "datalink.h" + +void dl_fill_pack_ascii(unsigned char * to, unsigned char * from, int size, + char fill) +{ + int l = strlen(from); + int i; + + if (l > size) + l = size; + + for (i = 0; i < l; i++) + to[i] = dl_pack_char(from[i]); + + for (i = l; i < size; i++) + to[i] = dl_pack_char(fill); + +} diff --git a/dl_free_download.c b/dl_free_download.c new file mode 100644 index 0000000..cfd69a7 --- /dev/null +++ b/dl_free_download.c @@ -0,0 +1,65 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <stdlib.h> +#include <string.h> +#include "datalink.h" +#include "datalink_private.h" + + +void dl_free_download() +{ +/* Free up old download structure if it exists. */ + if (dl_download_data.times) + free(dl_download_data.times); + + if (dl_download_data.alarms) + free(dl_download_data.alarms); + + if (dl_download_data.timers) + free(dl_download_data.timers); + + if (dl_download_data.apps) + free(dl_download_data.apps); + + if (dl_download_data.chron) + free(dl_download_data.chron); + + if (dl_download_data.phones) + free(dl_download_data.phones); + + if (dl_download_data.todos) + free(dl_download_data.todos); + + if (dl_download_data.annivs) + free(dl_download_data.annivs); + + if (dl_download_data.system) + free(dl_download_data.system); + + if (dl_download_data.wristapp) + free(dl_download_data.wristapp); + + if (dl_download_data.melody) + free(dl_download_data.melody); + + memset((char *) &dl_download_data, 0, sizeof(Download)); +} diff --git a/dl_init_download.c b/dl_init_download.c new file mode 100644 index 0000000..92dc9c8 --- /dev/null +++ b/dl_init_download.c @@ -0,0 +1,607 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "datalink.h" +#include "datalink_private.h" + +int +dl_init_download(WatchInfoPtr wi, ListPtr times, ListPtr alarms, + ListPtr chron, ListPtr timers, ListPtr apps, ListPtr todos, + ListPtr phones, ListPtr annivs, ListPtr system, ListPtr wristapp, + ListPtr melody) +{ + ItemPtr ip; + char buf[1024]; + int i; + int last_warn = 0; + +/* Free up old download structure if it exists. */ + dl_free_download(); + + dl_download_data.memory = 0; + dl_download_data.app_size = 0; + dl_download_data.phone_size = 0; + dl_download_data.todo_size = 0; + dl_download_data.anniv_size = 0; + dl_download_data.pre_notification_time = wi->pre_notification_time; + dl_download_data.max_alarm_str = wi->max_alarm_str; + dl_download_data.max_timer_str = wi->max_timer_str; + dl_download_data.max_phone_str = wi->max_phone_str; + dl_download_data.max_chron_str = wi->max_chron_str; + +/* Count and verify items. */ + if (times && times->download) + { + + for (i = 0, ip = times->first; ip; ip = ip->next, i++) + { + + if (!ip->data.time.tz_num) + ip->data.time.tz_num = i + 1; + + if (!dl_item_ok(wi, ip)) + { + sprintf(buf, "Bad time item #%d", i + 1); + return ((*dl_error_proc) (buf)); + } + + if (i >= wi->max_tz) + return ((*dl_error_proc) + ("Too many time items.")); + + } + + if (i != times->count) + { + last_warn = + (*dl_warn_proc) + ("Time count value incorrect."); + times->count = i; + } + + } + + if (chron && chron->download) + { + + for (i = 0, ip = chron->first; ip; ip = ip->next, i++) + { + + if (!dl_item_ok(wi, ip)) + { + sprintf(buf, "Bad chron item #%d", i + 1); + return ((*dl_error_proc) (buf)); + } + + if (i >= wi->max_chrons) + return ((*dl_error_proc) + ("Too many chron items.")); + + } + + if (i != chron->count) + { + last_warn = + (*dl_warn_proc) + ("Chron count value incorrect."); + chron->count = i; + } + + } + + if (alarms && alarms->download) + { + + for (i = 0, ip = alarms->first; ip; ip = ip->next, i++) + { + + if (!ip->data.alarm.alarm_num) + ip->data.alarm.alarm_num = i + 1; + + if (!dl_item_ok(wi, ip)) + { + sprintf(buf, "Bad alarm item #%d", i + 1); + return ((*dl_error_proc) (buf)); + } + + if (i >= wi->max_alarms) + return ((*dl_error_proc) + ("Too many alarm items.")); + + } + + if (i != alarms->count) + { + last_warn = + (*dl_warn_proc) + ("Alarm count value incorrect."); + alarms->count = i; + } + + } + + if (timers && timers->download) + { + + for (i = 0, ip = timers->first; ip; ip = ip->next, i++) + { + + if (!ip->data.timer.timer_num) + ip->data.timer.timer_num = i + 1; + + if (!dl_item_ok(wi, ip)) + { + sprintf(buf, "Bad timer item #%d", i + 1); + return ((*dl_error_proc) (buf)); + } + + if (i >= wi->max_timers) + return ((*dl_error_proc) + ("Too many timer items.")); + + } + + if (i != timers->count) + { + last_warn = + (*dl_warn_proc) + ("Timer count value incorrect."); + timers->count = i; + } + + } + + if (apps && apps->download) + { + + for (i = 0, ip = apps->first; ip; ip = ip->next, i++) + { + + if (!dl_item_ok(wi, ip)) + { + sprintf(buf, "Bad appointment item #%d", + i + 1); + return ((*dl_error_proc) (buf)); + } + + if (i >= wi->max_apps) + return ((*dl_error_proc) + ("Too many appointment items.")); + + dl_download_data.memory += dl_sizeof_item(wi, ip); + dl_download_data.app_size += + dl_sizeof_item(wi, ip); + } + + if (i != apps->count) + { + last_warn = + (*dl_warn_proc) + ("Appointment count value incorrect."); + apps->count = i; + } + + } + + if (todos && todos->download) + { + + for (i = 0, ip = todos->first; ip; ip = ip->next, i++) + { + + if (!dl_item_ok(wi, ip)) + { + sprintf(buf, "Bad todo item #%d", i + 1); + return ((*dl_error_proc) (buf)); + } + + if (i >= wi->max_todos) + return ((*dl_error_proc) + ("Too many todo items.")); + + dl_download_data.memory += dl_sizeof_item(wi, ip); + dl_download_data.todo_size += + dl_sizeof_item(wi, ip); + } + + if (i != todos->count) + { + last_warn = + (*dl_warn_proc) + ("To Do count value incorrect."); + todos->count = i; + } + + } + + if (phones && phones->download) + { + + for (i = 0, ip = phones->first; ip; ip = ip->next, i++) + { + + if (!dl_item_ok(wi, ip)) + { + sprintf(buf, "Bad phone item #%d", i + 1); + return ((*dl_error_proc) (buf)); + } + + if (i >= wi->max_phones) + return ((*dl_error_proc) + ("Too many phone items.")); + + dl_download_data.memory += dl_sizeof_item(wi, ip); + dl_download_data.phone_size += + dl_sizeof_item(wi, ip); + } + + if (i != phones->count) + { + last_warn = + (*dl_warn_proc) + ("Phone count value incorrect."); + phones->count = i; + } + + } + + if (annivs && annivs->download) + { + + for (i = 0, ip = annivs->first; ip; ip = ip->next, i++) + { + + if (!dl_item_ok(wi, ip)) + { + sprintf(buf, "Bad anniversary item #%d", + i + 1); + return ((*dl_error_proc) (buf)); + } + + if (i >= wi->max_annivs) + return ((*dl_error_proc) + ("Too many anniversary items.")); + + dl_download_data.memory += dl_sizeof_item(wi, ip); + dl_download_data.anniv_size += + dl_sizeof_item(wi, ip); + } + + if (i != annivs->count) + { + last_warn = + (*dl_warn_proc) + ("Anniversary count value incorrect."); + annivs->count = i; + } + + } + + if (system && system->download) + { + + for (i = 0, ip = system->first; ip; ip = ip->next, i++) + { + + if (!dl_item_ok(wi, ip)) + { + sprintf(buf, "Bad sytem item #%d", i + 1); + return ((*dl_error_proc) (buf)); + } + + if (i >= wi->max_system) + return ((*dl_error_proc) + ("Too many sytem items.")); + + } + + if (i != system->count) + { + last_warn = + (*dl_warn_proc) + ("System count value incorrect."); + system->count = i; + } + + } + + if (wristapp && wristapp->download) + { + + for (i = 0, ip = wristapp->first; ip; ip = ip->next, i++) + { + + if (!dl_item_ok(wi, ip)) + { + sprintf(buf, "Bad wristapp item #%d", + i + 1); + return ((*dl_error_proc) (buf)); + } + + if (i >= wi->max_wristapp) + return ((*dl_error_proc) + ("Too many wristapp items.")); + + } + + if (i != wristapp->count) + { + last_warn = + (*dl_warn_proc) + ("WristApp count value incorrect."); + wristapp->count = i; + } + + } + + if (melody && melody->download) + { + + for (i = 0, ip = melody->first; ip; ip = ip->next, i++) + { + + if (!dl_item_ok(wi, ip)) + { + sprintf(buf, "Bad melody item #%d", i + 1); + return ((*dl_error_proc) (buf)); + } + + if (i >= wi->max_melody) + return ((*dl_error_proc) + ("Too many melody items.")); + + } + + if (i != melody->count) + { + last_warn = + (*dl_warn_proc) + ("Melody count value incorrect."); + melody->count = i; + } + + } + +/* Check to see if memory usage has been exceeded. */ + + if (dl_download_data.memory > wi->max_mem) + return ((*dl_error_proc) ("Too much data.")); + +/* OK. We know we have valid data that will fit in the watch. Allocate + download structure. */ + + if (times && times->download) + { + + if ((dl_download_data.times = + (TimePtr) calloc(times->count, sizeof(Time))) == NULL) + return ((*dl_error_proc) + ("Can't allocate time download data.")); + + dl_download_data.num_times = times->count; + + for (i = 0, ip = times->first; ip; ip = ip->next, i++) + { + memcpy((char *) &dl_download_data.times[i], + (char *) &ip->data.time, sizeof(Time)); + } + + } + + if (chron && chron->download) + { + + if ((dl_download_data.chron = + (ChronPtr) calloc(chron->count, + sizeof(Chron))) == NULL) + return ((*dl_error_proc) + ("Can't allocate chron download data.")); + + dl_download_data.num_chron = chron->count; + + for (i = 0, ip = chron->first; ip; ip = ip->next, i++) + { + memcpy((char *) &dl_download_data.chron[i], + (char *) &ip->data.chron, sizeof(Chron)); + dl_download_data.chron[i].memused = + 14 + 4 * dl_download_data.chron[i].chron_laps; + } + + } + + if (alarms && alarms->download) + { + + if ((dl_download_data.alarms = + (AlarmPtr) calloc(alarms->count, + sizeof(Alarm))) == NULL) + return ((*dl_error_proc) + ("Can't allocate alarm download data.")); + + dl_download_data.num_alarms = alarms->count; + + for (i = 0, ip = alarms->first; ip; ip = ip->next, i++) + { + memcpy((char *) &dl_download_data.alarms[i], + (char *) &ip->data.alarm, sizeof(Alarm)); + } + + } + + if (timers && timers->download) + { + + if ((dl_download_data.timers = + (TimerPtr) calloc(timers->count, + sizeof(Timer))) == NULL) + return ((*dl_error_proc) + ("Can't allocate timer download data.")); + + dl_download_data.num_timers = timers->count; + + for (i = 0, ip = timers->first; ip; ip = ip->next, i++) + { + memcpy((char *) &dl_download_data.timers[i], + (char *) &ip->data.timer, sizeof(Timer)); + } + + } + + if (apps && apps->download) + { + + if ((dl_download_data.apps = + (AppointmentPtr) calloc(apps->count, + sizeof(Appointment))) == NULL) + return ((*dl_error_proc) + ("Can't allocate appointment download data.")); + + dl_download_data.num_apps = apps->count; + + for (i = 0, ip = apps->first; ip; ip = ip->next, i++) + { + memcpy((char *) &dl_download_data.apps[i], + (char *) &ip->data.app, + sizeof(Appointment)); + } + + } + + if (todos && todos->download) + { + + if ((dl_download_data.todos = + (ToDoPtr) calloc(todos->count, sizeof(ToDo))) == NULL) + return ((*dl_error_proc) + ("Can't allocate todo download data.")); + + dl_download_data.num_todos = todos->count; + + for (i = 0, ip = todos->first; ip; ip = ip->next, i++) + { + memcpy((char *) &dl_download_data.todos[i], + (char *) &ip->data.todo, sizeof(ToDo)); + } + + } + + if (phones && phones->download) + { + + if ((dl_download_data.phones = + (PhonePtr) calloc(phones->count, + sizeof(Phone))) == NULL) + return ((*dl_error_proc) + ("Can't allocate phone download data.")); + + dl_download_data.num_phones = phones->count; + + for (i = 0, ip = phones->first; ip; ip = ip->next, i++) + { + memcpy((char *) &dl_download_data.phones[i], + (char *) &ip->data.phone, sizeof(Phone)); + } + + } + + if (annivs && annivs->download) + { + + if ((dl_download_data.annivs = + (AnniversaryPtr) calloc(annivs->count, + sizeof(Anniversary))) == NULL) + return ((*dl_error_proc) + ("Can't allocate anniversary download data.")); + + dl_download_data.num_annivs = annivs->count; + + for (i = 0, ip = annivs->first; ip; ip = ip->next, i++) + { + memcpy((char *) &dl_download_data.annivs[i], + (char *) &ip->data.anniv, + sizeof(Anniversary)); + } + + } + + if (system && system->download) + { + + if ((dl_download_data.system = + (SystemPtr) calloc(system->count, + sizeof(System))) == NULL) + return ((*dl_error_proc) + ("Can't allocate system download data.")); + + dl_download_data.num_system = system->count; + + for (i = 0, ip = system->first; ip; ip = ip->next, i++) + { + memcpy((char *) &dl_download_data.system[i], + (char *) &ip->data.system, sizeof(System)); + } + + } + + if (wristapp && wristapp->download) + { + + if ((dl_download_data.wristapp = + (WristAppPtr) calloc(wristapp->count, + sizeof(WristApp))) == NULL) + return ((*dl_error_proc) + ("Can't allocate wristapp download data.")); + + dl_download_data.num_wristapp = wristapp->count; + + for (i = 0, ip = wristapp->first; ip; ip = ip->next, i++) + { + memcpy((char *) &dl_download_data.wristapp[i], + (char *) &ip->data.wristapp, + sizeof(WristApp)); + } + + } + + if (melody && melody->download) + { + + if ((dl_download_data.melody = + (MelodyPtr) calloc(melody->count, + sizeof(Melody))) == NULL) + return ((*dl_error_proc) + ("Can't allocate melody download data.")); + + dl_download_data.num_melody = melody->count; + + for (i = 0, ip = melody->first; ip; ip = ip->next, i++) + { + memcpy((char *) &dl_download_data.melody[i], + (char *) &ip->data.melody, sizeof(Melody)); + } + + } + + return (0); +} diff --git a/dl_init_watch.c b/dl_init_watch.c new file mode 100644 index 0000000..9cfc929 --- /dev/null +++ b/dl_init_watch.c @@ -0,0 +1,150 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "datalink.h" +#include "datalink_private.h" + +int (*dl_error_proc) (char *); +int (*dl_warn_proc) (char *); + +Download dl_download_data = { 0 }; + +int dl_default_error(char *msg) +{ + fprintf(stderr, "ERROR: %s\n", msg); + return (-1); +} + +int dl_default_warn(char *msg) +{ + fprintf(stderr, "WARNING: %s\n", msg); + return (1); +} + +WatchInfoPtr dl_init_watch(int type) +{ + WatchInfoPtr result; + + if (!dl_error_proc) + dl_error_proc = dl_default_error; + + if (!dl_warn_proc) + dl_warn_proc = dl_default_warn; + + if ((result = (WatchInfoPtr) malloc(sizeof(WatchInfo))) == NULL) + { + (*dl_error_proc) ("Could not allocate WatchInfo structure."); + return (NULL); + } + + memset((char *) result, 0, sizeof(WatchInfo)); + + switch (type) + { + case DATALINK_70: + result->dl_device = type; + result->max_tz = 2; + result->max_alarms = 5; + result->max_chrons = 0; + result->max_chron_str = 0; + result->max_apps = 255; + result->max_phones = 255; + result->max_timers = 0; + result->max_todos = 255; + result->max_annivs = 255; + result->max_system = 1; + result->max_wristapp = 0; + result->max_melody = 0; + result->max_tzlen = 3; + result->max_mem = 850; + result->mem_size = 0; + result->max_str = 15; + result->max_alarm_str = 8; + result->max_phone_str = 12; + result->max_timer_str = 0; + result->max_wristapp_len = 0; + result->max_mel_len = 0; + result->pre_notification_time = 0; + result->time_adjust = 9; + break; + case DATALINK_150: + case DATALINK_150S: + result->dl_device = type; + result->max_tz = 2; + result->max_alarms = 5; + result->max_chrons = 0; + result->max_chron_str = 0; + result->max_apps = 255; + result->max_phones = 255; + result->max_timers = 0; + result->max_todos = 255; + result->max_annivs = 255; + result->max_system = 1; + result->max_wristapp = 1; + result->max_melody = 1; + result->max_tzlen = 3; + result->max_mem = 2048; + result->mem_size = 0; + result->max_str = 31; + result->max_alarm_str = 8; + result->max_phone_str = 12; + result->max_timer_str = 0; + result->max_wristapp_len = 742; + result->max_mel_len = 64; + result->pre_notification_time = 0; + result->time_adjust = 9; + break; + case DATALINK_IRONMAN: + result->dl_device = type; + result->max_tz = 2; + result->max_alarms = 10; + result->max_chrons = 1; + result->max_apps = 0; + result->max_phones = 255; + result->max_timers = 5; + result->max_todos = 0; + result->max_annivs = 0; + result->max_system = 1; + result->max_wristapp = 0; + result->max_melody = 0; + result->max_tzlen = 3; + result->max_mem = 850; + result->mem_size = 0; + result->max_str = 15; + result->max_alarm_str = 16; + result->max_chron_str = 8; + result->max_phone_str = 12; + result->max_timer_str = 8; + result->max_wristapp_len = 0; + result->max_mel_len = 0; + result->pre_notification_time = 0; + result->time_adjust = 9; + break; + default: + (*dl_error_proc) ("Unknown watch type."); + return (NULL); + } + + return (result); +} diff --git a/dl_item_ok.c b/dl_item_ok.c new file mode 100644 index 0000000..ef919f6 --- /dev/null +++ b/dl_item_ok.c @@ -0,0 +1,306 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include "datalink.h" +#include "datalink_private.h" + + +int dl_item_ok(WatchInfoPtr wi, ItemPtr ip) +{ + char buf[1024]; + + switch (ip->type) + { + case DL_TIME_TYPE: + + if (ip->data.time.tz_num < 1 + || ip->data.time.tz_num > wi->max_tz) + { + sprintf(buf, "Bad time zone number #%d", + ip->data.time.tz_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.time.hours > 23) + { + sprintf(buf, "Bad hour in time #%d", + ip->data.time.tz_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.time.minutes > 59) + { + sprintf(buf, "Bad minute in time #%d", + ip->data.time.tz_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.time.month < 1 || ip->data.time.month > 12) + { + sprintf(buf, "Bad month in time #%d", + ip->data.time.tz_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.time.day < 1 || ip->data.time.day > 31) + { + sprintf(buf, "Bad day in time #%d", + ip->data.time.tz_num); + (*dl_error_proc) (buf); + return (0); + } + + if (!dl_string_ok(ip->data.time.label, wi->max_str)) + { + sprintf(buf, "Bad characters in label in time #%d", + ip->data.time.tz_num); + (*dl_warn_proc) (buf); + } + + break; + case DL_ALARM_TYPE: + + if (ip->data.alarm.alarm_num < 1 || + ip->data.alarm.alarm_num > wi->max_alarms) + { + sprintf(buf, "Bad alarm number #%d", + ip->data.alarm.alarm_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.alarm.hours > 23) + { + sprintf(buf, "Bad hour in alarm #%d", + ip->data.alarm.alarm_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.alarm.minutes > 59) + { + sprintf(buf, "Bad minute in alarm #%d", + ip->data.alarm.alarm_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.alarm.month > 12) + { + sprintf(buf, "Bad month in alarm #%d", + ip->data.alarm.alarm_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.alarm.day > 31) + { + sprintf(buf, "Bad day in alarm #%d", + ip->data.alarm.alarm_num); + (*dl_error_proc) (buf); + return (0); + } + + if (!dl_string_ok(ip->data.alarm.label, wi->max_alarm_str)) + { + sprintf(buf, "Bad string in alarm #%d", + ip->data.alarm.alarm_num); + (*dl_warn_proc) (buf); + } + + break; + case DL_TIMER_TYPE: + + if (ip->data.timer.timer_num < 1 || + ip->data.timer.timer_num > wi->max_timers) + { + sprintf(buf, "Bad timer number #%d", + ip->data.timer.timer_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.timer.hours > 99) + { + sprintf(buf, "Bad hour in timer #%d", + ip->data.timer.timer_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.timer.minutes > 59) + { + sprintf(buf, "Bad minute in timer #%d", + ip->data.timer.timer_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.timer.second > 59) + { + sprintf(buf, "Bad second in timer #%d", + ip->data.timer.timer_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.timer.repeat != 0 + && ip->data.timer.repeat != 1) + { + sprintf(buf, "Bad repeat in timer #%d", + ip->data.timer.timer_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.timer.chron != 0 && ip->data.timer.chron != 1) + { + sprintf(buf, "Bad chron in timer #%d", + ip->data.timer.timer_num); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.timer.chron && ip->data.timer.repeat) + { + sprintf(buf, + "Can't do repeat and chron at the end of a timer, in timer #%d", + ip->data.timer.timer_num); + (*dl_error_proc) (buf); + return (0); + } + + if (!dl_string_ok(ip->data.timer.label, wi->max_timer_str)) + { + sprintf(buf, "Bad string in timer #%d", + ip->data.timer.timer_num); + (*dl_warn_proc) (buf); + } + + break; + case DL_APP_TYPE: + + if (ip->data.app.month < 1 || ip->data.app.month > 12) + { + sprintf(buf, "Bad month in appointment."); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.app.day < 1 || ip->data.app.day > 31) + { + sprintf(buf, "Bad day in appointment."); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.app.time > 0x7f) + { + sprintf(buf, "Bad time in appointment."); + (*dl_error_proc) (buf); + return (0); + } + + if (!dl_string_ok(ip->data.app.label, wi->max_str)) + { + sprintf(buf, + "Bad characters in label in appointment."); + (*dl_warn_proc) (buf); + } + + break; + case DL_CHRON_TYPE: + + if (!dl_string_ok(ip->data.chron.label, wi->max_chron_str)) + { + sprintf(buf, "Bad characters in label in chron."); + (*dl_warn_proc) (buf); + } + + break; + case DL_PHONE_TYPE: + + if (!dl_string_ok + (ip->data.phone.number, wi->max_phone_str)) + { + sprintf(buf, "Bad characters in phone number."); + (*dl_warn_proc) (buf); + } + + if (!dl_string_ok(ip->data.phone.label, wi->max_str)) + { + sprintf(buf, "Bad characters in label in phone."); + (*dl_warn_proc) (buf); + } + + break; + case DL_TODO_TYPE: + + if (!dl_string_ok(ip->data.todo.label, wi->max_str)) + { + sprintf(buf, "Bad characters in label in todo."); + (*dl_warn_proc) (buf); + } + + break; + case DL_ANNIV_TYPE: + + if (ip->data.anniv.month < 1 || ip->data.anniv.month > 12) + { + sprintf(buf, "Bad month in anniversary."); + (*dl_error_proc) (buf); + return (0); + } + + if (ip->data.anniv.day < 1 || ip->data.anniv.day > 31) + { + sprintf(buf, "Bad day in anniversary."); + (*dl_error_proc) (buf); + return (0); + } + + if (!dl_string_ok(ip->data.anniv.label, wi->max_str)) + { + sprintf(buf, + "Bad characters in label in anniversary."); + (*dl_warn_proc) (buf); + } + + break; + case DL_SYSTEM_TYPE: + break; + case DL_WRISTAPP_TYPE: + break; + case DL_MELODY_TYPE: + break; + default: + (*dl_error_proc) ("Unknown type"); + return (0); + } + + return (1); +} diff --git a/dl_new_item.c b/dl_new_item.c new file mode 100644 index 0000000..ec0908b --- /dev/null +++ b/dl_new_item.c @@ -0,0 +1,48 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <stdlib.h> +#include <string.h> +#include "datalink.h" + +ItemPtr dl_new_item(WatchInfoPtr wi, int type) +{ + ItemPtr ni; + +/* Since there is only one supported device, wi is not used. */ + + if (type <= DL_NO_TYPE && type > DL_MAX_TYPE) + { + (*dl_error_proc) ("Unknown type, can't allocate."); + return (NULL); + } + + if ((ni = (ItemPtr) malloc(sizeof(Item))) == NULL) + { + (*dl_error_proc) ("Could not allocate item."); + return (NULL); + } + + memset((char *) ni, 0, sizeof(Item)); + + ni->type = type; + return (ni); +} diff --git a/dl_new_list.c b/dl_new_list.c new file mode 100644 index 0000000..495f915 --- /dev/null +++ b/dl_new_list.c @@ -0,0 +1,38 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <stdlib.h> +#include <string.h> +#include "datalink.h" + +ListPtr dl_new_list() +{ + ListPtr nl; + + if ((nl = (ListPtr) malloc(sizeof(List))) == NULL) + { + (*dl_error_proc) ("Could not allocate new list."); + return (NULL); + } + + memset((char *) nl, 0, sizeof(List)); + return (nl); +} diff --git a/dl_pack_ascii.c b/dl_pack_ascii.c new file mode 100644 index 0000000..fe8f08d --- /dev/null +++ b/dl_pack_ascii.c @@ -0,0 +1,59 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "datalink.h" + +int dl_pack_ascii(unsigned char *to, unsigned char *from) +{ + int c; + int p = 0; + int o = 0; + + while (*from) + { + + if (o == 0) + { + to[p] = dl_pack_char(*from); + o = 6; + from++; + continue; + } + + c = dl_pack_char(*from); + to[p] |= c << o; + to[++p] = c >> (8 - o); + o = (o + 6) % 8; + from++; + } + + if (o) + { + to[p] |= 0x3f << o; + to[++p] = 0x3f >> (8 - o); + o = (o + 6) % 8; + if (o) + p++; + } else + to[p++] = 0x3f; + + return (p); +} diff --git a/dl_pack_char.c b/dl_pack_char.c new file mode 100644 index 0000000..1e9cbe4 --- /dev/null +++ b/dl_pack_char.c @@ -0,0 +1,42 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <ctype.h> + +int dl_pack_char(char c) +{ + c = toupper(c); + + if (c >= '0' && c <= '9') + return (c - '0'); + + if (c >= 'A' && c <= 'Z') + return (10 + c - 'A'); + + if (c >= ' ' && c < '0') + return (36 + c - ' '); + + + if (c >= ':' && c <= '~') + return (26 + c - ' '); + + return (0x3f); +} diff --git a/dl_pack_digit.c b/dl_pack_digit.c new file mode 100644 index 0000000..d874240 --- /dev/null +++ b/dl_pack_digit.c @@ -0,0 +1,42 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <ctype.h> + +int dl_pack_digit(char c) +{ + int i; + + c = toupper(c); + + if (c >= '0' && c <= '9') + return (c - '0'); + + for (i = 0; i < 6; i++) + { + + if (c == "CFHPW "[i]) + return (i + 10); + + } + + return (0xf); +} diff --git a/dl_pack_phone.c b/dl_pack_phone.c new file mode 100644 index 0000000..6023961 --- /dev/null +++ b/dl_pack_phone.c @@ -0,0 +1,55 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <string.h> +#include "datalink.h" + +void dl_pack_phone(unsigned char *to, unsigned char *from, int len) +{ + int i; + int l; + + l = strlen(from); + + if (l > len) + l = len; + + for (i = 0; i < l; i++) + { + + if (i & 1) + *to++ |= dl_pack_digit(from[i]) << 4; + else + *to = dl_pack_digit(from[i]); + + } + + for (i = l; i < len; i++) + { + + if (i & 1) + *to++ |= dl_pack_digit(' ') << 4; + else + *to = dl_pack_digit(' '); + + } + +} diff --git a/dl_pack_size.c b/dl_pack_size.c new file mode 100644 index 0000000..b4a4521 --- /dev/null +++ b/dl_pack_size.c @@ -0,0 +1,34 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <string.h> +#include "datalink.h" +#include "datalink_private.h" + +int dl_pack_size(char *string) +{ + int size; + int l; + + l = (strlen(string) + 1) * 3; + size = (l % 4) ? l / 4 + 1 : l / 4; + return (size); +} diff --git a/dl_phone_by_label.c b/dl_phone_by_label.c new file mode 100644 index 0000000..de30ce8 --- /dev/null +++ b/dl_phone_by_label.c @@ -0,0 +1,28 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <string.h> +#include "datalink.h" + +int dl_phone_by_label(ItemPtr a, ItemPtr b) +{ + return (strcmp(a->data.phone.label, b->data.phone.label)); +} diff --git a/dl_send_data.c b/dl_send_data.c new file mode 100644 index 0000000..3dfa12e --- /dev/null +++ b/dl_send_data.c @@ -0,0 +1,897 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <stdlib.h> +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <string.h> +#include <limits.h> +#include "datalink.h" +#include "datalink_private.h" + +#define MAX_PCKT 38 + +#define TIME_70 0x30 +#define DSTART_70 0x60 +#define DATA_70 0x61 +#define DEND_70 0x62 + +static unsigned char start1[] = { 7, 0x20, 0, 0, 3, 0, 0 }; +static unsigned char datablock1[] = { 0x20, 0x70, 0x02, 0x40, + 0x05, 0xa9, 0x22, 0x5f, + 0xe6, 0xb2, 0xe8, 0xbb, + 0xe7, 0xb2, 0xe8, 0xbb, + 0xe7, 0xbb, 0xe8, 0xb2, + 0xe7, 0xb2, 0x5c, 0xa3, + 0x09, 0x26, 0xed, 0x15, + 0xa9, 0x01, 0x00, 0x00 +}; +static unsigned char datablock2[] = { 0x14, 0x70, 0x02, 0x5a, + 0xa9, 0x02, 0x14, 0xa9, + 0xb6, 0xa9, 0xa4, 0x07, + 0x47, 0xb7, 0xa9, 0xcc, + 0x74, 0x6f, 0x00, 0x00 +}; +static unsigned char time[] = { 17, 0x32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0 +}; +static unsigned char dstart[] = { 5, 0x93, 0, 0, 0 }; +static unsigned char dinfo[] = { 20, 0x90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0 +}; +static unsigned char dspace[] = { 4, 0x91, 0, 0 }; +static unsigned char dend[] = { 5, 0x92, 0, 0, 0 }; +static unsigned char blank_alarm[] = { 18, 0x50, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +static unsigned char timer[] = + { 0x11, 0x43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +static unsigned char sysinfo[] = { 6, 0x71, 0, 0, 0, 0 }; +static unsigned char end1[] = { 4, 0x21, 0, 0 }; + +static unsigned char pre60[] = { 6, 0x23, 2, 0x40, 0, 0 }; +static unsigned char numdatapackets[] = { 5, 0x60, 0, 0, 0 }; + +int _write_data(int fd, unsigned char *buf, unsigned char *data, int size, + int *pnum, int type, WatchInfoPtr wi) +{ + int bytes_left; + + while (*buf + size > MAX_PCKT - 2) + { + bytes_left = *buf + size - MAX_PCKT + 2; + memcpy(&buf[buf[0]], data, size - bytes_left); + buf[0] = MAX_PCKT; + dl_docrc(buf); + + if (write(fd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write data to tmp file.")); + + data += size - bytes_left; + size = bytes_left; + + memcpy(buf, dspace, *dspace); + + if (wi->dl_device == DATALINK_70) + buf[1] = DATA_70; + + buf[2] = type; + buf[3] = (*pnum)++; + } + + if (!size) + return (0); + + memcpy(&buf[buf[0]], data, size); + buf[0] += size; + return (1); +} + +/* TODO: If there is any errors we currently leak a file descriptor, + * it might be nice to close the file first. + */ +int dl_send_data(WatchInfoPtr wi, int type) +{ + char fname[PATH_MAX]; + char * tmpdir; + char * template="/datalink_XXXXXX"; + unsigned char buf[64]; + unsigned char data[64]; + unsigned short addr = 0x0236; + char *protocol; + AppointmentPtr ap; + ToDoPtr tp; + PhonePtr pp; + AnniversaryPtr anp; + WristAppPtr wristapp; + SystemPtr sys; + MelodyPtr melody; + int ofd; + int i; + int pnum; + int pid; + int status; + int ret=0; + int p; + + if (type == BLINK_FILE) + { + strcpy(fname, "DEBUGOUTPUT"); + if ((ofd = open(fname, + O_WRONLY | O_CREAT | O_TRUNC, 0644)) == -1) + { + sprintf(buf, "Can't open %s for writing.", fname); + return ((*dl_error_proc) (buf)); + } + } + else + { + /* Try to get the directory for a temporary file from + * the envinronment variable TMPDIR + * Try P_tmpdir if that fails + * Fallback to /tmp if need be + */ + if(tmpdir=getenv("TMPDIR")) + if(strlen(tmpdir)+strlen(template)+1 >= PATH_MAX) + tmpdir=0; // invalid path, string too long + if(!tmpdir) + { + #ifdef P_tmpdir + tmpdir=P_tmpdir; + #else + tmpdir="/tmp"; + #endif + } + strcpy(fname, tmpdir); + strcat(fname, template); + if ((ofd = mkstemp(fname)) == -1) + { + sprintf(buf, "Can't open %s for writing.", fname); + return ((*dl_error_proc) (buf)); + } + } + + memcpy(buf, start1, *start1); + + if (wi->dl_device == DATALINK_70) + { + buf[4] = 1; + } + else if (wi->dl_device == DATALINK_IRONMAN) + { + buf[4] = 9; + } + else if (wi->dl_device == DATALINK_150S) + { + buf[4] = 4; + } + + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write start to tmp file.")); + + if (wi->dl_device == DATALINK_IRONMAN) + { + memcpy(buf, datablock1, *datablock1); + dl_docrc(buf); + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write start block1 to tmp file.")); + + memcpy(buf, datablock2, *datablock1); + dl_docrc(buf); + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write start block2 to tmp file.")); + } + + + for (i = 0; i < dl_download_data.num_times; i++) + { + memcpy(buf, time, *time); + p = 2; + if (wi->dl_device == DATALINK_IRONMAN) + { + buf[0] = 0x0e; + buf[1] = 0x30; + } + + buf[p++] = dl_download_data.times[i].tz_num; + + if (wi->dl_device == DATALINK_150 || + wi->dl_device == DATALINK_150S) + buf[p++] = dl_download_data.times[i].seconds; + + if (wi->dl_device == DATALINK_IRONMAN) + { + buf[p++] = dl_download_data.times[i].hours; + buf[p++] = dl_download_data.times[i].minutes; + buf[p++] = dl_download_data.times[i].month; + buf[p++] = dl_download_data.times[i].day; + buf[p++] = dl_download_data.times[i].year; + buf[p++] = dl_download_data.times[i].dow; + buf[p++] = dl_download_data.times[i].seconds; + } else + { + buf[p++] = dl_download_data.times[i].hours; + buf[p++] = dl_download_data.times[i].minutes; + buf[p++] = dl_download_data.times[i].month; + buf[p++] = dl_download_data.times[i].day; + buf[p++] = dl_download_data.times[i].year; + buf[p++] = + dl_pack_char(dl_download_data. + times[i].label[0]); + buf[p++] = + dl_pack_char(dl_download_data. + times[i].label[1]); + buf[p++] = + dl_pack_char(dl_download_data. + times[i].label[2]); + buf[p++] = dl_download_data.times[i].dow - 1; + } + + if (wi->dl_device == DATALINK_150 || + wi->dl_device == DATALINK_150 || + wi->dl_device == DATALINK_IRONMAN) + { + buf[p++] = dl_download_data.times[i].hour_fmt; + buf[p++] = + dl_download_data.times[i].date_fmt & 0xFF; + } + + if (wi->dl_device == DATALINK_70) + buf[1] = TIME_70; + + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write time to tmp file.")); + + } + + if (wi->dl_device != DATALINK_IRONMAN && dl_download_data.memory) + { + memcpy(buf, dstart, *dstart); + buf[2] = 1; + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write dstart to tmp file.")); + + memcpy(buf, dinfo, *dinfo); + buf[2] = 1; + buf[3] = dl_download_data.memory / (MAX_PCKT - 6); + + if (dl_download_data.memory % (MAX_PCKT - 6)) + buf[3]++; + + buf[12] = dl_download_data.num_apps; + buf[13] = dl_download_data.num_todos; + buf[14] = dl_download_data.num_phones; + buf[15] = dl_download_data.num_annivs; + buf[4] = (addr >> 8) & 0xff; + buf[5] = addr & 0xff; + addr += dl_download_data.app_size; + buf[6] = (addr >> 8) & 0xff; + buf[7] = addr & 0xff; + addr += dl_download_data.todo_size; + buf[8] = (addr >> 8) & 0xff; + buf[9] = addr & 0xff; + addr += dl_download_data.phone_size; + buf[10] = (addr >> 8) & 0xff; + buf[11] = addr & 0xff; + buf[16] = 0x62; + buf[17] = dl_download_data.pre_notification_time / 5; + if (!buf[17]) + buf[17] = 0xff; + + if (wi->dl_device == DATALINK_70) + buf[1] = DATA_70; + + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write dinfo to tmp file.")); + + pnum = 1; + memcpy(buf, dspace, *dspace); + + if (wi->dl_device == DATALINK_70) + buf[1] = DATA_70; + + buf[2] = 1; + buf[3] = pnum++; + + for (i = 0; i < dl_download_data.num_apps; i++) + { + ap = &dl_download_data.apps[i]; + data[0] = dl_pack_size(ap->label); + data[1] = ap->month; + data[2] = ap->day; + data[3] = ap->time; + + if (data[0] != dl_pack_ascii(&data[4], ap->label)) + return ((*dl_error_proc) + ("ERROR Bad pack_ascii.\n")); + + *data += 4; + + if (!_write_data + (ofd, buf, data, *data, &pnum, 1, wi)) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + } + + for (i = 0; i < dl_download_data.num_todos; i++) + { + tp = &dl_download_data.todos[i]; + data[0] = dl_pack_size(tp->label); + data[1] = tp->priority; + + if (data[0] != dl_pack_ascii(&data[2], tp->label)) + return ((*dl_error_proc) + ("ERROR Bad pack_ascii.\n")); + + *data += 2; + + if (!_write_data + (ofd, buf, data, *data, &pnum, 1, wi)) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + } + + for (i = 0; i < dl_download_data.num_phones; i++) + { + pp = &dl_download_data.phones[i]; + data[0] = dl_pack_size(pp->label); + dl_pack_phone(&data[1], pp->number, + dl_download_data.max_phone_str); + + if (data[0] != dl_pack_ascii(&data[7], pp->label)) + { + printf("ERROR Bad pack_ascii.\n"); + exit(-1); + } + + *data += dl_download_data.max_phone_str / 2; + (*data)++; + + if (!_write_data + (ofd, buf, data, *data, &pnum, 1, wi)) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + } + + for (i = 0; i < dl_download_data.num_annivs; i++) + { + anp = &dl_download_data.annivs[i]; + data[0] = dl_pack_size(anp->label); + data[1] = anp->month; + data[2] = anp->day; + + if (data[0] != dl_pack_ascii(&data[3], anp->label)) + { + printf("ERROR Bad pack_ascii.\n"); + exit(-1); + } + + *data += 4; + + if (!_write_data + (ofd, buf, data, *data, &pnum, 1, wi)) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + } + + *buf += 2; + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + memcpy(buf, dend, *dend); + buf[2] = 1; + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + } + + if (wi->dl_device == DATALINK_IRONMAN && dl_download_data.chron) + { + /* The memdata is a where all the data is stored and when all the + * information to be sent that inclues the chron label and laps, and the + * phone data. The information is broken up into packets and sent one at + * a time. + */ + /* should be overkill, don't know the right value */ +#define maxdatasize 4096 + char memdata[maxdatasize] = { 0 }; + int p = 0; + int labelsize; + int packets; + int offset = 0; + int size; + + for (i = 0; i < dl_download_data.num_chron; i++) + { + memdata[p++] = 0; + memdata[p++] = 0xe; + memdata[p++] = 0; +#warning TODO has dl_download_data.chron[i].memused been initalized + memdata[p++] = dl_download_data.chron[i].memused; + memdata[p++] = + dl_download_data.chron[i].chron_laps; + if (dl_download_data.num_phones) + memdata[p++] = dl_download_data.num_phones; + else + memdata[p++] = 0; + dl_fill_pack_ascii(&memdata[p], + dl_download_data.chron[i].label, + dl_download_data.max_chron_str, + ' '); + p += 8; + } + + for (i = 0; i < dl_download_data.num_phones; i++) + { + pp = &dl_download_data.phones[i]; + labelsize = dl_pack_size(pp->label); + /* This is the size taken up by this phone entry, + * the size of the label + 6 for the digits and + * one for this byte + */ + memdata[p++] = labelsize + 7; + dl_pack_phone(&memdata[p], pp->number, + dl_download_data.max_phone_str); + p += 6; + + if (labelsize != + dl_pack_ascii(&memdata[p], pp->label)) + { + printf("ERROR Bad pack_ascii.\n"); + exit(-1); + } + p += labelsize; + } + + if (p > maxdatasize) + { + printf + ("Error buffer overflow, too much data or too small of buffer\n"); + exit(-1); + } + + /* set how many packets it will take to send the data, there are up + * to 32 bytes per packet, 27 of those are data bytes */ + packets = p / 27 + (p % 27 ? 1 : 0); + + /* packet before the one that lists how many data packets to send */ + memcpy(buf, pre60, *pre60); + dl_docrc(buf); + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + /* send the packet that lists how many data packets are to follow */ + memcpy(buf, numdatapackets, *numdatapackets); + buf[2] = packets; + dl_docrc(buf); + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + for (i = 0; i < packets; i++) + { + if (i < packets - 1) + buf[0] = 32; + else + buf[0] = p - 27 * (packets - 1) + 5; + size = buf[0] - 5; + buf[1] = 0x61; + buf[2] = i + 1; + buf[3] = i; + memcpy(&buf[3], &memdata[offset], size); + dl_docrc(buf); + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + offset += size; + } + + buf[0] = 4; + buf[1] = 0x62; + dl_docrc(buf); + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + /* + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return((*dl_error_proc)("Can't write to tmp file.")); + */ + for (i = 0; i < p; i++) + { +#ifdef DEBUGGING_FILE + printf(" 0x%0.2x", + 0xff & ((unsigned int) memdata[i])); +#endif /* DEBUGGING_FILE */ + if (!p % 8) + printf("\n"); + } + } + + /* timezone label packet for IRONMAN watch */ + if (wi->dl_device == DATALINK_IRONMAN) + for (i = 0; i < dl_download_data.num_times; i++) + { + p = 0; + buf[p++] = 8; + buf[p++] = 0x31; + + buf[p++] = dl_download_data.times[i].tz_num; + buf[p++] = + dl_pack_char(dl_download_data. + times[i].label[0]); + buf[p++] = + dl_pack_char(dl_download_data. + times[i].label[1]); + buf[p++] = + dl_pack_char(dl_download_data. + times[i].label[2]); + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write timezone label to tmp file.")); + } + + + + for (i = 0; i < dl_download_data.num_alarms; i++) + { + /* blank out buf with the blank_alarm data template, + * *blank_alarm gives the first byte of the alarm data + * and also the lenght which tells how much to copy + */ + memcpy(buf, blank_alarm, *blank_alarm); + buf[2] = dl_download_data.alarms[i].alarm_num; + buf[3] = dl_download_data.alarms[i].hours; + buf[4] = dl_download_data.alarms[i].minutes; + buf[5] = dl_download_data.alarms[i].month; + buf[6] = dl_download_data.alarms[i].day; + if (wi->dl_device == DATALINK_IRONMAN) + { + buf[7] = dl_download_data.alarms[i].audible; + dl_fill_pack_ascii(&buf[8], + dl_download_data. + alarms[i].label, + dl_download_data.max_alarm_str, + ' '); + buf[0] = 0x1a; + buf[1] = 0x50; + } else + { + dl_fill_pack_ascii(&buf[7], + dl_download_data. + alarms[i].label, + dl_download_data.max_alarm_str, + ' '); + buf[15] = dl_download_data.alarms[i].audible; + } + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + } + + for (i = 0; i < dl_download_data.num_timers; i++) + { + memcpy(buf, timer, *timer); + buf[2] = dl_download_data.timers[i].timer_num; + buf[3] = dl_download_data.timers[i].hours; + buf[4] = dl_download_data.timers[i].minutes; + buf[5] = dl_download_data.timers[i].second; + buf[6] = dl_download_data.timers[i].repeat; + buf[6] |= dl_download_data.timers[i].chron << 1; + + dl_fill_pack_ascii(&buf[7], + dl_download_data.timers[i].label, + dl_download_data.max_timer_str, ' '); + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + } + + if (dl_download_data.num_wristapp) + { + wristapp = dl_download_data.wristapp; + memcpy(buf, dstart, *dstart); + buf[2] = 2; + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + memcpy(buf, dinfo, *dinfo); + buf[2] = 2; + buf[3] = wristapp->len / (MAX_PCKT - 6); + + if (wristapp->len % (MAX_PCKT - 6)) + buf[3]++; + + buf[4] = 1; + *buf = 7; + + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + memcpy(buf, dspace, *dspace); + + if (wi->dl_device == DATALINK_70) + buf[1] = DATA_70; + + pnum = 1; + buf[2] = 2; + buf[3] = pnum++; + + if (!_write_data + (ofd, buf, wristapp->data, wristapp->len, &pnum, 2, + wi)) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + if (*buf != 4) + { + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + } + + memcpy(buf, dend, *dend); + buf[2] = 2; + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + } + + if (dl_download_data.num_melody) + { + melody = dl_download_data.melody; + memcpy(buf, dstart, *dstart); + buf[2] = 3; + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + memcpy(buf, dinfo, *dinfo); + buf[2] = 3; + buf[3] = melody->len / (MAX_PCKT - 6); + + if (melody->len % (MAX_PCKT - 6)) + buf[3]++; + + buf[4] = 0xff - melody->len; + *buf = 7; + + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + memcpy(buf, dspace, *dspace); + + if (wi->dl_device == DATALINK_70) + buf[1] = DATA_70; + + pnum = 1; + buf[2] = 3; + buf[3] = pnum++; + + if (!_write_data + (ofd, buf, melody->data, melody->len, &pnum, 3, wi)) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + if (*buf != 4) + { + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + } + + memcpy(buf, dend, *dend); + buf[2] = 3; + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + } + + if (dl_download_data.num_system) + { + sys = dl_download_data.system; + memcpy(buf, sysinfo, *sysinfo); + if (wi->dl_device == DATALINK_IRONMAN) + { + buf[0] = 5; + buf[1] = 0x32; + buf[2] = sys->chime; + buf[2] |= sys->beep << 1; + } else + { + buf[2] = sys->chime; + buf[3] = sys->beep; + } + + dl_docrc(buf); + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) + ("Can't write to tmp file.")); + + } + + memcpy(buf, end1, *end1); + dl_docrc(buf); + + if (write(ofd, buf, *buf) != *buf) + return ((*dl_error_proc) ("Can't write to tmp file.")); + + close(ofd); + + switch (type) + { + case BLINK_FILE: + ret = 0; + break; + case SVGA_BLINK: + + switch ((pid = fork())) + { + case -1: + return ((*dl_error_proc) + ("Could not execute svga blink engine.")); + return (-1); + case 0: /* Child */ + /* execute svgablink useing the version of + * exec that will search the users active path, + * if it isn't there (we can't run it). + */ + switch(wi->dl_device) + { + case DATALINK_IRONMAN: + protocol="-ironman"; + break; + case DATALINK_150: + protocol="-150"; + break; + case DATALINK_150S: + protocol="-150s"; + break; + case DATALINK_70: + protocol="-70"; + break; + default: + (*dl_error_proc) + ("Don't know what watch for svgablink."); + exit(-1); + } + execlp("svgablink", "svgablink", protocol, fname, NULL); + + (*dl_error_proc) + ("Could not execute svga blink engine."); + exit(-1); + default: + + if (waitpid(pid, &status, 0) < 0) + perror("waitpid"); + + (void) unlink(fname); + + if (WIFEXITED(status)) + ret = WEXITSTATUS(status); + else + ret = -1; + + break; + } + + break; + case SER_BLINK: + + switch ((pid = fork())) + { + case -1: + return ((*dl_error_proc) + ("Could not fork child for serial blink engine.")); + return (-1); + case 0: /* Child */ + /* execute serblink useing the version of + * exec that will search the users active path, + * if it isn't there (we can't run it). + */ + execlp("serblink", "serblink", fname, NULL); + + + (*dl_error_proc) + ("Could not execute serial blink engine."); + exit(-1); + default: + + if (waitpid(pid, &status, 0) < 0) + perror("waitpid"); + + (void) unlink(fname); + + if (WIFEXITED(status)) + ret = WEXITSTATUS(status); + else + ret = -1; + + break; + } + + break; + } + + return (ret); +} diff --git a/dl_set_error.c b/dl_set_error.c new file mode 100644 index 0000000..17268c4 --- /dev/null +++ b/dl_set_error.c @@ -0,0 +1,27 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "datalink.h" + +void dl_set_error(int (*func)()) +{ + dl_error_proc = func; +} diff --git a/dl_set_warn.c b/dl_set_warn.c new file mode 100644 index 0000000..7c4aebb --- /dev/null +++ b/dl_set_warn.c @@ -0,0 +1,27 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "datalink.h" + +void dl_set_warn(int (*func) ()) +{ + dl_warn_proc = func; +} diff --git a/dl_sizeof_item.c b/dl_sizeof_item.c new file mode 100644 index 0000000..0cdb22b --- /dev/null +++ b/dl_sizeof_item.c @@ -0,0 +1,103 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <string.h> +#include "datalink.h" +#include "datalink_private.h" + +int dl_sizeof_item(WatchInfoPtr wi, ItemPtr item) +{ + int size; + int l; + + switch (item->type) + { + case DL_TIME_TYPE: + size = 0; + break; + case DL_ALARM_TYPE: + size = 0; + break; + case DL_APP_TYPE: + l = strlen(item->data.app.label); + + if (l > wi->max_str) + { + + + (void) (*dl_warn_proc) ("Appointment label too long."); + l = wi->max_str; + } + + size = dl_pack_size(item->data.app.label) + 4; + break; + case DL_PHONE_TYPE: + l = strlen(item->data.app.label); + + if (l > wi->max_str) + { + (void) (*dl_warn_proc) ("Phone label too long."); + l = wi->max_str; + } + + size = dl_pack_size(item->data.app.label) + 1; + size += wi->max_phone_str / 2; + break; + case DL_TODO_TYPE: + l = strlen(item->data.app.label); + + if (l > wi->max_str) + { + (void) (*dl_warn_proc) ("Todo label too long."); + l = wi->max_str; + } + + size = dl_pack_size(item->data.app.label) + 2; + break; + case DL_ANNIV_TYPE: + l = strlen(item->data.app.label); + + if (l > wi->max_str) + { + + + (void) (*dl_warn_proc) ("Anniversary label too long."); + l = wi->max_str; + } + + size = dl_pack_size(item->data.app.label) + 4; + break; + case DL_SYSTEM_TYPE: + size = 0; + break; + case DL_WRISTAPP_TYPE: + size = 0; + break; + case DL_MELODY_TYPE: + size = 0; + break; + default: + size = 0; + (void) (*dl_error_proc) ("Unknown type"); + } + + return (size); +} diff --git a/dl_sizeof_list.c b/dl_sizeof_list.c new file mode 100644 index 0000000..9324ddd --- /dev/null +++ b/dl_sizeof_list.c @@ -0,0 +1,34 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "datalink.h" +#include "datalink_private.h" + +int dl_sizeof_list(WatchInfoPtr wi, ListPtr list) +{ + ItemPtr ip; + int size = 0; + + for (ip = list->first; ip; ip = ip->next) + size += dl_sizeof_item(wi, ip); + + return (size); +} diff --git a/dl_sort.c b/dl_sort.c new file mode 100644 index 0000000..729158e --- /dev/null +++ b/dl_sort.c @@ -0,0 +1,83 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <stdlib.h> +#include "datalink.h" + +int dl_sort(ListPtr list, int (*cmp_proc) ()) +{ + ListPtr nl; + ItemPtr ip; + ItemPtr ni; + ItemPtr si; + ItemPtr pi; + + if ((nl = dl_new_list()) == NULL) + return ((*dl_error_proc) ("List alloc error.")); + + for (ip = list->first; ip; ip = ni) + { + ni = ip->next; + + for (pi = NULL, si = nl->first; si; si = si->next) + { + + if ((*cmp_proc) (ip, si) >= 0) + { + pi = si; + continue; + } + + if (pi) + { + ip->next = pi->next; + pi->next = ip; + } else + { + ip->next = nl->first; + nl->first = ip; + } + + nl->count++; + + if (!nl->last) + { + nl->last = ip; + ip->next = NULL; + } + + break; + + } + + if (!si) + { + dl_add_to_list(nl, ip); + ip->next = NULL; + } + + } + + list->first = nl->first; + list->last = nl->last; + free(nl); + return 0; +} diff --git a/dl_string_ok.c b/dl_string_ok.c new file mode 100644 index 0000000..b57f12f --- /dev/null +++ b/dl_string_ok.c @@ -0,0 +1,44 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <string.h> +#include "datalink.h" + +int dl_string_ok(char *string, int maxl) +{ + int i; + int l; + + l = strlen(string); + + if (l > maxl) + return (0); + + for (i = 0; i < l; i++) + { + + if (string[i] < ' ' || string[i] > '~') + return (0); + + } + + return (1); +} diff --git a/dl_todo_by_label.c b/dl_todo_by_label.c new file mode 100644 index 0000000..44d2f1c --- /dev/null +++ b/dl_todo_by_label.c @@ -0,0 +1,28 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <string.h> +#include "datalink.h" + +int dl_todo_by_label(ItemPtr a, ItemPtr b) +{ + return (strcmp(a->data.todo.label, b->data.todo.label)); +} diff --git a/dl_todo_by_prio.c b/dl_todo_by_prio.c new file mode 100644 index 0000000..c46c8f3 --- /dev/null +++ b/dl_todo_by_prio.c @@ -0,0 +1,27 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include "datalink.h" + +int dl_todo_by_prio(ItemPtr a, ItemPtr b) +{ + return (a->data.todo.priority - b->data.todo.priority); +} diff --git a/dl_write_save.c b/dl_write_save.c new file mode 100644 index 0000000..feeea86 --- /dev/null +++ b/dl_write_save.c @@ -0,0 +1,153 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <stdio.h> +#include <unistd.h> + +#include "datalink.h" +#include "datalink_private.h" + +int dl_write_save(char *datafile, char *wristappfile, char *melodyfile) +{ + FILE *fp; + char bakfile[1024]; + int last_warn = 0; + TimePtr tip; + AlarmPtr alp; + AppointmentPtr ap; + ToDoPtr tp; + PhonePtr pp; + AnniversaryPtr anp; + SystemPtr sp; + int hour, min; + int i; + +/* Create backup of old datafile. */ + + sprintf(bakfile, "%s.bak", datafile); + (void) unlink(bakfile); + + if (link(datafile, bakfile) < 0) + last_warn = (*dl_warn_proc) ("Could not make backup."); + + (void) unlink(datafile); + + if ((fp = fopen(datafile, "w")) == NULL) + return ((*dl_error_proc) ("Could not write save file.")); + + fprintf(fp, + "# Data Link save file created by the datalink library.\n\n"); + +/* Save each type of data. */ + + for (i = 0; i < dl_download_data.num_times; i++) + { + tip = &dl_download_data.times[i]; + fprintf(fp, "timezone = %d, \"%s\", %d, %d, %d\n", + tip->tz_num, tip->label, tip->offset, + tip->hour_fmt, tip->date_fmt); + } + + if (dl_download_data.num_times) + fprintf(fp, "\n"); + + for (i = 0; i < dl_download_data.num_alarms; i++) + { + alp = &dl_download_data.alarms[i]; + fprintf(fp, + "alarm = %d, %02d/%02d, %02d:%02d, \"%s\", %d\n", + alp->alarm_num, alp->month, alp->day, alp->hours, + alp->minutes, alp->label, alp->audible); + } + + if (dl_download_data.num_alarms) + fprintf(fp, "\n"); + + for (i = 0; i < dl_download_data.num_apps; i++) + { + ap = &dl_download_data.apps[i]; + min = 0; + + for (i = 1; i < 0xFF; i <<= 1) + { + + if ((i & ap->time)) + min += i * 15; + + } + + hour = min / 60; + min = hour * 60; + + fprintf(fp, "appointment = %02d/%02d, %02d:%02d, \"%s\"\n", + ap->month, ap->day, hour, min, ap->label); + } + + if (dl_download_data.num_apps) + fprintf(fp, "\n"); + + for (i = 0; i < dl_download_data.num_todos; i++) + { + tp = &dl_download_data.todos[i]; + fprintf(fp, "todo = %d, \"%s\"\n", tp->priority, + tp->label); + } + + if (dl_download_data.num_todos) + fprintf(fp, "\n"); + + for (i = 0; i < dl_download_data.num_phones; i++) + { + pp = &dl_download_data.phones[i]; + fprintf(fp, "phone = \"%s\", \"%s\"\n", pp->number, + pp->label); + } + + if (dl_download_data.num_phones) + fprintf(fp, "\n"); + + for (i = 0; i < dl_download_data.num_annivs; i++) + { + anp = &dl_download_data.annivs[i]; + fprintf(fp, "anniversary = %02d/%02d, \"%s\"\n", + anp->month, anp->day, anp->label); + } + + if (dl_download_data.num_annivs) + fprintf(fp, "\n"); + + for (i = 0; i < dl_download_data.num_system; i++) + { + sp = &dl_download_data.system[i]; + fprintf(fp, "system = %d, %d\n", sp->chime, sp->beep); + } + + if (dl_download_data.num_system) + fprintf(fp, "\n"); + + if (wristappfile && *wristappfile) + fprintf(fp, "wristapp = \"%s\"\n\n", wristappfile); + + if (melodyfile && *melodyfile) + fprintf(fp, "melody = \"%s\"\n\n", melodyfile); + + return (last_warn); +} diff --git a/doc/datalink.ps b/doc/datalink.ps new file mode 100644 index 0000000..91c9798 --- /dev/null +++ b/doc/datalink.ps @@ -0,0 +1,228 @@ +%!PS-Adobe-2.0 +%%Title: datalink.fig +%%Creator: fig2dev Version 3.1 Patchlevel 1 +%%CreationDate: Sat Oct 12 15:13:51 1996 +%%For: protius@keman (Tommy Johnson,Ivers 226,4192,4192) +%%Orientation: Portrait +%%BoundingBox: 47 168 565 623 +%%Pages: 1 +%%BeginSetup +%%IncludeFeature: *PageSize Letter +%%EndSetup +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {} def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +-79.0 661.5 translate +1 -1 scale + +/clp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/l {lineto} bind def +/m {moveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def +%%EndProlog + +$F2psBegin +10 setmiterlimit + 0.06000 0.06000 sc +/Times-Roman findfont 180.00 scalefont setfont +2325 8175 m +gs 1 -1 sc (Drawn with XFig 3.1 patch level 4. ) col-1 show gr +7.500 slw +% Polyline +n 2850 1650 m 3900 1650 l gs col-1 s gr +% Polyline +n 2850 2100 m 3900 2100 l gs col-1 s gr +% Polyline +n 2850 2550 m 3900 2550 l gs col-1 s gr +% Polyline +n 3900 1650 m 3900 2550 l gs col-1 s gr +% Polyline +n 3900 1650 m 4950 1650 l 4950 2625 l gs col-1 s gr +% Polyline +n 4800 2625 m 5100 2625 l gs col-1 s gr +% Polyline +n 4800 2625 m 4950 2850 l 5100 2625 l gs col-1 s gr +% Polyline +n 4800 2850 m 5100 2850 l gs col-1 s gr +% Polyline +n 4950 2850 m 4950 3375 l 4725 3600 l gs col-1 s gr +% Polyline +n 4725 3750 m 4950 3975 l gs col-1 s gr +% Polyline +n 4725 3450 m 4725 3525 l 4725 3900 l gs col-1 s gr +% Polyline +n 4725 3675 m 3975 3675 l gs col-1 s gr +% Polyline +n 3975 3675 m 3900 3600 l 3825 3750 l 3750 3600 l 3675 3750 l 3600 3600 l + 3525 3750 l 3450 3675 l gs col-1 s gr +% Polyline +n 3450 3675 m 2925 3675 l gs col-1 s gr +% Polyline +n 4275 3675 m 4275 4125 l gs col-1 s gr +% Polyline +n 4125 4125 m 4425 4125 l gs col-1 s gr +% Polyline +n 4125 4200 m 4425 4200 l gs col-1 s gr +% Polyline +n 4275 4200 m 4275 4500 l 4950 4500 l gs col-1 s gr +% Polyline +n 4950 3975 m 4950 4950 l 2925 4950 l gs col-1 s gr +% Polyline +n 4875 3900 m 4800 3900 l gs col-1 s gr +% Polyline +n 4875 3900 m 4875 3825 l gs col-1 s gr +/Times-Roman findfont 180.00 scalefont setfont +2400 1725 m +gs 1 -1 sc (DSR) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2400 2175 m +gs 1 -1 sc (CD) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2400 2625 m +gs 1 -1 sc (DTR) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2400 3750 m +gs 1 -1 sc (TD) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2400 5025 m +gs 1 -1 sc (GND) col-1 show gr +/Times-Roman findfont 150.00 scalefont setfont +3600 3525 m +gs 1 -1 sc (10K) col-1 show gr +/Times-Roman findfont 150.00 scalefont setfont +3825 4275 m +gs 1 -1 sc (1uf) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2400 6225 m +gs 1 -1 sc (The data is transmitted at 115200 bps, well above the) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2400 6450 m +gs 1 -1 sc (Timex baud rate, to allow the rather odd word format to) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2400 6675 m +gs 1 -1 sc (be generated. However the start bits of the 115200) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2400 6900 m +gs 1 -1 sc (data are still present, and confuse the watch. So the) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2400 7125 m +gs 1 -1 sc (resistor and capacitor filter out the start bits, which) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2400 7350 m +gs 1 -1 sc (are much shorter than the real data bits.) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2400 5775 m +gs 1 -1 sc (Theory: ) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +2400 6000 m +gs 1 -1 sc (Tie DSR, CD, DTR togather to form a null-modem.) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6675 4425 m +gs 1 -1 sc (Timex and Datalink are registered trademarks) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6675 4650 m +gs 1 -1 sc (of the Timex Corp.) col-1 show gr +/Times-Roman findfont 150.00 scalefont setfont +5175 2850 m +gs 1 -1 sc (LED) col-1 show gr +/Times-Roman findfont 360.00 scalefont setfont +2100 900 m +gs 1 -1 sc (Extra Cheesy Timex Datalink) col-1 show gr +/Times-Roman findfont 360.00 scalefont setfont +2700 1320 m +gs 1 -1 sc (Serial Port Interface) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6675 2025 m +gs 1 -1 sc (Developed by Tommy Johnson) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6675 2250 m +gs 1 -1 sc (See http://csgrad.cs.vt.edu/~tjohnson/ for more) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6675 2475 m +gs 1 -1 sc (info.) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6675 2850 m +gs 1 -1 sc (I am not affiliated with Timex. This was developed) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6675 3075 m +gs 1 -1 sc (without support from Timex. They DO NOT support) col-1 show gr +/Times-Roman findfont 180.00 scalefont setfont +6675 3300 m +gs 1 -1 sc (it, DO NOT ask them questions about it.) col-1 show gr +% Ellipse +n 4725 3675 300 300 0 360 DrawEllipse gs col-1 s gr + +showpage +%%Page: 1 1 +$F2psEnd +restore diff --git a/doc/usage b/doc/usage new file mode 100644 index 0000000..5c60df9 --- /dev/null +++ b/doc/usage @@ -0,0 +1,115 @@ +#include <datalink.h> + +WatchInfoPtr dl_init_watch(int which_watch); + + which_watch is currently only DATALINK_150; + + returns a pointer to a new WatchInfo pointer, NULL on error. If there + is an error, dl_error_proc will also be called. dl_error_proc can be + set with dl_set_error + +ItemPtr dl_new_item(WatchInfoPtr wi, int type); + + wi is the WatchInfoPtr returned by dl_init_watch. + type can be one of + DL_TIME_TYPE for time packet + DL_ALARM_TYPE for alarm packet + DL_APP_TYPE for appointment packet + DL_PHONE_TYPE for phone packet + DL_TODO_TYPE for todo packet + DL_ANNIV_TYPE for anniversary packet + DL_SYSTEM_TYPE for system packet + DL_WRISTAPP_TYPE for wristapp packet + DL_MELODY_TYPE for melody packet + + dl_new_item allocate an item structure and initializes it with the item + type supplied. + + returns a pointer to a new item, NULL on error. If there is an error, + dl_error_proc will also be called. dl_error_proc can be set with + dl_set_error + +int dl_init_download(WatchInfoPtr wi, List times, List alarms, + List apps, List phones, List todos, List annivs, + List system, List wristapp, List melody); + + wi is the WatchInfoPtr returned by dl_init_watch. times is the list + of times to download. alarams is the list of alarms to download, apps + is the list of appointments to download, phones is the list of phone + numbers to download, todos is the list of todo items to download, + annivs is the list of anniversaries to download, system is the list of + system data to download, wristapp is the list of wristapps to download + and melody is the list of melodies to download. Currently, system, + wristapp and melody can only be a list of 1 item. + + dl_init_download will check the validity of the data being + downloaded to the watch. If everything is ready for the download, + dl_init_download will copy all of the data in preparation for a call + to dl_send_data. + + If there are any problems with the data, depending on the severity, + dl_error_proc or dl_warn_proc will be called and the value of that + call will be retuned from dl_init_download. + +int dl_send_data(int device); + + device is the type of output device to use in the download to + (SVGA_BLINK, SER_BLINK, PACKET_FILE). + + dl_send_data will send the data prepared by dl_init_download using the + the selected blink engine. On error dl_error_proc is called and its + return value is returned. + +int dl_sizeof_item(ItemPtr item); + + item is the item that you want to get a size of. The size is how + much of the database space in the watch that will be taken up by the + item. For Time, Alarm, System, WristApp, and Melody packets, the size + is 0. + +int dl_sizeof_list(List list); + + list is a list of item that you want to get a size of. The size is how + much of the database space in the watch that will be taken up by the + item. For Time, Alarm, System, WristApp, and Melody packets, the size + is 0. + +int dl_item_ok(WatchInfoPtr wi, ItemPtr item); + + wi is the WatchInfoPtr returned by dl_init_watch. times is the list + item is the item returned from dl_new_item that has had the data + portion filled by the calling application. + + returns 1 if the item is OK, 0 otherwise. + +void dl_free_download() + + free up space allocated for a download by dl_init_download. + +WatchInfoPtr dl_read_save(char *file, ListPtr *alarms, ListPtr *apps, + ListPtr *phones, ListPtr *todos, ListPtr *annivs, ListPtr *system, + ListPtr *wristapp, ListPtr *melody); + + Initialize a watch structure with the contects of file. Return a watch + info structure and the lists. + +int dl_write_save(char *file, char *wristappfile, char *melodyfile); + + Save the contents of a download to a reloadable file. dl_write_save + must be called after dl_init_download. file is the file to write the + save to. wristappfile is the file that the selected wristapp can be + read from. melodyfile is the file that the selected melody scheme can + be read from. + +int dl_pack_ascii(char *to, char *from); + + Pack the characters in from into to using the watch character set. + +void dl_pack_fill_ascii(char *to, char *from, int size, char fill); + + Pack the characters in from into to using the watch character + set. This is packed one character perl byte (unlike dl_pack_ascii). + +char dl_pack_char(char c); + + Convert c into the watch characters set. diff --git a/send_data.c b/send_data.c new file mode 100644 index 0000000..1e91d4a --- /dev/null +++ b/send_data.c @@ -0,0 +1,93 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <unistd.h> +#include <stdio.h> +#include <vga.h> +#include "datalink.h" +#include "datalink_macros.h" + +int send_data(int type, unsigned char **packets, int npckts) +{ + int i; + register int j; + register unsigned char byte; + unsigned char white[80]; + unsigned char black[80]; + int inc = (type == DATALINK_70) ? 1 : 2; + + for (i = 0; i < 80; i++) + { + white[i] = 0xff; + black[i] = 0x00; + } + +/* Become root to set vga mode. */ + seteuid(0); + vga_init(); + +/* This is redundant - vga_init() should do this itself... */ +/* but there's no harm in being sure */ + seteuid(getuid()); + +#ifdef MACH64_HACK +/* For some reason, the latest mach 64 svga driver requires root on the + next call even though vga_init gave up root privileges. */ + seteuid(0); +#endif + vga_setmode(G640x480x2); +#ifdef MACH64_HACK + seteuid(getuid()); +#endif + + SYNC DATASTART for (i = 0; i < npckts; i++) + { + + for (j = 0; j <= *packets[i]; j += inc) + { + vga_waitretrace(); + byte = packets[i][j]; + WRITE_BYTE1(1, byte) if (type == DATALINK_70) + continue; + + if (j + 1 == packets[i][0]) + WRITE_BYTE2(0, 0xff) + else + { + byte = packets[i][j + 1]; + WRITE_BYTE2(1, byte)} + + } + + END_PACKET} + +#ifdef MACH64_HACK +/* For some reason, the latest mach 64 svga driver requires root on the + next call even though vga_init gave up root privileges. */ + seteuid(0); +#endif + vga_setmode(TEXT); +#ifdef MACH64_HACK + seteuid(getuid()); +#endif + + return 0; +} diff --git a/serblink.1 b/serblink.1 new file mode 100644 index 0000000..1e5c748 --- /dev/null +++ b/serblink.1 @@ -0,0 +1,51 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH DATALINK 1 "December 1, 2001" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp <n> insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +svgablink, serblink \- programs to send raw data to your Timex Datalink watch +.SH SYNOPSIS +.B svgablink +.RI <DATA_FILE> +.br +.B serblink +.RI <DATA_FILE> +.SH DESCRIPTION +This manual page documents briefly the +.B svgablink +and +.B serblink +commands. +This manual page was written for the Debian GNU/Linux distribution +because the original programs do not have manual pages. +.PP +.\" TeX users may be more comfortable with the \fB<whatever>\fP and +.\" \fI<whatever>\fP escape sequences to invode bold face and italics, +.\" respectively. +\fBsvgablink\fP and \fBserblink\fP are programs that send data to the +screen or serial transmitter (respectively) to communicate with a Timex +Datalink watch. They are used by the programs "setwatch" and "settime". +.SH "SEE ALSO" +setwatch(1), settime(1). +.SH AUTHOR +The original datalink software was written by Karl R. Hakimian. +.PP +David Fries <dfries@mail.win.org> added support for the Ironman Datalink to +the datalink software and now is the maintainer. http://datalink.fries.net/ +is the current home. +.PP +This manual page was written by Steaphan Greene <stea@cs.binghamton.edu>, +for the Debian GNU/Linux system (but may be used by others). diff --git a/serblink.c b/serblink.c new file mode 100644 index 0000000..9ca9fdc --- /dev/null +++ b/serblink.c @@ -0,0 +1,208 @@ +/* + * Copyright 1996-2002 - Tommy Johnson <tjohnson@bobdbob.com> + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * Unix implementation of the Timex Datalink protocol using an LED on a serial + * port. (see datalink.ps) + * + * See http://csgrad.cs.vt.edu/~tjohnson/ for more info. + */ + +#include <unistd.h> +#include <stdio.h> +#include <fcntl.h> +#include <stdlib.h> +#include <termios.h> +#include <string.h> + +#include <sys/time.h> +#include <sys/resource.h> + +#ifdef linux +#define cfsetspeed cfsetospeed +#endif + +#ifndef PORT +#define PORT "/dev/ttyd1" +#endif + +void sendbyte(int fil, unsigned char dat) +#define ZERO "\0xff\0\0\0\0\0" +#define ONE "\0\0\0\0\0\0" +#define LEN 6 +{ + static int frame = 0; + char buff[1024]; + int c = 0; + int i; + memcpy(&buff[c], ZERO, LEN); + c += LEN; + for (i = 0; i < 8; i++) + { + memcpy(&buff[c], (dat & 1) ? ONE : ZERO, LEN); + c += LEN - (i & 1); /* CHEESY! the baud rate dosn't quite */ + /* match, so alternate too long and too */ + /* short. */ + dat >>= 1; /* and... IT WORKS... (shudder) */ + } + for (i = 0; i < (frame ? 12 : 4); i++) + { + memcpy(&buff[c], ONE, LEN); + c += LEN; + } + frame = !frame; /* a frame is 2 words, which would have been on */ + /* a single CRT frame (different inter-word pause) */ + + write(fil, buff, c); +} + +/* For pauses between packets: */ +static void __pause(int fil, int count) +{ + char buff[8192]; + int i, c; + + c = 0; + for (i = 0; i < (count * LEN); i++) + buff[c++] = 0x0; + write(fil, buff, c); +} + +#undef ZERO +#undef ONE +#undef LEN + +int main(int argc, char **argv) +{ + int port; + int data; + struct termios old, new; + int i, j, len, plen; + unsigned char buff[4096]; + char fil[1024]; + char device[1024]; + + setpriority(PRIO_PROCESS, 0, -20); /* pauses will screwup the timing */ + + strcpy(fil, "DEBUGOUTPUT"); + strcpy(device, PORT); /* defaults */ + +#ifdef OTHERCMDLINE + while ((c = getopt(argc, argv, "h?d:f:")) != -1) + { + switch (c) + { + case 'h': + case '?': + fprintf(stderr, + "%s [-d device] [-f file]\n" + "Transmitt a file to a Timex Datalink watch useing an LED on a serial\n" + "port. Timex does not support this product, DO NOT ask them questions about\n" + "it. See http://csgrad.cs.vt.edu/~tjohnson/ for more info.\n" + "Version $Id: serblink.c,v 1.6 2002/07/10 04:14:22 david Exp $\n", + argv[0]); + exit(0); + break; + case 'd': + strcpy(device, optarg); + break; + case 'f': + strcpy(fil, optarg); + break; + } + } +#else + if (argc == 2) + strcpy(fil, argv[1]); + else + { + fprintf(stderr, + "%s file\nTransmitt a file to a Timex Datalink watch useing an LED on a serial\n" + "port. Timex does not support this product, DO NOT ask them questions about\n" + "it. See http://csgrad.cs.vt.edu/~tjohnson/ for more info.\n" + "Version $Id: serblink.c,v 1.6 2002/07/10 04:14:22 david Exp $\n", + argv[0]); + exit(0); + } +#endif + + data = open(fil, O_RDONLY); + if (!data) + { + perror("open datafile failed:"); + exit(1); + } + len = read(data, buff, 4096); + close(data); + printf("data length:%d\n", len); + + port = open(device, O_RDWR); + if (port < 0) + { + perror("open of device failed:"); + exit(1); + } + + if (tcgetattr(port, &old) < 0) + { + perror("tcgetattr failed:"); + exit(1); + } + new = old; + cfsetspeed(&new, B115200); + if (tcsetattr(port, TCSANOW, &new) < 0) + { + perror("tcsetattr failed:"); + exit(1); + } +#if 0 + while (1) + __pause(port, 20); /* used for hardware debugging */ +#endif + printf("sync1\n"); + for (i = 0; i < 500; i++) + { + sendbyte(port, 0x55); + if (!(i % 100)) + printf("%d\n", 5 - (i / 100)); + } + for (i = 0; i < 50; i++) + sendbyte(port, 0xAA); + printf("sync2\n"); + i = 0; + do + { + plen = buff[i]; + printf("%d\n", plen); + for (j = 0; j < plen; j++) + sendbyte(port, buff[i++]); + if (plen & 1) + sendbyte(port, 0); + __pause(port, 240); + } + while (i < len); + + __pause(port, 240); + tcsetattr(port, TCSADRAIN, &new); + sleep(1); + close(port); + return 0; +} diff --git a/settime.1 b/settime.1 new file mode 100644 index 0000000..31a065a --- /dev/null +++ b/settime.1 @@ -0,0 +1,77 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH DATALINK 1 "December 1, 2001" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp <n> insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +setwatch, settime \- programs to send data to your Timex Datalink watch +.SH SYNOPSIS +.B setwatch +.RI [ WATCH_TYPE ]\ [ OPTIONS ]\ [ DATAFILE ] +.br +.B settime +.RI [ WATCH_TYPE ] +.SH DESCRIPTION +This manual page documents briefly the +.B setwatch +and +.B settime +commands. +This manual page was written for the Debian GNU/Linux distribution +because the original programs do not have manual pages. +.PP +.\" TeX users may be more comfortable with the \fB<whatever>\fP and +.\" \fI<whatever>\fP escape sequences to invode bold face and italics, +.\" respectively. +\fBsetwatch\fP is the main program in the datalink suite that can send +data to your Timex Datalink watch. It can send all types of data used +by these watches. +.PP +\fBsettime\fP is a simple utility that will just update the time on your +watch. It will only accept a watch-type argument (defaulting to +-ironman) and sends just the time. +.SH WATCH_TYPE +.TP +.B \-\-help +Show summary of options. +.TP +.B \-ironman +Use if you have an Ironman Datalink watch. This is the default. +.TP +.B \-70, \-\-model70 +Use if you have a model 70 watch. +.TP +.B \-150s, \-\-model150 +Use if you have a model 150 watch. +.TP +.B \-150, \-\-model150s +Use if you have a model 150s watch. +.SH OPTIONS +Run "setwatch -help" for options summary. +.SH DATAFILE +By default, the datafile will be loaded from ~/.datalink/datafile. Just +copy the example file (/usr/doc/datalink/datafile) to this location and +edit it as you please before running setwatch. Note that if you specify +no options, nothing will happen. Perhaps you want to try the -all +option to start. +.SH AUTHOR +The original datalink software was written by Karl R. Hakimian. +.PP +David Fries <dfries@mail.win.org> added support for the Ironman Datalink to +the datalink software and now is the maintainer. http://datalink.fries.net/ +is the current home. +.PP +This manual page was written by Steaphan Greene <stea@cs.binghamton.edu>, +for the Debian GNU/Linux system (but may be used by others). diff --git a/settime.c b/settime.c new file mode 100644 index 0000000..7361599 --- /dev/null +++ b/settime.c @@ -0,0 +1,156 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* settime: Example of Linux SDK for Timex watch. */ +/* Written by Karl R. Hakimian 10/3/96 */ +/* */ +/* Now warranty expressed or implied, use it as you see fit. */ + /* + * + * Modified by David Fries <dfries@mail.win.org> 7/11/99 + * - Added support for the Timex Datalink Ironman Triathlon + */ + +#include <stdio.h> +#include <time.h> +#include <stdlib.h> +#include <string.h> +#include "datalink.h" + +extern char *tzname[]; + +int set_time(WatchInfoPtr wi) +{ + time_t now; + struct tm *now_s; + ListPtr times; + ItemPtr tp; + int isdst; + + now = time(NULL) + 9; /* Offset for sending to watch. */ + now_s = localtime(&now); + isdst = (now_s->tm_isdst > 0) ? 1 : 0; + + times = dl_new_list(); + times->download = 1; + tp = dl_new_item(wi, DL_TIME_TYPE); + + tp->data.time.hours = now_s->tm_hour; + tp->data.time.minutes = now_s->tm_min; + tp->data.time.seconds = now_s->tm_sec; + tp->data.time.month = now_s->tm_mon + 1; + tp->data.time.day = now_s->tm_mday; + tp->data.time.year = now_s->tm_year; +/* TODO: investigate, see change log */ + tp->data.time.dow = (now_s->tm_wday + 6) % 7; + tp->data.time.hour_fmt = 1; + tp->data.time.download = 1; + tp->data.time.label = tzname[isdst]; + dl_add_to_list(times, tp); + + if (isdst) + now -= 60 * 60; + else + now += 60 * 60; + + now_s = localtime(&now); + + tp = dl_new_item(wi, DL_TIME_TYPE); + + tp->data.time.hours = now_s->tm_hour; + tp->data.time.minutes = now_s->tm_min; + tp->data.time.seconds = now_s->tm_sec; + tp->data.time.month = now_s->tm_mon + 1; + tp->data.time.day = now_s->tm_mday; + tp->data.time.year = now_s->tm_year; +/* TODO: investigate, see change log */ + tp->data.time.dow = (now_s->tm_wday + 6) % 7; + tp->data.time.hour_fmt = 1; + tp->data.time.download = 1; + tp->data.time.label = tzname[1 - isdst]; + dl_add_to_list(times, tp); + + dl_init_download(wi, times, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL); + return (0); +} + +int my_error_proc(char *msg) +{ + fprintf(stderr, "ERROR: %s\n", msg); + exit(-1); +} + +int my_warn_proc(char *msg) +{ + fprintf(stderr, "WARNING: %s\n", msg); + return (0); +} + +int main( int argc, char ** argv) +{ + WatchInfoPtr wi; + +/* + Use my error proc to exit on error and my warn proc to ignore warnings +*/ + dl_set_error(my_error_proc); + dl_set_warn(my_error_proc); + + if(argc==2) + { + if(!strcmp("-model70",argv[1])||!strcmp("-70",argv[1])) + wi = dl_init_watch(DATALINK_70); + else + if(!strcmp("-model150",argv[1])||!strcmp("-150",argv[1])) + wi = dl_init_watch(DATALINK_150); + else + if(!strcmp("-model150s",argv[1])||!strcmp("-150s",argv[1])) + wi = dl_init_watch(DATALINK_150S); + else + if(!strcmp("-ironman",argv[1])) + wi = dl_init_watch(DATALINK_IRONMAN); + else + { + printf("Usage: %s [ -model70 | -70 | -model70 | " + "-150 | -model150 | -model150s | -150s |" + " -ironman]\nVersion " + "$Id: settime.c,v 1.13 2002/07/10 04:23:23 david Exp $\n", argv[0]); + printf("The default is -model150 " + "if none is specified\n"); + exit(1); + } + } + else + { + wi = dl_init_watch(DATALINK_IRONMAN); + } +/* + Set the time. +*/ + if (set_time(wi)) + exit(-1); +/* + Send it to the watch +*/ + dl_send_data(wi, SVGA_BLINK); + return 0; +} diff --git a/setwatch.1 b/setwatch.1 new file mode 100644 index 0000000..8efdfe7 --- /dev/null +++ b/setwatch.1 @@ -0,0 +1,77 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH DATALINK 1 "December 1, 2001" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp <n> insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +setwatch, settime \- programs to send data to your Timex Datalink watch +.SH SYNOPSIS +.B setwatch +.RI [ WATCH_TYPE ]\ [ OPTIONS ]\ [ DATAFILE ] +.br +.B settime +.RI [ WATCH_TYPE ] +.SH DESCRIPTION +This manual page documents briefly the +.B setwatch +and +.B settime +commands. +This manual page was written for the Debian GNU/Linux distribution +because the original programs do not have manual pages. +.PP +.\" TeX users may be more comfortable with the \fB<whatever>\fP and +.\" \fI<whatever>\fP escape sequences to invode bold face and italics, +.\" respectively. +\fBsetwatch\fP is the main program in the datalink suite that can send +data to your Timex Datalink watch. It can send all types of data used +by these watches. +.PP +\fBsettime\fP is a simple utility that will just update the time on your +watch. It will only accept a watch-type argument (defaulting to +-ironman) and sends just the time. +.SH WATCH_TYPE +.TP +.B \-\-help +Show summary of options. +.TP +.B \-ironman +Use if you have an Ironman Datalink watch. This is the default. +.TP +.B \-70, \-\-model70 +Use if you have a model 70 watch. +.TP +.B \-150s, \-\-model150 +Use if you have a model 150 watch. +.TP +.B \-150, \-\-model150s +Use if you have a model 150s watch. +.SH OPTIONS +Run "setwatch -help" for options summary. +.SH DATAFILE +By default, the datafile will be loaded from ~/.datalink/datafile. Just +copy the example file (perhaps installed as /usr/doc/datalink/datafile?) +to this location and edit it as you please before running setwatch. +Note that if you specify no options, nothing will happen. Perhaps you +want to try the -all option to start. +.SH AUTHOR +The original datalink software was written by Karl R. Hakimian. +.PP +David Fries <dfries@mail.win.org> added support for the Ironman Datalink to +the datalink software and now is the maintainer. http://datalink.fries.net/ +is the current home. +.PP +This manual page was written by Steaphan Greene <stea@cs.binghamton.edu>, +for the Debian GNU/Linux system (but may be used by others). diff --git a/setwatch.c b/setwatch.c new file mode 100644 index 0000000..93a9364 --- /dev/null +++ b/setwatch.c @@ -0,0 +1,444 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * setwatch: Example of Linux SDK for Timex watch. + * Written by Karl R. Hakimian 10/3/96 + * + * Modified by David Fries <dfries@mail.win.org> 7/11/99 + * - Added support for the Timex Datalink Ironman Triathlon + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <sys/time.h> +#include <unistd.h> +#include <datalink.h> + +int my_error_proc(char *msg) +{ + fprintf(stderr, "ERROR: %s\n", msg); + exit(-1); +} + +int my_warn_proc(char *msg) +{ + fprintf(stderr, "WARNING: %s\n", msg); + return (0); +} + +ListPtr set_time(WatchInfoPtr wi, ListPtr times) +{ + time_t now; + time_t tztime; + struct tm *time_s; + ItemPtr tp; + int isdst; + int i; + + now = time(NULL) + wi->time_adjust; /* Offset for sending to watch. */ + time_s = localtime(&now); + isdst = (time_s->tm_isdst) ? 1 : 0; + + if (!times->count) + { + tp = dl_new_item(wi, DL_TIME_TYPE); + tp->data.time.label = tzname[isdst]; + tp->data.time.offset = timezone / 60; + tp->data.time.offset = + (isdst) ? (timezone / 60) - 60 : (timezone / 60); + tp->data.time.hour_fmt = 1; + dl_add_to_list(times, tp); + tp = dl_new_item(wi, DL_TIME_TYPE); + tp->data.time.label = tzname[1 - isdst]; + tp->data.time.offset = + (isdst) ? (timezone / 60) : (timezone / 60) - 60; + tp->data.time.hour_fmt = 1; + dl_add_to_list(times, tp); + } + + for (i = 0, tp = times->first; i < times->count; + i++, tp = tp->next) + { + + if (!*tp->data.time.label) + { + tp->data.time.label = tzname[isdst]; + tp->data.time.offset = timezone / 60; + } + + tztime = now - tp->data.time.offset * 60; + time_s = localtime(&tztime); + tp->data.time.hours = time_s->tm_hour; + tp->data.time.minutes = time_s->tm_min; + tp->data.time.seconds = time_s->tm_sec; + tp->data.time.month = time_s->tm_mon + 1; + tp->data.time.day = time_s->tm_mday; + tp->data.time.year = time_s->tm_year % 100; + /* TODO: investigate, see change log about day of week */ + tp->data.time.dow = (time_s->tm_wday + 6) % 7; + tp->data.time.download = 1; +#ifdef DEBUGGING + printf("now %d, offset %d, dz %d, timezone %d\n", now, + tp->data.time.offset, time_s->tm_isdst, timezone); + printf("%d:%d:%d %d/%d/%d DOW %d\n", time_s->tm_hour, + time_s->tm_min, time_s->tm_sec, time_s->tm_mon + 1, + time_s->tm_mday, time_s->tm_year, + (time_s->tm_wday + 6) % 7); +#endif + + } + + return (times); +} + +void Usage() +{ + printf("DataLink Library Karl Hakimian <hakimian@eecs.wsu.edu>\n"); + printf + ("\tIronman support added by David Fries <dfries@mail.win.org>\n"); + printf("Usage: datalink [watch type] [options] [datafile]\n"); + printf + ("watchtype (ironman is default, must be specified before other options)\n"); + printf(" -model70\t use if you have this watch\n"); + printf(" -70\t use if you have this watch\n"); + printf(" -model70\t use if you have this watch\n"); + printf(" -150\t use if you have this watch\n"); + printf(" -model150\t use if you have this watch\n"); + printf(" -150s\t use if you have this watch\n"); + printf(" -model150s\t use if you have this watch\n"); + printf(" -ironman\t use if you have this watch\n"); + printf("options:\n"); + printf("\tNot all options are available for all watches\n"); + printf + ("\tIf you specify any of the send only... options following\n"); + printf("\twill affect what other data is also sent\n"); + printf("\tYou must specify at least one option to send data.\n"); + printf(" -all\tsend all data to watch\n"); + printf(" -db\tsend only database information\n"); + printf(" -db\talso send database information\n"); + printf(" -time\tonly send time information\n"); + printf(" +time\talso send time information\n"); + printf(" -alarm\tonly send alarm information\n"); + printf(" +alarm\talso send alarm information\n"); + printf(" -timer\tonly send timer information\n"); + printf(" +timer\talso send timer information\n"); + printf(" -wristapp\tonly send wristapp information\n"); + printf(" +wristapp\talso send wristapp information\n"); + printf(" -app\tonly send appointment information\n"); + printf(" +app\talso send appointment information\n"); + printf(" -melody\tonly send melody information\n"); + printf(" +melody\talso send melody information\n"); + printf(" -phone\tonly send phone information\n"); + printf(" +phone\talso send phone information\n"); + printf(" -chron\tonly send chronograph information\n"); + printf(" +chron\talso send chronograph information\n"); + printf + (" -system\tonly send system (hour/button beep) information\n"); + printf + (" +system\talso send system (hour/button beep) information\n"); + printf(" -reset\n"); + printf(" +reset\n"); + printf(" -sort-app-by-datetime\n"); + printf(" -sort-app-by-label\n"); + printf(" -sort-todo-by-label\n"); + printf(" -sort-todo-by-prio\n"); + printf(" -sort-phone\n"); + printf(" -sort-anniv-by-date\n"); + printf(" -sort-anniv-by-label\n"); + printf(" -file\t dump data to DEBUGOUTPUT and do not display\n"); + printf(" -serial\t send with the serial link\n"); + printf + ("datafile: If not specified ~/.datalink/datafile is used\n"); + printf + (" If any option is after the datafile, it will be ignored\n"); + printf("Version $Id: setwatch.c,v 1.25 2002/07/21 23:04:49 david Exp $\n"); +} + +// ability to set the time +#define TIME 0x001 +// ability to send alarms +#define ALARM 0x002 +// ability to set appointments +#define APP 0x004 +// ability to send todo +#define TODO 0x008 +// ability to send phone list +#define PHONE 0x010 +// ability to set anniversary +#define ANNIV 0x020 +// ability to set key beep and hour beep +#define SYSTEM 0x040 +// ability to send a program +#define WRISTAPP 0x080 +// ability to set the beep sound +#define MELODY 0x100 +// ability to preset timers and label +#define TIMER 0x200 +// ability to set the lap count and label +#define CHRON 0x400 + +/* All would be 0x755 */ +#define ALL70 0x07F +#define ALL150 0x1FF +#define ALLIRONMAN 0x653 +#define DB 0x03C +/* +#define DEFAULT 0x03F +*/ +#define DEFAULT 0 + +int main(int argc, char **argv) +{ + char *prog = argv[0]; + WatchInfoPtr wi; + ListPtr times, alarms, chron, timers, apps, todos, phones, annivs; + ListPtr system, wristapp, melody; + char datafile[1024]; + int output = SVGA_BLINK; + int flags = DEFAULT; + int (*app_sort) () = dl_app_by_datetime; + int (*todo_sort) () = dl_todo_by_prio; + int (*phone_sort) () = dl_phone_by_label; + int (*anniv_sort) () = dl_anniv_by_date; + int type = DATALINK_IRONMAN; + + while (argc > 1 && (*argv[1] == '-' || *argv[1] == '+')) + { + + if (strcmp("-all", argv[1]) == 0) + { + if (type == DATALINK_70) + flags = ALL70; + if (type == DATALINK_150 || type == DATALINK_150S) + flags = ALL150; + if (type == DATALINK_IRONMAN) + flags = ALLIRONMAN; + } else if (strcmp("-db", argv[1]) == 0) + flags = DB; + else if (strcmp("+db", argv[1]) == 0) + flags |= DB; + else if (strcmp("-time", argv[1]) == 0) + flags = TIME; + else if (strcmp("+time", argv[1]) == 0) + flags |= TIME; + else if (strcmp("-alarm", argv[1]) == 0) + flags = ALARM; + else if (strcmp("+alarm", argv[1]) == 0) + flags |= ALARM; + else if (strcmp("-timer", argv[1]) == 0) + flags = TIMER; + else if (strcmp("+timer", argv[1]) == 0) + flags |= TIMER; + else if (strcmp("-wristapp", argv[1]) == 0) + flags = WRISTAPP; + else if (strcmp("+wristapp", argv[1]) == 0) + flags |= WRISTAPP; + else if (strcmp("-app", argv[1]) == 0) + flags = WRISTAPP; + else if (strcmp("+app", argv[1]) == 0) + flags |= WRISTAPP; + else if (strcmp("-melody", argv[1]) == 0) + flags = MELODY; + else if (strcmp("+melody", argv[1]) == 0) + flags |= MELODY; + /* on IRONMAN to send phone information we must + * also send chron information + */ + else if (strcmp("-phone", argv[1]) == 0) + flags = PHONE | CHRON; + else if (strcmp("+phone", argv[1]) == 0) + flags |= PHONE | CHRON; + else if (strcmp("-chron", argv[1]) == 0) + flags = CHRON; + else if (strcmp("+chron", argv[1]) == 0) + flags |= CHRON; + else if (strcmp("-system", argv[1]) == 0) + flags = SYSTEM; + else if (strcmp("+system", argv[1]) == 0) + flags |= SYSTEM; + else if (strcmp("-reset", argv[1]) == 0) + { + flags = 0; + app_sort = todo_sort = phone_sort = anniv_sort = + NULL; + } else if (strcmp("-sort-app-by-datetime", argv[1]) == 0) + app_sort = dl_app_by_datetime; + else if (strcmp("-sort-app-by-label", argv[1]) == 0) + app_sort = dl_app_by_label; + else if (strcmp("-sort-todo-by-label", argv[1]) == 0) + todo_sort = dl_todo_by_label; + else if (strcmp("-sort-todo-by-prio", argv[1]) == 0) + todo_sort = dl_todo_by_prio; + else if (strcmp("-sort-phone", argv[1]) == 0) + phone_sort = dl_phone_by_label; + else if (strcmp("-sort-anniv-by-date", argv[1]) == 0) + anniv_sort = dl_anniv_by_date; + else if (strcmp("-sort-anniv-by-label", argv[1]) == 0) + anniv_sort = dl_anniv_by_label; + else if (strcmp("-file", argv[1]) == 0) + output = BLINK_FILE; + else if (strcmp("-serial", argv[1]) == 0) + output = SER_BLINK; + else if (strcmp("-model70", argv[1]) == 0) + type = DATALINK_70; + else if (strcmp("-70", argv[1]) == 0) + type = DATALINK_70; + else if (strcmp("-model150", argv[1]) == 0) + type = DATALINK_150; + else if (strcmp("-150", argv[1]) == 0) + type = DATALINK_150; + else if (strcmp("-model150s", argv[1]) == 0) + type = DATALINK_150S; + else if (strcmp("-150s", argv[1]) == 0) + type = DATALINK_150S; + else if (strcmp("-ironman", argv[1]) == 0) + type = DATALINK_IRONMAN; + else if (strcmp("--help", argv[1]) == 0) + { + Usage(); + exit(-1); + } else if (strcmp("-h", argv[1]) == 0) + { + Usage(); + exit(-1); + } else + { + fprintf(stderr, "%s: Unknown option (%s).\n", prog, + argv[1]); + Usage(); + exit(-1); + } + + argc--; + argv++; + } + + if (flags&ALARM && !(flags&PHONE)) + { + printf("Warning: Sending alarm information has been known to " + "corrupt the phone list on the watch, please check " + "and add +phone if you find this is the case.\n"); + } + + if (flags == DEFAULT) + { + Usage(); + printf("**************** ERROR ****************\n"); + printf + ("Error: the given options specify that no data be sent to the watch\n"); + exit(-1); + } + + if (argc == 2) + strcpy(datafile, argv[1]); + else if (argc > 2) + { + fprintf(stderr, "Usage: %s [datafile]\n", argv[0]); + exit(-1); + } else + { + strcpy(datafile, getenv("HOME")); + strcat(datafile, "/"); + strcat(datafile, ".datalink/datafile"); + } +/* + Use my error proc to exit on error and my warn proc to ignore warnings +*/ + dl_set_error(my_error_proc); + dl_set_warn(my_warn_proc); + + wi = dl_read_save(datafile, type, ×, &alarms, &chron, &timers, + &apps, &todos, &phones, &annivs, &system, + &wristapp, &melody); + +/* Mark for download. */ + + if ((flags & CHRON) && chron->count) + chron->download = 1; + + if ((flags & ALARM) && alarms->count) + alarms->download = 1; + + if ((flags & TIMER) && timers->count) + timers->download = 1; + + if ((flags & APP) && apps->count) + { + apps->download = 1; + + if (app_sort) + dl_sort(apps, app_sort); + + } + + if ((flags & TODO) && todos->count) + { + todos->download = 1; + + if (todo_sort) + dl_sort(todos, todo_sort); + + } + + if ((flags & PHONE) && phones->count) + { + phones->download = 1; + + if (phone_sort) + dl_sort(phones, phone_sort); + + } + + if ((flags & ANNIV) && annivs->count) + { + annivs->download = 1; + + if (anniv_sort) + dl_sort(annivs, anniv_sort); + + } + + if ((flags & SYSTEM) && system->count) + system->download = 1; + + if ((flags & WRISTAPP) && wristapp->count) + wristapp->download = 1; + + if ((flags & MELODY) && melody->count) + melody->download = 1; + + if ((flags & TIME)) + { + times = set_time(wi, times); + times->download = 1; + } else + times = NULL; +/* + Send it to the watch +*/ + dl_init_download(wi, times, alarms, chron, timers, apps, todos, + phones, annivs, system, wristapp, melody); + dl_send_data(wi, output); + return 0; +} diff --git a/sgiglblink.c b/sgiglblink.c new file mode 100644 index 0000000..63f5492 --- /dev/null +++ b/sgiglblink.c @@ -0,0 +1,264 @@ +/* + * Copyright 1997-2002 - Harold Zatz <hzatz@alumni.caltech.edu> + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * sgiglblink: SGI / Open GL program from writing to Timex datalink watches + * Note the Open GL implimentation must support switching the buffers durring + * the vertical retrace. This program is SGI specific in the way it selects a + * 60Hz screen refresh. Alternate code just doesn't exist. + */ + +#include <stdio.h> +#include <sys/fcntl.h> +#include <signal.h> +#include <X11/Xlib.h> +#include <GL/glx.h> +#include <GL/gl.h> + +struct packet +{ + char *data; + unsigned char size; + struct packet *next; +}; + +static int attribList[] = { GLX_RGBA, GLX_DOUBLEBUFFER, None }; + +Display *display; +Window window; +int width; +int height; + +#define SPACE 28 + +send(int sync0, unsigned char b0, int sync1, unsigned char b1) +{ + unsigned int mask = 1, scanline = 150; + + glClear(GL_COLOR_BUFFER_BIT); + glColor3f(1.0, 1.0, 1.0); + glBegin(GL_LINES); + + if (sync0) + { + glVertex2d(0, height - scanline); + glVertex2d(width - 1, height - scanline++); + glVertex2d(0, height - scanline); + glVertex2d(width - 1, height - scanline++); + } else + scanline += 2; + + scanline += SPACE; + + while (mask != 256) + { + if (!(b0 & mask)) + { + glVertex2d(0, height - scanline); + glVertex2d(width - 1, height - scanline++); + glVertex2d(0, height - scanline); + glVertex2d(width - 1, height - scanline++); + } else + scanline += 2; + + mask <<= 1; + scanline += SPACE; + } + + mask = 1; + scanline = 598; + + if (sync1) + { + glVertex2d(0, height - scanline); + glVertex2d(width - 1, height - scanline++); + glVertex2d(0, height - scanline); + glVertex2d(width - 1, height - scanline++); + } else + scanline += 2; + + scanline += SPACE; + + while (mask != 256) + { + if (!(b1 & mask)) + { + glVertex2d(0, height - scanline); + glVertex2d(width - 1, height - scanline++); + glVertex2d(0, height - scanline); + glVertex2d(width - 1, height - scanline++); + } else + scanline += 2; + + mask <<= 1; + scanline += SPACE; + } + + glEnd(); + + glXSwapBuffers(display, window); +} + +main(int argc, char **argv) +{ + int fd, status, i; + unsigned char size; + struct packet *last = 0, *cur, *first = 0; + XVisualInfo *visualInfo; + XEvent event; + XSetWindowAttributes attribs; + GLXContext context; + + /* Check proper number of args. */ + if (argc != 2) + { + fprintf(stderr, "Usage: %s data_file\n", argv[0]); + exit(-1); + } + + /* Open the data file. */ + if ((fd = open(argv[1], O_RDONLY)) == -1) + { + fprintf(stderr, "Could not open %s for reading.\n", + argv[1]); + exit(-1); + } + + /* Build some packets. */ + while (status = read(fd, &size, 1) == 1) + { + cur = (struct packet *) malloc(sizeof(struct packet)); + + if (cur == 0) + { + fprintf(stderr, + "Could not allocate packet memory.\n"); + exit(-1); + } + + cur->data = (char *) malloc(size); + cur->data[0] = size; + if (read(fd, cur->data + 1, size - 1) != size - 1) + { + fprintf(stderr, "Could not read packet data.\n"); + exit(-1); + } + + if (cur == 0) + { + fprintf(stderr, + "Could not allocate packet data memory.\n"); + exit(-1); + } + + cur->size = size; + cur->next = 0; + + if (last) + last->next = cur; + else + first = cur; + + last = cur; + } + + if (status != 0) + { + fprintf(stderr, "File error reading from %s.\n", argv[1]); + exit(-1); + } + + close(fd); + + /* Build a window. */ + display = XOpenDisplay(0); + if (!display) + { + fprintf(stderr, "Can't open display\n"); + exit(-1); + } + + /* Set the monitor to a 60 Hz scanrate. */ + system("/usr/gfx/setmon -n 60HZ"); + + /* Get a visual. */ + visualInfo = glXChooseVisual(display, 0, attribList); + + /* Get a colormap for that visual. */ + attribs.colormap = XCreateColormap(display, + DefaultRootWindow(display), + visualInfo->visual, AllocNone); + + /* We want no borders. */ + attribs.border_pixel = 0; + + /* We don't want the window manager mucking with us. */ + attribs.override_redirect = 1; + + width = XDisplayWidth(display, 0); + height = XDisplayHeight(display, 0); + + /* Build a window filling the display in that visual. */ + window = XCreateWindow(display, DefaultRootWindow(display), + 0, 0, width, height, 0, + visualInfo->depth, InputOutput, + visualInfo->visual, + CWBorderPixel | CWColormap | + CWOverrideRedirect, &attribs); + + /* Build a gl context. */ + context = glXCreateContext(display, visualInfo, 0, True); + glXMakeCurrent(display, window, context); + glOrtho(0, width - 1, 0, height - 1, 0, 1); + + /* Map and raise the window. */ + XMapRaised(display, window); + XFlush(display); + + /* Send sync stuff... */ + for (i = 0; i < 400; i++) + send(1, 0x55, 1, 0x55); + + for (i = 0; i < 10; i++) + send(0, 0xff, 0, 0xff); + + for (i = 0; i < 50; i++) + send(1, 0xaa, 0, 0xff); + + for (i = 0; i < 10; i++) + send(0, 0xff, 0, 0xff); + + /* Send the packets. */ + for (cur = first; cur; cur = cur->next) + { + for (i = 0; i < cur->size; i += 2) + if (i - 1 == cur->size) + send(1, cur->data[i], 0, 0xff); + else + send(1, cur->data[i], 1, cur->data[i + 1]); + + for (i = 0; i < 10; i++) + send(0, 0xff, 0, 0xff); + } + + /* Set the monitor back to a 72 Hz scanrate. */ + system("/usr/gfx/setmon -n 72HZ"); +} diff --git a/svgablink.1 b/svgablink.1 new file mode 100644 index 0000000..1e5c748 --- /dev/null +++ b/svgablink.1 @@ -0,0 +1,51 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH DATALINK 1 "December 1, 2001" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp <n> insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +svgablink, serblink \- programs to send raw data to your Timex Datalink watch +.SH SYNOPSIS +.B svgablink +.RI <DATA_FILE> +.br +.B serblink +.RI <DATA_FILE> +.SH DESCRIPTION +This manual page documents briefly the +.B svgablink +and +.B serblink +commands. +This manual page was written for the Debian GNU/Linux distribution +because the original programs do not have manual pages. +.PP +.\" TeX users may be more comfortable with the \fB<whatever>\fP and +.\" \fI<whatever>\fP escape sequences to invode bold face and italics, +.\" respectively. +\fBsvgablink\fP and \fBserblink\fP are programs that send data to the +screen or serial transmitter (respectively) to communicate with a Timex +Datalink watch. They are used by the programs "setwatch" and "settime". +.SH "SEE ALSO" +setwatch(1), settime(1). +.SH AUTHOR +The original datalink software was written by Karl R. Hakimian. +.PP +David Fries <dfries@mail.win.org> added support for the Ironman Datalink to +the datalink software and now is the maintainer. http://datalink.fries.net/ +is the current home. +.PP +This manual page was written by Steaphan Greene <stea@cs.binghamton.edu>, +for the Debian GNU/Linux system (but may be used by others). diff --git a/svgablink.c b/svgablink.c new file mode 100644 index 0000000..185a2ca --- /dev/null +++ b/svgablink.c @@ -0,0 +1,171 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * Linux version of Timex/Microsoft SDK for Timex datalink watches making use + * of the svga library to select a graphic mode and draw on it. + */ + +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/fcntl.h> +#include <signal.h> +#include <sched.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include "datalink.h" + +static void maxPriority(); + +int main(int argc, char **argv) +{ + int oldvt; + unsigned char **data; + char buf[256]; + int fd; + unsigned char size; + int n; + int p = 0; + int type = DATALINK_IRONMAN; + +/* Drop down to user privileges until we need root privs. */ + seteuid(getuid()); + + while (argc > 1 && *argv[1] == '-') + { + + if (strcmp(argv[1], "-ironman") == 0 + || strcmp(argv[1], "-modelironman") == 0) + type = DATALINK_IRONMAN; + else + if (strcmp(argv[1], "-150") == 0 + || strcmp(argv[1], "-model150") == 0) + type = DATALINK_150; + else + if (strcmp(argv[1], "-150s") == 0 + || strcmp(argv[1], "-model150s") == 0) + type = DATALINK_150S; + else + if (strcmp(argv[1], "-70") == 0 + || strcmp(argv[1], "-model70") == 0) + type = DATALINK_70; + else + { + fprintf(stderr, "Unknown option %s.\n", argv[1]); + fprintf(stderr, "Usage: %s [ -ironman | -modelironman | -150 | -model150 | -150s | \n" + "\t-model150s | -70 | -model70 ] datafile\n" + "Version $Id: svgablink.c,v 1.12 2002/07/10 04:27:08 david Exp $\n", argv[0]); + exit(-1); + } + + argc--; + argv++; + } + + if (argc != 2) + { + fprintf(stderr, "Usage: %s data_file\n", argv[0]); + exit(-1); + } + + if ((data = (unsigned char **) calloc(sizeof(unsigned char *), + 1024)) == NULL) + { + fprintf(stderr, "Could not allocate data array.\n"); + exit(-1); + } + +/* Open data file */ + if ((fd = open(argv[1], O_RDONLY)) < 0) + { + fprintf(stderr, "Could not open %s for reading.\n", + argv[1]); + exit(-1); + } + +/* Read in packets. */ + while ((n = read(fd, &size, 1)) == 1) + { + size--; + + if ((n = read(fd, buf, size)) != size) + break; + + size++; + + if ((data[p] = (char *) malloc(size)) == NULL) + { + fprintf(stderr, + "Could not allocate data buffer.\n"); + exit(-1); + } + + *data[p] = size; + memcpy(&data[p++][1], buf, size - 1); + }; + + if (n != 0) + { + fprintf(stderr, "File error reading from %s\n", argv[1]); + fprintf(stderr, "%d, %d, %d\n", n, size, p); + exit(-1); + } + +/* We need to detach from the terminal and our parent may need to wait for us + time to fork a child. */ + + switch (fork()) + { + case 0: + break; + case -1: + perror("fork"); + exit(-1); + default: + exit(0); + } + +/* The rest of this needs to be as root, open_vt, will raise privileges */ + + if ((oldvt = open_vt()) == -1) + exit(-1); + + maxPriority(); + send_data(type, data, p); + close_vt(oldvt); + return 0; +} + + +static void maxPriority() +{ + struct sched_param scp; + + memset(&scp, '\0', sizeof(scp)); + scp.sched_priority = sched_get_priority_max(SCHED_RR); + if (sched_setscheduler(0, SCHED_RR, &scp) < 0) + fprintf(stderr, "WARNING: Cannot set RR-scheduler.\n"); + if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0) + fprintf(stderr, "WARNING: Cannot disable paging.\n"); + +} @@ -0,0 +1,196 @@ +/* + * Copyright 1996-2002 - Karl R. Hakimian and David Fries + * + * This file is part of datalink. + * + * Datalink is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Datalink is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with datalink (see COPYING); if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* + * Linux version of Timex/Microsoft SDK for Timex datalink watches. + * SVGA needs a terminal when going to graphics mode. This will take + * care of that. + */ + +#include <unistd.h> +#include <stdio.h> +#include <sys/vt.h> +#include <sys/ioctl.h> +#include <sys/fcntl.h> + +#define VTFMT "/dev/tty%d" + +int open_vt() +{ + struct vt_stat vts; + int fd; + int newvt; + char buf[1024]; + +/* Need to become root again to deal with vt's */ + seteuid(0); + + if ((fd = open("/dev/tty", O_RDWR)) == -1) + { + perror("open"); + return (-1); + } + +/* See if we are on a VT. */ + if (ioctl(fd, VT_GETSTATE, &vts) == 0) + { + close(fd); + return (0); + } + +/* We are not on a VT, switch to one. */ + close(fd); + + if ((fd = open("/dev/tty0", O_RDWR)) == -1) + { + perror("open"); + return (-1); + } + +/* Get info on current vt. */ + if (ioctl(fd, VT_GETSTATE, &vts) == -1) + { + perror("VT_GETSTATE"); + return (-1); + } + +/* Open a new vt. */ + if (ioctl(fd, VT_OPENQRY, &newvt) == -1) + { + perror("VT_OPENQRY"); + return (-1); + } + + if (newvt == -1) + { + fprintf(stderr, "No free vts to open\n"); + return (-1); + } + +/* Make the new vt, the active vt. */ + if (ioctl(fd, VT_ACTIVATE, newvt) == -1) + { + perror("VT_ACTIVATE"); + return (-1); + } + + if (ioctl(fd, VT_WAITACTIVE, newvt) == -1) + { + perror("VT_WAITACTIVE"); + return (-1); + } + + close(fd); + close(2); + close(1); + close(0); +/* + Detach from controlling terminal here so that we can get a new + controlling terminal. +*/ + setsid(); + sprintf(buf, VTFMT, newvt); + (void) open(buf, O_RDWR); + (void) open(buf, O_RDWR); + (void) open(buf, O_RDWR); + +/* No longer need root privs - drop them*/ + seteuid(getuid()); + + return (vts.v_active); +} + +void close_vt(int oldvt) +{ + int fd; + struct vt_stat vts; + struct vt_mode VT; + int vt; + + if (!oldvt) + return; + +/* Need to become root again to deal with vt's */ + seteuid(0); + +/* SVGA lib sets the tty change mode to require a call back. + * We aren't in graphics mode, so set it back to auto. + */ + if( ioctl(0, VT_GETMODE, &VT) == -1) + { + perror("VT_GETMODE"); + return; + } + + VT.mode = VT_AUTO; + if( ioctl(0, VT_SETMODE, &VT)== -1) + { + perror("VT_SETMODE"); + return; + } + +/* Get info on current vt. */ + if (ioctl(0, VT_GETSTATE, &vts) == -1) + { + perror("VT_GETSTATE"); + return; + } + + vt = vts.v_active; + +/* Switch back to previous vt. */ + + if (ioctl(0, VT_ACTIVATE, oldvt) == -1) + { + perror("VT_ACTIVATE"); + return; + } + + if (ioctl(0, VT_WAITACTIVE, oldvt) == -1) + { + perror("VT_WAITACTIVE"); + return; + } + + close(0); + close(1); + close(2); + setsid(); + +/* Open current vt. */ + if ((fd = open("/dev/tty0", O_RDWR)) == -1) + { + perror("open"); + return; + } + +/* Free up our old vt. */ + if (ioctl(fd, VT_DISALLOCATE, vt) == -1) + { + perror("VT_DISALLOCATE"); + return; + } + + close(fd); + +/* No longer need root privs - drop them*/ + seteuid(getuid()); +} |