/[dtapublic]/to_be_filed/winprojs/scirfmmon/source/c_main.c
ViewVC logotype

Annotation of /to_be_filed/winprojs/scirfmmon/source/c_main.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 22 - (hide annotations) (download)
Sat Oct 8 06:05:29 2016 UTC (8 years ago) by dashley
Original Path: winprojs/scirfmmon/source/c_main.c
File MIME type: text/plain
File size: 110504 byte(s)
Initial commit.
1 dashley 22 //$Header: /home/dashley/cvsrep/e3ft_gpl01/e3ft_gpl01/winprojs/scirfmmon/source/c_main.c,v 1.45 2009/01/17 19:16:15 dashley Exp $
2     //--------------------------------------------------------------------------------
3     //Copyright 2008 David T. Ashley
4     //-------------------------------------------------------------------------------------------------
5     //This source code and any program in which it is compiled/used is provided under the GNU GENERAL
6     //PUBLIC LICENSE, Version 3, full license text below.
7     //-------------------------------------------------------------------------------------------------
8     // GNU GENERAL PUBLIC LICENSE
9     // Version 3, 29 June 2007
10     //
11     // Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
12     // Everyone is permitted to copy and distribute verbatim copies
13     // of this license document, but changing it is not allowed.
14     //
15     // Preamble
16     //
17     // The GNU General Public License is a free, copyleft license for
18     //software and other kinds of works.
19     //
20     // The licenses for most software and other practical works are designed
21     //to take away your freedom to share and change the works. By contrast,
22     //the GNU General Public License is intended to guarantee your freedom to
23     //share and change all versions of a program--to make sure it remains free
24     //software for all its users. We, the Free Software Foundation, use the
25     //GNU General Public License for most of our software; it applies also to
26     //any other work released this way by its authors. You can apply it to
27     //your programs, too.
28     //
29     // When we speak of free software, we are referring to freedom, not
30     //price. Our General Public Licenses are designed to make sure that you
31     //have the freedom to distribute copies of free software (and charge for
32     //them if you wish), that you receive source code or can get it if you
33     //want it, that you can change the software or use pieces of it in new
34     //free programs, and that you know you can do these things.
35     //
36     // To protect your rights, we need to prevent others from denying you
37     //these rights or asking you to surrender the rights. Therefore, you have
38     //certain responsibilities if you distribute copies of the software, or if
39     //you modify it: responsibilities to respect the freedom of others.
40     //
41     // For example, if you distribute copies of such a program, whether
42     //gratis or for a fee, you must pass on to the recipients the same
43     //freedoms that you received. You must make sure that they, too, receive
44     //or can get the source code. And you must show them these terms so they
45     //know their rights.
46     //
47     // Developers that use the GNU GPL protect your rights with two steps:
48     //(1) assert copyright on the software, and (2) offer you this License
49     //giving you legal permission to copy, distribute and/or modify it.
50     //
51     // For the developers' and authors' protection, the GPL clearly explains
52     //that there is no warranty for this free software. For both users' and
53     //authors' sake, the GPL requires that modified versions be marked as
54     //changed, so that their problems will not be attributed erroneously to
55     //authors of previous versions.
56     //
57     // Some devices are designed to deny users access to install or run
58     //modified versions of the software inside them, although the manufacturer
59     //can do so. This is fundamentally incompatible with the aim of
60     //protecting users' freedom to change the software. The systematic
61     //pattern of such abuse occurs in the area of products for individuals to
62     //use, which is precisely where it is most unacceptable. Therefore, we
63     //have designed this version of the GPL to prohibit the practice for those
64     //products. If such problems arise substantially in other domains, we
65     //stand ready to extend this provision to those domains in future versions
66     //of the GPL, as needed to protect the freedom of users.
67     //
68     // Finally, every program is threatened constantly by software patents.
69     //States should not allow patents to restrict development and use of
70     //software on general-purpose computers, but in those that do, we wish to
71     //avoid the special danger that patents applied to a free program could
72     //make it effectively proprietary. To prevent this, the GPL assures that
73     //patents cannot be used to render the program non-free.
74     //
75     // The precise terms and conditions for copying, distribution and
76     //modification follow.
77     //
78     // TERMS AND CONDITIONS
79     //
80     // 0. Definitions.
81     //
82     // "This License" refers to version 3 of the GNU General Public License.
83     //
84     // "Copyright" also means copyright-like laws that apply to other kinds of
85     //works, such as semiconductor masks.
86     //
87     // "The Program" refers to any copyrightable work licensed under this
88     //License. Each licensee is addressed as "you". "Licensees" and
89     //"recipients" may be individuals or organizations.
90     //
91     // To "modify" a work means to copy from or adapt all or part of the work
92     //in a fashion requiring copyright permission, other than the making of an
93     //exact copy. The resulting work is called a "modified version" of the
94     //earlier work or a work "based on" the earlier work.
95     //
96     // A "covered work" means either the unmodified Program or a work based
97     //on the Program.
98     //
99     // To "propagate" a work means to do anything with it that, without
100     //permission, would make you directly or secondarily liable for
101     //infringement under applicable copyright law, except executing it on a
102     //computer or modifying a private copy. Propagation includes copying,
103     //distribution (with or without modification), making available to the
104     //public, and in some countries other activities as well.
105     //
106     // To "convey" a work means any kind of propagation that enables other
107     //parties to make or receive copies. Mere interaction with a user through
108     //a computer network, with no transfer of a copy, is not conveying.
109     //
110     // An interactive user interface displays "Appropriate Legal Notices"
111     //to the extent that it includes a convenient and prominently visible
112     //feature that (1) displays an appropriate copyright notice, and (2)
113     //tells the user that there is no warranty for the work (except to the
114     //extent that warranties are provided), that licensees may convey the
115     //work under this License, and how to view a copy of this License. If
116     //the interface presents a list of user commands or options, such as a
117     //menu, a prominent item in the list meets this criterion.
118     //
119     // 1. Source Code.
120     //
121     // The "source code" for a work means the preferred form of the work
122     //for making modifications to it. "Object code" means any non-source
123     //form of a work.
124     //
125     // A "Standard Interface" means an interface that either is an official
126     //standard defined by a recognized standards body, or, in the case of
127     //interfaces specified for a particular programming language, one that
128     //is widely used among developers working in that language.
129     //
130     // The "System Libraries" of an executable work include anything, other
131     //than the work as a whole, that (a) is included in the normal form of
132     //packaging a Major Component, but which is not part of that Major
133     //Component, and (b) serves only to enable use of the work with that
134     //Major Component, or to implement a Standard Interface for which an
135     //implementation is available to the public in source code form. A
136     //"Major Component", in this context, means a major essential component
137     //(kernel, window system, and so on) of the specific operating system
138     //(if any) on which the executable work runs, or a compiler used to
139     //produce the work, or an object code interpreter used to run it.
140     //
141     // The "Corresponding Source" for a work in object code form means all
142     //the source code needed to generate, install, and (for an executable
143     //work) run the object code and to modify the work, including scripts to
144     //control those activities. However, it does not include the work's
145     //System Libraries, or general-purpose tools or generally available free
146     //programs which are used unmodified in performing those activities but
147     //which are not part of the work. For example, Corresponding Source
148     //includes interface definition files associated with source files for
149     //the work, and the source code for shared libraries and dynamically
150     //linked subprograms that the work is specifically designed to require,
151     //such as by intimate data communication or control flow between those
152     //subprograms and other parts of the work.
153     //
154     // The Corresponding Source need not include anything that users
155     //can regenerate automatically from other parts of the Corresponding
156     //Source.
157     //
158     // The Corresponding Source for a work in source code form is that
159     //same work.
160     //
161     // 2. Basic Permissions.
162     //
163     // All rights granted under this License are granted for the term of
164     //copyright on the Program, and are irrevocable provided the stated
165     //conditions are met. This License explicitly affirms your unlimited
166     //permission to run the unmodified Program. The output from running a
167     //covered work is covered by this License only if the output, given its
168     //content, constitutes a covered work. This License acknowledges your
169     //rights of fair use or other equivalent, as provided by copyright law.
170     //
171     // You may make, run and propagate covered works that you do not
172     //convey, without conditions so long as your license otherwise remains
173     //in force. You may convey covered works to others for the sole purpose
174     //of having them make modifications exclusively for you, or provide you
175     //with facilities for running those works, provided that you comply with
176     //the terms of this License in conveying all material for which you do
177     //not control copyright. Those thus making or running the covered works
178     //for you must do so exclusively on your behalf, under your direction
179     //and control, on terms that prohibit them from making any copies of
180     //your copyrighted material outside their relationship with you.
181     //
182     // Conveying under any other circumstances is permitted solely under
183     //the conditions stated below. Sublicensing is not allowed; section 10
184     //makes it unnecessary.
185     //
186     // 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
187     //
188     // No covered work shall be deemed part of an effective technological
189     //measure under any applicable law fulfilling obligations under article
190     //11 of the WIPO copyright treaty adopted on 20 December 1996, or
191     //similar laws prohibiting or restricting circumvention of such
192     //measures.
193     //
194     // When you convey a covered work, you waive any legal power to forbid
195     //circumvention of technological measures to the extent such circumvention
196     //is effected by exercising rights under this License with respect to
197     //the covered work, and you disclaim any intention to limit operation or
198     //modification of the work as a means of enforcing, against the work's
199     //users, your or third parties' legal rights to forbid circumvention of
200     //technological measures.
201     //
202     // 4. Conveying Verbatim Copies.
203     //
204     // You may convey verbatim copies of the Program's source code as you
205     //receive it, in any medium, provided that you conspicuously and
206     //appropriately publish on each copy an appropriate copyright notice;
207     //keep intact all notices stating that this License and any
208     //non-permissive terms added in accord with section 7 apply to the code;
209     //keep intact all notices of the absence of any warranty; and give all
210     //recipients a copy of this License along with the Program.
211     //
212     // You may charge any price or no price for each copy that you convey,
213     //and you may offer support or warranty protection for a fee.
214     //
215     // 5. Conveying Modified Source Versions.
216     //
217     // You may convey a work based on the Program, or the modifications to
218     //produce it from the Program, in the form of source code under the
219     //terms of section 4, provided that you also meet all of these conditions:
220     //
221     // a) The work must carry prominent notices stating that you modified
222     // it, and giving a relevant date.
223     //
224     // b) The work must carry prominent notices stating that it is
225     // released under this License and any conditions added under section
226     // 7. This requirement modifies the requirement in section 4 to
227     // "keep intact all notices".
228     //
229     // c) You must license the entire work, as a whole, under this
230     // License to anyone who comes into possession of a copy. This
231     // License will therefore apply, along with any applicable section 7
232     // additional terms, to the whole of the work, and all its parts,
233     // regardless of how they are packaged. This License gives no
234     // permission to license the work in any other way, but it does not
235     // invalidate such permission if you have separately received it.
236     //
237     // d) If the work has interactive user interfaces, each must display
238     // Appropriate Legal Notices; however, if the Program has interactive
239     // interfaces that do not display Appropriate Legal Notices, your
240     // work need not make them do so.
241     //
242     // A compilation of a covered work with other separate and independent
243     //works, which are not by their nature extensions of the covered work,
244     //and which are not combined with it such as to form a larger program,
245     //in or on a volume of a storage or distribution medium, is called an
246     //"aggregate" if the compilation and its resulting copyright are not
247     //used to limit the access or legal rights of the compilation's users
248     //beyond what the individual works permit. Inclusion of a covered work
249     //in an aggregate does not cause this License to apply to the other
250     //parts of the aggregate.
251     //
252     // 6. Conveying Non-Source Forms.
253     //
254     // You may convey a covered work in object code form under the terms
255     //of sections 4 and 5, provided that you also convey the
256     //machine-readable Corresponding Source under the terms of this License,
257     //in one of these ways:
258     //
259     // a) Convey the object code in, or embodied in, a physical product
260     // (including a physical distribution medium), accompanied by the
261     // Corresponding Source fixed on a durable physical medium
262     // customarily used for software interchange.
263     //
264     // b) Convey the object code in, or embodied in, a physical product
265     // (including a physical distribution medium), accompanied by a
266     // written offer, valid for at least three years and valid for as
267     // long as you offer spare parts or customer support for that product
268     // model, to give anyone who possesses the object code either (1) a
269     // copy of the Corresponding Source for all the software in the
270     // product that is covered by this License, on a durable physical
271     // medium customarily used for software interchange, for a price no
272     // more than your reasonable cost of physically performing this
273     // conveying of source, or (2) access to copy the
274     // Corresponding Source from a network server at no charge.
275     //
276     // c) Convey individual copies of the object code with a copy of the
277     // written offer to provide the Corresponding Source. This
278     // alternative is allowed only occasionally and noncommercially, and
279     // only if you received the object code with such an offer, in accord
280     // with subsection 6b.
281     //
282     // d) Convey the object code by offering access from a designated
283     // place (gratis or for a charge), and offer equivalent access to the
284     // Corresponding Source in the same way through the same place at no
285     // further charge. You need not require recipients to copy the
286     // Corresponding Source along with the object code. If the place to
287     // copy the object code is a network server, the Corresponding Source
288     // may be on a different server (operated by you or a third party)
289     // that supports equivalent copying facilities, provided you maintain
290     // clear directions next to the object code saying where to find the
291     // Corresponding Source. Regardless of what server hosts the
292     // Corresponding Source, you remain obligated to ensure that it is
293     // available for as long as needed to satisfy these requirements.
294     //
295     // e) Convey the object code using peer-to-peer transmission, provided
296     // you inform other peers where the object code and Corresponding
297     // Source of the work are being offered to the general public at no
298     // charge under subsection 6d.
299     //
300     // A separable portion of the object code, whose source code is excluded
301     //from the Corresponding Source as a System Library, need not be
302     //included in conveying the object code work.
303     //
304     // A "User Product" is either (1) a "consumer product", which means any
305     //tangible personal property which is normally used for personal, family,
306     //or household purposes, or (2) anything designed or sold for incorporation
307     //into a dwelling. In determining whether a product is a consumer product,
308     //doubtful cases shall be resolved in favor of coverage. For a particular
309     //product received by a particular user, "normally used" refers to a
310     //typical or common use of that class of product, regardless of the status
311     //of the particular user or of the way in which the particular user
312     //actually uses, or expects or is expected to use, the product. A product
313     //is a consumer product regardless of whether the product has substantial
314     //commercial, industrial or non-consumer uses, unless such uses represent
315     //the only significant mode of use of the product.
316     //
317     // "Installation Information" for a User Product means any methods,
318     //procedures, authorization keys, or other information required to install
319     //and execute modified versions of a covered work in that User Product from
320     //a modified version of its Corresponding Source. The information must
321     //suffice to ensure that the continued functioning of the modified object
322     //code is in no case prevented or interfered with solely because
323     //modification has been made.
324     //
325     // If you convey an object code work under this section in, or with, or
326     //specifically for use in, a User Product, and the conveying occurs as
327     //part of a transaction in which the right of possession and use of the
328     //User Product is transferred to the recipient in perpetuity or for a
329     //fixed term (regardless of how the transaction is characterized), the
330     //Corresponding Source conveyed under this section must be accompanied
331     //by the Installation Information. But this requirement does not apply
332     //if neither you nor any third party retains the ability to install
333     //modified object code on the User Product (for example, the work has
334     //been installed in ROM).
335     //
336     // The requirement to provide Installation Information does not include a
337     //requirement to continue to provide support service, warranty, or updates
338     //for a work that has been modified or installed by the recipient, or for
339     //the User Product in which it has been modified or installed. Access to a
340     //network may be denied when the modification itself materially and
341     //adversely affects the operation of the network or violates the rules and
342     //protocols for communication across the network.
343     //
344     // Corresponding Source conveyed, and Installation Information provided,
345     //in accord with this section must be in a format that is publicly
346     //documented (and with an implementation available to the public in
347     //source code form), and must require no special password or key for
348     //unpacking, reading or copying.
349     //
350     // 7. Additional Terms.
351     //
352     // "Additional permissions" are terms that supplement the terms of this
353     //License by making exceptions from one or more of its conditions.
354     //Additional permissions that are applicable to the entire Program shall
355     //be treated as though they were included in this License, to the extent
356     //that they are valid under applicable law. If additional permissions
357     //apply only to part of the Program, that part may be used separately
358     //under those permissions, but the entire Program remains governed by
359     //this License without regard to the additional permissions.
360     //
361     // When you convey a copy of a covered work, you may at your option
362     //remove any additional permissions from that copy, or from any part of
363     //it. (Additional permissions may be written to require their own
364     //removal in certain cases when you modify the work.) You may place
365     //additional permissions on material, added by you to a covered work,
366     //for which you have or can give appropriate copyright permission.
367     //
368     // Notwithstanding any other provision of this License, for material you
369     //add to a covered work, you may (if authorized by the copyright holders of
370     //that material) supplement the terms of this License with terms:
371     //
372     // a) Disclaiming warranty or limiting liability differently from the
373     // terms of sections 15 and 16 of this License; or
374     //
375     // b) Requiring preservation of specified reasonable legal notices or
376     // author attributions in that material or in the Appropriate Legal
377     // Notices displayed by works containing it; or
378     //
379     // c) Prohibiting misrepresentation of the origin of that material, or
380     // requiring that modified versions of such material be marked in
381     // reasonable ways as different from the original version; or
382     //
383     // d) Limiting the use for publicity purposes of names of licensors or
384     // authors of the material; or
385     //
386     // e) Declining to grant rights under trademark law for use of some
387     // trade names, trademarks, or service marks; or
388     //
389     // f) Requiring indemnification of licensors and authors of that
390     // material by anyone who conveys the material (or modified versions of
391     // it) with contractual assumptions of liability to the recipient, for
392     // any liability that these contractual assumptions directly impose on
393     // those licensors and authors.
394     //
395     // All other non-permissive additional terms are considered "further
396     //restrictions" within the meaning of section 10. If the Program as you
397     //received it, or any part of it, contains a notice stating that it is
398     //governed by this License along with a term that is a further
399     //restriction, you may remove that term. If a license document contains
400     //a further restriction but permits relicensing or conveying under this
401     //License, you may add to a covered work material governed by the terms
402     //of that license document, provided that the further restriction does
403     //not survive such relicensing or conveying.
404     //
405     // If you add terms to a covered work in accord with this section, you
406     //must place, in the relevant source files, a statement of the
407     //additional terms that apply to those files, or a notice indicating
408     //where to find the applicable terms.
409     //
410     // Additional terms, permissive or non-permissive, may be stated in the
411     //form of a separately written license, or stated as exceptions;
412     //the above requirements apply either way.
413     //
414     // 8. Termination.
415     //
416     // You may not propagate or modify a covered work except as expressly
417     //provided under this License. Any attempt otherwise to propagate or
418     //modify it is void, and will automatically terminate your rights under
419     //this License (including any patent licenses granted under the third
420     //paragraph of section 11).
421     //
422     // However, if you cease all violation of this License, then your
423     //license from a particular copyright holder is reinstated (a)
424     //provisionally, unless and until the copyright holder explicitly and
425     //finally terminates your license, and (b) permanently, if the copyright
426     //holder fails to notify you of the violation by some reasonable means
427     //prior to 60 days after the cessation.
428     //
429     // Moreover, your license from a particular copyright holder is
430     //reinstated permanently if the copyright holder notifies you of the
431     //violation by some reasonable means, this is the first time you have
432     //received notice of violation of this License (for any work) from that
433     //copyright holder, and you cure the violation prior to 30 days after
434     //your receipt of the notice.
435     //
436     // Termination of your rights under this section does not terminate the
437     //licenses of parties who have received copies or rights from you under
438     //this License. If your rights have been terminated and not permanently
439     //reinstated, you do not qualify to receive new licenses for the same
440     //material under section 10.
441     //
442     // 9. Acceptance Not Required for Having Copies.
443     //
444     // You are not required to accept this License in order to receive or
445     //run a copy of the Program. Ancillary propagation of a covered work
446     //occurring solely as a consequence of using peer-to-peer transmission
447     //to receive a copy likewise does not require acceptance. However,
448     //nothing other than this License grants you permission to propagate or
449     //modify any covered work. These actions infringe copyright if you do
450     //not accept this License. Therefore, by modifying or propagating a
451     //covered work, you indicate your acceptance of this License to do so.
452     //
453     // 10. Automatic Licensing of Downstream Recipients.
454     //
455     // Each time you convey a covered work, the recipient automatically
456     //receives a license from the original licensors, to run, modify and
457     //propagate that work, subject to this License. You are not responsible
458     //for enforcing compliance by third parties with this License.
459     //
460     // An "entity transaction" is a transaction transferring control of an
461     //organization, or substantially all assets of one, or subdividing an
462     //organization, or merging organizations. If propagation of a covered
463     //work results from an entity transaction, each party to that
464     //transaction who receives a copy of the work also receives whatever
465     //licenses to the work the party's predecessor in interest had or could
466     //give under the previous paragraph, plus a right to possession of the
467     //Corresponding Source of the work from the predecessor in interest, if
468     //the predecessor has it or can get it with reasonable efforts.
469     //
470     // You may not impose any further restrictions on the exercise of the
471     //rights granted or affirmed under this License. For example, you may
472     //not impose a license fee, royalty, or other charge for exercise of
473     //rights granted under this License, and you may not initiate litigation
474     //(including a cross-claim or counterclaim in a lawsuit) alleging that
475     //any patent claim is infringed by making, using, selling, offering for
476     //sale, or importing the Program or any portion of it.
477     //
478     // 11. Patents.
479     //
480     // A "contributor" is a copyright holder who authorizes use under this
481     //License of the Program or a work on which the Program is based. The
482     //work thus licensed is called the contributor's "contributor version".
483     //
484     // A contributor's "essential patent claims" are all patent claims
485     //owned or controlled by the contributor, whether already acquired or
486     //hereafter acquired, that would be infringed by some manner, permitted
487     //by this License, of making, using, or selling its contributor version,
488     //but do not include claims that would be infringed only as a
489     //consequence of further modification of the contributor version. For
490     //purposes of this definition, "control" includes the right to grant
491     //patent sublicenses in a manner consistent with the requirements of
492     //this License.
493     //
494     // Each contributor grants you a non-exclusive, worldwide, royalty-free
495     //patent license under the contributor's essential patent claims, to
496     //make, use, sell, offer for sale, import and otherwise run, modify and
497     //propagate the contents of its contributor version.
498     //
499     // In the following three paragraphs, a "patent license" is any express
500     //agreement or commitment, however denominated, not to enforce a patent
501     //(such as an express permission to practice a patent or covenant not to
502     //sue for patent infringement). To "grant" such a patent license to a
503     //party means to make such an agreement or commitment not to enforce a
504     //patent against the party.
505     //
506     // If you convey a covered work, knowingly relying on a patent license,
507     //and the Corresponding Source of the work is not available for anyone
508     //to copy, free of charge and under the terms of this License, through a
509     //publicly available network server or other readily accessible means,
510     //then you must either (1) cause the Corresponding Source to be so
511     //available, or (2) arrange to deprive yourself of the benefit of the
512     //patent license for this particular work, or (3) arrange, in a manner
513     //consistent with the requirements of this License, to extend the patent
514     //license to downstream recipients. "Knowingly relying" means you have
515     //actual knowledge that, but for the patent license, your conveying the
516     //covered work in a country, or your recipient's use of the covered work
517     //in a country, would infringe one or more identifiable patents in that
518     //country that you have reason to believe are valid.
519     //
520     // If, pursuant to or in connection with a single transaction or
521     //arrangement, you convey, or propagate by procuring conveyance of, a
522     //covered work, and grant a patent license to some of the parties
523     //receiving the covered work authorizing them to use, propagate, modify
524     //or convey a specific copy of the covered work, then the patent license
525     //you grant is automatically extended to all recipients of the covered
526     //work and works based on it.
527     //
528     // A patent license is "discriminatory" if it does not include within
529     //the scope of its coverage, prohibits the exercise of, or is
530     //conditioned on the non-exercise of one or more of the rights that are
531     //specifically granted under this License. You may not convey a covered
532     //work if you are a party to an arrangement with a third party that is
533     //in the business of distributing software, under which you make payment
534     //to the third party based on the extent of your activity of conveying
535     //the work, and under which the third party grants, to any of the
536     //parties who would receive the covered work from you, a discriminatory
537     //patent license (a) in connection with copies of the covered work
538     //conveyed by you (or copies made from those copies), or (b) primarily
539     //for and in connection with specific products or compilations that
540     //contain the covered work, unless you entered into that arrangement,
541     //or that patent license was granted, prior to 28 March 2007.
542     //
543     // Nothing in this License shall be construed as excluding or limiting
544     //any implied license or other defenses to infringement that may
545     //otherwise be available to you under applicable patent law.
546     //
547     // 12. No Surrender of Others' Freedom.
548     //
549     // If conditions are imposed on you (whether by court order, agreement or
550     //otherwise) that contradict the conditions of this License, they do not
551     //excuse you from the conditions of this License. If you cannot convey a
552     //covered work so as to satisfy simultaneously your obligations under this
553     //License and any other pertinent obligations, then as a consequence you may
554     //not convey it at all. For example, if you agree to terms that obligate you
555     //to collect a royalty for further conveying from those to whom you convey
556     //the Program, the only way you could satisfy both those terms and this
557     //License would be to refrain entirely from conveying the Program.
558     //
559     // 13. Use with the GNU Affero General Public License.
560     //
561     // Notwithstanding any other provision of this License, you have
562     //permission to link or combine any covered work with a work licensed
563     //under version 3 of the GNU Affero General Public License into a single
564     //combined work, and to convey the resulting work. The terms of this
565     //License will continue to apply to the part which is the covered work,
566     //but the special requirements of the GNU Affero General Public License,
567     //section 13, concerning interaction through a network will apply to the
568     //combination as such.
569     //
570     // 14. Revised Versions of this License.
571     //
572     // The Free Software Foundation may publish revised and/or new versions of
573     //the GNU General Public License from time to time. Such new versions will
574     //be similar in spirit to the present version, but may differ in detail to
575     //address new problems or concerns.
576     //
577     // Each version is given a distinguishing version number. If the
578     //Program specifies that a certain numbered version of the GNU General
579     //Public License "or any later version" applies to it, you have the
580     //option of following the terms and conditions either of that numbered
581     //version or of any later version published by the Free Software
582     //Foundation. If the Program does not specify a version number of the
583     //GNU General Public License, you may choose any version ever published
584     //by the Free Software Foundation.
585     //
586     // If the Program specifies that a proxy can decide which future
587     //versions of the GNU General Public License can be used, that proxy's
588     //public statement of acceptance of a version permanently authorizes you
589     //to choose that version for the Program.
590     //
591     // Later license versions may give you additional or different
592     //permissions. However, no additional obligations are imposed on any
593     //author or copyright holder as a result of your choosing to follow a
594     //later version.
595     //
596     // 15. Disclaimer of Warranty.
597     //
598     // THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
599     //APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
600     //HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
601     //OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
602     //THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
603     //PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
604     //IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
605     //ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
606     //
607     // 16. Limitation of Liability.
608     //
609     // IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
610     //WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
611     //THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
612     //GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
613     //USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
614     //DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
615     //PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
616     //EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
617     //SUCH DAMAGES.
618     //
619     // 17. Interpretation of Sections 15 and 16.
620     //
621     // If the disclaimer of warranty and limitation of liability provided
622     //above cannot be given local legal effect according to their terms,
623     //reviewing courts shall apply local law that most closely approximates
624     //an absolute waiver of all civil liability in connection with the
625     //Program, unless a warranty or assumption of liability accompanies a
626     //copy of the Program in return for a fee.
627     //
628     // END OF TERMS AND CONDITIONS
629     //
630     // How to Apply These Terms to Your New Programs
631     //
632     // If you develop a new program, and you want it to be of the greatest
633     //possible use to the public, the best way to achieve this is to make it
634     //free software which everyone can redistribute and change under these terms.
635     //
636     // To do so, attach the following notices to the program. It is safest
637     //to attach them to the start of each source file to most effectively
638     //state the exclusion of warranty; and each file should have at least
639     //the "copyright" line and a pointer to where the full notice is found.
640     //
641     // <one line to give the program's name and a brief idea of what it does.>
642     // Copyright (C) <year> <name of author>
643     //
644     // This program is free software: you can redistribute it and/or modify
645     // it under the terms of the GNU General Public License as published by
646     // the Free Software Foundation, either version 3 of the License, or
647     // (at your option) any later version.
648     //
649     // This program is distributed in the hope that it will be useful,
650     // but WITHOUT ANY WARRANTY; without even the implied warranty of
651     // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
652     // GNU General Public License for more details.
653     //
654     // You should have received a copy of the GNU General Public License
655     // along with this program. If not, see <http://www.gnu.org/licenses/>.
656     //
657     //Also add information on how to contact you by electronic and paper mail.
658     //
659     // If the program does terminal interaction, make it output a short
660     //notice like this when it starts in an interactive mode:
661     //
662     // <program> Copyright (C) <year> <name of author>
663     // This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
664     // This is free software, and you are welcome to redistribute it
665     // under certain conditions; type `show c' for details.
666     //
667     //The hypothetical commands `show w' and `show c' should show the appropriate
668     //parts of the General Public License. Of course, your program's commands
669     //might be different; for a GUI interface, you would use an "about box".
670     //
671     // You should also get your employer (if you work as a programmer) or school,
672     //if any, to sign a "copyright disclaimer" for the program, if necessary.
673     //For more information on this, and how to apply and follow the GNU GPL, see
674     //<http://www.gnu.org/licenses/>.
675     //
676     // The GNU General Public License does not permit incorporating your program
677     //into proprietary programs. If your program is a subroutine library, you
678     //may consider it more useful to permit linking proprietary applications with
679     //the library. If this is what you want to do, use the GNU Lesser General
680     //Public License instead of this License. But first, please read
681     //<http://www.gnu.org/philosophy/why-not-lgpl.html>.
682     //-------------------------------------------------------------------------------------------------
683     //--------------------------------------------------------------------------------
684     //This file is part of scirfmmon.
685     //
686     //scirfmmon is free software: you can redistribute it and/or modify
687     //it under the terms of the GNU General Public License as published by
688     //the Free Software Foundation, either version 3 of the License, or
689     //(at your option) any later version.
690     //
691     //scirfmmon is distributed in the hope that it will be useful,
692     //but WITHOUT ANY WARRANTY; without even the implied warranty of
693     //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
694     //GNU General Public License for more details.
695     //
696     //You should have received a copy of the GNU General Public License
697     //along with scirfmmon (see the file copying.txt). If not,
698     //see <http://www.gnu.org/licenses/>.
699     //--------------------------------------------------------------------------------
700    
701     #define MODULE_C_MAIN
702    
703     #include <signal.h>
704     #include <stdio.h>
705     #include <tchar.h>
706     #include <sys/timeb.h>
707     #include <time.h>
708     #include <windows.h>
709    
710     #include "c_main.h"
711    
712     #include "ccmfatal.h"
713     #include "charfunc.h"
714     #include "config_release.h"
715     #include "config_behavior.h"
716     #include "cw_threads.h"
717     #include "log.h"
718     #include "log_char.h"
719     #include "log_packet.h"
720     #include "log_pkt_int.h"
721     #include "log_sys_int.h"
722     #include "outsf.h"
723     #include "thread_test.h"
724     #include "timefunc.h"
725     #include "vcinfo.h"
726    
727    
728     static volatile LONG ctrl_c_pressed = 0;
729     //Set TRUE if CTRL-C is used. volatile because Win32 spawns a thread on SIGINT.
730    
731     //Signal function called if CTRL-C is used.
732     //
733     void sigfunc_SIGINT(int n)
734     {
735     ctrl_c_pressed = 1;
736     }
737    
738    
739     //Parses a communication port name to see if it is sane. Returns TRUE if sane, FALSE
740     //otherwise.
741     //
742     static int MAIN_C_comport_arg_parse(const wchar_t *s)
743     {
744     char buf[100];
745     size_t i;
746    
747     if (wcslen(s) > 6)
748     {
749     //String too long.
750     return(FALSE);
751     }
752     else if (wcslen(s) < 3)
753     {
754     //String too short.
755     return(FALSE);
756     }
757     else
758     {
759     //Convert to a "normal" string for analysis. There is probably a function for this,
760     //but sprintf() should work quick and dirty.
761     sprintf_s(buf, sizeof(buf), "%S", s);
762    
763     if ((strlen(buf) > 6) || (strlen(buf) < 3))
764     return(FALSE);
765    
766     //The first three characters must be "COM" or similar.
767     if ((buf[0] != 'C') && (buf[0] != 'c'))
768     return(FALSE);
769     if ((buf[1] != 'O') && (buf[1] != 'o'))
770     return(FALSE);
771     if ((buf[2] != 'M') && (buf[2] != 'm'))
772     return(FALSE);
773    
774     //Any remaining characters must be digits.
775     for (i=3; i<strlen(buf); i++)
776     {
777     if (!CHARFUNC_is_digit(buf[i]))
778     return(FALSE);
779     }
780    
781     //If we made it here, looks sane.
782     return(TRUE);
783     }
784     }
785    
786    
787     //Parses a Boolean argument to see if it is sane. Returns 1 if true, 0 if false, or -1 if error.
788     //TRUE can be indicated by 1, Y, y, T, or t. FALSE can be indicated by 0, N, n, F, or f.
789     //
790     static int MAIN_C_bool_arg_parse(const wchar_t *s)
791     {
792     char buf[100];
793    
794     if (wcslen(s) > 1)
795     {
796     //String too long.
797     return(-1);
798     }
799     else if (wcslen(s) < 1)
800     {
801     //String too short.
802     return(-1);
803     }
804     else
805     {
806     //Convert to a "normal" string for analysis. There is probably a function for this,
807     //but sprintf() should work quick and dirty.
808     sprintf_s(buf, sizeof(buf), "%S", s);
809    
810     if ((strlen(buf) > 1) || (strlen(buf) < 1))
811     return(-1);
812    
813     //Check for FALSE, TRUE, etc.
814     if ((buf[0] == '0') || (buf[0] == 'N') || (buf[0] == 'n') || (buf[0] == 'F') || (buf[0] == 'f'))
815     return(0);
816     else if ((buf[0] == '1') || (buf[0] == 'Y') || (buf[0] == 'y') || (buf[0] == 'T') || (buf[0] == 't'))
817     return(1);
818     else
819     return(-1);
820     }
821     }
822    
823    
824    
825     //Inpsects a received TSE and flags it if there is something
826     //amiss.
827     //
828     static void C_MAIN_tse_inspect_and_flag(const QCHAR_TSE *ev)
829     {
830     char bufmsg[200];
831     char buflog[200];
832    
833     if (ev->ev == QCHAR_EV_CHAR)
834     {
835     //This is the normal case. Do exactly nothing.
836     }
837     else if ((ev->ev < 0) || (ev->ev >= QCHAR_EV_MAX))
838     {
839     //The event is wrong. This indicates an internal software error and is fatal.
840     sprintf_s(buflog, sizeof(buflog), "Bad event enum, ch: %d, value: %d. Exiting.", ev->channel, ev->ev);
841     LOG_write_ls(&(ev->ts),
842     LOG_MT_ALERT,
843     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
844     buflog);
845     C_MAIN_pthrd_error_nonspecific = TRUE;
846     }
847     else
848     {
849     //The event is a reportable serial communication error or anomaly.
850     //
851     //First decide what it is.
852     switch(ev->ev)
853     {
854     case QCHAR_EV_BREAK:
855     sprintf_s(bufmsg, sizeof(bufmsg), "Serial BREAK detected, ");
856     break;
857     case QCHAR_EV_FRAME:
858     sprintf_s(bufmsg, sizeof(bufmsg), "Serial framing error detected, ");
859     break;
860     case QCHAR_EV_OVERRUN:
861     sprintf_s(bufmsg, sizeof(bufmsg), "Serial overrun error detected, ");
862     break;
863     case QCHAR_EV_RXOVER:
864     sprintf_s(bufmsg, sizeof(bufmsg), "Serial receive overrun error detected, ");
865     break;
866     case QCHAR_EV_RXPARITY:
867     sprintf_s(bufmsg, sizeof(bufmsg), "Serial parity error detected, ");
868     break;
869     default:
870     sprintf_s(bufmsg, sizeof(bufmsg), "Serious fatal internal software error detected, ");
871     C_MAIN_pthrd_error_nonspecific = TRUE;
872     break;
873     }
874    
875     //Tack on the rest of the message.
876     sprintf_s(buflog, sizeof(buflog), "%sch %d.", bufmsg, ev->channel);
877    
878     //Emit it.
879     LOG_write_ls(&(ev->ts),
880     LOG_MT_ALERT,
881     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
882     buflog);
883     }
884     }
885    
886     //Initializes a DCB per desired settings.
887     //
888     static void C_MAIN_dcb_config(DCB *out_arg)
889     {
890     BOOL rv;
891     size_t n_converted;
892     errno_t ecode;
893     wchar_t wbuf[150];
894    
895     //Be sure nothing funky happens (although function documentation says will always
896     //have terminator on string).
897     wbuf[0] = 0;
898    
899     //Convert the nominal string to the wide character version.
900     ecode = mbstowcs_s(&n_converted, wbuf, sizeof(wbuf)/sizeof(wbuf[0]), CFG_BHV_COMM_SETTINGS, 100);
901     if (ecode)
902     {
903     CCMFATAL_fatal("Failure code from mbstowcs_s().",
904     __FILE__,
905     __LINE__);
906     }
907    
908     //Zero out the DCB and assign its size appropriately. This was copied from the recommendations
909     //in a Microsoft application note.
910     FillMemory(out_arg, sizeof(DCB), 0);
911     out_arg->DCBlength = sizeof(DCB);
912    
913     rv = BuildCommDCB(wbuf, out_arg);
914     if (!rv)
915     {
916     //In this case really have no alternative but to declare a fatal error.
917     CCMFATAL_fatal("Failure code from BuildCommDCB().",
918     __FILE__,
919     __LINE__);
920     }
921    
922     //Be sure that the "Abort On Error" field is set.
923     out_arg->fAbortOnError = TRUE;
924     }
925    
926    
927     int c_main(int argc, _TCHAR* argv[])
928     {
929     int return_value = 0;
930     //Default return is no error.
931     errno_t errno_return;
932     //Return value from functions that return errno_t.
933     int main_loop_exit_flag = FALSE;
934     //TRUE if should exit the main loop.
935     int main_loop_first_time = TRUE;
936     //TRUE if first time through main loop.
937     int must_close_com0 = FALSE;
938     int must_close_com1 = FALSE;
939     //TRUE if must close this port (meaning had successfully opened it).
940     int may_restore_com0_state = FALSE;
941     int may_restore_com1_state = FALSE;
942     //TRUE if state from port has been retrieved and is available to store back
943     //at program termination.
944     int must_end_thread0 = FALSE;
945     int must_end_thread1 = FALSE;
946     //TRUE if must end communication worker threads.
947     int con_write_char_log = FALSE;
948     int con_write_packet_log = TRUE;
949     int con_write_packet_interaction_log = TRUE;
950     int con_write_system_interaction_log = TRUE;
951     //This program should ideally process keystrokes and modify its behavior, i.e.
952     //give the user the ability to dynamically adjust what gets sent to the console.
953     //However, my single attempt to do this didn't go as planned. The variables above
954     //are placeholders for the possibility that this will be added. First one is whether
955     //the character log should be mirrored to the console, the second one is
956     //whether the packet log should be mirrored, third one is whether the packet
957     //interaction log should be mirrored, and the fourth one is whether the system
958     //interaction log should be mirrored.
959    
960     //Be sure the queues are zero'd. I think C guarantees they are, but need to check. These statement
961     //can probably be removed after this is verified.
962     FillMemory(&C_MAIN_tsceq0, sizeof(C_MAIN_tsceq0), 0);
963     FillMemory(&C_MAIN_tsceq1, sizeof(C_MAIN_tsceq1), 0);
964     FillMemory(&C_MAIN_ptceq0, sizeof(C_MAIN_ptceq0), 0);
965     FillMemory(&C_MAIN_ptceq1, sizeof(C_MAIN_ptceq1), 0);
966     FillMemory(&C_MAIN_cceq0_charlog, sizeof(C_MAIN_cceq0_charlog), 0);
967     FillMemory(&C_MAIN_cceq1_charlog, sizeof(C_MAIN_cceq1_charlog), 0);
968     FillMemory(&C_MAIN_cceq0_packetparselog, sizeof(C_MAIN_cceq0_packetparselog), 0);
969     FillMemory(&C_MAIN_cceq1_packetparselog, sizeof(C_MAIN_cceq1_packetparselog), 0);
970    
971     signal(SIGINT, sigfunc_SIGINT);
972     //Set up so that if CTRL-C is used, the passed function is called.
973     //The function is called asynchronously in its own thread.
974    
975     //Form the self identity string.
976     {
977     char self_id_string[100]; //String identifying software, including VC hash.
978     VCINFO_SIGNATURE vcinfo_sig;
979    
980     VCINFO_signature(&vcinfo_sig);
981    
982     sprintf_s(self_id_string, sizeof(self_id_string),
983     #ifdef NDEBUG //If assertions enabled, capital "A" else lower-case "a".
984     "%s, v%d.%d%c (%s, a, %s)",
985     #else
986     "%s, v%d.%d%c (%s, A, %s)",
987     #endif
988     CONFIG_RELEASE_PRODUCT_NAME,
989     CONFIG_RELEASE_VERSION_MAJOR,
990     CONFIG_RELEASE_VERSION_MINOR,
991     CHARFUNC_int_to_lower(CONFIG_RELEASE_VERSION_SUFFIX_ALPHA),
992     __DATE__,
993     vcinfo_sig.sig);
994    
995     //Get the current time.
996     errno_return = _ftime64_s(&C_MAIN_time_current);
997     if (errno_return)
998     CCMFATAL_fatal("Failure code from _ftime64_s().",
999     __FILE__,
1000     __LINE__);
1001    
1002     //Try to open up the log files.
1003     LOG_open(&C_MAIN_time_current, self_id_string);
1004     }
1005    
1006     //Write the first line to the console and all log files.
1007     {
1008     char buf[200];
1009     TIMEFUNC_TIME_ASCII_RESULT ts;
1010    
1011     TIMEFUNC_to_ascii_hr_form(&C_MAIN_time_current, &ts);
1012     strcpy_s(buf, sizeof(buf), "Execution begins on ");
1013     strcat_s(buf, sizeof(buf), ts.result);
1014     strcat_s(buf, sizeof(buf), ".");
1015     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_ALL, buf);
1016     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_ALL,
1017     "This application is multi-threaded (two threads to handle");
1018     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_ALL,
1019     "incoming received characters and one primary thread). Each");
1020     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_ALL,
1021     "thread maintains time separately, so there can be a slight ");
1022     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_ALL,
1023     "discrepancy in timestamps. The primary thread processes");
1024     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_ALL,
1025     "characters that were timestamped as they were queued by the");
1026     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_ALL,
1027     "two serial communication worker threads. Timestamps issued");
1028     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_ALL,
1029     "by the primary thread as it processes characters will thus");
1030     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_ALL,
1031     "be later than the timestamps of the characters it is");
1032     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_ALL,
1033     "processing.");
1034    
1035     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_STDOUT | LOG_LI_COMP,
1036     "");
1037     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_STDOUT | LOG_LI_COMP,
1038     "Use CONTROL-C to terminate this program.");
1039     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_STDOUT | LOG_LI_COMP,
1040     "");
1041     }
1042    
1043     main_loop_exit_flag = FALSE;
1044    
1045     while (! main_loop_exit_flag)
1046     {
1047     //********************************************************************************
1048     //********************************************************************************
1049     //***** T I M E S N A P S H O T *********************************************
1050     //********************************************************************************
1051     //********************************************************************************
1052     //Snapshot the current time.
1053     errno_return = _ftime64_s(&C_MAIN_time_current);
1054    
1055     //Crap out if can't get the time.
1056     if (errno_return)
1057     CCMFATAL_fatal("Failure code from _ftime64_s().",
1058     __FILE__,
1059     __LINE__);
1060    
1061    
1062     //********************************************************************************
1063     //********************************************************************************
1064     //***** F I R S T T I M E A C T I V I T Y ********************************
1065     //********************************************************************************
1066     //********************************************************************************
1067     //This portion of the loop handles the activities that should happen once only,
1068     //first time through. They generally also could have been placed outside the
1069     //loop, but easier to have them occur after the logs are started up.
1070     //
1071     if (main_loop_first_time)
1072     {
1073     //================================================================================
1074     //===== N U M B E R O F P A R A M E T E R S ==============================
1075     //================================================================================
1076     if ((! main_loop_exit_flag) && (argc != 5))
1077     {
1078     char buf_n[100];
1079    
1080     LOG_write_ls(&C_MAIN_time_current,
1081     LOG_MT_ALERT,
1082     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1083     "This program must be invoked as");
1084     LOG_write_ls(&C_MAIN_time_current,
1085     LOG_MT_ALERT,
1086     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1087     "");
1088     sprintf_s(buf_n, sizeof(buf_n), " \"%s PORT0 PORT1 CHARLOGTOCON PACKETLOGTOCON\",", CONFIG_RELEASE_PRODUCT_NAME);
1089     LOG_write_ls(&C_MAIN_time_current,
1090     LOG_MT_ALERT,
1091     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1092     buf_n);
1093     LOG_write_ls(&C_MAIN_time_current,
1094     LOG_MT_ALERT,
1095     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1096     "");
1097     LOG_write_ls(&C_MAIN_time_current,
1098     LOG_MT_ALERT,
1099     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1100     "where \"PORT0\" is the name of the serial port capturing data");
1101     LOG_write_ls(&C_MAIN_time_current,
1102     LOG_MT_ALERT,
1103     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1104     "from the host microcontroller to the RF daughterboard,");
1105     LOG_write_ls(&C_MAIN_time_current,
1106     LOG_MT_ALERT,
1107     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1108     "\"PORT1\" is the name of the serial port capturing data from");
1109     LOG_write_ls(&C_MAIN_time_current,
1110     LOG_MT_ALERT,
1111     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1112     "the RF daughterboard to the host microcontroller,");
1113     LOG_write_ls(&C_MAIN_time_current,
1114     LOG_MT_ALERT,
1115     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1116     "\"CHARLOGTOCON\" is Y/N to indicate whether the character");
1117     LOG_write_ls(&C_MAIN_time_current,
1118     LOG_MT_ALERT,
1119     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1120     "log should be duplicated to the console, and \"PACKETLOGTOCON\"");
1121     LOG_write_ls(&C_MAIN_time_current,
1122     LOG_MT_ALERT,
1123     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1124     "is Y/N to indicate whether the packet log should be");
1125     LOG_write_ls(&C_MAIN_time_current,
1126     LOG_MT_ALERT,
1127     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1128     "duplicated to the console.");
1129     LOG_write_ls(&C_MAIN_time_current,
1130     LOG_MT_ALERT,
1131     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1132     "");
1133     LOG_write_ls(&C_MAIN_time_current,
1134     LOG_MT_ALERT,
1135     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1136     "\"COM3\" is a typical name for a communication port. In");
1137     LOG_write_ls(&C_MAIN_time_current,
1138     LOG_MT_ALERT,
1139     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1140     "Windows, the names of serial ports can typically be found");
1141     LOG_write_ls(&C_MAIN_time_current,
1142     LOG_MT_ALERT,
1143     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1144     "under Control Panel->System->Device Manager->Ports.");
1145     LOG_write_ls(&C_MAIN_time_current,
1146     LOG_MT_ALERT,
1147     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1148     "");
1149     LOG_write_ls(&C_MAIN_time_current,
1150     LOG_MT_ALERT,
1151     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1152     "Exiting.");
1153     LOG_write_ls(&C_MAIN_time_current,
1154     LOG_MT_ALERT,
1155     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1156     "");
1157    
1158     main_loop_exit_flag = TRUE;
1159    
1160     //printf("Exiting clause.\n");
1161     }
1162     //================================================================================
1163     //===== F I R S T P A R A M E T E R P A R S E ============================
1164     //================================================================================
1165     if ((! main_loop_exit_flag) && (!MAIN_C_comport_arg_parse(argv[1])))
1166     {
1167     char buf_n[100];
1168    
1169     sprintf_s(buf_n, sizeof(buf_n), "The first communication port specified (%S) appears", argv[1]);
1170     LOG_write_ls(&C_MAIN_time_current,
1171     LOG_MT_ALERT,
1172     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1173     buf_n);
1174     LOG_write_ls(&C_MAIN_time_current,
1175     LOG_MT_ALERT,
1176     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1177     "to be invalid. Only ports of the form \"COMn\" may be");
1178     LOG_write_ls(&C_MAIN_time_current,
1179     LOG_MT_ALERT,
1180     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1181     "specified.");
1182     LOG_write_ls(&C_MAIN_time_current,
1183     LOG_MT_ALERT,
1184     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1185     "");
1186     LOG_write_ls(&C_MAIN_time_current,
1187     LOG_MT_ALERT,
1188     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1189     "Exiting.");
1190     LOG_write_ls(&C_MAIN_time_current,
1191     LOG_MT_ALERT,
1192     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1193     "");
1194    
1195     main_loop_exit_flag = TRUE;
1196     }
1197     //================================================================================
1198     //===== S E C O N D P A R A M E T E R P A R S E ==========================
1199     //================================================================================
1200     if ((! main_loop_exit_flag) && (!MAIN_C_comport_arg_parse(argv[2])))
1201     {
1202     char buf_n[100];
1203    
1204     sprintf_s(buf_n, sizeof(buf_n), "The second communication port specified (%S) appears", argv[2]);
1205     LOG_write_ls(&C_MAIN_time_current,
1206     LOG_MT_ALERT,
1207     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1208     buf_n);
1209     LOG_write_ls(&C_MAIN_time_current,
1210     LOG_MT_ALERT,
1211     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1212     "to be invalid. Only ports of the form \"COMn\" may be");
1213     LOG_write_ls(&C_MAIN_time_current,
1214     LOG_MT_ALERT,
1215     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1216     "specified.");
1217     LOG_write_ls(&C_MAIN_time_current,
1218     LOG_MT_ALERT,
1219     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1220     "");
1221     LOG_write_ls(&C_MAIN_time_current,
1222     LOG_MT_ALERT,
1223     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1224     "Exiting.");
1225     LOG_write_ls(&C_MAIN_time_current,
1226     LOG_MT_ALERT,
1227     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1228     "");
1229    
1230     main_loop_exit_flag = TRUE;
1231     }
1232     //================================================================================
1233     //===== T H I R D P A R A M E T E R P A R S E ============================
1234     //================================================================================
1235     if (! main_loop_exit_flag)
1236     {
1237     if (MAIN_C_bool_arg_parse(argv[3]) < 0)
1238     {
1239     char buf_n[100];
1240    
1241     sprintf_s(buf_n, sizeof(buf_n), "The CHARLOGTOCON parameter (%S) appears", argv[3]);
1242     LOG_write_ls(&C_MAIN_time_current,
1243     LOG_MT_ALERT,
1244     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1245     buf_n);
1246     LOG_write_ls(&C_MAIN_time_current,
1247     LOG_MT_ALERT,
1248     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1249     "to be invalid.");
1250     LOG_write_ls(&C_MAIN_time_current,
1251     LOG_MT_ALERT,
1252     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1253     "");
1254     LOG_write_ls(&C_MAIN_time_current,
1255     LOG_MT_ALERT,
1256     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1257     "Exiting.");
1258     LOG_write_ls(&C_MAIN_time_current,
1259     LOG_MT_ALERT,
1260     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1261     "");
1262    
1263     main_loop_exit_flag = TRUE;
1264     }
1265     else
1266     {
1267     con_write_char_log = MAIN_C_bool_arg_parse(argv[3]);
1268     }
1269     }
1270     //================================================================================
1271     //===== F O U R T H P A R A M E T E R P A R S E ==========================
1272     //================================================================================
1273     if (! main_loop_exit_flag)
1274     {
1275     if (MAIN_C_bool_arg_parse(argv[4]) < 0)
1276     {
1277     char buf_n[100];
1278    
1279     sprintf_s(buf_n, sizeof(buf_n), "The PACKETLOGTOCON parameter (%S) appears", argv[4]);
1280     LOG_write_ls(&C_MAIN_time_current,
1281     LOG_MT_ALERT,
1282     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1283     buf_n);
1284     LOG_write_ls(&C_MAIN_time_current,
1285     LOG_MT_ALERT,
1286     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1287     "to be invalid.");
1288     LOG_write_ls(&C_MAIN_time_current,
1289     LOG_MT_ALERT,
1290     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1291     "");
1292     LOG_write_ls(&C_MAIN_time_current,
1293     LOG_MT_ALERT,
1294     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1295     "Exiting.");
1296     LOG_write_ls(&C_MAIN_time_current,
1297     LOG_MT_ALERT,
1298     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1299     "");
1300    
1301     main_loop_exit_flag = TRUE;
1302     }
1303     else
1304     {
1305     con_write_packet_log = MAIN_C_bool_arg_parse(argv[4]);
1306     }
1307     }
1308     //================================================================================
1309     //===== F I R S T C O M P O R T O P E N ===============================
1310     //================================================================================
1311     if (! main_loop_exit_flag)
1312     {
1313     size_t n_converted;
1314     wchar_t namebuf[50];
1315    
1316     //Start with the \\.\ sequence (required to handle COM port numbers of 10 or
1317     //larger.
1318     mbstowcs_s(&n_converted, namebuf, sizeof(namebuf)/sizeof(namebuf[0]), "\\\\.\\", 10);
1319    
1320     //Tack on the parameter specified by the user as the COM port name.
1321     wcscat_s(namebuf, sizeof(namebuf)/sizeof(namebuf[0]), argv[1]);
1322    
1323     //Try to open the port.
1324     C_MAIN_hCommPort0 = CreateFile(namebuf,
1325     GENERIC_READ | GENERIC_WRITE,
1326     0,
1327     0,
1328     OPEN_EXISTING,
1329     0,
1330     0);
1331    
1332     if (C_MAIN_hCommPort0 == INVALID_HANDLE_VALUE)
1333     {
1334     char buf_n[100];
1335    
1336     sprintf_s(buf_n, sizeof(buf_n), "Failed to open \"%S\". Exiting.", argv[1]);
1337     LOG_write_ls(&C_MAIN_time_current,
1338     LOG_MT_ALERT,
1339     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1340     buf_n);
1341     LOG_write_ls(&C_MAIN_time_current,
1342     LOG_MT_ALERT,
1343     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1344     "");
1345    
1346     main_loop_exit_flag = TRUE;
1347     }
1348     else
1349     {
1350     char buf_n[100];
1351    
1352     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" opened successfully.", argv[1]);
1353     LOG_write_ls(&C_MAIN_time_current,
1354     LOG_MT_STARTSTOP,
1355     LOG_LI_STDOUT | LOG_LI_COMP,
1356     buf_n);
1357    
1358     must_close_com0 = TRUE;
1359     }
1360     }
1361     //================================================================================
1362     //===== S E C O N D C O M P O R T O P E N =============================
1363     //================================================================================
1364     if (! main_loop_exit_flag)
1365     {
1366     size_t n_converted;
1367     wchar_t namebuf[50];
1368    
1369     //Start with the \\.\ sequence (required to handle COM port numbers of 10 or
1370     //larger.
1371     mbstowcs_s(&n_converted, namebuf, sizeof(namebuf)/sizeof(namebuf[0]), "\\\\.\\", 10);
1372    
1373     //Tack on the parameter specified by the user as the COM port name.
1374     wcscat_s(namebuf, sizeof(namebuf)/sizeof(namebuf[0]), argv[2]);
1375    
1376     //Try to open the port.
1377     C_MAIN_hCommPort1 = CreateFile(namebuf,
1378     GENERIC_READ | GENERIC_WRITE,
1379     0,
1380     0,
1381     OPEN_EXISTING,
1382     0,
1383     0);
1384    
1385     if (C_MAIN_hCommPort1 == INVALID_HANDLE_VALUE)
1386     {
1387     char buf_n[100];
1388    
1389     sprintf_s(buf_n, sizeof(buf_n), "Failed to open \"%S\". Exiting.", argv[2]);
1390     LOG_write_ls(&C_MAIN_time_current,
1391     LOG_MT_ALERT,
1392     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1393     buf_n);
1394     LOG_write_ls(&C_MAIN_time_current,
1395     LOG_MT_ALERT,
1396     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1397     "");
1398    
1399     main_loop_exit_flag = TRUE;
1400     }
1401     else
1402     {
1403     char buf_n[100];
1404    
1405     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" opened successfully.", argv[2]);
1406     LOG_write_ls(&C_MAIN_time_current,
1407     LOG_MT_STARTSTOP,
1408     LOG_LI_STDOUT | LOG_LI_COMP,
1409     buf_n);
1410    
1411     must_close_com1 = TRUE;
1412     }
1413     }
1414     //================================================================================
1415     //===== F I R S T C O M M P O R T S T A T E R E T R I E V A L ======
1416     //================================================================================
1417     if (! main_loop_exit_flag)
1418     {
1419     BOOL rv;
1420     char buf_n[100];
1421    
1422     rv = GetCommState(C_MAIN_hCommPort0, &C_MAIN_CommPort0SavedState);
1423     if (rv)
1424     {
1425     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" state retrieval successful.", argv[1]);
1426     LOG_write_ls(&C_MAIN_time_current,
1427     LOG_MT_STARTSTOP,
1428     LOG_LI_STDOUT | LOG_LI_COMP,
1429     buf_n);
1430    
1431     may_restore_com0_state = TRUE;
1432     }
1433     else
1434     {
1435     sprintf_s(buf_n, sizeof(buf_n), "Failed to retrieve \"%S\" state. Exiting.", argv[1]);
1436     LOG_write_ls(&C_MAIN_time_current,
1437     LOG_MT_ALERT,
1438     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1439     buf_n);
1440    
1441     main_loop_exit_flag = TRUE;
1442     }
1443     }
1444     //================================================================================
1445     //===== S E C O N D C O M M P O R T S T A T E R E T R I E V A L ====
1446     //================================================================================
1447     if (! main_loop_exit_flag)
1448     {
1449     BOOL rv;
1450     char buf_n[100];
1451    
1452     rv = GetCommState(C_MAIN_hCommPort1, &C_MAIN_CommPort1SavedState);
1453     if (rv)
1454     {
1455     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" state retrieval successful.", argv[2]);
1456     LOG_write_ls(&C_MAIN_time_current,
1457     LOG_MT_STARTSTOP,
1458     LOG_LI_STDOUT | LOG_LI_COMP,
1459     buf_n);
1460    
1461     may_restore_com1_state = TRUE;
1462     }
1463     else
1464     {
1465     sprintf_s(buf_n, sizeof(buf_n), "Failed to retrieve \"%S\" state. Exiting.", argv[2]);
1466     LOG_write_ls(&C_MAIN_time_current,
1467     LOG_MT_ALERT,
1468     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1469     buf_n);
1470    
1471     main_loop_exit_flag = TRUE;
1472     }
1473     }
1474     //================================================================================
1475     //===== F I R S T C O M M P O R T S E T U P ===========================
1476     //================================================================================
1477     if (! main_loop_exit_flag)
1478     {
1479     BOOL rv;
1480     DCB dcb_scratch;
1481     char buf_n[100];
1482    
1483     C_MAIN_dcb_config(&dcb_scratch);
1484    
1485     rv = SetCommState(C_MAIN_hCommPort0, &dcb_scratch);
1486    
1487     if (rv)
1488     {
1489     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" setup successful.", argv[1]);
1490     LOG_write_ls(&C_MAIN_time_current,
1491     LOG_MT_STARTSTOP,
1492     LOG_LI_STDOUT | LOG_LI_COMP,
1493     buf_n);
1494     }
1495     else
1496     {
1497     sprintf_s(buf_n, sizeof(buf_n), "Failed to set up \"%S\". Exiting.", argv[1]);
1498     LOG_write_ls(&C_MAIN_time_current,
1499     LOG_MT_ALERT,
1500     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1501     buf_n);
1502    
1503     main_loop_exit_flag = TRUE;
1504     }
1505     }
1506     //================================================================================
1507     //===== S E C O N D C O M M P O R T S E T U P =========================
1508     //================================================================================
1509     if (! main_loop_exit_flag)
1510     {
1511     BOOL rv;
1512     DCB dcb_scratch;
1513     char buf_n[100];
1514    
1515     C_MAIN_dcb_config(&dcb_scratch);
1516    
1517     rv = SetCommState(C_MAIN_hCommPort1, &dcb_scratch);
1518    
1519     if (rv)
1520     {
1521     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" setup successful.", argv[2]);
1522     LOG_write_ls(&C_MAIN_time_current,
1523     LOG_MT_STARTSTOP,
1524     LOG_LI_STDOUT | LOG_LI_COMP,
1525     buf_n);
1526     }
1527     else
1528     {
1529     sprintf_s(buf_n, sizeof(buf_n), "Failed to set up \"%S\". Exiting.", argv[2]);
1530     LOG_write_ls(&C_MAIN_time_current,
1531     LOG_MT_ALERT,
1532     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1533     buf_n);
1534    
1535     main_loop_exit_flag = TRUE;
1536     }
1537     }
1538     //================================================================================
1539     //===== F I R S T C O M M P O R T T I M E O U T S S E T U P ========
1540     //================================================================================
1541     if (! main_loop_exit_flag)
1542     {
1543     BOOL rv;
1544     char buf_n[100];
1545     COMMTIMEOUTS to;
1546    
1547     //Zero out the data structure, just in case the definition changes later, to
1548     //get consistent results.
1549     FillMemory(&to, sizeof(to), 0);
1550    
1551     //Assign the values.
1552     to.ReadIntervalTimeout = CFG_BHV_COMM_TO_READ_INTERVAL_TO;
1553     to.ReadTotalTimeoutMultiplier = CFG_BHV_COMM_TO_READ_TOTAL_TO_MULTIPLIER;
1554     to.ReadTotalTimeoutConstant = CFG_BHV_COMM_TO_READ_TOTAL_TO_CONSTANT;
1555     to.WriteTotalTimeoutMultiplier = CFG_BHV_COMM_TO_WRITE_TOTAL_TO_MULTIPLIER;
1556     to.WriteTotalTimeoutConstant = CFG_BHV_COMM_TO_WRITE_TOTAL_TO_CONSTANT;
1557    
1558     //Do the deed.
1559     rv = SetCommTimeouts(C_MAIN_hCommPort0, &to);
1560    
1561     //Process the result code.
1562     if (rv)
1563     {
1564     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" communication timeout setup successful.", argv[1]);
1565     LOG_write_ls(&C_MAIN_time_current,
1566     LOG_MT_STARTSTOP,
1567     LOG_LI_STDOUT | LOG_LI_COMP,
1568     buf_n);
1569     }
1570     else
1571     {
1572     sprintf_s(buf_n, sizeof(buf_n), "Failed to set up \"%S\" communication timeouts. Exiting.", argv[1]);
1573     LOG_write_ls(&C_MAIN_time_current,
1574     LOG_MT_ALERT,
1575     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1576     buf_n);
1577    
1578     main_loop_exit_flag = TRUE;
1579     }
1580     }
1581     //================================================================================
1582     //===== S E C O N D C O M M P O R T T I M E O U T S S E T U P ======
1583     //================================================================================
1584     if (! main_loop_exit_flag)
1585     {
1586     BOOL rv;
1587     char buf_n[100];
1588     COMMTIMEOUTS to;
1589    
1590     //Zero out the data structure, just in case the definition changes later, to
1591     //get consistent results.
1592     FillMemory(&to, sizeof(to), 0);
1593    
1594     //Assign the values.
1595     to.ReadIntervalTimeout = CFG_BHV_COMM_TO_READ_INTERVAL_TO;
1596     to.ReadTotalTimeoutMultiplier = CFG_BHV_COMM_TO_READ_TOTAL_TO_MULTIPLIER;
1597     to.ReadTotalTimeoutConstant = CFG_BHV_COMM_TO_READ_TOTAL_TO_CONSTANT;
1598     to.WriteTotalTimeoutMultiplier = CFG_BHV_COMM_TO_WRITE_TOTAL_TO_MULTIPLIER;
1599     to.WriteTotalTimeoutConstant = CFG_BHV_COMM_TO_WRITE_TOTAL_TO_CONSTANT;
1600    
1601     //Do the deed.
1602     rv = SetCommTimeouts(C_MAIN_hCommPort1, &to);
1603    
1604     //Process the result code.
1605     if (rv)
1606     {
1607     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" communication timeout setup successful.", argv[2]);
1608     LOG_write_ls(&C_MAIN_time_current,
1609     LOG_MT_STARTSTOP,
1610     LOG_LI_STDOUT | LOG_LI_COMP,
1611     buf_n);
1612     }
1613     else
1614     {
1615     sprintf_s(buf_n, sizeof(buf_n), "Failed to set up \"%S\" communication timeouts. Exiting.", argv[2]);
1616     LOG_write_ls(&C_MAIN_time_current,
1617     LOG_MT_ALERT,
1618     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1619     buf_n);
1620    
1621     main_loop_exit_flag = TRUE;
1622     }
1623     }
1624     //================================================================================
1625     //===== F I R S T C O M M P O R T C O M M M A S K S E T U P =====
1626     //================================================================================
1627     if (! main_loop_exit_flag)
1628     {
1629     BOOL rv;
1630     char buf_n[100];
1631    
1632     //Do the deed.
1633     rv = SetCommMask(C_MAIN_hCommPort0, 0);
1634    
1635     //Process the result code.
1636     if (rv)
1637     {
1638     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" communication comm mask setup successful.", argv[1]);
1639     LOG_write_ls(&C_MAIN_time_current,
1640     LOG_MT_STARTSTOP,
1641     LOG_LI_STDOUT | LOG_LI_COMP,
1642     buf_n);
1643     }
1644     else
1645     {
1646     sprintf_s(buf_n, sizeof(buf_n), "Failed to set up \"%S\" comm mask. Exiting.", argv[1]);
1647     LOG_write_ls(&C_MAIN_time_current,
1648     LOG_MT_ALERT,
1649     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1650     buf_n);
1651    
1652     main_loop_exit_flag = TRUE;
1653     }
1654     }
1655     //================================================================================
1656     //===== S E C O N D C O M M P O R T C O M M M A S K S E T U P ===
1657     //================================================================================
1658     if (! main_loop_exit_flag)
1659     {
1660     BOOL rv;
1661     char buf_n[100];
1662    
1663     //Do the deed.
1664     rv = SetCommMask(C_MAIN_hCommPort1, 0);
1665    
1666     //Process the result code.
1667     if (rv)
1668     {
1669     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" communication comm mask setup successful.", argv[2]);
1670     LOG_write_ls(&C_MAIN_time_current,
1671     LOG_MT_STARTSTOP,
1672     LOG_LI_STDOUT | LOG_LI_COMP,
1673     buf_n);
1674     }
1675     else
1676     {
1677     sprintf_s(buf_n, sizeof(buf_n), "Failed to set up \"%S\" comm mask. Exiting.", argv[2]);
1678     LOG_write_ls(&C_MAIN_time_current,
1679     LOG_MT_ALERT,
1680     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
1681     buf_n);
1682    
1683     main_loop_exit_flag = TRUE;
1684     }
1685     }
1686     //================================================================================
1687     //===== F I R S T C O M M W O R K E R T H R E A D S T A R T ========
1688     //================================================================================
1689     if (! main_loop_exit_flag)
1690     {
1691     C_MAIN_hCwThread0 = CreateThread(
1692     NULL,
1693     0,
1694     CW_THREADS_Cw0,
1695     (LPVOID)0,
1696     0,
1697     &C_MAIN_dwCwThread0Id);
1698     if (C_MAIN_hCwThread0 != NULL)
1699     {
1700     //Success
1701     LOG_write_ls(&C_MAIN_time_current,
1702     LOG_MT_STARTSTOP,
1703     LOG_LI_STDOUT | LOG_LI_COMP,
1704     "Communication worker thread 0 started successfully.");
1705     must_end_thread0 = TRUE;
1706     }
1707     else
1708     {
1709     //Failure
1710     LOG_write_ls(&C_MAIN_time_current,
1711     LOG_MT_ALERT,
1712     LOG_LI_STDOUT | LOG_LI_COMP,
1713     "Failure starting communication worker thread 0. Exiting");
1714     }
1715     }
1716     //================================================================================
1717     //===== S E C O N D C O M M W O R K E R T H R E A D S T A R T ======
1718     //================================================================================
1719     if (! main_loop_exit_flag)
1720     {
1721     C_MAIN_hCwThread1 = CreateThread(
1722     NULL,
1723     0,
1724     CW_THREADS_Cw1,
1725     (LPVOID)0,
1726     0,
1727     &C_MAIN_dwCwThread1Id);
1728     if (C_MAIN_hCwThread1 != NULL)
1729     {
1730     //Success
1731     LOG_write_ls(&C_MAIN_time_current,
1732     LOG_MT_STARTSTOP,
1733     LOG_LI_STDOUT | LOG_LI_COMP,
1734     "Communication worker thread 1 started successfully.");
1735     must_end_thread1 = TRUE;
1736     }
1737     else
1738     {
1739     //Failure
1740     LOG_write_ls(&C_MAIN_time_current,
1741     LOG_MT_ALERT,
1742     LOG_LI_STDOUT | LOG_LI_COMP,
1743     "Failure starting communication worker thread 1. Exiting");
1744     }
1745     }
1746     //================================================================================
1747     //================================================================================
1748     main_loop_first_time = FALSE;
1749     }
1750     //================================================================================
1751     //================================================================================
1752    
1753     //********************************************************************************
1754     //********************************************************************************
1755     //***** T R A N S F E R T O P T C E Q ************************************
1756     //********************************************************************************
1757     //********************************************************************************
1758     //The transfer out of the TSCEQs has to be coordinated with the worker threads,
1759     //hence the use of the semaphore variables. Without coordination, bizarre
1760     //effects could result with interleaving of access.
1761     //
1762     if (! main_loop_exit_flag)
1763     {
1764     //printf("Transfer to PTCEQ.\n");
1765     if (C_MAIN_TsQueueSyncSemaphore0 != 0) //Belongs to primary thread.
1766     {
1767     QCHAR_tsceq_ptceq_transfer(&C_MAIN_tsceq0, &C_MAIN_ptceq0);
1768     C_MAIN_TsQueueSyncSemaphore0 = 0; //Belongs to worker thread.
1769     }
1770     if (C_MAIN_TsQueueSyncSemaphore1 != 0) //Belongs to primary thread.
1771     {
1772     QCHAR_tsceq_ptceq_transfer(&C_MAIN_tsceq1, &C_MAIN_ptceq1);
1773     C_MAIN_TsQueueSyncSemaphore1 = 0; //Belongs to worker thread.
1774     }
1775     }
1776     //
1777     //********************************************************************************
1778     //********************************************************************************
1779     //***** E V E N T F A N O U T ***********************************************
1780     //********************************************************************************
1781     //********************************************************************************
1782     //The incoming events from the communication channels need to be fanned out.
1783     //This involves propagating the events to multiple queues.
1784     //
1785     //This is also a good time to flag any errors related to flag any non-fatal
1786     //errors related to serial communication that might otherwise be missed.
1787     if (! main_loop_exit_flag)
1788     {
1789     QCHAR_TSE tse;
1790    
1791     //printf("Event fanout.\n");
1792    
1793     //Fan out the Channel 0 events.
1794     while(QCHAR_ptceq_nelem(&C_MAIN_ptceq0))
1795     {
1796     QCHAR_ptceq_get(&C_MAIN_ptceq0, &tse);
1797     C_MAIN_tse_inspect_and_flag(&tse);
1798     QCHAR_cceq_put(&C_MAIN_cceq0_charlog, &tse);
1799     QCHAR_cceq_put(&C_MAIN_cceq0_packetparselog, &tse);
1800     }
1801    
1802     //Fan out the Channel 1 events.
1803     while(QCHAR_ptceq_nelem(&C_MAIN_ptceq1))
1804     {
1805     QCHAR_ptceq_get(&C_MAIN_ptceq1, &tse);
1806     C_MAIN_tse_inspect_and_flag(&tse);
1807     QCHAR_cceq_put(&C_MAIN_cceq1_charlog, &tse);
1808     QCHAR_cceq_put(&C_MAIN_cceq1_packetparselog, &tse);
1809     }
1810    
1811     //printf("%d %d %d %d\n",
1812     // QCHAR_cceq_nelem(&C_MAIN_cceq0_charlog),
1813     // QCHAR_cceq_nelem(&C_MAIN_cceq0_packetparselog),
1814     // QCHAR_cceq_nelem(&C_MAIN_cceq1_charlog),
1815     // QCHAR_cceq_nelem(&C_MAIN_cceq1_packetparselog));
1816     }
1817    
1818     //********************************************************************************
1819     //********************************************************************************
1820     //***** C H A R A C T E R L O G G I N G *************************************
1821     //********************************************************************************
1822     //********************************************************************************
1823     //Form the log at the character level. It is the callee's responsibility to
1824     //consume the queues.
1825     //
1826     if (! main_loop_exit_flag)
1827     {
1828     //printf("Character logging.\n");
1829     LOG_CHAR_advance(&C_MAIN_cceq0_charlog,
1830     &C_MAIN_cceq1_charlog,
1831     &C_MAIN_time_current,
1832     con_write_char_log);
1833     }
1834     //
1835     //********************************************************************************
1836     //********************************************************************************
1837     //***** P A C K E T P A R S I N G A N D L O G G I N G ******************
1838     //********************************************************************************
1839     //********************************************************************************
1840     //Form the log at the character level. It is the callee's responsibility to
1841     //consume the queues.
1842     //
1843     if (! main_loop_exit_flag)
1844     {
1845     //printf("Packet logging.\n");
1846     LOG_PACKET_advance(&C_MAIN_cceq0_packetparselog,
1847     &C_MAIN_cceq1_packetparselog,
1848     &C_MAIN_time_current,
1849     con_write_packet_log);
1850     }
1851     //
1852     //**********************************************************************************************
1853     //**********************************************************************************************
1854     //***** P A C K E T I N T E R A C T I O N A N A L Y S I S A N D L O G G I N G *****
1855     //**********************************************************************************************
1856     //**********************************************************************************************
1857     //Form the log at the character level. It is the callee's responsibility to
1858     //consume the queues.
1859     //
1860     //TBD.
1861     //
1862     //********************************************************************************
1863     //********************************************************************************
1864     //***** A L I V E N E S S L O G G I N G *************************************
1865     //********************************************************************************
1866     //********************************************************************************
1867     if (! main_loop_exit_flag)
1868     {
1869     //printf("Aliveness logging.\n");
1870     #if (CFG_BHV_LIVENESS_ANNOUNCE_MOD_TIME > 0)
1871     {
1872     static int state_n = 0;
1873     //Small state machine so that only print the liveness announcement
1874     //once each time the modulo time test is met. Otherwise, would
1875     //print repeatedly for entire second.
1876     char buf_n[100];
1877    
1878     switch(state_n)
1879     {
1880     default:
1881     case 0:
1882     if ((C_MAIN_time_current.time % CFG_BHV_LIVENESS_ANNOUNCE_MOD_TIME) > (CFG_BHV_LIVENESS_ANNOUNCE_MOD_TIME / 2))
1883     state_n = 1;
1884     break;
1885     case 1:
1886     if ((C_MAIN_time_current.time % CFG_BHV_LIVENESS_ANNOUNCE_MOD_TIME) <= (CFG_BHV_LIVENESS_ANNOUNCE_MOD_TIME / 2))
1887     {
1888     sprintf_s(buf_n, sizeof(buf_n), "%s primary thread alive.", CONFIG_RELEASE_PRODUCT_NAME);
1889     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ROUTINE, LOG_LI_ALL,
1890     buf_n);
1891     state_n = 2;
1892     }
1893     break;
1894     case 2:
1895     if ((C_MAIN_time_current.time % CFG_BHV_LIVENESS_ANNOUNCE_MOD_TIME) > (CFG_BHV_LIVENESS_ANNOUNCE_MOD_TIME / 2))
1896     state_n = 1;
1897     break;
1898     }
1899     }
1900     #endif
1901     }
1902    
1903     //********************************************************************************
1904     //********************************************************************************
1905     //***** L O G F I L E F L U S H I N G ************************************
1906     //********************************************************************************
1907     //********************************************************************************
1908     //This ensures that opening the logs concurrently with a text editor will work
1909     //OK.
1910     if (! main_loop_exit_flag)
1911     {
1912     static __time64_t tref = 0;
1913     __time64_t tcmp;
1914    
1915     tcmp = _time64(NULL);
1916    
1917     if ((tcmp - tref) > C_MAIN_FILE_FLUSH_INTERVAL_S)
1918     {
1919     //printf("Log file flush.\n");
1920     LOG_flush();
1921     tref = tcmp;
1922     }
1923     }
1924    
1925     //********************************************************************************
1926     //********************************************************************************
1927     //***** S L A C K **************************************************************
1928     //********************************************************************************
1929     //********************************************************************************
1930     //The rationale for slack is to make the PC overall more responsive in case the
1931     //user is running multiple applications. The queues that by default are set up
1932     //under direct control of the worker threads can handle on the order of 10
1933     //seconds of data. The slack won't cause lost data. Because the queues are
1934     //so large, lost data won't occur until the average rate of data input exceeds
1935     //the average rate at which it can be processed.
1936     //printf("Slack.\n");
1937     Sleep(C_MAIN_SLACK_TIME_MS);
1938     //
1939     //********************************************************************************
1940     //********************************************************************************
1941     //***** L O O P E X I T C R I T E R I A **********************************
1942     //********************************************************************************
1943     //********************************************************************************
1944     //printf("Loop exit criteria.\n");
1945     if ( ctrl_c_pressed
1946     || C_MAIN_queue_overflow
1947     || C_MAIN_overrun_hw_rx
1948     || C_MAIN_pthrd_error_nonspecific
1949     || C_MAIN_wthrd_error_nonspecific
1950     )
1951     {
1952     if (ctrl_c_pressed)
1953     {
1954     main_loop_exit_flag = TRUE;
1955     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_ALL, "CTRL-C pressed. Exiting.");
1956     }
1957     if (C_MAIN_queue_overflow)
1958     {
1959     main_loop_exit_flag = TRUE;
1960     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ALERT, LOG_LI_ALL, "Queue overflow (lost data). Exiting.");
1961     }
1962     if (C_MAIN_overrun_hw_rx)
1963     {
1964     main_loop_exit_flag = TRUE;
1965     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ALERT, LOG_LI_ALL, "Hardware communication buffers have been overrun. Exiting.");
1966     }
1967     if (C_MAIN_pthrd_error_nonspecific)
1968     {
1969     main_loop_exit_flag = TRUE;
1970     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ALERT, LOG_LI_ALL, "Nonspecific error from primary thread. Exiting.");
1971     }
1972     if (C_MAIN_wthrd_error_nonspecific)
1973     {
1974     main_loop_exit_flag = TRUE;
1975     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ALERT, LOG_LI_ALL, "Nonspecific error from worker thread(s). Exiting.");
1976     }
1977     }
1978     }
1979    
1980     //================================================================================
1981     //===== T I M E S N A P S H O T =============================================
1982     //================================================================================
1983     //printf("Time snapshot.\n");
1984     errno_return = _ftime64_s(&C_MAIN_time_current);
1985     if (errno_return)
1986     CCMFATAL_fatal("Failure code from _ftime64_s().",
1987     __FILE__,
1988     __LINE__);
1989    
1990     //================================================================================
1991     //===== T H R E A D 0 T E R M I N A T I O N ==============================
1992     //================================================================================
1993     //Try to end the first communication worker thread if we are so required.
1994     //printf("Thread 0 termination.\n");
1995     if (must_end_thread0)
1996     {
1997     int i = 50;
1998     int killed_gracefully = FALSE;
1999     int status_query_error = FALSE;
2000     BOOL rv;
2001     DWORD exit_code;
2002    
2003     C_MAIN_SigTermCwThread0 = TRUE;
2004    
2005     while((i--) && (!killed_gracefully) && (!status_query_error))
2006     {
2007     Sleep(100);
2008     rv = GetExitCodeThread(C_MAIN_hCwThread0, &exit_code);
2009     if (!rv)
2010     {
2011     //Failure on the function call.
2012     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ALERT, LOG_LI_STDOUT | LOG_LI_ALERT | LOG_LI_COMP,
2013     "Error determining status of worker thread 0. Cannot terminate thread.");
2014     }
2015     else
2016     {
2017     //Success on the function call.
2018     if (exit_code == STILL_ACTIVE)
2019     {
2020     //Can't do anything. Thread still going.
2021     }
2022     else
2023     {
2024     LOG_write_ls(&C_MAIN_time_current,
2025     LOG_MT_STARTSTOP,
2026     LOG_LI_STDOUT | LOG_LI_ALERT | LOG_LI_COMP,
2027     "Worker thread 0 gracefully terminated.");
2028     killed_gracefully = TRUE;
2029     }
2030     }
2031     }
2032    
2033     if ((!killed_gracefully) && (!status_query_error))
2034     {
2035     //Forcible termination.
2036     rv = TerminateThread(C_MAIN_hCwThread0, 0);
2037     if (rv)
2038     {
2039     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ALERT, LOG_LI_STDOUT | LOG_LI_ALERT | LOG_LI_COMP,
2040     "Forced termination of worker thread 0.");
2041     }
2042     else
2043     {
2044     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ALERT, LOG_LI_STDOUT | LOG_LI_ALERT | LOG_LI_COMP,
2045     "Failed call to force termination of worker thread 0.");
2046     }
2047     }
2048    
2049     //In any case, we have no further use for the handle to the thread.
2050     rv = CloseHandle(C_MAIN_hCwThread0);
2051     if (!rv)
2052     {
2053     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ALERT, LOG_LI_STDOUT | LOG_LI_ALERT | LOG_LI_COMP,
2054     "Failed call to close handle of worker thread 0.");
2055     }
2056     }
2057    
2058     //================================================================================
2059     //===== T I M E S N A P S H O T =============================================
2060     //================================================================================
2061     //printf("Time snapshot.\n");
2062     errno_return = _ftime64_s(&C_MAIN_time_current);
2063     if (errno_return)
2064     CCMFATAL_fatal("Failure code from _ftime64_s().",
2065     __FILE__,
2066     __LINE__);
2067    
2068     //================================================================================
2069     //===== T H R E A D 1 T E R M I N A T I O N ==============================
2070     //================================================================================
2071     //printf("Thread 1 termination.\n");
2072     if (must_end_thread1)
2073     {
2074     int i = 50;
2075     int killed_gracefully = FALSE;
2076     int status_query_error = FALSE;
2077     BOOL rv;
2078     DWORD exit_code;
2079    
2080     C_MAIN_SigTermCwThread1 = TRUE;
2081    
2082     while((i--) && (!killed_gracefully) && (!status_query_error))
2083     {
2084     Sleep(100);
2085     rv = GetExitCodeThread(C_MAIN_hCwThread1, &exit_code);
2086     if (!rv)
2087     {
2088     //Failure on the function call.
2089     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ALERT, LOG_LI_STDOUT | LOG_LI_ALERT | LOG_LI_COMP,
2090     "Error determining status of worker thread 1. Cannot terminate thread.");
2091     }
2092     else
2093     {
2094     //Success on the function call.
2095     if (exit_code == STILL_ACTIVE)
2096     {
2097     //Can't do anything. Thread still going.
2098     }
2099     else
2100     {
2101     LOG_write_ls(&C_MAIN_time_current,
2102     LOG_MT_STARTSTOP,
2103     LOG_LI_STDOUT | LOG_LI_ALERT | LOG_LI_COMP,
2104     "Worker thread 1 gracefully terminated.");
2105     killed_gracefully = TRUE;
2106     }
2107     }
2108     }
2109    
2110     if ((!killed_gracefully) && (!status_query_error))
2111     {
2112     //Forcible termination.
2113     rv = TerminateThread(C_MAIN_hCwThread1, 0);
2114     if (rv)
2115     {
2116     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ALERT, LOG_LI_STDOUT | LOG_LI_ALERT | LOG_LI_COMP,
2117     "Forced termination of worker thread 1.");
2118     }
2119     else
2120     {
2121     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ALERT, LOG_LI_STDOUT | LOG_LI_ALERT | LOG_LI_COMP,
2122     "Failed call to force termination of worker thread 1.");
2123     }
2124     }
2125    
2126     //In any case, we have no further use for the handle to the thread.
2127     rv = CloseHandle(C_MAIN_hCwThread1);
2128     if (!rv)
2129     {
2130     LOG_write_ls(&C_MAIN_time_current, LOG_MT_ALERT, LOG_LI_STDOUT | LOG_LI_ALERT | LOG_LI_COMP,
2131     "Failed call to close handle of worker thread 1.");
2132     }
2133     }
2134    
2135     //================================================================================
2136     //===== T I M E S N A P S H O T =============================================
2137     //================================================================================
2138     //printf("Time snapshot.\n");
2139     errno_return = _ftime64_s(&C_MAIN_time_current);
2140     if (errno_return)
2141     CCMFATAL_fatal("Failure code from _ftime64_s().",
2142     __FILE__,
2143     __LINE__);
2144    
2145     //================================================================================
2146     //===== C O M M 0 S T A T E R E S T O R A T I O N =====================
2147     //================================================================================
2148     //printf("COMM 0 state restoration.\n");
2149     if (may_restore_com0_state)
2150     {
2151     BOOL rv;
2152     char buf_n[100];
2153    
2154     rv = SetCommState(C_MAIN_hCommPort0, &C_MAIN_CommPort0SavedState);
2155    
2156     if (rv)
2157     {
2158     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" state restoration successful.", argv[1]);
2159     LOG_write_ls(&C_MAIN_time_current,
2160     LOG_MT_STARTSTOP,
2161     LOG_LI_STDOUT | LOG_LI_COMP,
2162     buf_n);
2163     }
2164     else
2165     {
2166     sprintf_s(buf_n, sizeof(buf_n), "Failed to restore \"%S\" state. Exiting.", argv[1]);
2167     LOG_write_ls(&C_MAIN_time_current,
2168     LOG_MT_ALERT,
2169     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
2170     buf_n);
2171     }
2172     }
2173    
2174     //================================================================================
2175     //===== T I M E S N A P S H O T =============================================
2176     //================================================================================
2177     //printf("Time snapshot.\n");
2178     errno_return = _ftime64_s(&C_MAIN_time_current);
2179     if (errno_return)
2180     CCMFATAL_fatal("Failure code from _ftime64_s().",
2181     __FILE__,
2182     __LINE__);
2183    
2184     //================================================================================
2185     //===== C O M M 1 S T A T E R E S T O R A T I O N =====================
2186     //================================================================================
2187     //printf("COMM 1 state restoration.\n");
2188     if (may_restore_com1_state)
2189     {
2190     BOOL rv;
2191     char buf_n[100];
2192    
2193     rv = SetCommState(C_MAIN_hCommPort1, &C_MAIN_CommPort1SavedState);
2194    
2195     if (rv)
2196     {
2197     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" state restoration successful.", argv[2]);
2198     LOG_write_ls(&C_MAIN_time_current,
2199     LOG_MT_STARTSTOP,
2200     LOG_LI_STDOUT | LOG_LI_COMP,
2201     buf_n);
2202     }
2203     else
2204     {
2205     sprintf_s(buf_n, sizeof(buf_n), "Failed to restore \"%S\" state. Exiting.", argv[2]);
2206     LOG_write_ls(&C_MAIN_time_current,
2207     LOG_MT_ALERT,
2208     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
2209     buf_n);
2210     }
2211     }
2212    
2213     //================================================================================
2214     //===== T I M E S N A P S H O T =============================================
2215     //================================================================================
2216     //printf("Time snapshot.\n");
2217     errno_return = _ftime64_s(&C_MAIN_time_current);
2218     if (errno_return)
2219     CCMFATAL_fatal("Failure code from _ftime64_s().",
2220     __FILE__,
2221     __LINE__);
2222    
2223     //================================================================================
2224     //===== C O M M 0 C L O S U R E ==========================================
2225     //================================================================================
2226     //printf("COMM 0 closure.\n");
2227     if (must_close_com0)
2228     {
2229     BOOL rv;
2230    
2231     rv = CloseHandle(C_MAIN_hCommPort0);
2232    
2233     if (rv)
2234     {
2235     char buf_n[100];
2236    
2237     //Success
2238     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" closed successfully.", argv[1]);
2239     LOG_write_ls(&C_MAIN_time_current,
2240     LOG_MT_STARTSTOP,
2241     LOG_LI_STDOUT | LOG_LI_COMP,
2242     buf_n);
2243     }
2244     else
2245     {
2246     char buf_n[100];
2247    
2248     //Failure
2249     sprintf_s(buf_n, sizeof(buf_n), "Failed to close \"%S\".", argv[1]);
2250     LOG_write_ls(&C_MAIN_time_current,
2251     LOG_MT_ALERT,
2252     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
2253     buf_n);
2254    
2255     }
2256     }
2257    
2258     //================================================================================
2259     //===== T I M E S N A P S H O T =============================================
2260     //================================================================================
2261     //printf("Time snapshot.\n");
2262     errno_return = _ftime64_s(&C_MAIN_time_current);
2263     if (errno_return)
2264     CCMFATAL_fatal("Failure code from _ftime64_s().",
2265     __FILE__,
2266     __LINE__);
2267    
2268     //================================================================================
2269     //===== C O M M 1 C L O S U R E ==========================================
2270     //================================================================================
2271     //printf("COMM 1 closure.\n");
2272     if (must_close_com1)
2273     {
2274     BOOL rv;
2275    
2276     rv = CloseHandle(C_MAIN_hCommPort1);
2277    
2278     if (rv)
2279     {
2280     char buf_n[100];
2281    
2282     //Success
2283     sprintf_s(buf_n, sizeof(buf_n), "\"%S\" closed successfully.", argv[2]);
2284     LOG_write_ls(&C_MAIN_time_current,
2285     LOG_MT_STARTSTOP,
2286     LOG_LI_STDOUT | LOG_LI_COMP,
2287     buf_n);
2288     }
2289     else
2290     {
2291     char buf_n[100];
2292    
2293     //Failure
2294     sprintf_s(buf_n, sizeof(buf_n), "Failed to close \"%S\".", argv[2]);
2295     LOG_write_ls(&C_MAIN_time_current,
2296     LOG_MT_ALERT,
2297     LOG_LI_STDOUT | LOG_LI_COMP | LOG_LI_ALERT,
2298     buf_n);
2299    
2300     }
2301     }
2302    
2303     //Get the current time.
2304     errno_return = _ftime64_s(&C_MAIN_time_current);
2305     if (errno_return)
2306     CCMFATAL_fatal("Failure code from _ftime64_s().",
2307     __FILE__,
2308     __LINE__);
2309    
2310     //Write the last line.
2311     LOG_write_ls(&C_MAIN_time_current, LOG_MT_STARTSTOP, LOG_LI_ALL, "Execution ends.");
2312    
2313     //Close up the log files.
2314     //printf("Log file closure.\n");
2315     LOG_close(&C_MAIN_time_current);
2316    
2317     return(0);
2318     }
2319    
2320    
2321     const char *C_MAIN_cvcinfo(void)
2322     {
2323     return("$Header: /home/dashley/cvsrep/e3ft_gpl01/e3ft_gpl01/winprojs/scirfmmon/source/c_main.c,v 1.45 2009/01/17 19:16:15 dashley Exp $");
2324     }
2325    
2326    
2327     const char *C_MAIN_hvcinfo(void)
2328     {
2329     return(C_MAIN_H_VERSION);
2330     }
2331    
2332    
2333     //$Log: c_main.c,v $
2334     //Revision 1.45 2009/01/17 19:16:15 dashley
2335     //Edits.
2336     //
2337     //Revision 1.44 2009/01/17 06:20:45 dashley
2338     //Edits.
2339     //
2340     //Revision 1.43 2009/01/16 18:18:26 dashley
2341     //Log file flushing added.
2342     //
2343     //Revision 1.42 2009/01/14 00:13:42 dashley
2344     //Is working, but a little rough around the edges.
2345     //
2346     //Revision 1.41 2009/01/12 06:16:42 dashley
2347     //Edits.
2348     //
2349     //Revision 1.40 2009/01/11 18:37:23 dashley
2350     //Edits.
2351     //
2352     //Revision 1.39 2009/01/11 16:53:55 dashley
2353     //Edits.
2354     //
2355     //Revision 1.38 2009/01/11 06:11:31 dashley
2356     //Edits.
2357     //
2358     //Revision 1.37 2009/01/11 05:06:36 dashley
2359     //Edits.
2360     //
2361     //Revision 1.36 2009/01/11 04:10:46 dashley
2362     //Edits.
2363     //
2364     //Revision 1.35 2009/01/09 22:04:42 dashley
2365     //Commit before working at home.
2366     //
2367     //Revision 1.34 2008/12/18 22:00:36 dashley
2368     //Edits.
2369     //
2370     //Revision 1.33 2008/12/18 21:12:59 dashley
2371     //Edits.
2372     //
2373     //Revision 1.32 2008/12/18 19:46:25 dashley
2374     //Substantial edits.
2375     //
2376     //Revision 1.31 2008/12/18 17:18:08 dashley
2377     //Edits.
2378     //
2379     //Revision 1.30 2008/12/18 03:51:02 dashley
2380     //Slack time added in main loop.
2381     //
2382     //Revision 1.29 2008/12/18 03:37:08 dashley
2383     //Updated to set communication mask using SetCommMask().
2384     //
2385     //Revision 1.28 2008/12/18 00:34:28 dashley
2386     //Edits.
2387     //
2388     //Revision 1.27 2008/12/17 23:43:02 dashley
2389     //Edits.
2390     //
2391     //Revision 1.26 2008/12/17 22:46:45 dashley
2392     //Edits.
2393     //
2394     //Revision 1.25 2008/12/17 21:40:57 dashley
2395     //Edits.
2396     //
2397     //Revision 1.24 2008/12/17 17:02:55 dashley
2398     //Configuration of timeouts moved.
2399     //
2400     //Revision 1.23 2008/12/17 05:22:28 dashley
2401     //Edits.
2402     //
2403     //Revision 1.22 2008/12/17 03:17:38 dashley
2404     //Edits.
2405     //
2406     //Revision 1.21 2008/12/17 02:04:29 dashley
2407     //Edits.
2408     //
2409     //Revision 1.20 2008/12/16 22:08:45 dashley
2410     //Edits.
2411     //
2412     //Revision 1.19 2008/12/16 21:59:55 dashley
2413     //Edits.
2414     //
2415     //Revision 1.18 2008/12/16 20:14:19 dashley
2416     //Snapshot of console input (which didn't work as expected). Saving
2417     //this in version control. May come back to it.
2418     //
2419     //Revision 1.17 2008/12/16 19:40:32 dashley
2420     //Safety checkin.
2421     //
2422     //Revision 1.16 2008/12/15 23:21:17 dashley
2423     //Edits.
2424     //
2425     //Revision 1.15 2008/12/15 21:10:08 dashley
2426     //GPL license text added to source code and also to program output.
2427     //
2428     //End of $RCSfile: c_main.c,v $.

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25